You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Andre Piwoni (Created) (JIRA)" <ji...@apache.org> on 2012/02/22 23:27:49 UTC

[jira] [Created] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
------------------------------------------------------------------------

                 Key: CAMEL-5031
                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
             Project: Camel
          Issue Type: Bug
          Components: bean-integration, camel-core
    Affects Versions: 2.9.0, 2.6.0
            Reporter: Andre Piwoni
            Priority: Minor


DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).

Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)

<mapping  map-id="myMapping">
   <class-a>x.y.z.ComplexType</class-a>
   <class-b>java.util.Map</class-b>
   <field copy-by-reference="true">
      <a>complexTypeField</a>
      <b key="complexTypeFieldKeyName">this</b>
  </field>
  ...
</mapping>

DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
Interfaces for Dozer and Camel Conversion may not be fully compatible but least limitations should be stated in documentation.

Regards,
Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Updated] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Posted by "Andre Piwoni (Updated) (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5031?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Andre Piwoni updated CAMEL-5031:
--------------------------------

    Description: 
DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).

Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)

<mapping  map-id="myMapping">
   <class-a>x.y.z.ComplexType</class-a>
   <class-b>java.util.Map</class-b>
   <field copy-by-reference="true">
      <a>complexTypeField</a>
      <b key="complexTypeFieldKeyName">this</b>
  </field>
  ...
</mapping>

DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
Interfaces for Dozer and Camel Conversion may not be fully compatible but at least limitations should be stated in documentation.

Regards,
Andre Piwoni

  was:
DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).

Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)

<mapping  map-id="myMapping">
   <class-a>x.y.z.ComplexType</class-a>
   <class-b>java.util.Map</class-b>
   <field copy-by-reference="true">
      <a>complexTypeField</a>
      <b key="complexTypeFieldKeyName">this</b>
  </field>
  ...
</mapping>

DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
Interfaces for Dozer and Camel Conversion may not be fully compatible but least limitations should be stated in documentation.

Regards,
Andre Piwoni

    
> Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-5031
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
>             Project: Camel
>          Issue Type: Bug
>          Components: bean-integration, camel-core
>    Affects Versions: 2.6.0, 2.9.0
>            Reporter: Andre Piwoni
>            Priority: Minor
>
> DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).
> Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)
> <mapping  map-id="myMapping">
>    <class-a>x.y.z.ComplexType</class-a>
>    <class-b>java.util.Map</class-b>
>    <field copy-by-reference="true">
>       <a>complexTypeField</a>
>       <b key="complexTypeFieldKeyName">this</b>
>   </field>
>   ...
> </mapping>
> DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
> Interfaces for Dozer and Camel Conversion may not be fully compatible but at least limitations should be stated in documentation.
> Regards,
> Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Commented] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Posted by "Sergey Zhemzhitsky (Commented) (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-5031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13235545#comment-13235545 ] 

Sergey Zhemzhitsky commented on CAMEL-5031:
-------------------------------------------

Hi guys,

May be you can find it quite useful, but we were able to workaround such a limitation by create our own converter
{code:java}
public class DozerTypeConverter implements TypeConverter {

    public static final String MAP_ID_PROP = "DozerMapID";

    private DozerBeanMapper mapper;

    public DozerTypeConverter(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

    public <T> T convertTo(Class<T> type, Object value) {
        return convertTo(type, value, null);
    }

    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, null);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    private <T> T convertTo(Class<T> type, Object value, String mapId) {
        if(mapId != null) {
            return mapper.map(value, type, mapId);
        }
        return mapper.map(value, type);
    }

}
{code}

Here is how the camel route looks like

{code:xml}
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="startRoute">
        <from uri="direct://start" />
        <setProperty propertyName="DozerMapID">
            <constant>Type2Map</constant>
        </setProperty>
        <convertBodyTo type="java.util.Map"/>
        <to uri="mock://complete"/>
    </route>
</camelContext>
{code}

and mapping file

{code:xml}
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <mapping map-id="Type2Map">
        <class-a>ru.troika.cto.stdint.esb.dozer.DozerTypeConverterTest$Type</class-a>
        <class-b>java.util.HashMap</class-b>
        <field>
            <a>p1</a>
            <b key="P1">this</b>
        </field>
        <field>
            <a>p2</a>
            <b key="P2">this</b>
        </field>
    </mapping>

