All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mapstruct.DecoratedWith Maven / Gradle / Ivy

There is a newer version: 1.6.3
Show newest version
/**
 *  Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
 *  and/or other contributors as indicated by the @authors tag. See the
 *  copyright.txt file in the distribution for a full listing of all
 *  contributors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.mapstruct;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Specifies a decorator to be applied to a generated mapper, which e.g. can be used to amend mappings performed by
 * generated mapping methods.
 * 

* A typical decorator implementation will be an abstract class and only implement/override a subset of the methods of * the mapper type which it decorates. All methods not implemented or overridden by the decorator will be implemented by * the code generator by delegating to the generated mapper implementation. *

* NOTE: The usage of decorated mappers differs depending on the selected component model. *

* NOTE: This annotation is not supported for the component model {@code cdi}. Use CDI's own * {@code @Decorator} feature instead. *

* NOTE: The decorator feature when used with component model {@code jsr330} is considered experimental * and it may change in future releases. *

Examples

*

* For the examples below, consider the following mapper declaration: * *

 * @Mapper(componentModel = "...")
 * @DecoratedWith(PersonMapperDecorator.class)
 * public interface PersonMapper {
 *
 *     @Mapping(target = "name", ignore = true)
 *     PersonDto personToPersonDto(Person person);
 *
 *     AddressDto addressToAddressDto(Address address); // not touched by the decorator
 * }
 * 
* *

1. Component model 'default'

*

Referencing the original mapper in the decorator

*

* If a constructor with a single parameter accepting the type of the decorated mapper is present, a delegate with * generated implementations of all the mapper methods will be passed to this constructor. A typical implementation will * store the passed delegate in a field of the decorator and make use of it in the decorator methods: * *

 * public abstract class PersonMapperDecorator implements PersonMapper {
 *
 *     private PersonMapper delegate;
 *
 *     public PersonMapperDecorator(PersonMapper delegate) {
 *         this.delegate = delegate;
 *     }
 *
 *     @Override
 *     public PersonDto personToPersonDto(Person person) {
 *         PersonDto dto = delegate.personToPersonDto( person );
 *         dto.setName( person.getFirstName() + " " + person.getLastName() );
 *
 *         return dto;
 *     }
 * }
 * 
* *

Using the decorated mapper

*

* Nothing special needs to be done. When using {@code Mappers.getMapper( PersonMapper.class )}, the decorator * is returned, with the injected original mapper. *

2. Component model 'spring'

*

Referencing the original mapper in the decorator

*

* The generated implementation of the original mapper is annotated with the Spring annotation * {@code @org.springframework.beans.factory.annotation.Qualifier("delegate")}. To autowire that bean in your decorator, * add that qualifier annotation as well: * *

 * public abstract class PersonMapperDecorator implements PersonMapper {
 *
 *     @Autowired
 *     @org.springframework.beans.factory.annotation.Qualifier("delegate")
 *     private PersonMapper delegate;
 *
 *     @Override
 *     public PersonDto personToPersonDto(Person person) {
 *         PersonDto dto = delegate.personToPersonDto( person );
 *         dto.setName( person.getFirstName() + " " + person.getLastName() );
 *
 *         return dto;
 *     }
 * }
 * 
* *

Using the decorated mapper in the decorator

*

* The generated class that extends the decorator is annotated with Spring's {@code @Primary} annotation. To autowire * the decorated mapper in the application, nothing special needs to be done: * *

 * @Autowired
 * private PersonMapper personMapper; // injects the decorator, with the injected original mapper
 * 
* *

3. Component model 'jsr330'

*

Referencing the original mapper

*

* 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 * {@code @javax.inject.Named("fully-qualified-name-of-generated-impl")} and {@code @Singleton} (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): * *

 * public abstract class PersonMapperDecorator implements PersonMapper {
 *
 *     @Inject
 *     @javax.inject.Named("org.examples.PersonMapperImpl_")
 *     private PersonMapper delegate;
 *
 *     @Override
 *     public PersonDto personToPersonDto(Person person) {
 *         PersonDto dto = delegate.personToPersonDto( person );
 *         dto.setName( person.getFirstName() + " " + person.getLastName() );
 *
 *         return dto;
 *     }
 * }
 * 
* *

Using the decorated mapper in the decorator

*

* Unlike with the other component models, the usage site must be aware if a mapper is decorated or not, as for * decorated mappers, the parameterless {@code @javax.inject.Named} annotation must be added to select the * decorator to be injected: * *

 * @Inject
 * @javax.inject.Named
 * private PersonMapper personMapper; // injects the decorator, with the injected original mapper
 * 
*

* * @author Gunnar Morling */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface DecoratedWith { /** * The decorator type. Must be an abstract class that extends or implements the mapper type to which it is applied. *

* For component-model {@code default}, the decorator type must either have a default constructor or a constructor * with a single parameter accepting the type of the decorated mapper. * * @return the decorator type */ Class value(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy