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