Pergunta

Existe uma maneira de mapear o tamanho da coleta em Dozer?

class Source {
    Collection<String> images;
}

class Destination {
  int numOfImages;
}
Foi útil?

Solução

EDITAR: Atualizei minha resposta para usar um conversor personalizado no nível do campo, em vez de no nível da classe.

Pode haver outras soluções, mas uma maneira de fazer isso seria usar um Conversor personalizado. Adicionei getters e setters às suas aulas e escrevi o seguinte conversor:

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!");
    }
}

Então, declare -o em um Arquivo de mapeamento XML personalizado:

<?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>

Com esta configuração, o teste a seguir passa com sucesso:

@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());
}

Outras dicas

Aqui está uma abordagem para resolver isso com ModelMapper:

ModelMapper modelMapper = new ModelMapper();
modelMapper.createTypeMap(Source.class, Destination.class).setConverter(
    new AbstractConverter<Source, Destination>() {
      protected Destination convert(Source source) {
        Destination dest = new Destination();
        dest.numOfImages = source.images.size();
        return dest;
      }
    });

Este exemplo usa um conversor para as classes de origem e destino.

Mais exemplos e documentos podem ser encontrados em http://modelmapper.org

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top