</mappings>
{code}

We also had to modify DozerTypeConverterLoader to create our converter instead of the camel's one.

{code:java}
public class DozerTypeConverterLoader implements InitializingBean, CamelContextAware {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private DozerBeanMapper mapper;
    private CamelContext camelContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(mapper, "mapper: null");
        Assert.notNull(mapper, "camelContext: null");

        TypeConverterRegistry registry = getTypeConverterRegistry();
        load(registry);
    }

    public void load(TypeConverterRegistry registry) throws Exception {
        List<ClassMap> all = loadMappings(camelContext, mapper);
        registerClassMaps(registry, mapper, all);
    }

    private void registerClassMaps(TypeConverterRegistry registry, DozerBeanMapper dozer, List<ClassMap> all) {
        DozerTypeConverter converter = new DozerTypeConverter(dozer);
        for (ClassMap map : all) {
            if(logger.isInfoEnabled()) {
                logger.info("Added {} -> {} as type converter to: {}",
                        new Object[]{map.getSrcClassName(), map.getDestClassName(), registry});
            }
            registry.addTypeConverter(map.getSrcClassToMap(), map.getDestClassToMap(), converter);
            registry.addTypeConverter(map.getDestClassToMap(), map.getSrcClassToMap(), converter);
        }
    }

    private List<ClassMap> loadMappings(CamelContext camelContext, DozerBeanMapper mapper) {
        List<ClassMap> answer = new ArrayList<ClassMap>();

        // load the class map using the class resolver so we can load from classpath in OSGi
        MappingFileReader reader = new MappingFileReader(XMLParserFactory.getInstance());
        List<String> mappingFiles = mapper.getMappingFiles();
        if (mappingFiles == null) {
            return Collections.emptyList();
        }

        for (String name : mappingFiles) {
            URL url = camelContext.getClassResolver().loadResourceAsURL(name);
            MappingFileData data = reader.read(url);
            answer.addAll(data.getClassMaps());
        }

        return answer;
    }

    @Override
    public CamelContext getCamelContext() {
        return camelContext;
    }

    @Override
    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }

    private TypeConverterRegistry getTypeConverterRegistry() throws Exception {
        TypeConverterRegistry registry = camelContext.getTypeConverterRegistry();
        if(registry == null) {
            TypeConverter converter = camelContext.getTypeConverter();
            if (converter != null) {
                Method method = converter.getClass().getMethod("getRegistry");
                registry = (TypeConverterRegistry) method.invoke(converter);
            }
        }
        return registry;
    }

    public void setMapper(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

}
{code}

Unfortunately the codebase is for camel 2.4, so there are some workarounds for CAMEL-3143 (Take a look at getTypeConverterRegistry method)
                
> Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-5031
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
>             Project: Camel
>          Issue Type: Improvement
>          Components: bean-integration, camel-core
>    Affects Versions: 2.6.0, 2.9.0
>            Reporter: Andre Piwoni
>            Priority: Minor
>
> DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).
> Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)
> <mapping  map-id="myMapping">
>    <class-a>x.y.z.ComplexType</class-a>
>    <class-b>java.util.Map</class-b>
>    <field copy-by-reference="true">
>       <a>complexTypeField</a>
>       <b key="complexTypeFieldKeyName">this</b>
>   </field>
>   ...
> </mapping>
> DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
> Interfaces for Dozer and Camel Conversion may not be fully compatible but it would be great if at least limitations can be stated in documentation.
> Regards,
> Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Updated] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Posted by "Andre Piwoni (Updated) (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5031?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Andre Piwoni updated CAMEL-5031:
--------------------------------

    Description: 
DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).

Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)

<mapping  map-id="myMapping">
   <class-a>x.y.z.ComplexType</class-a>
   <class-b>java.util.Map</class-b>
   <field copy-by-reference="true">
      <a>complexTypeField</a>
      <b key="complexTypeFieldKeyName">this</b>
  </field>
  ...
</mapping>

DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
Interfaces for Dozer and Camel Conversion may not be fully compatible but it would be great if at least limitations can be stated in documentation.

Regards,
Andre Piwoni

  was:
DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).

Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)

