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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.model.common.Accessibility;
|
import org.mapstruct.ap.internal.model.common.Accessibility;
|
||||||
import org.mapstruct.ap.internal.model.common.ConversionContext;
|
import org.mapstruct.ap.internal.model.common.ConversionContext;
|
||||||
import org.mapstruct.ap.internal.model.common.Parameter;
|
import org.mapstruct.ap.internal.model.common.Parameter;
|
||||||
@ -44,8 +46,6 @@ import org.mapstruct.ap.internal.util.Strings;
|
|||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
public abstract class HelperMethod implements Method {
|
public abstract class HelperMethod implements Method {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc }
|
* {@inheritDoc }
|
||||||
*
|
*
|
||||||
@ -84,6 +84,11 @@ public abstract class HelperMethod implements Method {
|
|||||||
return getParameters();
|
return getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getContextParameters() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -189,6 +189,7 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
targetType,
|
targetType,
|
||||||
method.getMapperConfiguration(),
|
method.getMapperConfiguration(),
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
|
method.getContextParameters(),
|
||||||
forgedMethodHistory
|
forgedMethodHistory
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -238,7 +239,7 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
public Parameter getSourceParameter() {
|
public Parameter getSourceParameter() {
|
||||||
for ( Parameter parameter : getParameters() ) {
|
for ( Parameter parameter : getParameters() ) {
|
||||||
if ( !parameter.isMappingTarget() ) {
|
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +199,7 @@ public class MapMappingMethod extends MappingMethod {
|
|||||||
targetType,
|
targetType,
|
||||||
method.getMapperConfiguration(),
|
method.getMapperConfiguration(),
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
|
method.getContextParameters(),
|
||||||
history
|
history
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -247,7 +248,7 @@ public class MapMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
public Parameter getSourceParameter() {
|
public Parameter getSourceParameter() {
|
||||||
for ( Parameter parameter : getParameters() ) {
|
for ( Parameter parameter : getParameters() ) {
|
||||||
if ( !parameter.isMappingTarget() ) {
|
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,8 @@ import org.mapstruct.ap.internal.model.source.Method;
|
|||||||
public abstract class MappingMethod extends ModelElement {
|
public abstract class MappingMethod extends ModelElement {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
private List<Parameter> parameters;
|
private final List<Parameter> parameters;
|
||||||
|
private final List<Parameter> sourceParameters;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final Parameter targetParameter;
|
private final Parameter targetParameter;
|
||||||
private final Accessibility accessibility;
|
private final Accessibility accessibility;
|
||||||
@ -77,6 +78,7 @@ public abstract class MappingMethod extends ModelElement {
|
|||||||
List<ForgedMethod> forgedMethods) {
|
List<ForgedMethod> forgedMethods) {
|
||||||
this.name = method.getName();
|
this.name = method.getName();
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
|
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||||
this.returnType = method.getReturnType();
|
this.returnType = method.getReturnType();
|
||||||
this.targetParameter = method.getMappingTargetParameter();
|
this.targetParameter = method.getMappingTargetParameter();
|
||||||
this.accessibility = method.getAccessibility();
|
this.accessibility = method.getAccessibility();
|
||||||
@ -144,14 +146,6 @@ public abstract class MappingMethod extends ModelElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Parameter> getSourceParameters() {
|
public List<Parameter> getSourceParameters() {
|
||||||
List<Parameter> sourceParameters = new ArrayList<Parameter>();
|
|
||||||
|
|
||||||
for ( Parameter parameter : parameters ) {
|
|
||||||
if ( !parameter.isMappingTarget() ) {
|
|
||||||
sourceParameters.add( parameter );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sourceParameters;
|
return sourceParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public class NestedPropertyMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
public Parameter getSourceParameter() {
|
public Parameter getSourceParameter() {
|
||||||
for ( Parameter parameter : getParameters() ) {
|
for ( Parameter parameter : getParameters() ) {
|
||||||
if ( !parameter.isMappingTarget() ) {
|
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,12 +479,14 @@ public class PropertyMapping extends ModelElement {
|
|||||||
// forge a method from the parameter type to the last entry type.
|
// forge a method from the parameter type to the last entry type.
|
||||||
String forgedName = Strings.joinAndCamelize( sourceReference.getElementNames() );
|
String forgedName = Strings.joinAndCamelize( sourceReference.getElementNames() );
|
||||||
forgedName = Strings.getSaveVariableName( forgedName, ctx.getNamesOfMappingsToGenerate() );
|
forgedName = Strings.getSaveVariableName( forgedName, ctx.getNamesOfMappingsToGenerate() );
|
||||||
ForgedMethod methodRef = new ForgedMethod( forgedName,
|
ForgedMethod methodRef = new ForgedMethod(
|
||||||
|
forgedName,
|
||||||
sourceReference.getParameter().getType(),
|
sourceReference.getParameter().getType(),
|
||||||
sourceType,
|
sourceType,
|
||||||
config,
|
config,
|
||||||
method.getExecutable()
|
method.getExecutable(),
|
||||||
);
|
method.getContextParameters() );
|
||||||
|
|
||||||
NestedPropertyMappingMethod.Builder builder = new NestedPropertyMappingMethod.Builder();
|
NestedPropertyMappingMethod.Builder builder = new NestedPropertyMappingMethod.Builder();
|
||||||
NestedPropertyMappingMethod nestedPropertyMapping = builder
|
NestedPropertyMappingMethod nestedPropertyMapping = builder
|
||||||
.method( methodRef )
|
.method( methodRef )
|
||||||
@ -540,7 +542,13 @@ public class PropertyMapping extends ModelElement {
|
|||||||
|
|
||||||
// copy mapper configuration from the source method, its the same mapper
|
// copy mapper configuration from the source method, its the same mapper
|
||||||
MapperConfiguration config = method.getMapperConfiguration();
|
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 ),
|
new ForgedMethodHistory( getForgedMethodHistory( source ),
|
||||||
source.getSourceErrorMessagePart(),
|
source.getSourceErrorMessagePart(),
|
||||||
targetPropertyName,
|
targetPropertyName,
|
||||||
@ -588,7 +596,14 @@ public class PropertyMapping extends ModelElement {
|
|||||||
|
|
||||||
// copy mapper configuration from the source method, its the same mapper
|
// copy mapper configuration from the source method, its the same mapper
|
||||||
MapperConfiguration config = method.getMapperConfiguration();
|
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 ),
|
new ForgedMethodHistory( getForgedMethodHistory( source ),
|
||||||
source.getSourceErrorMessagePart(),
|
source.getSourceErrorMessagePart(),
|
||||||
targetPropertyName,
|
targetPropertyName,
|
||||||
@ -638,6 +653,7 @@ public class PropertyMapping extends ModelElement {
|
|||||||
targetType,
|
targetType,
|
||||||
method.getMapperConfiguration(),
|
method.getMapperConfiguration(),
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
|
method.getContextParameters(),
|
||||||
getForgedMethodHistory( sourceRHS )
|
getForgedMethodHistory( sourceRHS )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -18,8 +18,15 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.model.common;
|
package org.mapstruct.ap.internal.model.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
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;
|
import org.mapstruct.ap.internal.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,18 +41,20 @@ public class Parameter extends ModelElement {
|
|||||||
private final Type type;
|
private final Type type;
|
||||||
private final boolean mappingTarget;
|
private final boolean mappingTarget;
|
||||||
private final boolean targetType;
|
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
|
// issue #909: FreeMarker doesn't like "values" as a parameter name
|
||||||
this.name = "values".equals( name ) ? "values_" : name;
|
this.name = "values".equals( name ) ? "values_" : name;
|
||||||
this.originalName = name;
|
this.originalName = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.mappingTarget = mappingTarget;
|
this.mappingTarget = mappingTarget;
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Parameter(String name, Type type) {
|
public Parameter(String name, Type type) {
|
||||||
this( name, type, false, false );
|
this( name, type, false, false, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -66,7 +75,9 @@ public class Parameter extends ModelElement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return ( mappingTarget ? "@MappingTarget " : "" ) + ( targetType ? "@TargetType " : "" )
|
return ( mappingTarget ? "@MappingTarget " : "" )
|
||||||
|
+ ( targetType ? "@TargetType " : "" )
|
||||||
|
+ ( mappingContext ? "@Context " : "" )
|
||||||
+ type.toString() + " " + name;
|
+ type.toString() + " " + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +90,10 @@ public class Parameter extends ModelElement {
|
|||||||
return targetType;
|
return targetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMappingContext() {
|
||||||
|
return mappingContext;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
int hash = 5;
|
int hash = 5;
|
||||||
@ -100,4 +115,45 @@ public class Parameter extends ModelElement {
|
|||||||
}
|
}
|
||||||
return true;
|
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 String variableName;
|
||||||
private final boolean targetType;
|
private final boolean targetType;
|
||||||
private final boolean mappingTarget;
|
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.type = parameterType;
|
||||||
this.variableName = variableName;
|
this.variableName = variableName;
|
||||||
this.targetType = targetType;
|
this.targetType = targetType;
|
||||||
this.mappingTarget = mappingTarget;
|
this.mappingTarget = mappingTarget;
|
||||||
|
this.mappingContext = mappingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,6 +66,13 @@ public class ParameterBinding {
|
|||||||
return mappingTarget;
|
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
|
* @return the type of the parameter that is bound
|
||||||
*/
|
*/
|
||||||
@ -87,7 +97,8 @@ public class ParameterBinding {
|
|||||||
parameter.getType(),
|
parameter.getType(),
|
||||||
parameter.getName(),
|
parameter.getName(),
|
||||||
parameter.isMappingTarget(),
|
parameter.isMappingTarget(),
|
||||||
parameter.isTargetType() );
|
parameter.isTargetType(),
|
||||||
|
parameter.isMappingContext() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ParameterBinding> fromParameters(List<Parameter> parameters) {
|
public static List<ParameterBinding> fromParameters(List<Parameter> parameters) {
|
||||||
@ -103,7 +114,7 @@ public class ParameterBinding {
|
|||||||
* @return a parameter binding representing a target type parameter
|
* @return a parameter binding representing a target type parameter
|
||||||
*/
|
*/
|
||||||
public static ParameterBinding forTargetTypeBinding(Type classTypeOf) {
|
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
|
* @return a parameter binding representing a mapping target parameter
|
||||||
*/
|
*/
|
||||||
public static ParameterBinding forMappingTargetBinding(Type resultType) {
|
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
|
* @return a parameter binding representing a mapping source type
|
||||||
*/
|
*/
|
||||||
public static ParameterBinding forSourceTypeBinding(Type sourceType) {
|
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.ConcurrentMap;
|
||||||
import java.util.concurrent.ConcurrentNavigableMap;
|
import java.util.concurrent.ConcurrentNavigableMap;
|
||||||
import java.util.concurrent.ConcurrentSkipListMap;
|
import java.util.concurrent.ConcurrentSkipListMap;
|
||||||
|
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
import javax.lang.model.element.ElementKind;
|
import javax.lang.model.element.ElementKind;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
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.Elements;
|
||||||
import javax.lang.model.util.Types;
|
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.AnnotationProcessingException;
|
||||||
import org.mapstruct.ap.internal.util.Collections;
|
import org.mapstruct.ap.internal.util.Collections;
|
||||||
import org.mapstruct.ap.internal.util.accessor.Accessor;
|
import org.mapstruct.ap.internal.util.accessor.Accessor;
|
||||||
@ -321,11 +320,7 @@ public class TypeFactory {
|
|||||||
VariableElement parameter = varIt.next();
|
VariableElement parameter = varIt.next();
|
||||||
TypeMirror parameterType = typesIt.next();
|
TypeMirror parameterType = typesIt.next();
|
||||||
|
|
||||||
result.add( new Parameter(
|
result.add( Parameter.forElementAndType( parameter, getType( parameterType ) ) );
|
||||||
parameter.getSimpleName().toString(),
|
|
||||||
getType( parameterType ),
|
|
||||||
MappingTargetPrism.getInstanceOn( parameter ) != null,
|
|
||||||
TargetTypePrism.getInstanceOn( parameter ) != null ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -18,10 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.internal.model.source;
|
package org.mapstruct.ap.internal.model.source;
|
||||||
|
|
||||||
import static org.mapstruct.ap.internal.util.Collections.first;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
@ -45,7 +43,10 @@ public class ForgedMethod implements Method {
|
|||||||
private final ExecutableElement positionHintElement;
|
private final ExecutableElement positionHintElement;
|
||||||
private final List<Type> thrownTypes;
|
private final List<Type> thrownTypes;
|
||||||
private final MapperConfiguration mapperConfiguration;
|
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.
|
* Creates a new forged method with the given name.
|
||||||
@ -55,17 +56,11 @@ public class ForgedMethod implements Method {
|
|||||||
* @param targetType the target type.
|
* @param targetType the target type.
|
||||||
* @param mapperConfiguration the mapper configuration
|
* @param mapperConfiguration the mapper configuration
|
||||||
* @param positionHintElement element used to for reference to the position in the source file.
|
* @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,
|
public ForgedMethod(String name, Type sourceType, Type targetType, MapperConfiguration mapperConfiguration,
|
||||||
ExecutableElement positionHintElement) {
|
ExecutableElement positionHintElement, List<Parameter> additionalParameters) {
|
||||||
String sourceParamName = Strings.decapitalize( sourceType.getName() );
|
this( name, sourceType, targetType, mapperConfiguration, positionHintElement, additionalParameters, null );
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,13 +71,21 @@ public class ForgedMethod implements Method {
|
|||||||
* @param targetType the target type.
|
* @param targetType the target type.
|
||||||
* @param mapperConfiguration the mapper configuration
|
* @param mapperConfiguration the mapper configuration
|
||||||
* @param positionHintElement element used to for reference to the position in the source file.
|
* @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
|
* @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,
|
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 sourceParamName = Strings.decapitalize( sourceType.getName() );
|
||||||
String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName );
|
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.returnType = targetType;
|
||||||
this.thrownTypes = new ArrayList<Type>();
|
this.thrownTypes = new ArrayList<Type>();
|
||||||
this.name = Strings.sanitizeIdentifierName( name );
|
this.name = Strings.sanitizeIdentifierName( name );
|
||||||
@ -102,6 +105,11 @@ public class ForgedMethod implements Method {
|
|||||||
this.thrownTypes = new ArrayList<Type>();
|
this.thrownTypes = new ArrayList<Type>();
|
||||||
this.mapperConfiguration = forgedMethod.mapperConfiguration;
|
this.mapperConfiguration = forgedMethod.mapperConfiguration;
|
||||||
this.positionHintElement = forgedMethod.positionHintElement;
|
this.positionHintElement = forgedMethod.positionHintElement;
|
||||||
|
this.history = forgedMethod.history;
|
||||||
|
|
||||||
|
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||||
|
this.contextParameters = Parameter.getContextParameters( parameters );
|
||||||
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,13 +120,20 @@ public class ForgedMethod implements Method {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parameters.size() != 1 || sourceTypes.size() != 1 ) {
|
if ( parameters.size() != sourceTypes.size() ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !first( sourceTypes ).equals( first( parameters ).getType() ) ) {
|
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 false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -140,7 +155,12 @@ public class ForgedMethod implements Method {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Parameter> getSourceParameters() {
|
public List<Parameter> getSourceParameters() {
|
||||||
return parameters;
|
return sourceParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getContextParameters() {
|
||||||
|
return contextParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,13 +70,21 @@ public interface Method {
|
|||||||
List<Parameter> getParameters();
|
List<Parameter> getParameters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the list of 'true' source parameters excluding the parameter(s) that is designated as
|
* returns the list of 'true' source parameters excluding the parameter(s) that are designated as target, target
|
||||||
* target by means of the target annotation {@link #getMappingTargetParameter() }.
|
* type or context parameter.
|
||||||
*
|
*
|
||||||
* @return list of 'true' source parameters
|
* @return list of 'true' source parameters
|
||||||
*/
|
*/
|
||||||
List<Parameter> getSourceParameters();
|
List<Parameter> getSourceParameters();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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}
|
* Returns the parameter designated as mapping target (if present) {@link org.mapstruct.MappingTarget}
|
||||||
*
|
*
|
||||||
|
@ -69,7 +69,8 @@ public class SourceMethod implements Method {
|
|||||||
private final List<SourceMethod> prototypeMethods;
|
private final List<SourceMethod> prototypeMethods;
|
||||||
private final Type mapperToImplement;
|
private final Type mapperToImplement;
|
||||||
|
|
||||||
private List<Parameter> sourceParameters;
|
private final List<Parameter> sourceParameters;
|
||||||
|
private final List<Parameter> contextParameters;
|
||||||
|
|
||||||
private List<String> parameterNames;
|
private List<String> parameterNames;
|
||||||
|
|
||||||
@ -100,9 +101,6 @@ public class SourceMethod implements Method {
|
|||||||
private List<SourceMethod> prototypeMethods = Collections.emptyList();
|
private List<SourceMethod> prototypeMethods = Collections.emptyList();
|
||||||
private List<ValueMapping> valueMappings;
|
private List<ValueMapping> valueMappings;
|
||||||
|
|
||||||
public Builder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setDeclaringMapper(Type declaringMapper) {
|
public Builder setDeclaringMapper(Type declaringMapper) {
|
||||||
this.declaringMapper = declaringMapper;
|
this.declaringMapper = declaringMapper;
|
||||||
return this;
|
return this;
|
||||||
@ -226,6 +224,9 @@ public class SourceMethod implements Method {
|
|||||||
|
|
||||||
this.mappingOptions = mappingOptions;
|
this.mappingOptions = mappingOptions;
|
||||||
|
|
||||||
|
this.sourceParameters = Parameter.getSourceParameters( parameters );
|
||||||
|
this.contextParameters = Parameter.getContextParameters( parameters );
|
||||||
|
|
||||||
this.mappingTargetParameter = determineMappingTargetParameter( parameters );
|
this.mappingTargetParameter = determineMappingTargetParameter( parameters );
|
||||||
this.targetTypeParameter = determineTargetTypeParameter( parameters );
|
this.targetTypeParameter = determineTargetTypeParameter( parameters );
|
||||||
this.isObjectFactory = determineIfIsObjectFactory( executable );
|
this.isObjectFactory = determineIfIsObjectFactory( executable );
|
||||||
@ -239,9 +240,11 @@ public class SourceMethod implements Method {
|
|||||||
|
|
||||||
private boolean determineIfIsObjectFactory(ExecutableElement executable) {
|
private boolean determineIfIsObjectFactory(ExecutableElement executable) {
|
||||||
boolean hasFactoryAnnotation = ObjectFactoryPrism.getInstanceOn( executable ) != null;
|
boolean hasFactoryAnnotation = ObjectFactoryPrism.getInstanceOn( executable ) != null;
|
||||||
boolean isFactoryWithTargeTypeAnnotation = getTargetTypeParameter() != null && getSourceParameters().isEmpty();
|
boolean hasNoSourceParameters = getSourceParameters().isEmpty();
|
||||||
return !returnType.isVoid()
|
boolean hasNoMappingTargetParam = getMappingTargetParameter() == null;
|
||||||
&& ( hasFactoryAnnotation || isFactoryWithTargeTypeAnnotation || parameters.isEmpty() );
|
return !isLifecycleCallbackMethod() && !returnType.isVoid()
|
||||||
|
&& hasNoMappingTargetParam
|
||||||
|
&& ( hasFactoryAnnotation || hasNoSourceParameters );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Parameter determineMappingTargetParameter(Iterable<Parameter> parameters) {
|
private Parameter determineMappingTargetParameter(Iterable<Parameter> parameters) {
|
||||||
@ -264,9 +267,6 @@ public class SourceMethod implements Method {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Type getDeclaringMapper() {
|
public Type getDeclaringMapper() {
|
||||||
return declaringMapper;
|
return declaringMapper;
|
||||||
@ -277,40 +277,26 @@ public class SourceMethod implements Method {
|
|||||||
return executable;
|
return executable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return executable.getSimpleName().toString();
|
return executable.getSimpleName().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<Parameter> getParameters() {
|
public List<Parameter> getParameters() {
|
||||||
return parameters;
|
return parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<Parameter> getSourceParameters() {
|
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;
|
return sourceParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getContextParameters() {
|
||||||
|
return contextParameters;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getParameterNames() {
|
public List<String> getParameterNames() {
|
||||||
if ( parameterNames == null ) {
|
if ( parameterNames == null ) {
|
||||||
@ -331,9 +317,6 @@ public class SourceMethod implements Method {
|
|||||||
return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType;
|
return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Type getReturnType() {
|
public Type getReturnType() {
|
||||||
return returnType;
|
return returnType;
|
||||||
@ -544,9 +527,6 @@ public class SourceMethod implements Method {
|
|||||||
return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT );
|
return declaringMapper == null && executable.getModifiers().contains( Modifier.ABSTRACT );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc} {@link Method}
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
public boolean matches(List<Type> sourceTypes, Type targetType) {
|
||||||
MethodMatcher matcher = new MethodMatcher( typeUtils, typeFactory, this );
|
MethodMatcher matcher = new MethodMatcher( typeUtils, typeFactory, this );
|
||||||
@ -614,5 +594,4 @@ public class SourceMethod implements Method {
|
|||||||
public boolean isUpdateMethod() {
|
public boolean isUpdateMethod() {
|
||||||
return getMappingTargetParameter() != null;
|
return getMappingTargetParameter() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,11 @@ public abstract class BuiltInMethod implements Method {
|
|||||||
return getParameters();
|
return getParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Parameter> getContextParameters() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -62,7 +62,7 @@ public class TypeSelector implements MethodSelector {
|
|||||||
availableBindings = getAvailableParameterBindingsFromMethod( mappingMethod );
|
availableBindings = getAvailableParameterBindingsFromMethod( mappingMethod );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
availableBindings = getAvailableParameterBindingsFromSourceTypes( sourceTypes, targetType );
|
availableBindings = getAvailableParameterBindingsFromSourceTypes( sourceTypes, targetType, mappingMethod );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( SelectedMethod<T> method : methods ) {
|
for ( SelectedMethod<T> method : methods ) {
|
||||||
@ -91,7 +91,7 @@ public class TypeSelector implements MethodSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<ParameterBinding> getAvailableParameterBindingsFromSourceTypes(List<Type> sourceTypes,
|
private List<ParameterBinding> getAvailableParameterBindingsFromSourceTypes(List<Type> sourceTypes,
|
||||||
Type targetType) {
|
Type targetType, Method mappingMethod) {
|
||||||
|
|
||||||
List<ParameterBinding> availableParams = new ArrayList<ParameterBinding>( sourceTypes.size() + 2 );
|
List<ParameterBinding> availableParams = new ArrayList<ParameterBinding>( sourceTypes.size() + 2 );
|
||||||
|
|
||||||
@ -101,6 +101,12 @@ public class TypeSelector implements MethodSelector {
|
|||||||
availableParams.add( ParameterBinding.forSourceTypeBinding( sourceType ) );
|
availableParams.add( ParameterBinding.forSourceTypeBinding( sourceType ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for ( Parameter param : mappingMethod.getParameters() ) {
|
||||||
|
if ( param.isMappingContext() ) {
|
||||||
|
availableParams.add( ParameterBinding.fromParameter( param ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return availableParams;
|
return availableParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +191,8 @@ public class TypeSelector implements MethodSelector {
|
|||||||
|
|
||||||
for ( ParameterBinding candidate : candidateParameters ) {
|
for ( ParameterBinding candidate : candidateParameters ) {
|
||||||
if ( parameter.isTargetType() == candidate.isTargetType()
|
if ( parameter.isTargetType() == candidate.isTargetType()
|
||||||
&& parameter.isMappingTarget() == candidate.isMappingTarget() ) {
|
&& parameter.isMappingTarget() == candidate.isMappingTarget()
|
||||||
|
&& parameter.isMappingContext() == candidate.isMappingContext() ) {
|
||||||
result.add( candidate );
|
result.add( candidate );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import javax.xml.bind.annotation.XmlElementRef;
|
|||||||
import org.mapstruct.AfterMapping;
|
import org.mapstruct.AfterMapping;
|
||||||
import org.mapstruct.BeanMapping;
|
import org.mapstruct.BeanMapping;
|
||||||
import org.mapstruct.BeforeMapping;
|
import org.mapstruct.BeforeMapping;
|
||||||
|
import org.mapstruct.Context;
|
||||||
import org.mapstruct.DecoratedWith;
|
import org.mapstruct.DecoratedWith;
|
||||||
import org.mapstruct.InheritConfiguration;
|
import org.mapstruct.InheritConfiguration;
|
||||||
import org.mapstruct.InheritInverseConfiguration;
|
import org.mapstruct.InheritInverseConfiguration;
|
||||||
@ -69,6 +70,7 @@ import net.java.dev.hickory.prism.GeneratePrisms;
|
|||||||
@GeneratePrism(value = BeforeMapping.class, publicAccess = true),
|
@GeneratePrism(value = BeforeMapping.class, publicAccess = true),
|
||||||
@GeneratePrism(value = ValueMapping.class, publicAccess = true),
|
@GeneratePrism(value = ValueMapping.class, publicAccess = true),
|
||||||
@GeneratePrism(value = ValueMappings.class, publicAccess = true),
|
@GeneratePrism(value = ValueMappings.class, publicAccess = true),
|
||||||
|
@GeneratePrism(value = Context.class, publicAccess = true),
|
||||||
|
|
||||||
// external types
|
// external types
|
||||||
@GeneratePrism(value = XmlElementDecl.class, publicAccess = true),
|
@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.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
@ -215,7 +217,8 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
List<SourceMethod> prototypeMethods ) {
|
List<SourceMethod> prototypeMethods ) {
|
||||||
Type returnType = typeFactory.getReturnType( methodType );
|
Type returnType = typeFactory.getReturnType( methodType );
|
||||||
List<Type> exceptionTypes = typeFactory.getThrownTypes( 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 );
|
Parameter targetParameter = extractTargetParameter( parameters );
|
||||||
Type resultType = selectResultType( returnType, targetParameter );
|
Type resultType = selectResultType( returnType, targetParameter );
|
||||||
|
|
||||||
@ -223,6 +226,7 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
method,
|
method,
|
||||||
sourceParameters,
|
sourceParameters,
|
||||||
targetParameter,
|
targetParameter,
|
||||||
|
contextParameters,
|
||||||
resultType,
|
resultType,
|
||||||
returnType,
|
returnType,
|
||||||
containsTargetTypeParameter
|
containsTargetTypeParameter
|
||||||
@ -316,20 +320,17 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
if ( param.isMappingTarget() ) {
|
if ( param.isMappingTarget() ) {
|
||||||
targetParameters++;
|
targetParameters++;
|
||||||
}
|
}
|
||||||
|
else if ( param.isTargetType() ) {
|
||||||
if ( param.isTargetType() ) {
|
|
||||||
targetTypeParameters++;
|
targetTypeParameters++;
|
||||||
}
|
}
|
||||||
|
else if ( !param.isMappingContext() ) {
|
||||||
if ( !param.isMappingTarget() && !param.isTargetType() ) {
|
|
||||||
validSourceParameters++;
|
validSourceParameters++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return validSourceParameters == sourceParamCount
|
return validSourceParameters == sourceParamCount
|
||||||
&& targetParameters <= targetParamCount
|
&& targetParameters <= targetParamCount
|
||||||
&& targetTypeParameters <= 1
|
&& targetTypeParameters <= 1;
|
||||||
&& parameters.size() == validSourceParameters + targetParameters + targetTypeParameters;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Parameter extractTargetParameter(List<Parameter> parameters) {
|
private Parameter extractTargetParameter(List<Parameter> parameters) {
|
||||||
@ -342,17 +343,6 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
return null;
|
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) {
|
private Type selectResultType(Type returnType, Parameter targetParameter) {
|
||||||
if ( null != targetParameter ) {
|
if ( null != targetParameter ) {
|
||||||
return targetParameter.getType();
|
return targetParameter.getType();
|
||||||
@ -363,14 +353,16 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkParameterAndReturnType(ExecutableElement method, List<Parameter> sourceParameters,
|
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) {
|
boolean containsTargetTypeParameter) {
|
||||||
if ( sourceParameters.isEmpty() ) {
|
if ( sourceParameters.isEmpty() ) {
|
||||||
messager.printMessage( method, Message.RETRIEVAL_NO_INPUT_ARGS );
|
messager.printMessage( method, Message.RETRIEVAL_NO_INPUT_ARGS );
|
||||||
return false;
|
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 );
|
messager.printMessage( method, Message.RETRIEVAL_DUPLICATE_MAPPING_TARGETS );
|
||||||
return false;
|
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() ) {
|
if ( returnType.isTypeVar() || resultType.isTypeVar() ) {
|
||||||
messager.printMessage( method, Message.RETRIEVAL_TYPE_VAR_RESULT );
|
messager.printMessage( method, Message.RETRIEVAL_TYPE_VAR_RESULT );
|
||||||
return false;
|
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_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_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_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." ),
|
INHERITCONFIGURATION_BOTH( "Method cannot be annotated with both a @InheritConfiguration and @InheritInverseConfiguration." ),
|
||||||
INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ),
|
INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ),
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
<@includeModel object=ext.targetType raw=true/>.class<#t>
|
<@includeModel object=ext.targetType raw=true/>.class<#t>
|
||||||
<#elseif param.mappingTarget>
|
<#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??>
|
<#elseif assignment??>
|
||||||
<@_assignment/><#t>
|
<@_assignment/><#t>
|
||||||
<#else>
|
<#else>
|
||||||
|
@ -21,17 +21,17 @@ package org.mapstruct.ap.test.callbacks.returning;
|
|||||||
/**
|
/**
|
||||||
* @author Pascal Grün
|
* @author Pascal Grün
|
||||||
*/
|
*/
|
||||||
public class AttributeDTO {
|
public class AttributeDto {
|
||||||
private NodeDTO node;
|
|
||||||
|
|
||||||
|
private NodeDto node;
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
public NodeDTO getNode() {
|
public NodeDto getNode() {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNode(NodeDTO node) {
|
public void setNode(NodeDto node) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +53,6 @@ public class AttributeDTO {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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
|
* @author Pascal Grün
|
||||||
*/
|
*/
|
||||||
@IssueKey( "469" )
|
@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,
|
NodeMapperWithContext.class, NodeMapperContext.class, Number.class, NumberMapperDefault.class,
|
||||||
NumberMapperContext.class, NumberMapperWithContext.class } )
|
NumberMapperContext.class, NumberMapperWithContext.class } )
|
||||||
@RunWith( AnnotationProcessorTestRunner.class )
|
@RunWith( AnnotationProcessorTestRunner.class )
|
||||||
@ -44,13 +44,13 @@ public class CallbacksWithReturnValuesTest {
|
|||||||
@Test( expected = StackOverflowError.class )
|
@Test( expected = StackOverflowError.class )
|
||||||
public void mappingWithDefaultHandlingRaisesStackOverflowError() {
|
public void mappingWithDefaultHandlingRaisesStackOverflowError() {
|
||||||
Node root = buildNodes();
|
Node root = buildNodes();
|
||||||
NodeMapperDefault.INSTANCE.nodeToNodeDTO( root );
|
NodeMapperDefault.INSTANCE.nodeToNodeDto( root );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test( expected = StackOverflowError.class )
|
@Test( expected = StackOverflowError.class )
|
||||||
public void updatingWithDefaultHandlingRaisesStackOverflowError() {
|
public void updatingWithDefaultHandlingRaisesStackOverflowError() {
|
||||||
Node root = buildNodes();
|
Node root = buildNodes();
|
||||||
NodeMapperDefault.INSTANCE.nodeToNodeDTO( root, new NodeDTO() );
|
NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -66,8 +66,8 @@ public class CallbacksWithReturnValuesTest {
|
|||||||
NodeMapperContext.addContextListener( contextListener );
|
NodeMapperContext.addContextListener( contextListener );
|
||||||
try {
|
try {
|
||||||
Node root = buildNodes();
|
Node root = buildNodes();
|
||||||
NodeDTO rootDTO = NodeMapperWithContext.INSTANCE.nodeToNodeDTO( root );
|
NodeDto rootDto = NodeMapperWithContext.INSTANCE.nodeToNodeDto( root );
|
||||||
assertThat( rootDTO ).isNotNull();
|
assertThat( rootDto ).isNotNull();
|
||||||
assertThat( contextLevel.get() ).isEqualTo( Integer.valueOf( 1 ) );
|
assertThat( contextLevel.get() ).isEqualTo( Integer.valueOf( 1 ) );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
@ -23,19 +23,18 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @author Pascal Grün
|
* @author Pascal Grün
|
||||||
*/
|
*/
|
||||||
public class NodeDTO {
|
public class NodeDto {
|
||||||
private NodeDTO parent;
|
|
||||||
|
|
||||||
|
private NodeDto parent;
|
||||||
private String name;
|
private String name;
|
||||||
|
private List<NodeDto> children;
|
||||||
|
private List<AttributeDto> attributes;
|
||||||
|
|
||||||
private List<NodeDTO> children;
|
public NodeDto getParent() {
|
||||||
private List<AttributeDTO> attributes;
|
|
||||||
|
|
||||||
public NodeDTO getParent() {
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParent(NodeDTO parent) {
|
public void setParent(NodeDto parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,24 +46,24 @@ public class NodeDTO {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NodeDTO> getChildren() {
|
public List<NodeDto> getChildren() {
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChildren(List<NodeDTO> children) {
|
public void setChildren(List<NodeDto> children) {
|
||||||
this.children = children;
|
this.children = children;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AttributeDTO> getAttributes() {
|
public List<AttributeDto> getAttributes() {
|
||||||
return attributes;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAttributes(List<AttributeDTO> attributes) {
|
public void setAttributes(List<AttributeDto> attributes) {
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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 abstract class NodeMapperDefault {
|
||||||
public static final NodeMapperDefault INSTANCE = Mappers.getMapper( NodeMapperDefault.class );
|
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 abstract class NodeMapperWithContext {
|
||||||
public static final NodeMapperWithContext INSTANCE = Mappers.getMapper( NodeMapperWithContext.class );
|
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