2012-11-21 28 views
3

我使用Dozer框架Java組件之間的轉換。我想創建,以能夠操縱和配置我的自定義轉換器使用推土機,而不是XML的Java API的我映射。自定義轉換器由推土機的Java API設置不調用現場

如果我下面取出ALT 2中的代碼使用方案1運行我的轉換器 - 在XML文件映射,轉換工作正常,我的自定義轉換器調用。 如果我用我的運行轉換方案2 - 用Java API映射,映射器從來沒有調用我的轉換器。豆被轉換,但相同類型的嵌套字段被忽略,在下面的代碼,父字段是轉換後空。

Organization org = ...init organization.... 
OrganizationDto orgDto = new MyConverter().convert(organization, OrganizationDto.class); 
assertEquals(3,orgDto.getParent().getX()) //Fails due to NPE since parent field is not copied 

我知道,一流水平的定製的轉換並不通過Java API的支持,但場電平轉換器的樣子,因爲它是Java API映射在example他們提供支持。

(我也知道,推土機作者推薦使用推土機作爲一個單身,但多數民衆贊成在不低於列入樣本。)

任何提示?

public class OrganizationDto { 
    int x; 
    OrganizationDto parent ; 
    // getters and setters.... 
} 

public class Organization { 
    int x; 
    Organization parent ; 
    // getters and setters.... 
} 


public class MyConverter{ 


private DozerBeanMapper mapper = null; 

public MyConverter() { 
     mapper = new DozerBeanMapper(); 
     // Alternative 1 - works 
//   List<String> myMappingFiles = new ArrayList<String>(); 
//   myMappingFiles.add("myBeanMappings.xml"); 
//   mapper.setMappingFiles(myMappingFiles); 

     // Alternative 2 - does not work 
     Map<String,CustomConverter> customConvertersWithId = new HashMap<String, CustomConverter>(); 
     customConvertersWithId.put("OrganizationDetailsConverter", new OrganizationDetailsConverter()); 
     mapper.setCustomConvertersWithId(customConvertersWithId); 

     // Also tried variants using 
     //mapper.setCustomConverters(Collections.<CustomConverter> singletonList(new OrganizationDetailsConverter())); 

     BeanMappingBuilder builder = new BeanMappingBuilder() { 
      protected void configure() { 
       mapping(OrganizationDto.class, Organization.class) 
       .fields("parent", 
         "parent", 
         customConverterId("OrganizationDetailsConverter")); 
       } 
      };   
      mapper.addMapping(builder); 
    } 

    public <T, S> T convert(S fromBean, Class<T> toBeanClass) { 
    return mapper.map(fromBean, toBeanClass); 
    } 

} 



<?xml version="1.0" encoding="UTF-8"?> 
<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> 
     <class-a>foo.OrganizationDto</class-a> 
     <class-b>foo.Organization</class-b> 
     <field custom-converter="foo.OrganizationDetailsConverter"> 
      <a>parent</a> 
      <b>parent</b> 
     </field> 
    </mapping> 
</mappings> 

回答

1
public class DozerMap { 

    public static class ContainerA { 
     private A a; 
     public A getA() { return a; } 
     public void setA(A a) { this.a = a; } 
    } 

    public static class ContainerB { 
     private B b; 
     public B getB() { return b; } 
     public void setB(B b) { this.b = b; } 
    } 

    private static class A { }; 

    private static class B { }; 

    static class ConverterImpl extends DozerConverter<A, B> { 

     ConverterImpl() { 
     super(A.class, B.class); 
     } 

     @Override 
     public B convertTo(A source, B destination) { 
     Logger.getAnonymousLogger().info("Invoked"); 
     return destination; 
     } 

     @Override 
     public A convertFrom(B source, A destination) { 
     Logger.getAnonymousLogger().info("Invoked"); 
     return destination; 
     } 
    } 

    public static void main(String[] args) { 

     DozerBeanMapper mapper = new DozerBeanMapper(); 
     mapper.setCustomConverters(Collections.<CustomConverter> singletonList(new ConverterImpl())); 
     BeanMappingBuilder foo = new BeanMappingBuilder() { 

     @Override 
     protected void configure() { 
      mapping(ContainerA.class, ContainerB.class).fields("a", "b", FieldsMappingOptions.customConverter(ConverterImpl.class)); 
     } 
     }; 
     mapper.setMappings(Collections.singletonList(foo)); 
     ContainerA containerA = new ContainerA(); 
     containerA.a = new A(); 
     ContainerB containerB = mapper.map(containerA, ContainerB.class); 
    } 
}