Annotation Type Context
-
@Target(PARAMETER) @Retention(CLASS) public @interface Context
Marks a parameter of a method to be treated as mapping context. Such parameters are passed to other mapping methods,@
ObjectFactory
methods or@
BeforeMapping
/@
AfterMapping
methods when applicable and can thus be used in custom code.The type of an
@Context
parameter is also inspected for@
BeforeMapping
/@
AfterMapping
methods, which are called on the provided context parameter value if applicable.Note: no
null
checks are performed before calling before/after mapping methods or object factory methods on@
Context
annotated parameters. The caller needs to make sure that nonull
are passed in that case.For generated code to call a method that is declared with
@Context
parameters, the declaration of the mapping method being generated needs to contain at least those (or assignable)@Context
parameters as well. MapStruct will not create new instances of missing@Context
parameters nor will it passnull
instead.Example 1: Using
@Context
parameters for passing data down to hand-written property mapping methods and@
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
@Context
parameter with a type that provides its own@
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; }
Example 3: Using
@Context
parameters for creating an entity object by calling an@
ObjectFactory
methods:// type of the context parameter public class ContextObjectFactory { @PersistenceContext(unitName = "my-unit") private EntityManager em; @ObjectFactory public Valve create( String id ) { Query query = em.createNamedQuery("Valve.findById"); query.setParameter("id", id); Valve result = query.getSingleResult(); if ( result != null ) { result = new Valve( id ); } return result; } } @Mapper public interface ContextWithObjectFactoryMapper { Valve map(ValveDto dto, @Context ContextObjectFactory factory, String id); } // generates: public class ContextWithObjectFactoryMapperImpl implements ContextWithObjectFactoryMapper { @Override public Valve map(ValveDto dto, ContextObjectFactory factory, String id) { if ( dto == null ) { return null; } Valve valve = factory.create( id ); valve.setOneWay( dto.isOneWay() ); return valve; } }
- Since:
- 1.2
- Author:
- Andreas Gudian