Search code examples
javadozer

Map collection size in Dozer


Is there a way to map collection size in dozer?

class Source {
    Collection<String> images;
}

class Destination {
  int numOfImages;
}

Solution

  • EDIT: I've updated my answer to use a custom converter at the field level instead of at the class level.

    There might be other solutions but one way to do this would be to use a Custom Converter. I've added getters and setters to your classes and wrote the following converter:

    package com.mycompany.samples.dozer;
    
    import java.util.Collection;
    
    import org.dozer.DozerConverter;
    
    public class TestCustomFieldConverter extends 
            DozerConverter<Collection, Integer> {
    
        public TestCustomFieldConverter() {
            super(Collection.class, Integer.class);
        }
    
        @Override
        public Integer convertTo(Collection source, Integer destination) {
            if (source != null) {
                return source.size();
            } else {
                return 0;
            }
        }
    
        @Override
        public Collection convertFrom(Integer source, Collection destination) {
            throw new IllegalStateException("Unknown value!");
        }
    }
    

    Then, declare it in a custom XML mapping file:

    <?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>com.mycompany.samples.dozer.Source</class-a>
        <class-b>com.mycompany.samples.dozer.Destination</class-b>
        <field custom-converter="com.mycompany.samples.dozer.TestCustomFieldConverter">
          <a>images</a>
          <b>numOfImages</b>
        </field>
      </mapping>        
    </mappings>
    

    With this setup, the following test passes successfully:

    @Test
    public void testCollectionToIntMapping() {
        List<String> mappingFiles = new ArrayList<String>();
        mappingFiles.add("com/mycompany/samples/dozer/somedozermapping.xml");
        Mapper mapper = new DozerBeanMapper(mappingFiles);
    
        Source sourceObject = new Source();
        sourceObject.setImages(Arrays.asList( "a", "b", "C" ));
    
        Destination destObject = mapper.map(sourceObject, Destination.class);
    
        assertEquals(3, destObject.getNumOfImages());
    }