You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2013/08/30 10:04:13 UTC

git commit: CAMEL-6683: camel-dozer works better with OSGi. Allow to configure dozer bean mapper without causing it to init itself to eagerly (due dozer doing that automatic) which allows us to better setup classloader for OSGi.

Updated Branches:
  refs/heads/master 973ba6533 -> e3867e001


CAMEL-6683: camel-dozer works better with OSGi. Allow to configure dozer bean mapper without causing it to init itself to eagerly (due dozer doing that automatic) which allows us to better setup classloader for OSGi.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/e3867e00
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/e3867e00
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/e3867e00

Branch: refs/heads/master
Commit: e3867e001ca6dce834c71b1b8958b11f8cfb8079
Parents: 973ba65
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Aug 30 10:03:46 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Aug 30 10:03:59 2013 +0200

----------------------------------------------------------------------
 .../dozer/CamelToDozerClassResolverAdapter.java |  46 ++++++++
 .../dozer/DozerBeanMapperConfiguration.java     |  73 +++++++++++++
 .../dozer/DozerTypeConverterLoader.java         | 109 +++++++++++++++----
 ...ringDozerTypeConverterConfigurationTest.java |  43 ++++++++
 ...pringDozerTypeConverterConfigurationTest.xml |  43 ++++++++
 5 files changed, 295 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/e3867e00/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/CamelToDozerClassResolverAdapter.java
