org.mapstruct.Context Maven / Gradle / Ivy
Show all versions of mapstruct-jdk8 Show documentation
/**
* 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;
/**
* Marks a parameter of a method to be treated as mapping context. Such parameters are passed to other mapping
* methods, {@code @}{@link ObjectFactory} methods or {@code @}{@link BeforeMapping}/{@code @}{@link AfterMapping}
* methods when applicable and can thus be used in custom code.
*
* The type of an {@code @Context} parameter is also inspected for
* {@code @}{@link BeforeMapping}/{@code @}{@link AfterMapping} methods, which are called on the provided context
* parameter value if applicable.
*
* Note: no {@code null} checks are performed before calling before/after mapping methods on context
* parameters. The caller needs to make sure that no {@code null} are passed in that case.
*
* For generated code to call a method that is declared with {@code @Context} parameters, the declaration of the mapping
* method being generated needs to contain at least those (or assignable) {@code @Context} parameters as well. MapStruct
* will not create new instances of missing {@code @Context} parameters nor will it pass {@code null} instead.
*
* Example 1: Using {@code @Context} parameters for passing data down to hand-written property mapping
* methods and {@code @}{@link BeforeMapping} methods:
*
*
*
* // multiple @Context parameters can be added
* public abstract CarDto toCar(Car car, @Context VehicleRegistration context, @Context Locale localeToUse);
*
* protected OwnerManualDto translateOwnerManual(OwnerManual ownerManual, @Context Locale locale) {
* // manually implemented logic to translate the OwnerManual with the given Locale
* }
*
* @BeforeMapping
* protected void registerVehicle(Vehicle mappedVehicle, @Context VehicleRegistration context) {
* context.register( mappedVehicle );
* }
*
* @BeforeMapping
* protected void notCalled(Vehicle mappedVehicle, @Context DifferentMappingContextType context) {
* // not called, because no context parameter of type DifferentMappingContextType is available
* // within toCar(Car, VehicleRegistration, Locale)
* }
*
* // generates:
*
* public CarDto toCar(Car car, VehicleRegistration context, Locale localeToUse) {
* registerVehicle( car, context );
*
* if ( car == null ) {
* return null;
* }
*
* CarDto carDto = new CarDto();
*
* carDto.setOwnerManual( translateOwnerManual( car.getOwnerManual(), localeToUse );
* // more generated mapping code
*
* return carDto;
* }
*
*
*
* Example 2: Using an {@code @Context} parameter with a type that provides its own {@code @}
* {@link BeforeMapping} methods to handle cycles in Graph structures:
*
*
*
* // type of the context parameter
* public class CyclicGraphContext {
* private Map<Object, Object> knownInstances = new IdentityHashMap<>();
*
* @BeforeMapping
* public <T extends NodeDto> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
* return (T) knownInstances.get( source );
* }
*
* @BeforeMapping
* public void storeMappedInstance(Object source, @MappingTarget NodeDto target) {
* knownInstances.put( source, target );
* }
* }
*
* @Mapper
* public interface GraphMapper {
* NodeDto toNodeDto(Node node, @Context CyclicGraphContext cycleContext);
* }
*
*
* // generates:
*
* public NodeDto toNodeDto(Node node, CyclicGraphContext cycleContext) {
* NodeDto target = cycleContext.getMappedInstance( node, NodeDto.class );
* if ( target != null ) {
* return target;
* }
*
* if ( node == null ) {
* return null;
* }
*
* NodeDto nodeDto = new NodeDto();
*
* cycleContext.storeMappedInstance( node, nodeDto );
*
* nodeDto.setParent( toNodeDto( node.getParent(), cycleContext ) );
* List<NodeDto> list = nodeListToNodeDtoList( node.getChildren(), cycleContext );
* if ( list != null ) {
* nodeDto.setChildren( list );
* }
*
* // more mapping code
*
* return nodeDto;
* }
*
*
*
* @author Andreas Gudian
* @since 1.2
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.CLASS)
public @interface Context {
}