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     */
017    package org.apache.camel.converter.jaxb;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    import javax.xml.bind.JAXBContext;
023    import javax.xml.bind.JAXBElement;
024    import javax.xml.bind.JAXBException;
025    import javax.xml.bind.Marshaller;
026    
027    import org.apache.camel.Exchange;
028    import org.apache.camel.spi.DataFormat;
029    import org.apache.camel.util.IOHelper;
030    
031    /**
032     * A <a href="http://activemq.apache.org/camel/data-format.html">data format</a> ({@link DataFormat})
033     * using JAXB2 to marshal to and from XML
034     *
035     * @version $Revision: 759901 $
036     */
037    public class JaxbDataFormat implements DataFormat {
038        private JAXBContext context;
039        private String contextPath;
040        private boolean prettyPrint = true;
041        private boolean ignoreJAXBElement = true;
042        private String encoding;
043    
044        public JaxbDataFormat() {
045        }
046    
047        public JaxbDataFormat(JAXBContext context) {
048            this.context = context;
049        }
050    
051        public JaxbDataFormat(String contextPath) {
052            this.contextPath = contextPath;
053        }
054    
055        public void marshal(Exchange exchange, Object graph, OutputStream stream) throws IOException {
056            try {
057                // must create a new instance of marshaller as its not thred safe
058                Marshaller marshaller = getContext().createMarshaller();
059    
060                // exchange take precedense over encoding option
061                String charset = exchange.getProperty(Exchange.CHARSET_NAME, String.class);
062                if (charset == null) {
063                    charset = encoding;
064                }
065                if (charset != null) {
066                    marshaller.setProperty(Marshaller.JAXB_ENCODING, charset);
067                }
068    
069                marshaller.marshal(graph, stream);
070    
071            } catch (JAXBException e) {
072                throw IOHelper.createIOException(e);
073            }
074        }
075    
076        public Object unmarshal(Exchange exchange, InputStream stream) throws IOException, ClassNotFoundException {
077            try {
078                // must create a new instance of unmarshaller as its not thred safe
079                Object answer = getContext().createUnmarshaller().unmarshal(stream);
080                if (answer instanceof JAXBElement && isIgnoreJAXBElement()) {
081                    answer = ((JAXBElement)answer).getValue();
082                }
083                return answer;
084            } catch (JAXBException e) {
085                throw IOHelper.createIOException(e);
086            }
087        }    
088    
089        // Properties
090        // -------------------------------------------------------------------------
091        public boolean isIgnoreJAXBElement() {        
092            return ignoreJAXBElement;
093        }
094        
095        public void setIgnoreJAXBElement(boolean flag) {
096            ignoreJAXBElement = flag;
097        }
098        
099        public synchronized JAXBContext getContext() throws JAXBException {
100            if (context == null) {
101                context = createContext();
102            }
103            return context;
104        }
105    
106        public void setContext(JAXBContext context) {
107            this.context = context;
108        }
109    
110        public String getContextPath() {
111            return contextPath;
112        }
113    
114        public void setContextPath(String contextPath) {
115            this.contextPath = contextPath;
116        }
117    
118        public boolean isPrettyPrint() {
119            return prettyPrint;
120        }
121    
122        public void setPrettyPrint(boolean prettyPrint) {
123            this.prettyPrint = prettyPrint;
124        }
125    
126        public String getEncoding() {
127            return encoding;
128        }
129    
130        public void setEncoding(String encoding) {
131            this.encoding = encoding;
132        }
133    
134        protected JAXBContext createContext() throws JAXBException {
135            if (contextPath != null) {
136                return JAXBContext.newInstance(contextPath);
137            } else {
138                return JAXBContext.newInstance();
139            }
140        }
141    }