API Mappings

XML Mapping Flaws

XML-based approach is stable and is used in many production projects. However, it imposes several limitations.

  • First, and most important, is that it can not be dynamically generated. All XML mappings should be present on Dozer start-up and can not be modified afterwards. There are tricky ways, when you can generate and put mappings to the file system by your own templating engine, but this approach is not supported by Dozer itself. By generating custom mappings you are able to automate repetitive chunks of low-level Dozer language.

  • Second problem is that you are forced to duplicate all of your Bean class names in Xml mappings. This leads to lots of typing and copy-paste programming. This can be partly compensated by use of Expression Language inside Xml, but it is not solving all of the problems.

  • Refactoring support is limited as IDE should keep track of class names in Xml files and change them when you rename or move the referenced class. Auto-completion support is also not available in all IDEs.

API Mappings

API mappings are intended to solve all of the mentioned problems. To preserve backwards compatibility API mappings can be combined with existing Xml mappings. In fact some parts of the configuration (e.g. global configuration block) are only possible to express in Xml format.

To get a feeling of what are these mappings take a look at the following code example.

import com.github.dozermapper.core.classmap.RelationshipType;
import com.github.dozermapper.core.loader.api.BeanMappingBuilder;
import com.github.dozermapper.core.loader.api.FieldsMappingOptions;
import com.github.dozermapper.core.loader.api.TypeMappingOptions;

import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.collectionStrategy;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.copyByReference;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.customConverter;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.customConverterId;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.hintA;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.hintB;
import static com.github.dozermapper.core.loader.api.FieldsMappingOptions.useMapId;
import static com.github.dozermapper.core.loader.api.TypeMappingOptions.mapId;
import static com.github.dozermapper.core.loader.api.TypeMappingOptions.mapNull;

public class MyClass {

    public void create() {
        BeanMappingBuilder builder = new BeanMappingBuilder() {
            protected void configure() {
                mapping(Bean.class, Bean.class,
                        TypeMappingOptions.oneWay(),
                        mapId("A"),
                        mapNull(true)
                )
                    .exclude("excluded")
                    .fields("src", "dest",
                            copyByReference(),
                            collectionStrategy(true, RelationshipType.NON_CUMULATIVE),
                            hintA(String.class),
                            hintB(Integer.class),
                            FieldsMappingOptions.oneWay(),
                            useMapId("A"),
                            customConverterId("id")
                    )
                    .fields("src", "dest",
                            customConverter("com.github.dozermapper.core.CustomConverter")
                    );
            }
        };
    }
}

Constructed builder object should be then passed to DozerBeanMapperBuilder. It is possible to add multiple Builder classes.

Mapper mapper = DozerBeanMapperBuilder.create()
        .withMappingBuilder(builder)
        .build();

results matching ""

    No results matching ""