From 650a53318efac674d525d1acae92b856885ac7f4 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Sat, 13 Feb 2016 22:41:36 +0100 Subject: [PATCH] #754 Avoiding numbers in section ids --- .../src/main/asciidoc/index.asciidoc | 90 +++++++++---------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/documentation/src/main/asciidoc/index.asciidoc b/documentation/src/main/asciidoc/index.asciidoc index a4a536fa6..3b34c27da 100644 --- a/documentation/src/main/asciidoc/index.asciidoc +++ b/documentation/src/main/asciidoc/index.asciidoc @@ -92,7 +92,7 @@ For Maven based projects add the following to your POM file in order to use MapS ---- ==== -[[setup-configuration-options]] +[[configuration-options]] === Configuration options The MapStruct code generator can be configured using _annotation processor options_. @@ -142,7 +142,7 @@ suppressGeneratorVersionInfoComment` |`false` |`mapstruct.defaultComponentModel` -|The name of the component model (see <>) based on which mappers should be generated. +|The name of the component model (see <>) based on which mappers should be generated. Supported values are: @@ -172,7 +172,7 @@ If a policy is given for a specific mapper via `@Mapper#unmappedTargetPolicy()`, In this section you'll learn how to define a bean mapper with MapStruct and which options you have to do so. -[[section-def-mapper-01]] +[[basic-mappings]] === Basic mappings To create a mapper simply define a Java interface with the required mapping method(s) and annotate it with the `org.mapstruct.Mapper` annotation: @@ -253,16 +253,16 @@ public class CarMapperImpl implements CarMapper { The general philosophy of MapStruct is to generate code which looks as much as possible as if you had written it yourself from hand. In particular this means that the values are copied from source to target by plain getter/setter invocations instead of reflection or similar. -As the example shows the generated code takes into account any name mappings specified via `@Mapping`. If the type of a mapped attribute is different in source and target entity, MapStruct will either apply an automatic conversion (as e.g. for the _price_ property, see also <>) or optionally invoke another mapping method (as e.g. for the _driver_ property, see also <>). +As the example shows the generated code takes into account any name mappings specified via `@Mapping`. If the type of a mapped attribute is different in source and target entity, MapStruct will either apply an automatic conversion (as e.g. for the _price_ property, see also <>) or optionally invoke another mapping method (as e.g. for the _driver_ property, see also <>). -Collection-typed attributes with the same element type will be copied by creating a new instance of the target collection type containing the elements from the source property. For collection-typed attributes with different element types each element will mapped individually and added to the target collection (see <>). +Collection-typed attributes with the same element type will be copied by creating a new instance of the target collection type containing the elements from the source property. For collection-typed attributes with different element types each element will mapped individually and added to the target collection (see <>). MapStruct takes all public properties of the source and target types into account. This includes properties declared on super-types. -[[section-def-mapper-02]] +[[mappers-from-abstract-classes]] === Generating mappers from abstract classes -In some cases it can be required to manually implement a specific mapping from one type to another which can't be generated by MapStruct. One way for this is to implement such method on another class which then is used by mappers generated by MapStruct (see <>). +In some cases it can be required to manually implement a specific mapping from one type to another which can't be generated by MapStruct. One way for this is to implement such method on another class which then is used by mappers generated by MapStruct (see <>). Alternatively you can define a mapper in form of an abstract class instead of an interface and implement custom methods directly in this mapper class. In this case MapStruct will generate an extension of the abstract class with implementations of all abstract methods. @@ -288,7 +288,7 @@ public abstract class CarMapper { MapStruct will generate a sub-class of `CarMapper` with an implementation of the `carToCarDto()` method as it is declared abstract. The generated code in `carToCarDto()` will invoke the manually implemented `personToPersonDto()` method when mapping the `driver` attribute. -[[section-def-mapper-03]] +[[mappings-with-several-source-parameters]] === Mapping methods with several source parameters MapStruct also supports mapping methods with several source parameters. This is useful e.g. in order to combine several entities into one data transfer object. The following shows an example: @@ -324,7 +324,7 @@ Specifying the parameter in which the property resides is mandatory when using t Mapping methods with several source parameters will return `null` in case all the source parameters are `null`. Otherwise the target object will be instantiated and all properties from the provided parameters will be propagated. ==== -[[section-def-mapper-04]] +[[nested-mappings]] === Nested mappings MapStruct will handle nested mappings, by means of the `.` notation: @@ -355,7 +355,7 @@ MapStruct will perform a null check on each nested property in the source. Also non java bean source parameters (like the `java.lang.Integer`) can be mapped in this fashion. ==== -[[section-def-mapper-05]] +[[updating-bean-instances]] === Updating existing bean instances In some cases you need mappings which don't create a new instance of the target type but instead update an existing instance of that type. This sort of mapping can be realized by adding a parameter for the target object and marking this parameter with `@MappingTarget`. The following shows an example: @@ -377,10 +377,10 @@ The generated code of the `updateCarFromDto()` method will upate the passed `Car Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map. -[[section-retr-mapper]] +[[retrieving-mapper]] == Retrieving a mapper -[[section-retr-mapper-01]] +[[mappers-factory]] === The Mappers factory Mapper instances can be retrieved via the `org.mapstruct.factory.Mappers` class. Just invoke the `getMapper()` method, passing the interface type of the mapper to return: @@ -426,12 +426,12 @@ CarDto dto = CarMapper.INSTANCE.carToCarDto( car ); Note that mappers generated by MapStruct are thread-safe and thus can safely be accessed from several threads at the same time. -[[section-retr-mapper-02]] +[[using-dependency-injection]] === Using dependency injection -If you're working with a dependency injection framework such as http://jcp.org/en/jsr/detail?id=346[CDI] (Contexts and Dependency Injection for Java^TM^ EE) or the http://www.springsource.org/spring-framework[Spring Framework], it is recommended to obtain mapper objects via dependency injection as well. For that purpose you can specify the component model which generated mapper classes should be based on either via `@Mapper#componentModel` or using a processor option as described in <>. +If you're working with a dependency injection framework such as http://jcp.org/en/jsr/detail?id=346[CDI] (Contexts and Dependency Injection for Java^TM^ EE) or the http://www.springsource.org/spring-framework[Spring Framework], it is recommended to obtain mapper objects via dependency injection as well. For that purpose you can specify the component model which generated mapper classes should be based on either via `@Mapper#componentModel` or using a processor option as described in <>. -Currently there is support for CDI and Spring (the later either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: +Currently there is support for CDI and Spring (the later either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: .A mapper using the CDI component model ==== @@ -459,9 +459,9 @@ private CarMapper mapper; ---- ==== -A mapper which uses other mapper classes (see <>) will obtain these mappers using the configured component model. So if `CarMapper` from the previous example was using another mapper, this other mapper would have to be an injectable CDI bean as well. +A mapper which uses other mapper classes (see <>) will obtain these mappers using the configured component model. So if `CarMapper` from the previous example was using another mapper, this other mapper would have to be an injectable CDI bean as well. -[[section-datatype-conversion]] +[[datatype-conversions]] == Data type conversions Not always a mapped attribute has the same type in the source and target objects. For instance an attribute may be of type `int` in the source bean but of type `Long` in the target bean. @@ -470,7 +470,7 @@ Another example are references to other objects which should be mapped to the co In this section you'll learn how MapStruct deals with such data type conversions. -[[section-datatype-conversion-01]] +[[implicit-type-conversions]] === Implicit type conversions MapStruct takes care of type conversions automatically in many cases. If for instance an attribute is of type `int` in the source bean but of type `String` in the target bean, the generated code will transparently perform a conversion by calling `String#valueOf(int)` and `Integer#parseInt(String)`, respectively. @@ -531,7 +531,7 @@ public interface CarMapper { * When converting from a `String`, omitting `Mapping#dateFormat` results in using the default pattern and date format symbols for the default locale. An exception to this rule is `XmlGregorianCalendar` which results in parsing the `String` according to http://www.w3.org/TR/xmlschema-2/#dateTime[XML Schema 1.0 Part 2, Section 3.2.7-14.1, Lexical Representation]. -[[section-datatype-conversion-02]] +[[mapping-object-references]] === Mapping object references Typically an object has not only primitive attributes but also references other objects. E.g. the `Car` class could contain a reference to a `Person` object (representing the car's driver) which should be mapped to a `PersonDto` object referenced by the `CarDto` class. @@ -564,7 +564,7 @@ When generating the implementation of a mapping method, MapStruct will apply the * If no such method exists MapStruct will look whether a built-in conversion for the source and target type of the attribute exists. If this is the case, the generated mapping code will apply this conversion. * Otherwise an error will be raised at build time, indicating the non-mappable attribute. -[[section-datatype-conversion-03]] +[[invoking-other-mappers]] === Invoking other mappers In addition to methods defined on the same mapper type MapStruct can also invoke mapping methods defined in other classes, be it mappers generated by MapStruct or hand-written mapping methods. This can be useful to structure your mapping code in several classes (e.g. with on mapper type per application module) or you want to provide custom mapping logic which can't be generated by MapStruct. @@ -615,7 +615,7 @@ When generating code for the implementation of the `carToCarDto()` method, MapSt Generated mappers retrieve referenced mappers using the component model configured for them. If e.g. CDI was used as component model for `CarMapper`, `DateMapper` would have to be a CDI bean as well. When using the default component model, any hand-written mapper classes to be referenced by MapStruct generated mappers must declare a public no-args constructor in order to be instantiable. -[[section-datatype-conversion-04]] +[[passing-target-type]] === Passing the mapping target type to custom mappers When having a custom mapper hooked into the generated mapper with `@Mapper#uses()`, an additional parameter of type `Class` (or a super-type of it) can be defined in the custom mapping method in order to perform general mapping tasks for specific target object types. That attribute must be annotated with `@TargetType` for MapStruct to generate calls that pass the `Class` instance representing the corresponding property type of the target bean. @@ -681,10 +681,10 @@ public class CarMapperImpl implements CarMapper { ---- ==== -[[section-datatype-conversion-05]] +[[mapping-method-resolution]] === Mapping method resolution -When mapping a property from one type to another, MapStruct looks for the most specific method which maps the source type into the target type. The method may either be declared on the same mapper interface or on another mapper which is registered via `@Mapper#uses()`. The same applies for factory methods (see <>). +When mapping a property from one type to another, MapStruct looks for the most specific method which maps the source type into the target type. The method may either be declared on the same mapper interface or on another mapper which is registered via `@Mapper#uses()`. The same applies for factory methods (see <>). The algorithm for finding a mapping or factory method resembles Java's method resolution algorithm as much as possible. In particular, methods with a more specific source type will take precedence (e.g. if there are two methods, one which maps the searched source type, and another one which maps a super-type of the same). In case more than one most-specific method is found, an error will be raised. @@ -693,7 +693,7 @@ The algorithm for finding a mapping or factory method resembles Java's method re When working with JAXB, e.g. when converting a `String` to a corresponding `JAXBElement`, MapStruct will take the `scope` and `name` attributes of `@XmlElementDecl` annotations into account when looking for a mapping method. This makes sure that the created `JAXBElement` instances will have the right QNAME value. You can find a test which maps JAXB objects https://github.com/mapstruct/mapstruct/blob/{mapstructVersion}/integrationtest/src/test/java/org/mapstruct/itest/jaxb/JaxbBasedMapperTest.java[here]. ==== -[[section-collections]] +[[mapping-collections]] == Mapping collections The mapping of collection types (`List`, `Set` etc.) is done in the same way as mapping bean types, i.e. by defining mapping methods with the required source and target types in a mapper interface. MapStruct supports a wide range of iterable types from the http://docs.oracle.com/javase/tutorial/collections/intro/index.html[Java Collection Framework]. @@ -788,7 +788,7 @@ carDto.getPassengers().addAll( personsToPersonDtos( car.getPassengers() ) ); It is not allowed to declare mapping methods with an iterable source and a non-iterable target or the other way around. An error will be raised when detecting this situation. ==== -[[section-collections-01]] +[[mapping-maps]] === Mapping maps Also map-based mapping methods are supported. The following shows an example: @@ -883,7 +883,7 @@ The option `DEFAULT` should not be used explicitely. It is used to distinguish b When working with an `adder` method and JPA entities, Mapstruct assumes that the target collections are initialized with a collection implementation (e.g. an `ArrayList`). You can use factories to create a new target entity with intialized collections in stead of Mapstruct creating the target entity by its constructor. ==== -[[section-collections-02]] +[[implementation-types-for-collection-mappings]] === Implementation types used for collection mappings When an iterable or map mapping method declares an interface type as return type, one of its implementation types will be instantiated in the generated code. The following table shows the supported interface types and their corresponding implementation types as instantiated in the generated code: @@ -914,7 +914,7 @@ When an iterable or map mapping method declares an interface type as return type |`ConcurrentNavigableMap`|`ConcurrentSkipListMap` |=== -[[section-enums]] +[[mapping-enum-types]] == Mapping enum types MapStruct supports the generation of methods which map one Java enum type into another. @@ -945,14 +945,14 @@ public interface OrderMapper { Note that an error will be raised by MapStruct in case a constant of the source enum type does not have a corresponding constant with the same name in the target type and also is not mapped to another constant via `@Mapping`. This ensures that all constants are mapped in a safe and predictable manner. -[[section-factories]] +[[object-factories]] == Object factories By default, the generated code for mapping one bean type into another will call the default constructor to instantiate the target type. Alternatively you can plug in custom object factories which will be invoked to obtain instances of the target type. One use case for this is JAXB which creates `ObjectFactory` classes for obtaining new instances of schema types. -To do make use of custom factories register them via `@Mapper#uses()` as described in <>. When creating the target object of a bean mapping, MapStruct will look for a parameterless method, or a method with only one `@TargetType` parameter that returns the required target type and invoke this method instead of calling the default constructor: +To do make use of custom factories register them via `@Mapper#uses()` as described in <>. When creating the target object of a bean mapping, MapStruct will look for a parameterless method, or a method with only one `@TargetType` parameter that returns the required target type and invoke this method instead of calling the default constructor: .Custom object factories ==== @@ -1028,7 +1028,7 @@ public class CarMapperImpl implements CarMapper { ---- ==== -[[section-exceptions]] +[[exceptions]] == Exceptions Calling applications may require handling of exceptions when calling a mapping method. These exceptions could be thrown by hand-written logic and by the generated built-in mapping methods or type-conversions of MapStruct. When the calling application requires handling of exceptions, a throws clause can be defined in the mapping method: @@ -1100,7 +1100,7 @@ public CarDto carToCarDto(Car car) throws GearException { Some **notes** on null checks. MapStruct does provide null checking only when required: when applying type-conversions or constructing a new type by invoking its constructor. This means that the user is responsible in hand-written code for returning valid non-null objects. Also null objects can be handed to hand-written code, since MapStruct does not want to make assumptions on the meaning assigned by the user to a null object. Hand-written code has to deal with this. -[[section-constants]] +[[default-values-and-constants]] == Default values and constants Default values can be specified to set a predefined value to a target property if the corresponding source property is `null`. Constants can be specified to set such a predefined value in any case. Default values and constants are specified as String values and are subject to type conversion either via built-in conversions or the invocation of other mapping methods in order to match the type required by the target property. @@ -1134,7 +1134,7 @@ public interface SourceTargetMapper { If `s.getStringProp() == null`, then the target property `stringProperty` will be set to `"undefined"` instead of applying the value from `s.getStringProp()`. If `s.getLongProp() == null`, then the target property `longProperty` will be set to `-1`. The String `"Constant Value"` is set as is to the target property `stringConstant`. The value `"3001"` is type-converted to the `Long` (wrapper) class of target property `longWrapperConstant`. Date properties also require a date format. The constant `"jack-jill-tom"` demonstrates how the hand-written class `StringListMapper` is invoked to map the dash-separated list into a `List`. -[[section-expressions]] +[[expressions]] == Expressions By means of Expressions it will be possible to include constructs from a number of languages. @@ -1181,7 +1181,7 @@ public interface SourceTargetMapper { ---- ==== -[[section-qualifiers]] +[[selection-based-on-qualifiers]] == Selection based on Qualifiers In many occasions one requires mapping methods with the same method signature (appart from the name) that have different behavior. MapStruct has a handy mechanism to deal with such situations: `@Qualifier`. A ‘qualifier’ is a custom annotation that the user can write, ‘stick onto’ a mapping method which is included as used mapper, and can be referred to in a bean property mapping, iterable mapping or map mapping. Multiple qualifiers can be ‘stuck onto’ a method and mapping. @@ -1313,7 +1313,7 @@ A class / method annotated with a qualifier will not qualify anymore for mapping The same mechanism is also present on bean mappings: `@BeanMapping#qualifiedBy`: it selects the factory method marked with the indicated qualifier. ==== -[[section-resulttype]] +[[determining-result-type]] == Determining the result type When result types have an inheritance relation, selecting either mapping method (`@Mapping`) or a factory method (`@BeanMapping`) can becomes ambigious. Suppose an Apple and a Banana, which is are both specializations of Fruit. @@ -1359,7 +1359,7 @@ The same mechanism is present on mapping: `@Mapping#resultType` and works like y The mechanism is also present on iterable mapping and map mapping. `@IterableMapping#elementTargetType` is used to select the mapping method with the desired element in the resulting `Iterable`. For the `@MapMapping` a similar purpose is served by means of `#MapMapping#keyTargetType` and `MapMapping#valueTargetType`. ==== -[[section-null-source]] +[[mapping-result-for-null-arguments]] == Controlling mapping result for 'null' arguments MapStruct offers control over the object to create when the source argument of the mapping method equals `null`. By default `null` will be returned. @@ -1373,7 +1373,7 @@ However, by specifying `nullValueMappingStrategy = NullValueMappingStrategy.RETU The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy` on mapping method level will override `@Mapper#nullValueMappingStrategy`, and `@Mapper#nullValueMappingStrategy` will override `@MappingConfig#nullValueMappingStrategy`. -[[section-inherit-config]] +[[mapping-configuration-inheritance]] == Mapping configuration inheritance Method-level configuration annotations such as `@Mapping`, `@BeanMapping`, `@IterableMapping`, etc., can be *inherited* from one mapping method to a *similar* method using the annotation `@InheritConfiguration`: @@ -1399,13 +1399,13 @@ The example above declares a mapping method `carToDto()` with a configuration to One method *A* can inherit the configuration from another method *B* if all types of *A* (source types and result type) are assignable to the corresponding types of *B*. -Methods that are considered for inheritance need to be defined in the current mapper, a super class/interface, or in the shared configuration interface (as described in <>). +Methods that are considered for inheritance need to be defined in the current mapper, a super class/interface, or in the shared configuration interface (as described in <>). In case more than one method is applicable as source for the inheritance, the method name must be specified within the annotation: `@InheritConfiguration( name = "carDtoToCar" )`. A method can use `@InheritConfiguration` and override or amend the configuration by additionally applying `@Mapping`, `@BeanMapping`, etc. -[[section-inherit-config-01]] +[[inverse-mappings]] === Inverse mappings In case of bi-directional mappings, e.g. from entity to DTO and from DTO to entity, the mapping rules for the forward method and the reverse method are often similar and can simply be inversed by switching `source` and `target`. @@ -1441,7 +1441,7 @@ If multiple methods qualify, the method from which to inherit the configuration Nested properties are excluded (silently ignored) from reverse mapping. The same holds true for expressions and constants. Reverse mapping will take place automatically when the source property name and target property name are identical. Otherwise, `@Mapping` should specify both the target name and source name. In all cases, a suitable mapping method needs to be in place for the reverse mapping. -[[section-shared-config]] +[[shared-configurations]] == Shared configurations MapStruct offers the possibility to define a shared configuration by pointing to a central interface annotated with `@MapperConfig`. For a mapper to use the shared configuration, the configuration interface needs to be defined in the `@Mapper#config` property. @@ -1511,10 +1511,10 @@ public interface SourceTargetMapper { The attributes `@Mapper#mappingInheritanceStrategy()` / `@MapperConfig#mappingInheritanceStrategy()` configure when the method-level mapping configuration annotations are inherited from prototype methods in the interface to methods in the mapper: -* `EXPLICIT` (default): the configuration will only be inherited, if the target mapping method is annotated with `@InheritConfiguration` and the source and target types are assignable to the corresponding types of the prototype method, all as described in <>. +* `EXPLICIT` (default): the configuration will only be inherited, if the target mapping method is annotated with `@InheritConfiguration` and the source and target types are assignable to the corresponding types of the prototype method, all as described in <>. * `AUTO_INHERIT_FROM_CONFIG`: the configuration will be inherited automatically, if the source and target types of the target mapping method are assignable to the corresponding types of the prototype method. If multiple prototype methods match, the ambiguity must be resolved using `@InheritConfiguration(name = ...)`. -[[section-decorators]] +[[customizing-mappers-using-decorators]] == Customizing mappings using decorators In certain cases it may be required to customize a generated mapping method, e.g. to set an additional property in the target object which can't be set by a generated method implementation. MapStruct supports this requirement using decorators. @@ -1575,7 +1575,7 @@ For a mapper with `componentModel = "default"`, define a constructor with a sing When working with the component models `spring` or `jsr330`, this needs to be handled differently. -[[section-decorators-01]] +[[decorators-with-spring]] === Decorators with Spring component model When using `@DecoratedWith` on a mapper with component model `spring`, the generated implementation of the original mapper is annotated with the Spring annotation `@Qualifier("delegate")`. To autowire that bean in your decorator, add that qualifier annotation as well: @@ -1614,7 +1614,7 @@ private PersonMapper personMapper; // injects the decorator, with the injected o ---- ==== -[[section-decorators-02]] +[[decorators-with-jsr-330]] === Decorators with JSR 330 component model JSR 330 doesn't specify qualifiers and only allows to specifically name the beans. Hence, the generated implementation of the original mapper is annotated with `@Named("fully-qualified-name-of-generated-implementation")` (please note that when using a decorator, the class name of the mapper implementation ends with an underscore). To inject that bean in your decorator, add the same annotation to the delegate field (e.g. by copy/pasting it from the generated class): @@ -1659,7 +1659,7 @@ private PersonMapper personMapper; // injects the decorator, with the injected o `@DecoratedWith` in combination with component model `jsr330` is considered experimental as of the 1.0.0.CR2 release. The way the original mapper is referenced in the decorator or the way the decorated mapper is injected in the application code might still change. ==== -[[section-before-after]] +[[customizing-mappings-with-before-and-after]] == Customizing mappings using BeforeMapping/AfterMapping methods Decorators may not always fit the needs when it comes to customizing mappers. For example, if you need to perform the customization not only for a few selected methods, but for all methods that map specific super-types: in that case, you can use *callback methods* that are invoked before the mapping starts or after the mapping finished. @@ -1715,7 +1715,7 @@ If the `@BeforeMapping` / `@AfterMapping` method has parameters, the method invo * A parameter annotated with `@TargetType` is populated with the target type of the mapping. * Any other parameter is populated with a source parameter of the mapping, whereas each source parameter is used once at most. -All before/after-mapping methods that *can* be applied to a mapping method *will* be used. <> can be used to further control which methods may be chosen and which not. For that, the qualifier annotation needs to be applied to the before/after-method and referenced in `BeanMapping#qualifiedBy` or `IterableMapping#qualifiedBy`. +All before/after-mapping methods that *can* be applied to a mapping method *will* be used. <> can be used to further control which methods may be chosen and which not. For that, the qualifier annotation needs to be applied to the before/after-method and referenced in `BeanMapping#qualifiedBy` or `IterableMapping#qualifiedBy`. The order in which the selected methods are applied is roughly determined by their location of definition (although you should consider it a *code smell* if you need to rely on their order):