mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#975 Introduce @Context annotation for passing context parameters through generated mapping methods to custom methods
This commit is contained in:
parent
00b8ae01a1
commit
44fe197d3b
89
core-common/src/main/java/org/mapstruct/Context.java
Normal file
89
core-common/src/main/java/org/mapstruct/Context.java
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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 <em>mapping context</em>. Such parameters are passed to other mapping
|
||||
* methods, {@link ObjectFactory} methods or {@link BeforeMapping}/{@link AfterMapping} methods when applicable and can
|
||||
* thus be used in custom code. The {@link Context} parameters are otherwise ignored by MapStruct.
|
||||
* <p>
|
||||
* For generated code to call a method that is declared with {@link Context} parameters, the declaration of the mapping
|
||||
* method being generated needs to contain at least those (or assignable) {@link Context} parameters as well. MapStruct
|
||||
* will not create new instances of missing {@link Context} parameters nor will it pass {@code null} instead.
|
||||
* <p>
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
* // 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 logMappedVehicle(Vehicle mappedVehicle) {
|
||||
* // do something with the vehicle
|
||||
* }
|
||||
*
|
||||
* @BeforeMapping
|
||||
* protected void notCalled(Vehicle mappedVehicle, @Context DifferentMappingContextType context) {
|
||||
* // not called, because DifferentMappingContextType is not available
|
||||
* // within toCar(Car, VehicleRegistration, Locale)
|
||||
* }
|
||||
*
|
||||
* // generates:
|
||||
*
|
||||
* public CarDto toCar(Car car, VehicleRegistration context, Locale localeToUse) {
|
||||
* registerVehicle( car, context );
|
||||
* logMappedVehicle( car );
|
||||
*
|
||||
* if ( car == null ) {
|
||||
* return null;
|
||||
* }
|
||||
*
|
||||
* CarDto carDto = new CarDto();
|
||||
*
|
||||
* carDto.setOwnerManual( translateOwnerManual( car.getOwnerManual(), localeToUse );
|
||||
* // more generated mapping code
|
||||
*
|
||||
* return carDto;
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
* @since 1.2
|
||||
*/
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Context {
|
||||
|
||||
}
|
@ -23,7 +23,9 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
|
||||
import org.mapstruct.ap.internal.model.common.Accessibility;
|
||||
import org.mapstruct.ap.internal.model.common.ConversionContext;
|
||||
import org.mapstruct.ap.internal.model.common.Parameter;
|
||||
@ -44,8 +46,6 @@ import org.mapstruct.ap.internal.util.Strings;
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public abstract class HelperMethod implements Method {
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc }
|
||||
*
|
||||
@ -84,6 +84,11 @@ public abstract class HelperMethod implements Method {
|
||||
return getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Parameter> getContextParameters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
|
@ -189,6 +189,7 @@ public class IterableMappingMethod extends MappingMethod {
|
||||
targetType,
|
||||
method.getMapperConfiguration(),
|
||||
method.getExecutable(),
|
||||
method.getContextParameters(),
|
||||
forgedMethodHistory
|
||||
);
|
||||
|
||||
@ -238,7 +239,7 @@ public class IterableMappingMethod extends MappingMethod {
|
||||
|
||||
public Parameter getSourceParameter() {
|
||||
for ( Parameter parameter : getParameters() ) {
|
||||
if ( !parameter.isMappingTarget() ) {
|
||||
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ public class MapMappingMethod extends MappingMethod {
|
||||
targetType,
|
||||
method.getMapperConfiguration(),
|
||||
method.getExecutable(),
|
||||
method.getContextParameters(),
|
||||
history
|
||||
);
|
||||
|
||||
@ -247,7 +248,7 @@ public class MapMappingMethod extends MappingMethod {
|
||||
|
||||
public Parameter getSourceParameter() {
|
||||
for ( Parameter parameter : getParameters() ) {
|
||||
if ( !parameter.isMappingTarget() ) {
|
||||
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,8 @@ import org.mapstruct.ap.internal.model.source.Method;
|
||||
public abstract class MappingMethod extends ModelElement {
|
||||
|
||||
private final String name;
|
||||
private List<Parameter> parameters;
|
||||
private final List<Parameter> parameters;
|
||||
private final List<Parameter> sourceParameters;
|
||||
private final Type returnType;
|
||||
private final Parameter targetParameter;
|
||||
private final Accessibility accessibility;
|
||||
@ -77,6 +78,7 @@ public abstract class MappingMethod extends ModelElement {
|
||||
List<ForgedMethod> forgedMethods) {
|
||||
this.name = method.getName();
|
||||
this.parameters = parameters;
|
||||
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||
this.returnType = method.getReturnType();
|
||||
this.targetParameter = method.getMappingTargetParameter();
|
||||
this.accessibility = method.getAccessibility();
|
||||
@ -144,14 +146,6 @@ public abstract class MappingMethod extends ModelElement {
|
||||
}
|
||||
|
||||
public List<Parameter> getSourceParameters() {
|
||||
List<Parameter> sourceParameters = new ArrayList<Parameter>();
|
||||
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( !parameter.isMappingTarget() ) {
|
||||
sourceParameters.add( parameter );
|
||||
}
|
||||
}
|
||||
|
||||
return sourceParameters;
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class NestedPropertyMappingMethod extends MappingMethod {
|
||||
|
||||
public Parameter getSourceParameter() {
|
||||
for ( Parameter parameter : getParameters() ) {
|
||||
if ( !parameter.isMappingTarget() ) {
|
||||
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||
return parameter;
|
||||
}
|
||||
}
|
||||
|
@ -479,12 +479,14 @@ public class PropertyMapping extends ModelElement {
|
||||
// forge a method from the parameter type to the last entry type.
|
||||
String forgedName = Strings.joinAndCamelize( sourceReference.getElementNames() );
|
||||
forgedName = Strings.getSaveVariableName( forgedName, ctx.getNamesOfMappingsToGenerate() );
|
||||
ForgedMethod methodRef = new ForgedMethod( forgedName,
|
||||
sourceReference.getParameter().getType(),
|
||||
sourceType,
|
||||
config,
|
||||
method.getExecutable()
|
||||
);
|
||||
ForgedMethod methodRef = new ForgedMethod(
|
||||
forgedName,
|
||||
sourceReference.getParameter().getType(),
|
||||
sourceType,
|
||||
config,
|
||||
method.getExecutable(),
|
||||
method.getContextParameters() );
|
||||
|
||||
NestedPropertyMappingMethod.Builder builder = new NestedPropertyMappingMethod.Builder();
|
||||
NestedPropertyMappingMethod nestedPropertyMapping = builder
|
||||
.method( methodRef )
|
||||
@ -540,7 +542,13 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
// copy mapper configuration from the source method, its the same mapper
|
||||
MapperConfiguration config = method.getMapperConfiguration();
|
||||
ForgedMethod methodRef = new ForgedMethod( name, sourceType, targetType, config, element,
|
||||
ForgedMethod methodRef = new ForgedMethod(
|
||||
name,
|
||||
sourceType,
|
||||
targetType,
|
||||
config,
|
||||
element,
|
||||
method.getContextParameters(),
|
||||
new ForgedMethodHistory( getForgedMethodHistory( source ),
|
||||
source.getSourceErrorMessagePart(),
|
||||
targetPropertyName,
|
||||
@ -588,7 +596,14 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
// copy mapper configuration from the source method, its the same mapper
|
||||
MapperConfiguration config = method.getMapperConfiguration();
|
||||
ForgedMethod methodRef = new ForgedMethod( name, sourceType, targetType, config, element,
|
||||
ForgedMethod methodRef =
|
||||
new ForgedMethod(
|
||||
name,
|
||||
sourceType,
|
||||
targetType,
|
||||
config,
|
||||
element,
|
||||
method.getContextParameters(),
|
||||
new ForgedMethodHistory( getForgedMethodHistory( source ),
|
||||
source.getSourceErrorMessagePart(),
|
||||
targetPropertyName,
|
||||
@ -638,6 +653,7 @@ public class PropertyMapping extends ModelElement {
|
||||
targetType,
|
||||
method.getMapperConfiguration(),
|
||||
method.getExecutable(),
|
||||
method.getContextParameters(),
|
||||
getForgedMethodHistory( sourceRHS )
|
||||
);
|
||||
|
||||
|
@ -18,8 +18,15 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.model.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.VariableElement;
|
||||
|
||||
import org.mapstruct.ap.internal.prism.ContextPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingTargetPrism;
|
||||
import org.mapstruct.ap.internal.prism.TargetTypePrism;
|
||||
import org.mapstruct.ap.internal.util.Collections;
|
||||
|
||||
/**
|
||||
@ -34,18 +41,20 @@ public class Parameter extends ModelElement {
|
||||
private final Type type;
|
||||
private final boolean mappingTarget;
|
||||
private final boolean targetType;
|
||||
private final boolean mappingContext;
|
||||
|
||||
public Parameter(String name, Type type, boolean mappingTarget, boolean targetType) {
|
||||
private Parameter(String name, Type type, boolean mappingTarget, boolean targetType, boolean mappingContext) {
|
||||
// issue #909: FreeMarker doesn't like "values" as a parameter name
|
||||
this.name = "values".equals( name ) ? "values_" : name;
|
||||
this.originalName = name;
|
||||
this.type = type;
|
||||
this.mappingTarget = mappingTarget;
|
||||
this.targetType = targetType;
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
public Parameter(String name, Type type) {
|
||||
this( name, type, false, false );
|
||||
this( name, type, false, false, false );
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@ -66,7 +75,9 @@ public class Parameter extends ModelElement {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ( mappingTarget ? "@MappingTarget " : "" ) + ( targetType ? "@TargetType " : "" )
|
||||
return ( mappingTarget ? "@MappingTarget " : "" )
|
||||
+ ( targetType ? "@TargetType " : "" )
|
||||
+ ( mappingContext ? "@Context " : "" )
|
||||
+ type.toString() + " " + name;
|
||||
}
|
||||
|
||||
@ -79,6 +90,10 @@ public class Parameter extends ModelElement {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
public boolean isMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
@ -100,4 +115,45 @@ public class Parameter extends ModelElement {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Parameter forElementAndType(VariableElement element, Type parameterType) {
|
||||
return new Parameter(
|
||||
element.getSimpleName().toString(),
|
||||
parameterType,
|
||||
MappingTargetPrism.getInstanceOn( element ) != null,
|
||||
TargetTypePrism.getInstanceOn( element ) != null,
|
||||
ContextPrism.getInstanceOn( element ) != null );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parameters the parameters to filter
|
||||
* @return the parameters from the given list that are considered 'source parameters'
|
||||
*/
|
||||
public static List<Parameter> getSourceParameters(List<Parameter> parameters) {
|
||||
List<Parameter> sourceParameters = new ArrayList<Parameter>( parameters.size() );
|
||||
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( !parameter.isMappingTarget() && !parameter.isTargetType() && !parameter.isMappingContext() ) {
|
||||
sourceParameters.add( parameter );
|
||||
}
|
||||
}
|
||||
|
||||
return sourceParameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parameters the parameters to filter
|
||||
* @return the parameters from the given list that are marked as 'mapping context parameters'
|
||||
*/
|
||||
public static List<Parameter> getContextParameters(List<Parameter> parameters) {
|
||||
List<Parameter> contextParameters = new ArrayList<Parameter>( parameters.size() );
|
||||
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( parameter.isMappingContext() ) {
|
||||
contextParameters.add( parameter );
|
||||
}
|
||||
}
|
||||
|
||||
return contextParameters;
|
||||
}
|
||||
}
|
||||
|
@ -34,12 +34,15 @@ public class ParameterBinding {
|
||||
private final String variableName;
|
||||
private final boolean targetType;
|
||||
private final boolean mappingTarget;
|
||||
private final boolean mappingContext;
|
||||
|
||||
private ParameterBinding(Type parameterType, String variableName, boolean mappingTarget, boolean targetType) {
|
||||
private ParameterBinding(Type parameterType, String variableName, boolean mappingTarget, boolean targetType,
|
||||
boolean mappingContext) {
|
||||
this.type = parameterType;
|
||||
this.variableName = variableName;
|
||||
this.targetType = targetType;
|
||||
this.mappingTarget = mappingTarget;
|
||||
this.mappingContext = mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,6 +66,13 @@ public class ParameterBinding {
|
||||
return mappingTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true}, if the parameter being bound is a {@code @MappingContext} parameter.
|
||||
*/
|
||||
public boolean isMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type of the parameter that is bound
|
||||
*/
|
||||
@ -87,7 +97,8 @@ public class ParameterBinding {
|
||||
parameter.getType(),
|
||||
parameter.getName(),
|
||||
parameter.isMappingTarget(),
|
||||
parameter.isTargetType() );
|
||||
parameter.isTargetType(),
|
||||
parameter.isMappingContext() );
|
||||
}
|
||||
|
||||
public static List<ParameterBinding> fromParameters(List<Parameter> parameters) {
|
||||
@ -103,7 +114,7 @@ public class ParameterBinding {
|
||||
* @return a parameter binding representing a target type parameter
|
||||
*/
|
||||
public static ParameterBinding forTargetTypeBinding(Type classTypeOf) {
|
||||
return new ParameterBinding( classTypeOf, null, false, true );
|
||||
return new ParameterBinding( classTypeOf, null, false, true, false );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,7 +122,7 @@ public class ParameterBinding {
|
||||
* @return a parameter binding representing a mapping target parameter
|
||||
*/
|
||||
public static ParameterBinding forMappingTargetBinding(Type resultType) {
|
||||
return new ParameterBinding( resultType, null, true, false );
|
||||
return new ParameterBinding( resultType, null, true, false, false );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,6 +130,6 @@ public class ParameterBinding {
|
||||
* @return a parameter binding representing a mapping source type
|
||||
*/
|
||||
public static ParameterBinding forSourceTypeBinding(Type sourceType) {
|
||||
return new ParameterBinding( sourceType, null, false, false );
|
||||
return new ParameterBinding( sourceType, null, false, false, false );
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ConcurrentNavigableMap;
|
||||
import java.util.concurrent.ConcurrentSkipListMap;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@ -52,8 +53,6 @@ import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.lang.model.util.Types;
|
||||
|
||||
import org.mapstruct.ap.internal.prism.MappingTargetPrism;
|
||||
import org.mapstruct.ap.internal.prism.TargetTypePrism;
|
||||
import org.mapstruct.ap.internal.util.AnnotationProcessingException;
|
||||
import org.mapstruct.ap.internal.util.Collections;
|
||||
import org.mapstruct.ap.internal.util.accessor.Accessor;
|
||||
@ -321,11 +320,7 @@ public class TypeFactory {
|
||||
VariableElement parameter = varIt.next();
|
||||
TypeMirror parameterType = typesIt.next();
|
||||
|
||||
result.add( new Parameter(
|
||||
parameter.getSimpleName().toString(),
|
||||
getType( parameterType ),
|
||||
MappingTargetPrism.getInstanceOn( parameter ) != null,
|
||||
TargetTypePrism.getInstanceOn( parameter ) != null ) );
|
||||
result.add( Parameter.forElementAndType( parameter, getType( parameterType ) ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -18,10 +18,8 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.model.source;
|
||||
|
||||
import static org.mapstruct.ap.internal.util.Collections.first;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
@ -45,7 +43,10 @@ public class ForgedMethod implements Method {
|
||||
private final ExecutableElement positionHintElement;
|
||||
private final List<Type> thrownTypes;
|
||||
private final MapperConfiguration mapperConfiguration;
|
||||
private ForgedMethodHistory history;
|
||||
private final ForgedMethodHistory history;
|
||||
|
||||
private final List<Parameter> sourceParameters;
|
||||
private final List<Parameter> contextParameters;
|
||||
|
||||
/**
|
||||
* Creates a new forged method with the given name.
|
||||
@ -55,17 +56,11 @@ public class ForgedMethod implements Method {
|
||||
* @param targetType the target type.
|
||||
* @param mapperConfiguration the mapper configuration
|
||||
* @param positionHintElement element used to for reference to the position in the source file.
|
||||
* @param additionalParameters additional parameters to add to the forged method
|
||||
*/
|
||||
public ForgedMethod(String name, Type sourceType, Type targetType, MapperConfiguration mapperConfiguration,
|
||||
ExecutableElement positionHintElement) {
|
||||
String sourceParamName = Strings.decapitalize( sourceType.getName() );
|
||||
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
||||
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
||||
this.returnType = targetType;
|
||||
this.thrownTypes = new ArrayList<Type>();
|
||||
this.name = Strings.sanitizeIdentifierName( name );
|
||||
this.mapperConfiguration = mapperConfiguration;
|
||||
this.positionHintElement = positionHintElement;
|
||||
ExecutableElement positionHintElement, List<Parameter> additionalParameters) {
|
||||
this( name, sourceType, targetType, mapperConfiguration, positionHintElement, additionalParameters, null );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,13 +71,21 @@ public class ForgedMethod implements Method {
|
||||
* @param targetType the target type.
|
||||
* @param mapperConfiguration the mapper configuration
|
||||
* @param positionHintElement element used to for reference to the position in the source file.
|
||||
* @param additionalParameters additional parameters to add to the forged method
|
||||
* @param history a parent forged method if this is a forged method within a forged method
|
||||
*/
|
||||
public ForgedMethod(String name, Type sourceType, Type targetType, MapperConfiguration mapperConfiguration,
|
||||
ExecutableElement positionHintElement, ForgedMethodHistory history) {
|
||||
ExecutableElement positionHintElement, List<Parameter> additionalParameters,
|
||||
ForgedMethodHistory history) {
|
||||
String sourceParamName = Strings.decapitalize( sourceType.getName() );
|
||||
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
||||
this.parameters = Arrays.asList( new Parameter( sourceParamSafeName, sourceType ) );
|
||||
|
||||
this.parameters = new ArrayList<Parameter>( 1 + additionalParameters.size() );
|
||||
this.parameters.add( new Parameter( sourceParamSafeName, sourceType ) );
|
||||
this.parameters.addAll( additionalParameters );
|
||||
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||
this.contextParameters = Parameter.getContextParameters( parameters );
|
||||
|
||||
this.returnType = targetType;
|
||||
this.thrownTypes = new ArrayList<Type>();
|
||||
this.name = Strings.sanitizeIdentifierName( name );
|
||||
@ -102,6 +105,11 @@ public class ForgedMethod implements Method {
|
||||
this.thrownTypes = new ArrayList<Type>();
|
||||
this.mapperConfiguration = forgedMethod.mapperConfiguration;
|
||||
this.positionHintElement = forgedMethod.positionHintElement;
|
||||
this.history = forgedMethod.history;
|
||||
|
||||
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||
this.contextParameters = Parameter.getContextParameters( parameters );
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ -112,12 +120,19 @@ public class ForgedMethod implements Method {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( parameters.size() != 1 || sourceTypes.size() != 1 ) {
|
||||
if ( parameters.size() != sourceTypes.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !first( sourceTypes ).equals( first( parameters ).getType() ) ) {
|
||||
return false;
|
||||
Iterator<Type> srcTypeIt = sourceTypes.iterator();
|
||||
Iterator<Parameter> paramIt = parameters.iterator();
|
||||
|
||||
while ( srcTypeIt.hasNext() && paramIt.hasNext() ) {
|
||||
Type sourceType = srcTypeIt.next();
|
||||
Parameter param = paramIt.next();
|
||||
if ( !sourceType.equals( param.getType() ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -140,7 +155,12 @@ public class ForgedMethod implements Method {
|
||||
|
||||
@Override
|
||||
public List<Parameter> getSourceParameters() {
|
||||
return parameters;
|
||||
return sourceParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Parameter> getContextParameters() {
|
||||
return contextParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -70,15 +70,23 @@ public interface Method {
|
||||
List<Parameter> getParameters();
|
||||
|
||||
/**
|
||||
* returns the list of 'true' source parameters excluding the parameter(s) that is designated as
|
||||
* target by means of the target annotation {@link #getMappingTargetParameter() }.
|
||||
* returns the list of 'true' source parameters excluding the parameter(s) that are designated as target, target
|
||||
* type or context parameter.
|
||||
*
|
||||
* @return list of 'true' source parameters
|
||||
*/
|
||||
List<Parameter> getSourceParameters();
|
||||
|
||||
/**
|
||||
* Returns the parameter designated as mapping target (if present) {@link org.mapstruct.MappingTarget }
|
||||
* returns the list of mapping context parameters, i.e. those parameters that are annotated with
|
||||
* {@link org.mapstruct.Context}.
|
||||
*
|
||||
* @return list of context parameters
|
||||
*/
|
||||
List<Parameter> getContextParameters();
|
||||
|
||||
/**
|
||||
* Returns the parameter designated as mapping target (if present) {@link org.mapstruct.MappingTarget}
|
||||
*
|
||||
* @return mapping target parameter (when present) null otherwise.
|
||||
*/
|
||||
|
@ -69,7 +69,8 @@ public class SourceMethod implements Method {
|
||||
private final List<SourceMethod> prototypeMethods;
|
||||
private final Type mapperToImplement;
|
||||
|
||||
private List<Parameter> sourceParameters;
|
||||
private final List<Parameter> sourceParameters;
|
||||
private final List<Parameter> contextParameters;
|
||||
|
||||
private List<String> parameterNames;
|
||||
|
||||
@ -100,9 +101,6 @@ public class SourceMethod implements Method {
|
||||
private List<SourceMethod> prototypeMethods = Collections.emptyList();
|
||||
private List<ValueMapping> valueMappings;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder setDeclaringMapper(Type declaringMapper) {
|
||||
this.declaringMapper = declaringMapper;
|
||||
return this;
|
||||
@ -226,6 +224,9 @@ public class SourceMethod implements Method {
|
||||
|
||||
this.mappingOptions = mappingOptions;
|
||||
|
||||
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||
this.contextParameters = Parameter.getContextParameters( parameters );
|
||||
|
||||
this.mappingTargetParameter = determineMappingTargetParameter( parameters );
|
||||
this.targetTypeParameter = determineTargetTypeParameter( parameters );
|
||||
this.isObjectFactory = determineIfIsObjectFactory( executable );
|
||||
@ -239,9 +240,11 @@ public class SourceMethod implements Method {
|
||||
|
||||
private boolean determineIfIsObjectFactory(ExecutableElement executable) {
|
||||
boolean hasFactoryAnnotation = ObjectFactoryPrism.getInstanceOn( executable ) != null;
|
||||
boolean isFactoryWithTargeTypeAnnotation = getTargetTypeParameter() != null && getSourceParameters().isEmpty();
|
||||
return !returnType.isVoid()
|
||||
&& ( hasFactoryAnnotation || isFactoryWithTargeTypeAnnotation || parameters.isEmpty() );
|
||||
boolean hasNoSourceParameters = getSourceParameters().isEmpty();
|
||||
boolean hasNoMappingTargetParam = getMappingTargetParameter() == null;
|
||||
return !isLifecycleCallbackMethod() && !returnType.isVoid()
|
||||
&& hasNoMappingTargetParam
|
||||
&& ( hasFactoryAnnotation || hasNoSourceParameters );
|
||||
}
|
||||
|
||||
private Parameter determineMappingTargetParameter(Iterable<Parameter> parameters) {
|
||||
@ -264,9 +267,6 @@ public class SourceMethod implements Method {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public Type getDeclaringMapper() {
|
||||
return declaringMapper;
|
||||
@ -277,40 +277,26 @@ public class SourceMethod implements Method {
|
||||
return executable;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
return executable.getSimpleName().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public List<Parameter> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public List<Parameter> getSourceParameters() {
|
||||
if ( sourceParameters == null ) {
|
||||
sourceParameters = new ArrayList<Parameter>();
|
||||
|
||||
for ( Parameter parameter : parameters ) {
|
||||
if ( !parameter.isMappingTarget() && !parameter.isTargetType() ) {
|
||||
sourceParameters.add( parameter );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sourceParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Parameter> getContextParameters() {
|
||||
return contextParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getParameterNames() {
|
||||
if ( parameterNames == null ) {
|
||||
@ -331,9 +317,6 @@ public class SourceMethod implements Method {
|
||||
return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public Type getReturnType() {
|
||||
return returnType;
|
||||
@ -544,9 +527,6 @@ public class SourceMethod implements Method {
|
||||
return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc} {@link Method}
|
||||
*/
|
||||
@Override
|
||||
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||
MethodMatcher matcher = new MethodMatcher( typeUtils, typeFactory, this );
|
||||
@ -614,5 +594,4 @@ public class SourceMethod implements Method {
|
||||
public boolean isUpdateMethod() {
|
||||
return getMappingTargetParameter() != null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -103,6 +103,11 @@ public abstract class BuiltInMethod implements Method {
|
||||
return getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Parameter> getContextParameters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
|
@ -62,7 +62,7 @@ public class TypeSelector implements MethodSelector {
|
||||
availableBindings = getAvailableParameterBindingsFromMethod( mappingMethod );
|
||||
}
|
||||
else {
|
||||
availableBindings = getAvailableParameterBindingsFromSourceTypes( sourceTypes, targetType );
|
||||
availableBindings = getAvailableParameterBindingsFromSourceTypes( sourceTypes, targetType, mappingMethod );
|
||||
}
|
||||
|
||||
for ( SelectedMethod<T> method : methods ) {
|
||||
@ -91,7 +91,7 @@ public class TypeSelector implements MethodSelector {
|
||||
}
|
||||
|
||||
private List<ParameterBinding> getAvailableParameterBindingsFromSourceTypes(List<Type> sourceTypes,
|
||||
Type targetType) {
|
||||
Type targetType, Method mappingMethod) {
|
||||
|
||||
List<ParameterBinding> availableParams = new ArrayList<ParameterBinding>( sourceTypes.size() + 2 );
|
||||
|
||||
@ -101,6 +101,12 @@ public class TypeSelector implements MethodSelector {
|
||||
availableParams.add( ParameterBinding.forSourceTypeBinding( sourceType ) );
|
||||
}
|
||||
|
||||
for ( Parameter param : mappingMethod.getParameters() ) {
|
||||
if ( param.isMappingContext() ) {
|
||||
availableParams.add( ParameterBinding.fromParameter( param ) );
|
||||
}
|
||||
}
|
||||
|
||||
return availableParams;
|
||||
}
|
||||
|
||||
@ -185,7 +191,8 @@ public class TypeSelector implements MethodSelector {
|
||||
|
||||
for ( ParameterBinding candidate : candidateParameters ) {
|
||||
if ( parameter.isTargetType() == candidate.isTargetType()
|
||||
&& parameter.isMappingTarget() == candidate.isMappingTarget() ) {
|
||||
&& parameter.isMappingTarget() == candidate.isMappingTarget()
|
||||
&& parameter.isMappingContext() == candidate.isMappingContext() ) {
|
||||
result.add( candidate );
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlElementRef;
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.BeanMapping;
|
||||
import org.mapstruct.BeforeMapping;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.DecoratedWith;
|
||||
import org.mapstruct.InheritConfiguration;
|
||||
import org.mapstruct.InheritInverseConfiguration;
|
||||
@ -69,6 +70,7 @@ import net.java.dev.hickory.prism.GeneratePrisms;
|
||||
@GeneratePrism(value = BeforeMapping.class, publicAccess = true),
|
||||
@GeneratePrism(value = ValueMapping.class, publicAccess = true),
|
||||
@GeneratePrism(value = ValueMappings.class, publicAccess = true),
|
||||
@GeneratePrism(value = Context.class, publicAccess = true),
|
||||
|
||||
// external types
|
||||
@GeneratePrism(value = XmlElementDecl.class, publicAccess = true),
|
||||
|
@ -23,8 +23,10 @@ import static org.mapstruct.ap.internal.util.Executables.getAllEnclosedExecutabl
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
@ -215,7 +217,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
List<SourceMethod> prototypeMethods ) {
|
||||
Type returnType = typeFactory.getReturnType( methodType );
|
||||
List<Type> exceptionTypes = typeFactory.getThrownTypes( methodType );
|
||||
List<Parameter> sourceParameters = extractSourceParameters( parameters );
|
||||
List<Parameter> sourceParameters = Parameter.getSourceParameters( parameters );
|
||||
List<Parameter> contextParameters = Parameter.getContextParameters( parameters );
|
||||
Parameter targetParameter = extractTargetParameter( parameters );
|
||||
Type resultType = selectResultType( returnType, targetParameter );
|
||||
|
||||
@ -223,6 +226,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
method,
|
||||
sourceParameters,
|
||||
targetParameter,
|
||||
contextParameters,
|
||||
resultType,
|
||||
returnType,
|
||||
containsTargetTypeParameter
|
||||
@ -316,20 +320,17 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
if ( param.isMappingTarget() ) {
|
||||
targetParameters++;
|
||||
}
|
||||
|
||||
if ( param.isTargetType() ) {
|
||||
else if ( param.isTargetType() ) {
|
||||
targetTypeParameters++;
|
||||
}
|
||||
|
||||
if ( !param.isMappingTarget() && !param.isTargetType() ) {
|
||||
else if ( !param.isMappingContext() ) {
|
||||
validSourceParameters++;
|
||||
}
|
||||
}
|
||||
|
||||
return validSourceParameters == sourceParamCount
|
||||
&& targetParameters <= targetParamCount
|
||||
&& targetTypeParameters <= 1
|
||||
&& parameters.size() == validSourceParameters + targetParameters + targetTypeParameters;
|
||||
&& targetTypeParameters <= 1;
|
||||
}
|
||||
|
||||
private Parameter extractTargetParameter(List<Parameter> parameters) {
|
||||
@ -342,17 +343,6 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Parameter> extractSourceParameters(List<Parameter> parameters) {
|
||||
List<Parameter> sourceParameters = new ArrayList<Parameter>( parameters.size() );
|
||||
for ( Parameter param : parameters ) {
|
||||
if ( !param.isMappingTarget() ) {
|
||||
sourceParameters.add( param );
|
||||
}
|
||||
}
|
||||
|
||||
return sourceParameters;
|
||||
}
|
||||
|
||||
private Type selectResultType(Type returnType, Parameter targetParameter) {
|
||||
if ( null != targetParameter ) {
|
||||
return targetParameter.getType();
|
||||
@ -363,14 +353,16 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
}
|
||||
|
||||
private boolean checkParameterAndReturnType(ExecutableElement method, List<Parameter> sourceParameters,
|
||||
Parameter targetParameter, Type resultType, Type returnType,
|
||||
Parameter targetParameter, List<Parameter> contextParameters,
|
||||
Type resultType, Type returnType,
|
||||
boolean containsTargetTypeParameter) {
|
||||
if ( sourceParameters.isEmpty() ) {
|
||||
messager.printMessage( method, Message.RETRIEVAL_NO_INPUT_ARGS );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( targetParameter != null && ( sourceParameters.size() + 1 != method.getParameters().size() ) ) {
|
||||
if ( targetParameter != null
|
||||
&& ( sourceParameters.size() + contextParameters.size() + 1 != method.getParameters().size() ) ) {
|
||||
messager.printMessage( method, Message.RETRIEVAL_DUPLICATE_MAPPING_TARGETS );
|
||||
return false;
|
||||
}
|
||||
@ -393,6 +385,14 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
||||
}
|
||||
}
|
||||
|
||||
Set<Type> contextParameterTypes = new HashSet<Type>();
|
||||
for ( Parameter contextParameter : contextParameters ) {
|
||||
if ( !contextParameterTypes.add( contextParameter.getType() ) ) {
|
||||
messager.printMessage( method, Message.RETRIEVAL_CONTEXT_PARAMS_WITH_SAME_TYPE );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( returnType.isTypeVar() || resultType.isTypeVar() ) {
|
||||
messager.printMessage( method, Message.RETRIEVAL_TYPE_VAR_RESULT );
|
||||
return false;
|
||||
|
@ -98,6 +98,7 @@ public enum Message {
|
||||
RETRIEVAL_TYPE_VAR_RESULT( "Can't generate mapping method for a generic type variable target." ),
|
||||
RETRIEVAL_WILDCARD_SUPER_BOUND_SOURCE( "Can't generate mapping method for a wildcard super bound source." ),
|
||||
RETRIEVAL_WILDCARD_EXTENDS_BOUND_RESULT( "Can't generate mapping method for a wildcard extends bound result." ),
|
||||
RETRIEVAL_CONTEXT_PARAMS_WITH_SAME_TYPE( "The types of @Context parameters must be unique." ),
|
||||
|
||||
INHERITCONFIGURATION_BOTH( "Method cannot be annotated with both a @InheritConfiguration and @InheritInverseConfiguration." ),
|
||||
INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ),
|
||||
|
@ -37,7 +37,9 @@
|
||||
<#-- a class is passed on for casting, see @TargetType -->
|
||||
<@includeModel object=ext.targetType raw=true/>.class<#t>
|
||||
<#elseif param.mappingTarget>
|
||||
${ext.targetBeanName}<#if ext.targetReadAccessorName??>.${ext.targetReadAccessorName}</#if><#t>
|
||||
${ext.targetBeanName}<#if ext.targetReadAccessorName??>.${ext.targetReadAccessorName}</#if><#t>
|
||||
<#elseif param.mappingContext>
|
||||
${param.variableName}<#t>
|
||||
<#elseif assignment??>
|
||||
<@_assignment/><#t>
|
||||
<#else>
|
||||
|
@ -21,17 +21,17 @@ package org.mapstruct.ap.test.callbacks.returning;
|
||||
/**
|
||||
* @author Pascal Grün
|
||||
*/
|
||||
public class AttributeDTO {
|
||||
private NodeDTO node;
|
||||
public class AttributeDto {
|
||||
|
||||
private NodeDto node;
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public NodeDTO getNode() {
|
||||
public NodeDto getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(NodeDTO node) {
|
||||
public void setNode(NodeDto node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
@ -53,6 +53,6 @@ public class AttributeDTO {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AttributeDTO [name=" + name + ", value=" + value + "]";
|
||||
return "AttributeDto [name=" + name + ", value=" + value + "]";
|
||||
}
|
||||
}
|
@ -36,7 +36,7 @@ import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
* @author Pascal Grün
|
||||
*/
|
||||
@IssueKey( "469" )
|
||||
@WithClasses( { Attribute.class, AttributeDTO.class, Node.class, NodeDTO.class, NodeMapperDefault.class,
|
||||
@WithClasses( { Attribute.class, AttributeDto.class, Node.class, NodeDto.class, NodeMapperDefault.class,
|
||||
NodeMapperWithContext.class, NodeMapperContext.class, Number.class, NumberMapperDefault.class,
|
||||
NumberMapperContext.class, NumberMapperWithContext.class } )
|
||||
@RunWith( AnnotationProcessorTestRunner.class )
|
||||
@ -44,13 +44,13 @@ public class CallbacksWithReturnValuesTest {
|
||||
@Test( expected = StackOverflowError.class )
|
||||
public void mappingWithDefaultHandlingRaisesStackOverflowError() {
|
||||
Node root = buildNodes();
|
||||
NodeMapperDefault.INSTANCE.nodeToNodeDTO( root );
|
||||
NodeMapperDefault.INSTANCE.nodeToNodeDto( root );
|
||||
}
|
||||
|
||||
@Test( expected = StackOverflowError.class )
|
||||
public void updatingWithDefaultHandlingRaisesStackOverflowError() {
|
||||
Node root = buildNodes();
|
||||
NodeMapperDefault.INSTANCE.nodeToNodeDTO( root, new NodeDTO() );
|
||||
NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() );
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -66,8 +66,8 @@ public class CallbacksWithReturnValuesTest {
|
||||
NodeMapperContext.addContextListener( contextListener );
|
||||
try {
|
||||
Node root = buildNodes();
|
||||
NodeDTO rootDTO = NodeMapperWithContext.INSTANCE.nodeToNodeDTO( root );
|
||||
assertThat( rootDTO ).isNotNull();
|
||||
NodeDto rootDto = NodeMapperWithContext.INSTANCE.nodeToNodeDto( root );
|
||||
assertThat( rootDto ).isNotNull();
|
||||
assertThat( contextLevel.get() ).isEqualTo( Integer.valueOf( 1 ) );
|
||||
}
|
||||
finally {
|
||||
|
@ -23,19 +23,18 @@ import java.util.List;
|
||||
/**
|
||||
* @author Pascal Grün
|
||||
*/
|
||||
public class NodeDTO {
|
||||
private NodeDTO parent;
|
||||
public class NodeDto {
|
||||
|
||||
private NodeDto parent;
|
||||
private String name;
|
||||
private List<NodeDto> children;
|
||||
private List<AttributeDto> attributes;
|
||||
|
||||
private List<NodeDTO> children;
|
||||
private List<AttributeDTO> attributes;
|
||||
|
||||
public NodeDTO getParent() {
|
||||
public NodeDto getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(NodeDTO parent) {
|
||||
public void setParent(NodeDto parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@ -47,24 +46,24 @@ public class NodeDTO {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<NodeDTO> getChildren() {
|
||||
public List<NodeDto> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<NodeDTO> children) {
|
||||
public void setChildren(List<NodeDto> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public List<AttributeDTO> getAttributes() {
|
||||
public List<AttributeDto> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(List<AttributeDTO> attributes) {
|
||||
public void setAttributes(List<AttributeDto> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NodeDTO [name=" + name + "]";
|
||||
return "NodeDto [name=" + name + "]";
|
||||
}
|
||||
}
|
@ -29,11 +29,11 @@ import org.mapstruct.factory.Mappers;
|
||||
public abstract class NodeMapperDefault {
|
||||
public static final NodeMapperDefault INSTANCE = Mappers.getMapper( NodeMapperDefault.class );
|
||||
|
||||
public abstract NodeDTO nodeToNodeDTO(Node node);
|
||||
public abstract NodeDto nodeToNodeDto(Node node);
|
||||
|
||||
public abstract void nodeToNodeDTO(Node node, @MappingTarget NodeDTO nodeDto);
|
||||
public abstract void nodeToNodeDto(Node node, @MappingTarget NodeDto nodeDto);
|
||||
|
||||
protected abstract AttributeDTO attributeToAttributeDTO(Attribute attribute);
|
||||
protected abstract AttributeDto attributeToAttributeDto(Attribute attribute);
|
||||
|
||||
protected abstract void attributeToAttributeDTO(Attribute attribute, @MappingTarget AttributeDTO nodeDto);
|
||||
protected abstract void attributeToAttributeDto(Attribute attribute, @MappingTarget AttributeDto nodeDto);
|
||||
}
|
||||
|
@ -29,11 +29,11 @@ import org.mapstruct.factory.Mappers;
|
||||
public abstract class NodeMapperWithContext {
|
||||
public static final NodeMapperWithContext INSTANCE = Mappers.getMapper( NodeMapperWithContext.class );
|
||||
|
||||
public abstract NodeDTO nodeToNodeDTO(Node node);
|
||||
public abstract NodeDto nodeToNodeDto(Node node);
|
||||
|
||||
public abstract void nodeToNodeDTO(Node node, @MappingTarget NodeDTO nodeDto);
|
||||
public abstract void nodeToNodeDto(Node node, @MappingTarget NodeDto nodeDto);
|
||||
|
||||
protected abstract AttributeDTO attributeToAttributeDTO(Attribute attribute);
|
||||
protected abstract AttributeDto attributeToAttributeDto(Attribute attribute);
|
||||
|
||||
protected abstract void attributeToAttributeDTO(Attribute attribute, @MappingTarget AttributeDTO nodeDto);
|
||||
protected abstract void attributeToAttributeDto(Attribute attribute, @MappingTarget AttributeDto nodeDto);
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@Mapper(uses = CycleContextLifecycleMethods.class)
|
||||
public interface AutomappingNodeMapperWithContext {
|
||||
|
||||
AutomappingNodeMapperWithContext INSTANCE =
|
||||
Mappers.getMapper( AutomappingNodeMapperWithContext.class );
|
||||
|
||||
NodeDto nodeToNodeDto(Node node, @Context CycleContext cycleContext, @Context FactoryContext factoryContext);
|
||||
|
||||
void nodeToNodeDto(Node node, @MappingTarget NodeDto nodeDto, @Context CycleContext cycleContext,
|
||||
@Context FactoryContext factoryContext);
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.ap.test.context.erroneous.ErroneousNodeMapperWithNonUniqueContextTypes;
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
/**
|
||||
* Tests the erroneous usage of the {@link Context} annotation in the following situations:
|
||||
* <ul>
|
||||
* <li>using the the same context parameter type twice in the same method
|
||||
* </ul>
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@IssueKey("975")
|
||||
@WithClasses({
|
||||
Node.class,
|
||||
NodeDto.class,
|
||||
CycleContext.class })
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
public class ContextParameterErroneousTest {
|
||||
|
||||
@Test
|
||||
@WithClasses(ErroneousNodeMapperWithNonUniqueContextTypes.class)
|
||||
@ExpectedCompilationOutcome(value = CompilationResult.FAILED,
|
||||
diagnostics = @Diagnostic(
|
||||
kind = Kind.ERROR,
|
||||
line = 33,
|
||||
type = ErroneousNodeMapperWithNonUniqueContextTypes.class,
|
||||
messageRegExp = "The types of @Context parameters must be unique"))
|
||||
public void reportsNonUniqueContextParamType() {
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.BeforeMapping;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.ObjectFactory;
|
||||
import org.mapstruct.ap.test.context.Node.Attribute;
|
||||
import org.mapstruct.ap.test.context.NodeDto.AttributeDto;
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
/**
|
||||
* Tests the usage of the {@link Context} annotation in the following situations:
|
||||
* <ul>
|
||||
* <li>passing the parameter to property mapping methods (create and update)
|
||||
* <li>passing the parameter to forged iterable methods
|
||||
* <li>passing the parameter to forged bean mapping methods
|
||||
* <li>passing the parameter to factory methods (with and without {@link ObjectFactory})
|
||||
* <li>passing the parameter to lifecycle methods (in this case, {@link BeforeMapping}
|
||||
* <li>passing multiple parameters, with varied order of context params and mapping source params
|
||||
* </ul>
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@IssueKey("975")
|
||||
@WithClasses({
|
||||
Node.class,
|
||||
NodeDto.class,
|
||||
NodeMapperWithContext.class,
|
||||
AutomappingNodeMapperWithContext.class,
|
||||
CycleContext.class,
|
||||
FactoryContext.class,
|
||||
CycleContextLifecycleMethods.class })
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
public class ContextParameterTest {
|
||||
|
||||
private static final int MAGIC_NUMBER_OFFSET = 10;
|
||||
|
||||
@Test
|
||||
public void mappingWithContextCorrectlyResolvesCycles() {
|
||||
Node root = buildNodes();
|
||||
NodeDto rootDto =
|
||||
NodeMapperWithContext.INSTANCE.nodeToNodeDto( new FactoryContext( 0, 10 ), root, new CycleContext() );
|
||||
assertResult( rootDto );
|
||||
|
||||
NodeDto updated = new NodeDto( 0 );
|
||||
NodeMapperWithContext.INSTANCE.nodeToNodeDto( new FactoryContext( 1, 10 ), root, updated, new CycleContext() );
|
||||
assertResult( updated );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void automappingWithContextCorrectlyResolvesCycles() {
|
||||
Node root = buildNodes();
|
||||
NodeDto rootDto = AutomappingNodeMapperWithContext.INSTANCE
|
||||
.nodeToNodeDto( root, new CycleContext(), new FactoryContext( 0, MAGIC_NUMBER_OFFSET ) );
|
||||
assertResult( rootDto );
|
||||
|
||||
NodeDto updated = new NodeDto( 0 );
|
||||
AutomappingNodeMapperWithContext.INSTANCE
|
||||
.nodeToNodeDto( root, updated, new CycleContext(), new FactoryContext( 1, 10 ) );
|
||||
assertResult( updated );
|
||||
}
|
||||
|
||||
private void assertResult(NodeDto rootDto) {
|
||||
assertThat( rootDto ).isNotNull();
|
||||
assertThat( rootDto.getId() ).isEqualTo( 0 );
|
||||
|
||||
AttributeDto rootAttribute = rootDto.getAttributes().get( 0 );
|
||||
assertThat( rootAttribute.getNode() ).isSameAs( rootDto );
|
||||
assertThat( rootAttribute.getMagicNumber() ).isEqualTo( 1 + MAGIC_NUMBER_OFFSET );
|
||||
|
||||
assertThat( rootDto.getChildren() ).hasSize( 1 );
|
||||
|
||||
NodeDto node1 = rootDto.getChildren().get( 0 );
|
||||
assertThat( node1.getParent() ).isSameAs( rootDto );
|
||||
assertThat( node1.getId() ).isEqualTo( 1 );
|
||||
|
||||
AttributeDto node1Attribute = node1.getAttributes().get( 0 );
|
||||
assertThat( node1Attribute.getNode() ).isSameAs( node1 );
|
||||
assertThat( node1Attribute.getMagicNumber() ).isEqualTo( 2 + MAGIC_NUMBER_OFFSET );
|
||||
|
||||
}
|
||||
|
||||
private static Node buildNodes() {
|
||||
Node root = new Node( "root" );
|
||||
root.addAttribute( new Attribute( "name", "root", 1 ) );
|
||||
|
||||
Node node1 = new Node( "node1" );
|
||||
node1.addAttribute( new Attribute( "name", "node1", 2 ) );
|
||||
|
||||
root.addChild( node1 );
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
|
||||
/**
|
||||
* A type to be used as {@link Context} parameter to track cycles in graphs
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class CycleContext {
|
||||
private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getMappedInstance(Object source, Class<T> targetType) {
|
||||
return (T) knownInstances.get( source );
|
||||
}
|
||||
|
||||
public void storeMappedInstance(Object source, Object target) {
|
||||
knownInstances.put( source, target );
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import org.mapstruct.BeforeMapping;
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.ObjectFactory;
|
||||
import org.mapstruct.TargetType;
|
||||
import org.mapstruct.ap.test.context.Node.Attribute;
|
||||
import org.mapstruct.ap.test.context.NodeDto.AttributeDto;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class CycleContextLifecycleMethods {
|
||||
|
||||
public NodeDto createNodeDto(@Context FactoryContext context) {
|
||||
return context.createNode();
|
||||
}
|
||||
|
||||
@ObjectFactory
|
||||
public AttributeDto createAttributeDto(Attribute source, @Context FactoryContext context) {
|
||||
return context.createAttributeDto( source );
|
||||
}
|
||||
|
||||
@BeforeMapping
|
||||
public <T> T getInstance(Object source, @TargetType Class<T> type, @Context CycleContext cycleContext) {
|
||||
return cycleContext.getMappedInstance( source, type );
|
||||
}
|
||||
|
||||
@BeforeMapping
|
||||
public void setInstance(Object source, @MappingTarget Object target, @Context CycleContext cycleContext) {
|
||||
cycleContext.storeMappedInstance( source, target );
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.ap.test.context.Node.Attribute;
|
||||
import org.mapstruct.ap.test.context.NodeDto.AttributeDto;
|
||||
|
||||
/**
|
||||
* A type to be used as {@link Context} parameter to create NodeDto and AttributeDto instances
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class FactoryContext {
|
||||
private int nodeCounter;
|
||||
private int attributeMagicNumberOffset;
|
||||
|
||||
public FactoryContext(int initialCounter, int attributeMaticNumberOffset) {
|
||||
this.nodeCounter = initialCounter;
|
||||
this.attributeMagicNumberOffset = attributeMaticNumberOffset;
|
||||
}
|
||||
|
||||
public NodeDto createNode() {
|
||||
return new NodeDto( nodeCounter++ );
|
||||
}
|
||||
|
||||
public AttributeDto createAttributeDto(Attribute source) {
|
||||
return new AttributeDto( source.getMagicNumber() + attributeMagicNumberOffset );
|
||||
}
|
||||
}
|
100
processor/src/test/java/org/mapstruct/ap/test/context/Node.java
Normal file
100
processor/src/test/java/org/mapstruct/ap/test/context/Node.java
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class Node {
|
||||
private Node parent;
|
||||
|
||||
private String name;
|
||||
|
||||
private List<Node> children;
|
||||
private List<Attribute> attributes;
|
||||
|
||||
public Node(String name) {
|
||||
this.name = name;
|
||||
this.children = new ArrayList<Node>();
|
||||
this.attributes = new ArrayList<Attribute>();
|
||||
}
|
||||
|
||||
public Node getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Node> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void addChild(Node node) {
|
||||
children.add( node );
|
||||
node.parent = this;
|
||||
}
|
||||
|
||||
public List<Attribute> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void addAttribute(Attribute attribute) {
|
||||
attributes.add( attribute );
|
||||
attribute.setNode( this );
|
||||
}
|
||||
|
||||
public static class Attribute {
|
||||
private Node node;
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
private int magicNumber;
|
||||
|
||||
public Attribute(String name, String value, int magicNumber) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.magicNumber = magicNumber;
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(Node node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int getMagicNumber() {
|
||||
return magicNumber;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class NodeDto {
|
||||
private NodeDto parent;
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
private List<NodeDto> children;
|
||||
private List<AttributeDto> attributes;
|
||||
|
||||
public NodeDto(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public NodeDto getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(NodeDto parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<NodeDto> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<NodeDto> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public List<AttributeDto> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(List<AttributeDto> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public static class AttributeDto {
|
||||
private NodeDto node;
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
private int magicNumber;
|
||||
|
||||
public AttributeDto(int magicNumber) {
|
||||
this.magicNumber = magicNumber;
|
||||
}
|
||||
|
||||
public NodeDto getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public void setNode(NodeDto node) {
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public int getMagicNumber() {
|
||||
return magicNumber;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.ap.test.context.Node.Attribute;
|
||||
import org.mapstruct.ap.test.context.NodeDto.AttributeDto;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@Mapper(uses = CycleContextLifecycleMethods.class)
|
||||
public interface NodeMapperWithContext {
|
||||
NodeMapperWithContext INSTANCE = Mappers.getMapper( NodeMapperWithContext.class );
|
||||
|
||||
NodeDto nodeToNodeDto(@Context FactoryContext factoryContext, Node node, @Context CycleContext cycleContext);
|
||||
|
||||
void nodeToNodeDto(@Context FactoryContext factoryContext, Node node, @MappingTarget NodeDto nodeDto,
|
||||
@Context CycleContext cycleContext);
|
||||
|
||||
AttributeDto attributeToAttributeDto(Attribute attribute, @Context CycleContext cycleContext,
|
||||
@Context FactoryContext factoryContext);
|
||||
|
||||
void attributeToAttributeDto(Attribute attribute, @MappingTarget AttributeDto nodeDto,
|
||||
@Context CycleContext cycleContext, @Context FactoryContext factoryContext);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright 2012-2016 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.ap.test.context.erroneous;
|
||||
|
||||
import org.mapstruct.Context;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ap.test.context.CycleContext;
|
||||
import org.mapstruct.ap.test.context.Node;
|
||||
import org.mapstruct.ap.test.context.NodeDto;
|
||||
|
||||
/**
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
@Mapper
|
||||
public interface ErroneousNodeMapperWithNonUniqueContextTypes {
|
||||
|
||||
NodeDto nodeToNodeDto(Node node, @Context CycleContext cycleContext, @Context CycleContext otherCycleContext);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user