Repository: camel Updated Branches: refs/heads/master eb75e9636 -> 725ac9b09
CAMEL-8176: camel-jackson - Make it easier to register custom modules Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/725ac9b0 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/725ac9b0 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/725ac9b0 Branch: refs/heads/master Commit: 725ac9b099ad284b91460bf890816a398dd7c1e2 Parents: eb75e96 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Feb 12 10:29:19 2015 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Feb 12 10:29:19 2015 +0100 ---------------------------------------------------------------------- .../camel/model/dataformat/JsonDataFormat.java | 17 +++++ .../component/jackson/JacksonDataFormat.java | 65 +++++++++++++++++++- .../component/jackson/JacksonModuleTest.java | 56 +++++++++++++++++ .../camel/component/jackson/MyModule.java | 45 ++++++++++++++ 4 files changed, 181 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/725ac9b0/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java index edd3a8c..cd3d8d2 100644 --- a/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java +++ b/camel-core/src/main/java/org/apache/camel/model/dataformat/JsonDataFormat.java @@ -60,6 +60,8 @@ public class JsonDataFormat extends DataFormatDefinition { private Boolean useList; @XmlAttribute private Boolean enableJaxbAnnotationModule; + @XmlAttribute + private String moduleClassNames; public JsonDataFormat() { super("json"); @@ -189,6 +191,18 @@ public class JsonDataFormat extends DataFormatDefinition { this.enableJaxbAnnotationModule = enableJaxbAnnotationModule; } + public String getModuleClassNames() { + return moduleClassNames; + } + + /** + * To use custom Jackson modules com.fasterxml.jackson.databind.Module specified as a String with FQN class names. + * Multiple classes can be separated by comma. + */ + public void setModuleClassNames(String moduleClassNames) { + this.moduleClassNames = moduleClassNames; + } + @Override public String getDataFormatName() { // json data format is special as the name can be from different bundles @@ -249,6 +263,9 @@ public class JsonDataFormat extends DataFormatDefinition { if (enableJaxbAnnotationModule != null) { setProperty(camelContext, dataFormat, "enableJaxbAnnotationModule", enableJaxbAnnotationModule); } + if (moduleClassNames != null) { + setProperty(camelContext, dataFormat, "modulesClassNames", moduleClassNames); + } } } http://git-wip-us.apache.org/repos/asf/camel/blob/725ac9b0/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java ---------------------------------------------------------------------- diff --git a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java index c56363a..5b5ec80 100644 --- a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java +++ b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/JacksonDataFormat.java @@ -21,25 +21,37 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.Module; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.CollectionType; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; import org.apache.camel.Exchange; import org.apache.camel.spi.DataFormat; import org.apache.camel.support.ServiceSupport; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A <a href="http://camel.apache.org/data-format.html">data format</a> ({@link DataFormat}) * using <a href="http://jackson.codehaus.org/">Jackson</a> to marshal to and from JSON. */ -public class JacksonDataFormat extends ServiceSupport implements DataFormat { +public class JacksonDataFormat extends ServiceSupport implements DataFormat, CamelContextAware { + + private static final Logger LOG = LoggerFactory.getLogger(JacksonDataFormat.class); private final ObjectMapper objectMapper; + private CamelContext camelContext; private Class<? extends Collection> collectionType; + private List<Module> modules; + private String moduleClassNames; private Class<?> unmarshalType; private Class<?> jsonView; private String include; @@ -117,6 +129,14 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat { this.jsonView = jsonView; } + public CamelContext getCamelContext() { + return camelContext; + } + + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + public void marshal(Exchange exchange, Object graph, OutputStream stream) throws Exception { this.objectMapper.writerWithView(jsonView).writeValue(stream, graph); } @@ -207,6 +227,29 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat { this.enableJaxbAnnotationModule = enableJaxbAnnotationModule; } + public List<Module> getModules() { + return modules; + } + + /** + * To use custom Jackson {@link Module}s + */ + public void setModules(List<Module> modules) { + this.modules = modules; + } + + public String getModuleClassNames() { + return moduleClassNames; + } + + /** + * To use custom Jackson {@link Module}s specified as a String with FQN class names. + * Multiple classes can be separated by comma. + */ + public void setModuleClassNames(String moduleClassNames) { + this.moduleClassNames = moduleClassNames; + } + /** * Uses {@link java.util.ArrayList} when unmarshalling. */ @@ -237,9 +280,10 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat { if (enableJaxbAnnotationModule) { // Enables JAXB processing JaxbAnnotationModule module = new JaxbAnnotationModule(); + LOG.info("Registering module: {}", module); objectMapper.registerModule(module); } - + if (useList) { setCollectionType(ArrayList.class); } @@ -250,6 +294,23 @@ public class JacksonDataFormat extends ServiceSupport implements DataFormat { if (prettyPrint) { objectMapper.enable(SerializationFeature.INDENT_OUTPUT); } + + if (modules != null) { + for (Module module : modules) { + LOG.info("Registering module: {}", module); + objectMapper.registerModules(module); + } + } + if (moduleClassNames != null) { + Iterable<Object> it = ObjectHelper.createIterable(moduleClassNames); + for (Object o : it) { + String name = o.toString(); + Class<Module> clazz = camelContext.getClassResolver().resolveMandatoryClass(name, Module.class); + Module module = camelContext.getInjector().newInstance(clazz); + LOG.info("Registering module: {} -> {}", name, module); + objectMapper.registerModule(module); + } + } } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/725ac9b0/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonModuleTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonModuleTest.java b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonModuleTest.java new file mode 100644 index 0000000..d3f0bf0 --- /dev/null +++ b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/JacksonModuleTest.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jackson; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class JacksonModuleTest extends CamelTestSupport { + + @Test + public void testCustomModule() throws Exception { + MockEndpoint mock = getMockEndpoint("mock:marshal"); + mock.expectedMessageCount(1); + mock.message(0).body(String.class).isEqualTo("{\"my-name\":\"Camel\",\"my-country\":\"Denmark\"}"); + + TestOtherPojo pojo = new TestOtherPojo(); + pojo.setName("Camel"); + pojo.setCountry("Denmark"); + + template.sendBody("direct:marshal", pojo); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + + @Override + public void configure() throws Exception { + JacksonDataFormat format = new JacksonDataFormat(); + format.setInclude("NON_NULL"); + format.setModuleClassNames("org.apache.camel.component.jackson.MyModule"); + + from("direct:marshal").marshal(format).to("mock:marshal"); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/725ac9b0/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/MyModule.java ---------------------------------------------------------------------- diff --git a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/MyModule.java b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/MyModule.java new file mode 100644 index 0000000..c3f3c30 --- /dev/null +++ b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/MyModule.java @@ -0,0 +1,45 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jackson; + +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.PropertyNamingStrategy; + +public class MyModule extends Module { + + @Override + public String getModuleName() { + return "MyModule"; + } + + @Override + public Version version() { + return Version.unknownVersion(); + } + + @Override + public void setupModule(SetupContext context) { + context.setNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() { + @Override + public String translate(String propertyName) { + return "my-" + propertyName; + } + }); + } + +}