----------------------------------------------------------------------
diff --git a/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/CamelToDozerClassResolverAdapter.java b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/CamelToDozerClassResolverAdapter.java
new file mode 100644
index 0000000..ad913d1
--- /dev/null
+++ b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/CamelToDozerClassResolverAdapter.java
@@ -0,0 +1,46 @@
+/**
+ * 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.converter.dozer;
+
+import java.net.URL;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultClassResolver;
+import org.apache.camel.spi.ClassResolver;
+import org.dozer.util.DozerClassLoader;
+
+public final class CamelToDozerClassResolverAdapter implements DozerClassLoader {
+
+    private final ClassResolver classResolver;
+
+    public CamelToDozerClassResolverAdapter() {
+        // must have a default nor-arg constructor to allow Dozer to work with OSGi
+        classResolver = new DefaultClassResolver();
+    }
+
+    public CamelToDozerClassResolverAdapter(CamelContext camelContext) {
+        classResolver = camelContext.getClassResolver();
+    }
+
+    public Class<?> loadClass(String name) {
+        return classResolver.resolveClass(name);
+    }
+
+    public URL loadResource(String name) {
+        return DozerTypeConverterLoader.loadMappingFile(classResolver, name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e3867e00/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerBeanMapperConfiguration.java
----------------------------------------------------------------------
diff --git a/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerBeanMapperConfiguration.java b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerBeanMapperConfiguration.java
new file mode 100644
index 0000000..6257547
--- /dev/null
+++ b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerBeanMapperConfiguration.java
@@ -0,0 +1,73 @@
+/**
+ * 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.converter.dozer;
+
+import java.util.List;
+import java.util.Map;
+
+import org.dozer.CustomConverter;
+import org.dozer.CustomFieldMapper;
+import org.dozer.DozerEventListener;
+
+public class DozerBeanMapperConfiguration {
+
+    private List<String> mappingFiles;
+    private List<CustomConverter> customConverters;
+    private List<DozerEventListener> eventListeners;
+    private Map<String, CustomConverter> customConvertersWithId;
+    private CustomFieldMapper customFieldMapper;
+
+    public List<String> getMappingFiles() {
+        return mappingFiles;
+    }
+
+    public void setMappingFiles(List<String> mappingFiles) {
+        this.mappingFiles = mappingFiles;
+    }
+
+    public List<CustomConverter> getCustomConverters() {
+        return customConverters;
+    }
+
+    public void setCustomConverters(List<CustomConverter> customConverters) {
+        this.customConverters = customConverters;
+    }
+
+    public List<DozerEventListener> getEventListeners() {
+        return eventListeners;
+    }
+
+    public void setEventListeners(List<DozerEventListener> eventListeners) {
+        this.eventListeners = eventListeners;
+    }
+
+    public Map<String, CustomConverter> getCustomConvertersWithId() {
+        return customConvertersWithId;
+    }
+
+    public void setCustomConvertersWithId(Map<String, CustomConverter> customConvertersWithId) {
+        this.customConvertersWithId = customConvertersWithId;
+    }
+
+    public CustomFieldMapper getCustomFieldMapper() {
+        return customFieldMapper;
+    }
+
+    public void setCustomFieldMapper(CustomFieldMapper customFieldMapper) {
+        this.customFieldMapper = customFieldMapper;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e3867e00/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerTypeConverterLoader.java
----------------------------------------------------------------------
diff --git a/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerTypeConverterLoader.java b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerTypeConverterLoader.java
index bb488b0..317dfa8 100644
--- a/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerTypeConverterLoader.java
+++ b/components/camel-dozer/src/main/java/org/apache/camel/converter/dozer/DozerTypeConverterLoader.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.converter.dozer;
 
+import java.lang.reflect.Field;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
@@ -29,12 +30,14 @@ import org.apache.camel.CamelContextAware;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.util.ReflectionHelper;
 import org.apache.camel.util.ResourceHelper;
 import org.dozer.DozerBeanMapper;
 import org.dozer.Mapper;
 import org.dozer.classmap.ClassMap;
 import org.dozer.classmap.MappingFileData;
 import org.dozer.config.BeanContainer;
+import org.dozer.config.GlobalSettings;
 import org.dozer.loader.api.BeanMappingBuilder;
 import org.dozer.loader.xml.MappingFileReader;
 import org.dozer.loader.xml.XMLParserFactory;
@@ -59,7 +62,8 @@ public class DozerTypeConverterLoader implements CamelContextAware {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
     private CamelContext camelContext;
-    private DozerBeanMapper mapper;
+    private DozerBeanMapperConfiguration configuration;
+    private transient DozerBeanMapper mapper;
 
     /**
      * Creates a <code>DozerTypeConverter</code> performing no
@@ -82,6 +86,35 @@ public class DozerTypeConverterLoader implements CamelContextAware {
     }
 
     /**
+     * Creates a <code>DozerTypeConverter</code> using the given
+     * {@link DozerBeanMapperConfiguration} configuration.
+     *
+     * @param camelContext the context to register the
+     *                     {@link DozerTypeConverter} in
+     *
+     * @param configuration dozer mapping bean configuration.
+     */
+    public DozerTypeConverterLoader(CamelContext camelContext, DozerBeanMapperConfiguration configuration) {
+        GlobalSettings settings = GlobalSettings.getInstance();
+        try {
+            log.info("Configuring GlobalSettings to use Camel classloader: {}", CamelToDozerClassResolverAdapter.class.getName());
+            Field field = settings.getClass().getDeclaredField("classLoaderBeanName");
+            ReflectionHelper.setField(field, settings, CamelToDozerClassResolverAdapter.class.getName());
+        } catch (Exception e) {
+            throw new IllegalStateException("Cannot configure Dozer GlobalSettings to use CamelToDozerClassResolverAdapter as classloader due " + e.getMessage(), e);
+        }
+
+        // must set class loader before we create bean mapper
+        CamelToDozerClassResolverAdapter adapter = new CamelToDozerClassResolverAdapter(camelContext);
+        BeanContainer.getInstance().setClassLoader(adapter);
+
+        log.info("Using DozerBeanMapperConfiguration: {}", configuration);
+        DozerBeanMapper mapper = createDozerBeanMapper(configuration);
+
+        init(camelContext, mapper);
+    }
+
+    /**
      * Creates a <code>DozerTypeConverter</code> that will wrap the the given
      * {@link DozerBeanMapper} as a {@link DozerTypeConverter} and register it
      * with the given context. It will also search the context for
@@ -90,6 +123,7 @@ public class DozerTypeConverterLoader implements CamelContextAware {
      *                     {@link DozerTypeConverter} in
      * @param mapper       the DozerMapperBean to be wrapped as a type converter.
      */
