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 javax.xml.bind.annotation.XmlAccessType;
020import javax.xml.bind.annotation.XmlAccessorType;
021import javax.xml.bind.annotation.XmlAttribute;
022import javax.xml.bind.annotation.XmlRootElement;
023import javax.xml.bind.annotation.XmlTransient;
024
025import org.apache.camel.CamelContext;
026import org.apache.camel.model.DataFormatDefinition;
027import org.apache.camel.spi.DataFormat;
028import org.apache.camel.spi.Metadata;
029import org.apache.camel.spi.RouteContext;
030import org.apache.camel.util.ObjectHelper;
031
032/**
033 * Json data format
034 *
035 * @version 
036 */
037@Metadata(label = "dataformat,transformation", title = "JSon")
038@XmlRootElement(name = "json")
039@XmlAccessorType(XmlAccessType.FIELD)
040public class JsonDataFormat extends DataFormatDefinition {
041    @XmlAttribute
042    private Boolean prettyPrint;
043    @XmlAttribute @Metadata(defaultValue = "XStream")
044    private JsonLibrary library = JsonLibrary.XStream;
045    @XmlAttribute
046    private String unmarshalTypeName;
047    @XmlTransient
048    private Class<?> unmarshalType;
049    @XmlAttribute
050    private Class<?> jsonView;
051    @XmlAttribute
052    private String include;
053    @XmlAttribute
054    private Boolean allowJmsType;
055    @XmlAttribute
056    private String collectionTypeName;
057    @XmlTransient
058    private Class<?> collectionType;
059    @XmlAttribute
060    private Boolean useList;
061    @XmlAttribute
062    private Boolean enableJaxbAnnotationModule;
063    @XmlAttribute
064    private String moduleClassNames;
065    @XmlAttribute
066    private String moduleRefs;
067    @XmlAttribute
068    private String enableFeatures;
069    @XmlAttribute
070    private String disableFeatures;
071
072    public JsonDataFormat() {
073        super("json");
074    }
075
076    public JsonDataFormat(JsonLibrary library) {
077        this.library = library;
078    }
079
080    public Boolean getPrettyPrint() {
081        return prettyPrint;
082    }
083
084    /**
085     * To enable pretty printing output nicely formatted.
086     * <p/>
087     * Is by default false.
088     */
089    public void setPrettyPrint(Boolean prettyPrint) {
090        this.prettyPrint = prettyPrint;
091    }
092
093    public String getUnmarshalTypeName() {
094        return unmarshalTypeName;
095    }
096
097    /**
098     * Class name of the java type to use when unarmshalling
099     */
100    public void setUnmarshalTypeName(String unmarshalTypeName) {
101        this.unmarshalTypeName = unmarshalTypeName;
102    }
103
104    public Class<?> getUnmarshalType() {
105        return unmarshalType;
106    }
107
108    /**
109     * Class of the java type to use when unarmshalling
110     */
111    public void setUnmarshalType(Class<?> unmarshalType) {
112        this.unmarshalType = unmarshalType;
113    }
114
115    public JsonLibrary getLibrary() {
116        return library;
117    }
118
119    /**
120     * Which json library to use such.
121     * <p/>
122     * Is by default xstream
123     */
124    public void setLibrary(JsonLibrary library) {
125        this.library = library;
126    }
127
128    public Class<?> getJsonView() {
129        return jsonView;
130    }
131
132    /**
133     * When marshalling a POJO to JSON you might want to exclude certain fields from the JSON output.
134     * With Jackson you can use JSON views to accomplish this. This option is to refer to the class
135     * which has @JsonView annotations
136     */
137    public void setJsonView(Class<?> jsonView) {
138        this.jsonView = jsonView;
139    }
140
141    public String getInclude() {
142        return include;
143    }
144
145    /**
146     * If you want to marshal a pojo to JSON, and the pojo has some fields with null values.
147     * And you want to skip these null values, you can set this option to <tt>NOT_NULL</tt>
148     */
149    public void setInclude(String include) {
150        this.include = include;
151    }
152
153    public Boolean getAllowJmsType() {
154        return allowJmsType;
155    }
156
157    /**
158     * Used for JMS users to allow the JMSType header from the JMS spec to specify a FQN classname
159     * to use to unmarshal to.
160     */
161    public void setAllowJmsType(Boolean allowJmsType) {
162        this.allowJmsType = allowJmsType;
163    }
164
165    public String getCollectionTypeName() {
166        return collectionTypeName;
167    }
168
169    /**
170     * Refers to a custom collection type to lookup in the registry to use. This option should rarely be used, but allows
171     * to use different collection types than java.util.Collection based as default.
172     */
173    public void setCollectionTypeName(String collectionTypeName) {
174        this.collectionTypeName = collectionTypeName;
175    }
176
177    public Boolean getUseList() {
178        return useList;
179    }
180
181    /**
182     * To unarmshal to a List of Map or a List of Pojo.
183     */
184    public void setUseList(Boolean useList) {
185        this.useList = useList;
186    }
187
188    public Boolean getEnableJaxbAnnotationModule() {
189        return enableJaxbAnnotationModule;
190    }
191
192    /**
193     * Whether to enable the JAXB annotations module when using jackson. When enabled then JAXB annotations
194     * can be used by Jackson.
195     */
196    public void setEnableJaxbAnnotationModule(Boolean enableJaxbAnnotationModule) {
197        this.enableJaxbAnnotationModule = enableJaxbAnnotationModule;
198    }
199
200    public String getModuleClassNames() {
201        return moduleClassNames;
202    }
203
204    /**
205     * To use custom Jackson modules com.fasterxml.jackson.databind.Module specified as a String with FQN class names.
206     * Multiple classes can be separated by comma.
207     */
208    public void setModuleClassNames(String moduleClassNames) {
209        this.moduleClassNames = moduleClassNames;
210    }
211
212    public String getModuleRefs() {
213        return moduleRefs;
214    }
215
216    /**
217     * To use custom Jackson modules referred from the Camel registry.
218     * Multiple modules can be separated by comma.
219     */
220    public void setModuleRefs(String moduleRefs) {
221        this.moduleRefs = moduleRefs;
222    }
223
224    public String getEnableFeatures() {
225        return enableFeatures;
226    }
227
228    /**
229     * Set of features to enable on the Jackson <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>.
230     * <p/>
231     * The features should be a name that matches a enum from <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>,
232     * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or <tt>com.fasterxml.jackson.databind.MapperFeature</tt>
233     * <p/>
234     * Multiple features can be separated by comma
235     */
236    public void setEnableFeatures(String enableFeatures) {
237        this.enableFeatures = enableFeatures;
238    }
239
240    public String getDisableFeatures() {
241        return disableFeatures;
242    }
243
244    /**
245     * Set of features to disable on the Jackson <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>.
246     * <p/>
247     * The features should be a name that matches a enum from <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>,
248     * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or <tt>com.fasterxml.jackson.databind.MapperFeature</tt>
249     * <p/>
250     * Multiple features can be separated by comma
251     */
252    public void setDisableFeatures(String disableFeatures) {
253        this.disableFeatures = disableFeatures;
254    }
255
256    @Override
257    public String getDataFormatName() {
258        // json data format is special as the name can be from different bundles
259        return "json-" + library.name().toLowerCase();
260    }
261
262    @Override
263    protected DataFormat createDataFormat(RouteContext routeContext) {
264        if (library == JsonLibrary.XStream) {
265            setProperty(routeContext.getCamelContext(), this, "dataFormatName", "json-xstream");
266        } else if (library == JsonLibrary.Jackson) {
267            setProperty(routeContext.getCamelContext(), this, "dataFormatName", "json-jackson");
268        } else {
269            setProperty(routeContext.getCamelContext(), this, "dataFormatName", "json-gson");
270        }
271
272        if (unmarshalType == null && unmarshalTypeName != null) {
273            try {
274                unmarshalType = routeContext.getCamelContext().getClassResolver().resolveMandatoryClass(unmarshalTypeName);
275            } catch (ClassNotFoundException e) {
276                throw ObjectHelper.wrapRuntimeCamelException(e);
277            }
278        }
279        if (collectionType == null && collectionTypeName != null) {
280            try {
281                collectionType = routeContext.getCamelContext().getClassResolver().resolveMandatoryClass(collectionTypeName);
282            } catch (ClassNotFoundException e) {
283                throw ObjectHelper.wrapRuntimeCamelException(e);
284            }
285        }
286
287        return super.createDataFormat(routeContext);
288    }
289
290    @Override
291    protected void configureDataFormat(DataFormat dataFormat, CamelContext camelContext) {
292        if (unmarshalType != null) {
293            setProperty(camelContext, dataFormat, "unmarshalType", unmarshalType);
294        }
295        if (prettyPrint != null) {
296            setProperty(camelContext, dataFormat, "prettyPrint", prettyPrint);
297        }
298        if (jsonView != null) {
299            setProperty(camelContext, dataFormat, "jsonView", jsonView);
300        }
301        if (include != null) {
302            setProperty(camelContext, dataFormat, "include", include);
303        }
304        if (allowJmsType != null) {
305            setProperty(camelContext, dataFormat, "allowJmsType", allowJmsType);
306        }
307        if (collectionType != null) {
308            setProperty(camelContext, dataFormat, "collectionType", collectionType);
309        }
310        if (useList != null) {
311            setProperty(camelContext, dataFormat, "useList", useList);
312        }
313        if (enableJaxbAnnotationModule != null) {
314            setProperty(camelContext, dataFormat, "enableJaxbAnnotationModule", enableJaxbAnnotationModule);
315        }
316        if (moduleClassNames != null) {
317            setProperty(camelContext, dataFormat, "modulesClassNames", moduleClassNames);
318        }
319        if (moduleRefs != null) {
320            setProperty(camelContext, dataFormat, "moduleRefs", moduleRefs);
321        }
322        if (enableFeatures != null) {
323            setProperty(camelContext, dataFormat, "enableFeatures", enableFeatures);
324        }
325        if (disableFeatures != null) {
326            setProperty(camelContext, dataFormat, "disableFeatures", disableFeatures);
327        }
328    }
329
330}