<mapping  map-id="myMapping">
   <class-a>x.y.z.ComplexType</class-a>
   <class-b>java.util.Map</class-b>
   <field copy-by-reference="true">
      <a>complexTypeField</a>
      <b key="complexTypeFieldKeyName">this</b>
  </field>
  ...
</mapping>

DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
Interfaces for Dozer and Camel Conversion may not be fully compatible but at least limitations should be stated in documentation.

Regards,
Andre Piwoni

    
> Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-5031
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
>             Project: Camel
>          Issue Type: Bug
>          Components: bean-integration, camel-core
>    Affects Versions: 2.6.0, 2.9.0
>            Reporter: Andre Piwoni
>            Priority: Minor
>
> DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).
> Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)
> <mapping  map-id="myMapping">
>    <class-a>x.y.z.ComplexType</class-a>
>    <class-b>java.util.Map</class-b>
>    <field copy-by-reference="true">
>       <a>complexTypeField</a>
>       <b key="complexTypeFieldKeyName">this</b>
>   </field>
>   ...
> </mapping>
> DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
> Interfaces for Dozer and Camel Conversion may not be fully compatible but it would be great if at least limitations can be stated in documentation.
> Regards,
> Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Updated] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Posted by "Claus Ibsen (Updated) (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/CAMEL-5031?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Claus Ibsen updated CAMEL-5031:
-------------------------------

    Issue Type: Improvement  (was: Bug)

I added a note about this limitation on the wiki page.

I am not sure there is much we can do about the map-id thingy.
                
> Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-5031
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
>             Project: Camel
>          Issue Type: Improvement
>          Components: bean-integration, camel-core
>    Affects Versions: 2.6.0, 2.9.0
>            Reporter: Andre Piwoni
>            Priority: Minor
>
> DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).
> Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)
> <mapping  map-id="myMapping">
>    <class-a>x.y.z.ComplexType</class-a>
>    <class-b>java.util.Map</class-b>
>    <field copy-by-reference="true">
>       <a>complexTypeField</a>
>       <b key="complexTypeFieldKeyName">this</b>
>   </field>
>   ...
> </mapping>
> DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
> Interfaces for Dozer and Camel Conversion may not be fully compatible but it would be great if at least limitations can be stated in documentation.
> Regards,
> Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

[jira] [Issue Comment Edited] (CAMEL-5031) Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)

Posted by "Sergey Zhemzhitsky (Issue Comment Edited) (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/jira/browse/CAMEL-5031?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13235545#comment-13235545 ] 

Sergey Zhemzhitsky edited comment on CAMEL-5031 at 3/22/12 12:48 PM:
---------------------------------------------------------------------

Hi guys,

May be you can find it quite useful, but we were able to workaround such a limitation by create our own converter
{code:java}
public class DozerTypeConverter implements TypeConverter {

    public static final String MAP_ID_PROP = "DozerMapID";

    private DozerBeanMapper mapper;

    public DozerTypeConverter(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

    public <T> T convertTo(Class<T> type, Object value) {
        return convertTo(type, value, null);
    }

    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, null);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    private <T> T convertTo(Class<T> type, Object value, String mapId) {
        if(mapId != null) {
            return mapper.map(value, type, mapId);
        }
        return mapper.map(value, type);
    }

}
{code}

Here is how the camel route looks like

{code:xml}
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="startRoute">
        <from uri="direct://start" />
        <setProperty propertyName="DozerMapID">
            <constant>Type2Map</constant>
        </setProperty>
        <convertBodyTo type="java.util.Map"/>
        <to uri="mock://complete"/>
    </route>
</camelContext>
{code}

and mapping file

{code:xml}
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <mapping map-id="Type2Map">
        <class-a>org.foo.bar.dozer.DozerTypeConverterTest$Type</class-a>
        <class-b>java.util.HashMap</class-b>
        <field>
            <a>p1</a>
            <b key="P1">this</b>
        </field>
        <field>
            <a>p2</a>
            <b key="P2">this</b>
        </field>
    </mapping>

</mappings>
{code}

We also had to modify DozerTypeConverterLoader to create our converter instead of the camel's one.

{code:java}
public class DozerTypeConverterLoader implements InitializingBean, CamelContextAware {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private DozerBeanMapper mapper;
    private CamelContext camelContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(mapper, "mapper: null");
        Assert.notNull(mapper, "camelContext: null");

