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.dataformat;
018
019import java.util.Map;
020import javax.xml.bind.annotation.XmlAccessType;
021import javax.xml.bind.annotation.XmlAccessorType;
022import javax.xml.bind.annotation.XmlAttribute;
023import javax.xml.bind.annotation.XmlRootElement;
024import javax.xml.namespace.QName;
025
026import org.apache.camel.CamelContext;
027import org.apache.camel.model.DataFormatDefinition;
028import org.apache.camel.spi.DataFormat;
029import org.apache.camel.spi.Metadata;
030import org.apache.camel.util.CamelContextHelper;
031import org.apache.camel.util.ObjectHelper;
032
033/**
034 * JAXB data format uses the JAXB2 XML marshalling standard to unmarshal an XML payload into Java objects or to marshal Java objects into an XML payload.
035 *
036 * @version 
037 */
038@Metadata(firstVersion = "1.0.0", label = "dataformat,transformation,xml", title = "JAXB")
039@XmlRootElement(name = "jaxb")
040@XmlAccessorType(XmlAccessType.FIELD)
041public class JaxbDataFormat extends DataFormatDefinition {
042    @XmlAttribute(required = true)
043    private String contextPath;
044    @XmlAttribute
045    private String schema;
046    @XmlAttribute
047    private Boolean prettyPrint;
048    @XmlAttribute
049    private Boolean objectFactory;
050    @XmlAttribute
051    private Boolean ignoreJAXBElement;
052    @XmlAttribute
053    private Boolean mustBeJAXBElement;
054    @XmlAttribute
055    private Boolean filterNonXmlChars;
056    @XmlAttribute
057    private String encoding;
058    @XmlAttribute
059    private Boolean fragment;
060    // Partial encoding
061    @XmlAttribute
062    private String partClass;
063    @XmlAttribute
064    private String partNamespace;
065    @XmlAttribute
066    private String namespacePrefixRef;
067    @XmlAttribute @Metadata(label = "advanced")
068    private String xmlStreamWriterWrapper;
069    @XmlAttribute
070    private String schemaLocation;
071    @XmlAttribute
072    private String noNamespaceSchemaLocation;
073    @XmlAttribute @Metadata(label = "advanced")
074    private String jaxbProviderProperties;
075
076    public JaxbDataFormat() {
077        super("jaxb");
078    }
079
080    public JaxbDataFormat(boolean prettyPrint) {
081        this();
082        setPrettyPrint(prettyPrint);
083    }
084
085    public String getContextPath() {
086        return contextPath;
087    }
088
089    /**
090     * Package name where your JAXB classes are located.
091     */
092    public void setContextPath(String contextPath) {
093        this.contextPath = contextPath;
094    }
095
096    public String getSchema() {
097        return schema;
098    }
099
100    /**
101     * To validate against an existing schema.
102     * Your can use the prefix classpath:, file:* or *http: to specify how the resource should by resolved.
103     * You can separate multiple schema files by using the ',' character.
104     */
105    public void setSchema(String schema) {
106        this.schema = schema;
107    }
108
109    public Boolean getPrettyPrint() {
110        return prettyPrint;
111    }
112
113    /**
114     * To enable pretty printing output nicely formatted.
115     * <p/>
116     * Is by default false.
117     */
118    public void setPrettyPrint(Boolean prettyPrint) {
119        this.prettyPrint = prettyPrint;
120    }
121
122    public Boolean getObjectFactory() {
123        return objectFactory;
124    }
125
126    /**
127     * Whether to allow using ObjectFactory classes to create the POJO classes during marshalling.
128     * This only applies to POJO classes that has not been annotated with JAXB and providing jaxb.index descriptor files.
129     */
130    public void setObjectFactory(Boolean objectFactory) {
131        this.objectFactory = objectFactory;
132    }
133
134    public Boolean getIgnoreJAXBElement() {
135        return ignoreJAXBElement;
136    }
137
138    /**
139     * Whether to ignore JAXBElement elements - only needed to be set to false in very special use-cases.
140     */
141    public void setIgnoreJAXBElement(Boolean ignoreJAXBElement) {
142        this.ignoreJAXBElement = ignoreJAXBElement;
143    }
144
145    public Boolean getMustBeJAXBElement() {
146        return mustBeJAXBElement;
147    }
148
149    /**
150     * Whether marhsalling must be java objects with JAXB annotations. And if not then it fails.
151     * This option can be set to false to relax that, such as when the data is already in XML format.
152     */
153    public void setMustBeJAXBElement(Boolean mustBeJAXBElement) {
154        this.mustBeJAXBElement = mustBeJAXBElement;
155    }
156
157    /**
158     * To turn on marshalling XML fragment trees.
159     * By default JAXB looks for @XmlRootElement annotation on given class to operate on whole XML tree.
160     * This is useful but not always - sometimes generated code does not have @XmlRootElement annotation,
161     * sometimes you need unmarshall only part of tree.
162     * In that case you can use partial unmarshalling. To enable this behaviours you need set property partClass.
163     * Camel will pass this class to JAXB's unmarshaler.
164     */
165    public void setFragment(Boolean fragment) {
166        this.fragment = fragment;
167    }
168    
169    public Boolean getFragment() {
170        return fragment;
171    }
172
173    public Boolean getFilterNonXmlChars() {
174        return filterNonXmlChars;
175    }
176
177    /**
178     * To ignore non xml characheters and replace them with an empty space.
179     */
180    public void setFilterNonXmlChars(Boolean filterNonXmlChars) {
181        this.filterNonXmlChars = filterNonXmlChars;
182    }
183
184    public String getEncoding() {
185        return encoding;
186    }
187
188    /**
189     * To overrule and use a specific encoding
190     */
191    public void setEncoding(String encoding) {
192        this.encoding = encoding;
193    }
194
195    public String getPartClass() {
196        return partClass;
197    }
198
199    /**
200     * Name of class used for fragment parsing.
201     * <p/>
202     * See more details at the fragment option.
203     */
204    public void setPartClass(String partClass) {
205        this.partClass = partClass;
206    }
207
208    public String getPartNamespace() {
209        return partNamespace;
210    }
211
212    /**
213     * XML namespace to use for fragment parsing.
214     * <p/>
215     * See more details at the fragment option.
216     */
217    public void setPartNamespace(String partNamespace) {
218        this.partNamespace = partNamespace;
219    }
220
221    public String getNamespacePrefixRef() {
222        return namespacePrefixRef;
223    }
224
225    /**
226     * When marshalling using JAXB or SOAP then the JAXB implementation will automatic assign namespace prefixes,
227     * such as ns2, ns3, ns4 etc. To control this mapping, Camel allows you to refer to a map which contains the desired mapping.
228     */
229    public void setNamespacePrefixRef(String namespacePrefixRef) {
230        this.namespacePrefixRef = namespacePrefixRef;
231    }
232
233    public String getXmlStreamWriterWrapper() {
234        return xmlStreamWriterWrapper;
235    }
236
237    /**
238     * To use a custom xml stream writer.
239     */
240    public void setXmlStreamWriterWrapper(String xmlStreamWriterWrapperRef) {
241        this.xmlStreamWriterWrapper = xmlStreamWriterWrapperRef;
242    }
243
244    public String getSchemaLocation() {
245        return schemaLocation;
246    }
247
248    /**
249     * To define the location of the schema
250     */
251    public void setSchemaLocation(String schemaLocation) {
252        this.schemaLocation = schemaLocation;
253    }
254
255    public String getNoNamespaceSchemaLocation() {
256        return noNamespaceSchemaLocation;
257    }
258
259    /**
260     * To define the location of the namespaceless schema
261     */
262    public void setNoNamespaceSchemaLocation(String schemaLocation) {
263        this.noNamespaceSchemaLocation = schemaLocation;
264    }
265
266    public String getJaxbProviderProperties() {
267        return jaxbProviderProperties;
268    }
269
270    /**
271     * Refers to a custom java.util.Map to lookup in the registry containing custom JAXB provider properties
272     * to be used with the JAXB marshaller.
273     */
274    public void setJaxbProviderProperties(String jaxbProviderProperties) {
275        this.jaxbProviderProperties = jaxbProviderProperties;
276    }
277
278    @Override
279    protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) {
280        Boolean answer = ObjectHelper.toBoolean(getPrettyPrint());
281        if (answer != null && !answer) {
282            setProperty(camelContext, dataFormat, "prettyPrint", Boolean.FALSE);
283        } else { // the default value is true
284            setProperty(camelContext, dataFormat, "prettyPrint", Boolean.TRUE);
285        }
286        answer = ObjectHelper.toBoolean(getObjectFactory());
287        if (answer != null && !answer) {
288            setProperty(camelContext, dataFormat, "objectFactory", Boolean.FALSE);
289        } else { // the default value is true
290            setProperty(camelContext, dataFormat, "objectFactory", Boolean.TRUE);
291        }
292        answer = ObjectHelper.toBoolean(getIgnoreJAXBElement());
293        if (answer != null && !answer) {
294            setProperty(camelContext, dataFormat, "ignoreJAXBElement", Boolean.FALSE);
295        } else { // the default value is true
296            setProperty(camelContext, dataFormat, "ignoreJAXBElement", Boolean.TRUE);
297        }
298        answer = ObjectHelper.toBoolean(getMustBeJAXBElement());
299        if (answer != null && answer) {
300            setProperty(camelContext, dataFormat, "mustBeJAXBElement", Boolean.TRUE);
301        } else { // the default value is false
302            setProperty(camelContext, dataFormat, "mustBeJAXBElement", Boolean.FALSE);
303        }
304        answer = ObjectHelper.toBoolean(getFilterNonXmlChars());
305        if (answer != null && answer) {
306            setProperty(camelContext, dataFormat, "filterNonXmlChars", Boolean.TRUE);
307        } else { // the default value is false
308            setProperty(camelContext, dataFormat, "filterNonXmlChars", Boolean.FALSE);
309        }
310        answer = ObjectHelper.toBoolean(getFragment());
311        if (answer != null && answer) {
312            setProperty(camelContext, dataFormat, "fragment", Boolean.TRUE);
313        } else { // the default value is false
314            setProperty(camelContext, dataFormat, "fragment", Boolean.FALSE);
315        }
316
317        setProperty(camelContext, dataFormat, "contextPath", contextPath);
318        if (partClass != null) {
319            setProperty(camelContext, dataFormat, "partClass", partClass);
320        }
321        if (partNamespace != null) {
322            setProperty(camelContext, dataFormat, "partNamespace", QName.valueOf(partNamespace));
323        }
324        if (encoding != null) {
325            setProperty(camelContext, dataFormat, "encoding", encoding);
326        }
327        if (namespacePrefixRef != null) {
328            setProperty(camelContext, dataFormat, "namespacePrefixRef", namespacePrefixRef);
329        }
330        if (schema != null) {
331            setProperty(camelContext, dataFormat, "schema", schema);
332        }
333        if (xmlStreamWriterWrapper != null) {
334            setProperty(camelContext, dataFormat, "xmlStreamWriterWrapper", xmlStreamWriterWrapper);
335        }
336        if (schemaLocation != null) {
337            setProperty(camelContext, dataFormat, "schemaLocation", schemaLocation);
338        }
339        if (noNamespaceSchemaLocation != null) {
340            setProperty(camelContext, dataFormat, "noNamespaceSchemaLocation", noNamespaceSchemaLocation);
341        }
342        if (jaxbProviderProperties != null) {
343            Map map = CamelContextHelper.mandatoryLookup(camelContext, jaxbProviderProperties, Map.class);
344            setProperty(camelContext, dataFormat, "jaxbProviderProperties", map);
345        }
346    }
347}