+    @Deprecated
     public DozerTypeConverterLoader(CamelContext camelContext, DozerBeanMapper mapper) {
         init(camelContext, mapper);
     }
@@ -110,12 +144,30 @@ public class DozerTypeConverterLoader implements CamelContextAware {
 
         CamelToDozerClassResolverAdapter adapter = new CamelToDozerClassResolverAdapter(camelContext);
         BeanContainer.getInstance().setClassLoader(adapter);
-        
+
         Map<String, DozerBeanMapper> mappers = lookupDozerBeanMappers();
         // only add if we do not already have it
         if (mapper != null && !mappers.containsValue(mapper)) {
             mappers.put("parameter", mapper);
         }
+
+        // add any dozer bean mapper configurations
+        Map<String, DozerBeanMapperConfiguration> configurations = lookupDozerBeanMapperConfigurations();
+        if (configurations != null) {
+            if (configurations.size() > 1) {
+                log.warn("Loaded " + configurations.size() + " Dozer configurations from Camel registry."
+                        + " Dozer is most efficient when there is a single mapper instance. Consider amalgamating instances.");
+            }
+            for (Map.Entry<String, DozerBeanMapperConfiguration> entry : configurations.entrySet()) {
+                String id = entry.getKey();
+                DozerBeanMapper beanMapper = createDozerBeanMapper(entry.getValue());
+                // only add if we do not already have it
+                if (!mappers.containsValue(beanMapper)) {
+                    mappers.put(id, beanMapper);
+                }
+            }
+        }
+
         if (mappers.size() > 1) {
             log.warn("Loaded " + mappers.size() + " Dozer mappers from Camel registry."
                     + " Dozer is most efficient when there is a single mapper instance. Consider amalgamating instances.");
@@ -124,6 +176,7 @@ public class DozerTypeConverterLoader implements CamelContextAware {
                     + DozerBeanMapper.class.getName());
         }
 
+
         TypeConverterRegistry registry = camelContext.getTypeConverterRegistry();
         for (Map.Entry<String, DozerBeanMapper> entry : mappers.entrySet()) {
             String mapperId = entry.getKey();
@@ -134,12 +187,47 @@ public class DozerTypeConverterLoader implements CamelContextAware {
     }
 
     /**
+     * Creates a {@link DozerBeanMapper} from the given configuration.
+     *
+     * @param configuration  the dozer bean mapper configuration.
+     * @return the created mapper
+     */
+    protected DozerBeanMapper createDozerBeanMapper(DozerBeanMapperConfiguration configuration) {
+        DozerBeanMapper mapper;
+        if (configuration.getMappingFiles() != null) {
+            mapper = new DozerBeanMapper(configuration.getMappingFiles());
+        } else {
+            mapper = new DozerBeanMapper();
+        }
+        if (configuration.getCustomConverters() != null) {
+            mapper.setCustomConverters(configuration.getCustomConverters());
+        }
+        if (configuration.getEventListeners() != null) {
+            mapper.setEventListeners(configuration.getEventListeners());
+        }
+        if (configuration.getCustomConvertersWithId() != null) {
+            mapper.setCustomConvertersWithId(configuration.getCustomConvertersWithId());
+        }
+        if (configuration.getCustomFieldMapper() != null) {
+            mapper.setCustomFieldMapper(configuration.getCustomFieldMapper());
+        }
+        return mapper;
+    }
+
+    /**
      * Lookup the dozer {@link DozerBeanMapper} to be used.
      */
     protected Map<String, DozerBeanMapper> lookupDozerBeanMappers() {
         return new HashMap<String, DozerBeanMapper>(camelContext.getRegistry().findByTypeWithName(DozerBeanMapper.class));
     }
 
+    /**
+     * Lookup the dozer {@link DozerBeanMapperConfiguration} to be used.
+     */
+    protected Map<String, DozerBeanMapperConfiguration> lookupDozerBeanMapperConfigurations() {
+        return new HashMap<String, DozerBeanMapperConfiguration>(camelContext.getRegistry().findByTypeWithName(DozerBeanMapperConfiguration.class));
+    }
+
     protected void registerClassMaps(TypeConverterRegistry registry, String dozerId, DozerBeanMapper dozer, List<ClassMap> all) {
         DozerTypeConverter converter = new DozerTypeConverter(dozer);
         for (ClassMap map : all) {
@@ -244,21 +332,4 @@ public class DozerTypeConverterLoader implements CamelContextAware {
         return url;
     }
 
-    private static final class CamelToDozerClassResolverAdapter implements DozerClassLoader {
-
-        private final ClassResolver classResolver;
-
-        private CamelToDozerClassResolverAdapter(CamelContext camelContext) {
-            classResolver = camelContext.getClassResolver();
-        }
-
-        public Class<?> loadClass(String name) {
-            return classResolver.resolveClass(name);
-        }
-
-        public URL loadResource(String name) {
-            return loadMappingFile(classResolver, name);
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/e3867e00/components/camel-dozer/src/test/java/org/apache/camel/converter/dozer/SpringDozerTypeConverterConfigurationTest.java
----------------------------------------------------------------------
diff --git a/components/camel-dozer/src/test/java/org/apache/camel/converter/dozer/SpringDozerTypeConverterConfigurationTest.java b/components/camel-dozer/src/test/java/org/apache/camel/converter/dozer/SpringDozerTypeConverterConfigurationTest.java
new file mode 100644
index 0000000..2d51ad1
--- /dev/null
+++ b/components/camel-dozer/src/test/java/org/apache/camel/converter/dozer/SpringDozerTypeConverterConfigurationTest.java
@@ -0,0 +1,43 @@
+/**
+ * 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.converter.dozer;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.spring.CamelSpringTestSupport;
+import org.junit.Test;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.apache.camel.converter.dozer.DozerTestArtifactsFactory.createServiceCustomer;
+
+public class SpringDozerTypeConverterConfigurationTest extends CamelSpringTestSupport {
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext("SpringDozerTypeConverterConfigurationTest.xml");
+    }
+
+    @Test
+    public void verifyCamelConversionViaDozer() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:verify-model");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:service-in", createServiceCustomer());
+
+        assertMockEndpointsSatisfied();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/e3867e00/components/camel-dozer/src/test/resources/SpringDozerTypeConverterConfigurationTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-dozer/src/test/resources/SpringDozerTypeConverterConfigurationTest.xml b/components/camel-dozer/src/test/resources/SpringDozerTypeConverterConfigurationTest.xml
new file mode 100644
index 0000000..8a51385
--- /dev/null
+++ b/components/camel-dozer/src/test/resources/SpringDozerTypeConverterConfigurationTest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="
+            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+            http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
+
+  <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+    <route>
+      <from uri="direct:service-in"/>
+      <to uri="bean:customer-processor"/>
+      <to uri="mock:verify-model"/>
+    </route>
+  </camelContext>
+
+  <bean id="customer-processor" class="org.apache.camel.converter.dozer.CustomerProcessor"/>
+  <bean id="dozerConverterLoader" class="org.apache.camel.converter.dozer.DozerTypeConverterLoader"/>
+
+  <!-- use bean mapping configuration -->
+  <bean id="mapper" class="org.apache.camel.converter.dozer.DozerBeanMapperConfiguration">
+    <property name="mappingFiles">
+      <list>
+        <value>mapping.xml</value>
+      </list>
+    </property>
+  </bean>
+
+</beans>
\ No newline at end of file