        TypeConverterRegistry registry = getTypeConverterRegistry();
        load(registry);
    }

    public void load(TypeConverterRegistry registry) throws Exception {
        List<ClassMap> all = loadMappings(camelContext, mapper);
        registerClassMaps(registry, mapper, all);
    }

    private void registerClassMaps(TypeConverterRegistry registry, DozerBeanMapper dozer, List<ClassMap> all) {
        DozerTypeConverter converter = new DozerTypeConverter(dozer);
        for (ClassMap map : all) {
            if(logger.isInfoEnabled()) {
                logger.info("Added {} -> {} as type converter to: {}",
                        new Object[]{map.getSrcClassName(), map.getDestClassName(), registry});
            }
            registry.addTypeConverter(map.getSrcClassToMap(), map.getDestClassToMap(), converter);
            registry.addTypeConverter(map.getDestClassToMap(), map.getSrcClassToMap(), converter);
        }
    }

    private List<ClassMap> loadMappings(CamelContext camelContext, DozerBeanMapper mapper) {
        List<ClassMap> answer = new ArrayList<ClassMap>();

        // load the class map using the class resolver so we can load from classpath in OSGi
        MappingFileReader reader = new MappingFileReader(XMLParserFactory.getInstance());
        List<String> mappingFiles = mapper.getMappingFiles();
        if (mappingFiles == null) {
            return Collections.emptyList();
        }

        for (String name : mappingFiles) {
            URL url = camelContext.getClassResolver().loadResourceAsURL(name);
            MappingFileData data = reader.read(url);
            answer.addAll(data.getClassMaps());
        }

        return answer;
    }

    @Override
    public CamelContext getCamelContext() {
        return camelContext;
    }

    @Override
    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }

    private TypeConverterRegistry getTypeConverterRegistry() throws Exception {
        TypeConverterRegistry registry = camelContext.getTypeConverterRegistry();
        if(registry == null) {
            TypeConverter converter = camelContext.getTypeConverter();
            if (converter != null) {
                Method method = converter.getClass().getMethod("getRegistry");
                registry = (TypeConverterRegistry) method.invoke(converter);
            }
        }
        return registry;
    }

    public void setMapper(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

}
{code}

Unfortunately the codebase is for camel 2.4, so there are some workarounds for CAMEL-3143 (Take a look at getTypeConverterRegistry method)
                
      was (Author: szhemzhitsky):
    Hi guys,

May be you can find it quite useful, but we were able to workaround such a limitation by create our own converter
{code:java}
public class DozerTypeConverter implements TypeConverter {

    public static final String MAP_ID_PROP = "DozerMapID";

    private DozerBeanMapper mapper;

    public DozerTypeConverter(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

    public <T> T convertTo(Class<T> type, Object value) {
        return convertTo(type, value, null);
    }

    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, null);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
        return convertTo(type, value, exchange.getProperty(MAP_ID_PROP, null, String.class));
    }

    private <T> T convertTo(Class<T> type, Object value, String mapId) {
        if(mapId != null) {
            return mapper.map(value, type, mapId);
        }
        return mapper.map(value, type);
    }

}
{code}

Here is how the camel route looks like

{code:xml}
<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route id="startRoute">
        <from uri="direct://start" />
        <setProperty propertyName="DozerMapID">
            <constant>Type2Map</constant>
        </setProperty>
        <convertBodyTo type="java.util.Map"/>
        <to uri="mock://complete"/>
    </route>
</camelContext>
{code}

and mapping file

{code:xml}
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">

    <mapping map-id="Type2Map">
        <class-a>ru.troika.cto.stdint.esb.dozer.DozerTypeConverterTest$Type</class-a>
        <class-b>java.util.HashMap</class-b>
        <field>
            <a>p1</a>
            <b key="P1">this</b>
        </field>
        <field>
            <a>p2</a>
            <b key="P2">this</b>
        </field>
    </mapping>

</mappings>
{code}

We also had to modify DozerTypeConverterLoader to create our converter instead of the camel's one.

