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,@ObjectFactorymethods or@BeforeMapping/@AfterMappingmethods when applicable and can thus be used in custom code.The type of an
@Contextparameter is also inspected for@BeforeMapping/@AfterMappingmethods, which are called on the provided context parameter value if applicable.Note: no
nullchecks are performed before calling before/after mapping methods or object factory methods on@Contextannotated parameters. The caller needs to make sure that nonullare passed in that case.For generated code to call a method that is declared with
@Contextparameters, the declaration of the mapping method being generated needs to contain at least those (or assignable)@Contextparameters as well. MapStruct will not create new instances of missing@Contextparameters nor will it passnullinstead.Example 1: Using
@Contextparameters for passing data down to hand-written property mapping methods and@BeforeMappingmethods:// 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
@Contextparameter with a type that provides its own@BeforeMappingmethods 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
@Contextparameters for creating an entity object by calling an@ObjectFactorymethods:// 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