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.model.DataFormatDefinition; 026import org.apache.camel.spi.Metadata; 027import org.apache.camel.util.CollectionStringBuffer; 028 029/** 030 * Marshal POJOs to JSON and back. 031 */ 032@Metadata(label = "dataformat,transformation,json", title = "JSon") 033@XmlRootElement(name = "json") 034@XmlAccessorType(XmlAccessType.FIELD) 035public class JsonDataFormat extends DataFormatDefinition { 036 @XmlAttribute 037 private String objectMapper; 038 @XmlAttribute 039 @Metadata(javaType = "java.lang.Boolean", defaultValue = "true") 040 private String useDefaultObjectMapper; 041 @XmlAttribute 042 @Metadata(javaType = "java.lang.Boolean") 043 private String prettyPrint; 044 @XmlAttribute 045 @Metadata(defaultValue = "Jackson") 046 private JsonLibrary library = JsonLibrary.Jackson; 047 @XmlAttribute 048 private String unmarshalTypeName; 049 @XmlTransient 050 private Class<?> unmarshalType; 051 @XmlAttribute 052 private Class<?> jsonView; 053 @XmlAttribute 054 private String include; 055 @XmlAttribute 056 @Metadata(javaType = "java.lang.Boolean") 057 private String allowJmsType; 058 @XmlAttribute 059 private String collectionTypeName; 060 @XmlTransient 061 private Class<?> collectionType; 062 @XmlAttribute 063 @Metadata(javaType = "java.lang.Boolean") 064 private String useList; 065 @XmlAttribute 066 private String moduleClassNames; 067 @XmlAttribute 068 private String moduleRefs; 069 @XmlAttribute 070 private String enableFeatures; 071 @XmlAttribute 072 private String disableFeatures; 073 @XmlAttribute 074 private String permissions; 075 @XmlAttribute 076 @Metadata(javaType = "java.lang.Boolean") 077 private String allowUnmarshallType; 078 @XmlAttribute 079 private String timezone; 080 @XmlAttribute 081 @Metadata(javaType = "java.lang.Boolean", defaultValue = "false") 082 private String autoDiscoverObjectMapper; 083 @XmlAttribute 084 @Metadata(javaType = "java.lang.Boolean", defaultValue = "false") 085 private String dropRootNode; 086 087 public JsonDataFormat() { 088 super("json"); 089 } 090 091 public JsonDataFormat(JsonLibrary library) { 092 this.library = library; 093 } 094 095 public String getObjectMapper() { 096 return objectMapper; 097 } 098 099 /** 100 * Lookup and use the existing ObjectMapper with the given id when using 101 * Jackson. 102 */ 103 public void setObjectMapper(String objectMapper) { 104 this.objectMapper = objectMapper; 105 } 106 107 public String getUseDefaultObjectMapper() { 108 return useDefaultObjectMapper; 109 } 110 111 /** 112 * Whether to lookup and use default Jackson ObjectMapper from the registry. 113 */ 114 public void setUseDefaultObjectMapper(String useDefaultObjectMapper) { 115 this.useDefaultObjectMapper = useDefaultObjectMapper; 116 } 117 118 public String getPrettyPrint() { 119 return prettyPrint; 120 } 121 122 /** 123 * To enable pretty printing output nicely formatted. 124 * <p/> 125 * Is by default false. 126 */ 127 public void setPrettyPrint(String prettyPrint) { 128 this.prettyPrint = prettyPrint; 129 } 130 131 public String getUnmarshalTypeName() { 132 return unmarshalTypeName; 133 } 134 135 /** 136 * Class name of the java type to use when unmarshalling 137 */ 138 public void setUnmarshalTypeName(String unmarshalTypeName) { 139 this.unmarshalTypeName = unmarshalTypeName; 140 } 141 142 public Class<?> getUnmarshalType() { 143 return unmarshalType; 144 } 145 146 /** 147 * Class of the java type to use when unmarshalling 148 */ 149 public void setUnmarshalType(Class<?> unmarshalType) { 150 this.unmarshalType = unmarshalType; 151 } 152 153 public JsonLibrary getLibrary() { 154 return library; 155 } 156 157 /** 158 * Which json library to use. 159 */ 160 public void setLibrary(JsonLibrary library) { 161 this.library = library; 162 } 163 164 public Class<?> getJsonView() { 165 return jsonView; 166 } 167 168 /** 169 * When marshalling a POJO to JSON you might want to exclude certain fields 170 * from the JSON output. With Jackson you can use JSON views to accomplish 171 * this. This option is to refer to the class which has @JsonView 172 * annotations 173 */ 174 public void setJsonView(Class<?> jsonView) { 175 this.jsonView = jsonView; 176 } 177 178 public String getInclude() { 179 return include; 180 } 181 182 /** 183 * If you want to marshal a pojo to JSON, and the pojo has some fields with 184 * null values. And you want to skip these null values, you can set this 185 * option to <tt>NON_NULL</tt> 186 */ 187 public void setInclude(String include) { 188 this.include = include; 189 } 190 191 public String getAllowJmsType() { 192 return allowJmsType; 193 } 194 195 /** 196 * Used for JMS users to allow the JMSType header from the JMS spec to 197 * specify a FQN classname to use to unmarshal to. 198 */ 199 public void setAllowJmsType(String allowJmsType) { 200 this.allowJmsType = allowJmsType; 201 } 202 203 public String getCollectionTypeName() { 204 return collectionTypeName; 205 } 206 207 /** 208 * Refers to a custom collection type to lookup in the registry to use. This 209 * option should rarely be used, but allows to use different collection 210 * types than java.util.Collection based as default. 211 */ 212 public void setCollectionTypeName(String collectionTypeName) { 213 this.collectionTypeName = collectionTypeName; 214 } 215 216 public Class<?> getCollectionType() { 217 return collectionType; 218 } 219 220 public void setCollectionType(Class<?> collectionType) { 221 this.collectionType = collectionType; 222 } 223 224 public String getUseList() { 225 return useList; 226 } 227 228 /** 229 * To unmarshal to a List of Map or a List of Pojo. 230 */ 231 public void setUseList(String useList) { 232 this.useList = useList; 233 } 234 235 public String getModuleClassNames() { 236 return moduleClassNames; 237 } 238 239 /** 240 * To use custom Jackson modules com.fasterxml.jackson.databind.Module 241 * specified as a String with FQN class names. Multiple classes can be 242 * separated by comma. 243 */ 244 public void setModuleClassNames(String moduleClassNames) { 245 this.moduleClassNames = moduleClassNames; 246 } 247 248 public String getModuleRefs() { 249 return moduleRefs; 250 } 251 252 /** 253 * To use custom Jackson modules referred from the Camel registry. Multiple 254 * modules can be separated by comma. 255 */ 256 public void setModuleRefs(String moduleRefs) { 257 this.moduleRefs = moduleRefs; 258 } 259 260 public String getEnableFeatures() { 261 return enableFeatures; 262 } 263 264 /** 265 * Set of features to enable on the Jackson 266 * <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. 267 * <p/> 268 * The features should be a name that matches a enum from 269 * <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, 270 * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or 271 * <tt>com.fasterxml.jackson.databind.MapperFeature</tt> 272 * <p/> 273 * Multiple features can be separated by comma 274 */ 275 public void setEnableFeatures(String enableFeatures) { 276 this.enableFeatures = enableFeatures; 277 } 278 279 public String getDisableFeatures() { 280 return disableFeatures; 281 } 282 283 /** 284 * Set of features to disable on the Jackson 285 * <tt>com.fasterxml.jackson.databind.ObjectMapper</tt>. 286 * <p/> 287 * The features should be a name that matches a enum from 288 * <tt>com.fasterxml.jackson.databind.SerializationFeature</tt>, 289 * <tt>com.fasterxml.jackson.databind.DeserializationFeature</tt>, or 290 * <tt>com.fasterxml.jackson.databind.MapperFeature</tt> 291 * <p/> 292 * Multiple features can be separated by comma 293 */ 294 public void setDisableFeatures(String disableFeatures) { 295 this.disableFeatures = disableFeatures; 296 } 297 298 public String getPermissions() { 299 return permissions; 300 } 301 302 /** 303 * Adds permissions that controls which Java packages and classes XStream is 304 * allowed to use during unmarshal from xml/json to Java beans. 305 * <p/> 306 * A permission must be configured either here or globally using a JVM 307 * system property. The permission can be specified in a syntax where a plus 308 * sign is allow, and minus sign is deny. <br/> 309 * Wildcards is supported by using <tt>.*</tt> as prefix. For example to 310 * allow <tt>com.foo</tt> and all subpackages then specfy 311 * <tt>+com.foo.*</tt>. Multiple permissions can be configured separated by 312 * comma, such as <tt>+com.foo.*,-com.foo.bar.MySecretBean</tt>. <br/> 313 * The following default permission is always included: 314 * <tt>"-*,java.lang.*,java.util.*"</tt> unless its overridden by specifying 315 * a JVM system property with they key 316 * <tt>org.apache.camel.xstream.permissions</tt>. 317 */ 318 public void setPermissions(String permissions) { 319 this.permissions = permissions; 320 } 321 322 /** 323 * To add permission for the given pojo classes. 324 * 325 * @param type the pojo class(es) xstream should use as allowed permission 326 * @see #setPermissions(String) 327 */ 328 public void setPermissions(Class<?>... type) { 329 CollectionStringBuffer csb = new CollectionStringBuffer(","); 330 for (Class<?> clazz : type) { 331 csb.append("+"); 332 csb.append(clazz.getName()); 333 } 334 setPermissions(csb.toString()); 335 } 336 337 public String getAllowUnmarshallType() { 338 return allowUnmarshallType; 339 } 340 341 /** 342 * If enabled then Jackson is allowed to attempt to use the 343 * CamelJacksonUnmarshalType header during the unmarshalling. 344 * <p/> 345 * This should only be enabled when desired to be used. 346 */ 347 public void setAllowUnmarshallType(String allowUnmarshallType) { 348 this.allowUnmarshallType = allowUnmarshallType; 349 } 350 351 public String getTimezone() { 352 return timezone; 353 } 354 355 /** 356 * If set then Jackson will use the Timezone when marshalling/unmarshalling. 357 * This option will have no effect on the others Json DataFormat, like gson, 358 * fastjson and xstream. 359 */ 360 public void setTimezone(String timezone) { 361 this.timezone = timezone; 362 } 363 364 public String getAutoDiscoverObjectMapper() { 365 return autoDiscoverObjectMapper; 366 } 367 368 /** 369 * If set to true then Jackson will lookup for an objectMapper into the 370 * registry 371 */ 372 public void setAutoDiscoverObjectMapper(String autoDiscoverObjectMapper) { 373 this.autoDiscoverObjectMapper = autoDiscoverObjectMapper; 374 } 375 376 public String getDropRootNode() { 377 return dropRootNode; 378 } 379 380 /** 381 * Whether XStream will drop the root node in the generated JSon. 382 * You may want to enable this when using POJOs; as then the written object will include the class name 383 * as root node, which is often not intended to be written in the JSON output. 384 */ 385 public void setDropRootNode(String dropRootNode) { 386 this.dropRootNode = dropRootNode; 387 } 388 389 @Override 390 public String getDataFormatName() { 391 // json data format is special as the name can be from different bundles 392 return "json-" + library.name().toLowerCase(); 393 } 394 395 // 396 // Fluent builders 397 // 398 399 public JsonDataFormat objectMapper(String objectMapper) { 400 this.objectMapper = objectMapper; 401 return this; 402 } 403 404 public JsonDataFormat useDefaultObjectMapper(boolean useDefaultObjectMapper) { 405 return useDefaultObjectMapper(Boolean.toString(useDefaultObjectMapper)); 406 } 407 408 public JsonDataFormat useDefaultObjectMapper(String useDefaultObjectMapper) { 409 this.useDefaultObjectMapper = useDefaultObjectMapper; 410 return this; 411 } 412 413 public JsonDataFormat prettyPrint(boolean prettyPrint) { 414 return prettyPrint(Boolean.toString(prettyPrint)); 415 } 416 417 public JsonDataFormat prettyPrint(String prettyPrint) { 418 this.prettyPrint = prettyPrint; 419 return this; 420 } 421 422 public JsonDataFormat library(JsonLibrary library) { 423 this.library = library; 424 return this; 425 } 426 427 public JsonDataFormat unmarshalType(String unmarshalType) { 428 this.unmarshalTypeName = unmarshalType; 429 return this; 430 } 431 432 public JsonDataFormat unmarshalType(Class<?> unmarshalType) { 433 this.unmarshalType = unmarshalType; 434 return this; 435 } 436 437 public JsonDataFormat jsonView(Class<?> jsonView) { 438 this.jsonView = jsonView; 439 return this; 440 } 441 442 public JsonDataFormat include(String include) { 443 this.include = include; 444 return this; 445 } 446 447 public JsonDataFormat allowJmsType(boolean allowJmsType) { 448 return allowJmsType(Boolean.toString(allowJmsType)); 449 } 450 451 public JsonDataFormat allowJmsType(String allowJmsType) { 452 this.allowJmsType = allowJmsType; 453 return this; 454 } 455 456 public JsonDataFormat collectionType(String collectionType) { 457 this.collectionTypeName = collectionType; 458 return this; 459 } 460 461 public JsonDataFormat collectionType(Class<?> collectionType) { 462 this.collectionType = collectionType; 463 return this; 464 } 465 466 public JsonDataFormat useList(boolean useList) { 467 return useList(Boolean.toString(useList)); 468 } 469 470 public JsonDataFormat useList(String useList) { 471 this.useList = useList; 472 return this; 473 } 474 475 public JsonDataFormat moduleClassNames(String moduleClassNames) { 476 this.moduleClassNames = moduleClassNames; 477 return this; 478 } 479 480 public JsonDataFormat moduleRefs(String moduleRefs) { 481 this.moduleRefs = moduleRefs; 482 return this; 483 } 484 485 public JsonDataFormat enableFeatures(String enableFeatures) { 486 this.enableFeatures = enableFeatures; 487 return this; 488 } 489 490 public JsonDataFormat disableFeatures(String disableFeatures) { 491 this.disableFeatures = disableFeatures; 492 return this; 493 } 494 495 public JsonDataFormat permissions(String permissions) { 496 this.permissions = permissions; 497 return this; 498 } 499 500 public JsonDataFormat allowUnmarshallType(boolean allowUnmarshallType) { 501 return allowUnmarshallType(Boolean.toString(allowUnmarshallType)); 502 } 503 504 public JsonDataFormat allowUnmarshallType(String allowUnmarshallType) { 505 this.allowUnmarshallType = allowUnmarshallType; 506 return this; 507 } 508 509 public JsonDataFormat timezone(String timezone) { 510 this.timezone = timezone; 511 return this; 512 } 513 514 public JsonDataFormat autoDiscoverObjectMapper(boolean autoDiscoverObjectMapper) { 515 return autoDiscoverObjectMapper(Boolean.toString(autoDiscoverObjectMapper)); 516 } 517 518 public JsonDataFormat autoDiscoverObjectMapper(String autoDiscoverObjectMapper) { 519 this.autoDiscoverObjectMapper = autoDiscoverObjectMapper; 520 return this; 521 } 522 523 public JsonDataFormat dropRootNode(boolean dropRootNode) { 524 return dropRootNode(Boolean.toString(dropRootNode)); 525 } 526 527 public JsonDataFormat dropRootNode(String dropRootNode) { 528 this.dropRootNode = dropRootNode; 529 return this; 530 } 531 532}