{code:java}
public class DozerTypeConverterLoader implements InitializingBean, CamelContextAware {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private DozerBeanMapper mapper;
    private CamelContext camelContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(mapper, "mapper: null");
        Assert.notNull(mapper, "camelContext: null");

        TypeConverterRegistry registry = getTypeConverterRegistry();
        load(registry);
    }

    public void load(TypeConverterRegistry registry) throws Exception {
        List<ClassMap> all = loadMappings(camelContext, mapper);
        registerClassMaps(registry, mapper, all);
    }

    private void registerClassMaps(TypeConverterRegistry registry, DozerBeanMapper dozer, List<ClassMap> all) {
        DozerTypeConverter converter = new DozerTypeConverter(dozer);
        for (ClassMap map : all) {
            if(logger.isInfoEnabled()) {
                logger.info("Added {} -> {} as type converter to: {}",
                        new Object[]{map.getSrcClassName(), map.getDestClassName(), registry});
            }
            registry.addTypeConverter(map.getSrcClassToMap(), map.getDestClassToMap(), converter);
            registry.addTypeConverter(map.getDestClassToMap(), map.getSrcClassToMap(), converter);
        }
    }

    private List<ClassMap> loadMappings(CamelContext camelContext, DozerBeanMapper mapper) {
        List<ClassMap> answer = new ArrayList<ClassMap>();

        // load the class map using the class resolver so we can load from classpath in OSGi
        MappingFileReader reader = new MappingFileReader(XMLParserFactory.getInstance());
        List<String> mappingFiles = mapper.getMappingFiles();
        if (mappingFiles == null) {
            return Collections.emptyList();
        }

        for (String name : mappingFiles) {
            URL url = camelContext.getClassResolver().loadResourceAsURL(name);
            MappingFileData data = reader.read(url);
            answer.addAll(data.getClassMaps());
        }

        return answer;
    }

    @Override
    public CamelContext getCamelContext() {
        return camelContext;
    }

    @Override
    public void setCamelContext(CamelContext camelContext) {
        this.camelContext = camelContext;
    }

    private TypeConverterRegistry getTypeConverterRegistry() throws Exception {
        TypeConverterRegistry registry = camelContext.getTypeConverterRegistry();
        if(registry == null) {
            TypeConverter converter = camelContext.getTypeConverter();
            if (converter != null) {
                Method method = converter.getClass().getMethod("getRegistry");
                registry = (TypeConverterRegistry) method.invoke(converter);
            }
        }
        return registry;
    }

    public void setMapper(DozerBeanMapper mapper) {
        this.mapper = mapper;
    }

}
{code}

Unfortunately the codebase is for camel 2.4, so there are some workarounds for CAMEL-3143 (Take a look at getTypeConverterRegistry method)
                  
> Dozer Type Conversion Does Not Work With Context Based Mappings (map-id)
> ------------------------------------------------------------------------
>
>                 Key: CAMEL-5031
>                 URL: https://issues.apache.org/jira/browse/CAMEL-5031
>             Project: Camel
>          Issue Type: Improvement
>          Components: bean-integration, camel-core
>    Affects Versions: 2.6.0, 2.9.0
>            Reporter: Andre Piwoni
>            Priority: Minor
>
> DozerTypeConverter utilizes DozerBeanMappper's method map(Object source, Class<T> destinationClass) to convert objects. Unfortunately, this does not work for Dozer's context based mapping with map-id because it requires call to DozerBeanMappper.map(Object source, Class<T> destinationClass, String mapId).
> Example below does not work without map-id, which is actually required for this type of mapping (see http://dozer.sourceforge.net/documentation/faq.html#complex-to-map)
> <mapping  map-id="myMapping">
>    <class-a>x.y.z.ComplexType</class-a>
>    <class-b>java.util.Map</class-b>
>    <field copy-by-reference="true">
>       <a>complexTypeField</a>
>       <b key="complexTypeFieldKeyName">this</b>
>   </field>
>   ...
> </mapping>
> DozerTypeConverterLoader has access to ClassMap and its map-id, if any, in order to construct a lookup for map-id for a given conversion pair. This is tricky, however, since there can be multiple mappings with different ids for the same conversion pair.
> Interfaces for Dozer and Camel Conversion may not be fully compatible but it would be great if at least limitations can be stated in documentation.
> Regards,
> Andre Piwoni

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira