001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.model;
018
019import java.io.InputStream;
020import java.io.StringReader;
021import java.io.StringWriter;
022import javax.xml.bind.JAXBContext;
023import javax.xml.bind.JAXBException;
024import javax.xml.bind.Marshaller;
025import javax.xml.bind.Unmarshaller;
026
027import org.apache.camel.CamelContext;
028import org.apache.camel.NamedNode;
029
030/**
031 * Helper for the Camel {@link org.apache.camel.model model} classes.
032 */
033public final class ModelHelper {
034
035    private ModelHelper() {
036        // utility class
037    }
038
039    /**
040     * Dumps the definition as XML
041     *
042     * @param definition  the definition, such as a {@link org.apache.camel.NamedNode}
043     * @return            the output in XML (is formatted)
044     * @throws JAXBException is throw if error marshalling to XML
045     */
046    public static String dumpModelAsXml(NamedNode definition) throws JAXBException {
047        JAXBContext jaxbContext = createJaxbContext();
048
049        Marshaller marshaller = jaxbContext.createMarshaller();
050        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
051        StringWriter buffer = new StringWriter();
052        marshaller.marshal(definition, buffer);
053
054        return buffer.toString();
055    }
056
057    /**
058     * Marshal the xml to the model definition
059     *
060     * @param xml the xml
061     * @param type the definition type to return, will throw a {@link ClassCastException} if not the expected type
062     * @return the model definition
063     * @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model
064     */
065    public static <T extends NamedNode> T createModelFromXml(String xml, Class<T> type) throws JAXBException {
066        JAXBContext jaxbContext = createJaxbContext();
067        StringReader reader = new StringReader(xml);
068        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
069        Object result = unmarshaller.unmarshal(reader);
070        reader.close();
071
072        if (result == null) {
073            throw new JAXBException("Cannot unmarshal to " + type + " using JAXB from XML: " + xml);
074        }
075        return type.cast(result);
076    }
077
078    /**
079     * Marshal the xml to the model definition
080     *
081     * @param stream the xml stream
082     * @param type the definition type to return, will throw a {@link ClassCastException} if not the expected type
083     * @return the model definition
084     * @throws javax.xml.bind.JAXBException is thrown if error unmarshalling from xml to model
085     */
086    public static <T extends NamedNode> T createModelFromXml(InputStream stream, Class<T> type) throws JAXBException {
087        JAXBContext jaxbContext = createJaxbContext();
088        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
089        Object result = unmarshaller.unmarshal(stream);
090        return type.cast(result);
091    }
092
093    public static JAXBContext createJaxbContext() throws JAXBException {
094        // must use classloader from CamelContext to have JAXB working
095        return JAXBContext.newInstance(Constants.JAXB_CONTEXT_PACKAGES, CamelContext.class.getClassLoader());
096    }
097}