#750 Initial implementation of @Named annotation

This commit is contained in:
sjaakd 2016-02-14 20:49:02 +01:00
parent bb1ccac434
commit faedebc119
15 changed files with 770 additions and 616 deletions

View File

@ -80,6 +80,7 @@ public class BeanMappingMethod extends MappingMethod {
private final List<PropertyMapping> propertyMappings = new ArrayList<PropertyMapping>();
private final Set<Parameter> unprocessedSourceParameters = new HashSet<Parameter>();
private List<TypeMirror> qualifiers;
private List<String> qualifyingNames;
private NullValueMappingStrategyPrism nullValueMappingStrategy;
private TypeMirror resultTypeMirror;
private final Set<String> existingVariableNames = new HashSet<String>();
@ -107,6 +108,11 @@ public class BeanMappingMethod extends MappingMethod {
return this;
}
public Builder qualifyingNames(List<String> qualifyingNames) {
this.qualifyingNames = qualifyingNames;
return this;
}
public Builder nullValueMappingStrategy(NullValueMappingStrategyPrism nullValueMappingStrategy) {
this.nullValueMappingStrategy = nullValueMappingStrategy;
return this;
@ -145,6 +151,7 @@ public class BeanMappingMethod extends MappingMethod {
method,
method.getResultType(),
qualifiers,
qualifyingNames,
resultTypeMirror );
}
@ -300,6 +307,7 @@ public class BeanMappingMethod extends MappingMethod {
.targetPropertyName( mapping.getTargetName() )
.sourceReference( sourceRef )
.qualifiers( mapping.getQualifiers() )
.qualifyingNames( mapping.getQualifyingNames() )
.resultType( mapping.getResultType() )
.dateFormat( mapping.getDateFormat() )
.existingVariableNames( existingVariableNames )
@ -327,6 +335,7 @@ public class BeanMappingMethod extends MappingMethod {
.targetPropertyName( mapping.getTargetName() )
.dateFormat( mapping.getDateFormat() )
.qualifiers( mapping.getQualifiers() )
.qualifyingNames( mapping.getQualifyingNames() )
.resultType( mapping.getResultType() )
.existingVariableNames( existingVariableNames )
.dependsOn( mapping.getDependsOn() )
@ -424,6 +433,7 @@ public class BeanMappingMethod extends MappingMethod {
.targetPropertyName( targetProperty.getKey() )
.sourceReference( sourceRef )
.qualifiers( mapping != null ? mapping.getQualifiers() : null )
.qualifyingNames( mapping != null ? mapping.getQualifyingNames() : null )
.resultType( mapping != null ? mapping.getResultType() : null )
.dateFormat( mapping != null ? mapping.getDateFormat() : null )
.defaultValue( mapping != null ? mapping.getDefaultValue() : null )
@ -489,6 +499,7 @@ public class BeanMappingMethod extends MappingMethod {
.targetPropertyName( targetProperty.getKey() )
.sourceReference( sourceRef )
.qualifiers( mapping != null ? mapping.getQualifiers() : null )
.qualifyingNames( mapping != null ? mapping.getQualifyingNames() : null )
.resultType( mapping != null ? mapping.getResultType() : null )
.dateFormat( mapping != null ? mapping.getDateFormat() : null )
.existingVariableNames( existingVariableNames )

View File

@ -57,6 +57,7 @@ public class IterableMappingMethod extends MappingMethod {
private MappingBuilderContext ctx;
private String dateFormat;
private List<TypeMirror> qualifiers;
private List<String> qualifyingNames;
private TypeMirror qualifyingElementTargetType;
private NullValueMappingStrategyPrism nullValueMappingStrategy;
@ -80,6 +81,11 @@ public class IterableMappingMethod extends MappingMethod {
return this;
}
public Builder qualifyingNames(List<String> qualifyingNames) {
this.qualifyingNames = qualifyingNames;
return this;
}
public Builder qualifyingElementTargetType(TypeMirror qualifyingElementTargetType) {
this.qualifyingElementTargetType = qualifyingElementTargetType;
return this;
@ -112,6 +118,7 @@ public class IterableMappingMethod extends MappingMethod {
null, // there is no targetPropertyName
dateFormat,
qualifiers,
qualifyingNames,
qualifyingElementTargetType,
loopVariableName,
false
@ -148,7 +155,8 @@ public class IterableMappingMethod extends MappingMethod {
MethodReference factoryMethod = null;
if ( !method.isUpdateMethod() ) {
factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType(), null, null );
factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType(), null, null,
null );
}
List<LifecycleCallbackMethodReference> beforeMappingMethods =

View File

@ -94,6 +94,7 @@ public final class LifecycleCallbackFactory {
return selector.getMatchingMethods( method, candidates, null, null, new SelectionCriteria(
qualifiers,
null, /* todo */
null,
null,
false ) );

View File

@ -54,7 +54,9 @@ public class MapMappingMethod extends MappingMethod {
private String keyDateFormat;
private String valueDateFormat;
private List<TypeMirror> keyQualifiers;
private List<String> keyQualifyingNames;
private List<TypeMirror> valueQualifiers;
private List<String> valueQualifyingNames;
private TypeMirror keyQualifyingTargetType;
private TypeMirror valueQualifyingTargetType;
private Method method;
@ -86,11 +88,21 @@ public class MapMappingMethod extends MappingMethod {
return this;
}
public Builder keyQualifyingNames(List<String> keyQualifyingNames) {
this.keyQualifyingNames = keyQualifyingNames;
return this;
}
public Builder valueQualifiers(List<TypeMirror> valueQualifiers) {
this.valueQualifiers = valueQualifiers;
return this;
}
public Builder valueQualifyingNames(List<String> valueQualifyingNames) {
this.valueQualifyingNames = valueQualifyingNames;
return this;
}
public Builder keyQualifyingTargetType(TypeMirror keyQualifyingTargetType) {
this.keyQualifyingTargetType = keyQualifyingTargetType;
return this;
@ -125,6 +137,7 @@ public class MapMappingMethod extends MappingMethod {
null, // there is no targetPropertyName
keyDateFormat,
keyQualifiers,
keyQualifyingNames,
keyQualifyingTargetType,
"entry.getKey()",
false
@ -153,6 +166,7 @@ public class MapMappingMethod extends MappingMethod {
null, // there is no targetPropertyName
valueDateFormat,
valueQualifiers,
valueQualifyingNames,
valueQualifyingTargetType,
"entry.getValue()",
false
@ -187,7 +201,8 @@ public class MapMappingMethod extends MappingMethod {
MethodReference factoryMethod = null;
if ( !method.isUpdateMethod() ) {
factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType(), null, null );
factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, method.getResultType(), null, null,
null );
}
keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes() );

View File

@ -80,6 +80,7 @@ public class MappingBuilderContext {
* @param targetPropertyName name of the target property
* @param dateFormat used for formatting dates in build in methods that need context information
* @param qualifiers used for further select the appropriate mapping method based on class and name
* @param qualifyingNames see qualifiers, used in combination with with @Named
* @param resultType used for further select the appropriate mapping method based on resultType (bean mapping)
* targetType (Iterable- and MapMapping)
* @param sourceReference call to source type as string
@ -93,9 +94,11 @@ public class MappingBuilderContext {
* <li>null, no assignment found</li>
* </ol>
*/
@SuppressWarnings("checkstyle:parameternumber")
Assignment getTargetAssignment(Method mappingMethod, String mappedElement, Type sourceType, Type targetType,
String targetPropertyName, String dateFormat, List<TypeMirror> qualifiers,
TypeMirror resultType, String sourceReference, boolean preferUpdateMethods);
List<String> qualifyingNames, TypeMirror resultType, String sourceReference,
boolean preferUpdateMethods);
/**
* returns a no arg factory method
@ -103,6 +106,7 @@ public class MappingBuilderContext {
* @param mappingMethod target mapping method
* @param target return type to match
* @param qualifiers used for further select the appropriate mapping method based on class and name
* @param qualifyingNames see qualifiers, used in combination with with @Named
* @param resultType used for further select the appropriate mapping method based on resultType (bean mapping)
* targetType (Iterable- and MapMapping) *
*
@ -110,7 +114,7 @@ public class MappingBuilderContext {
*
*/
MethodReference getFactoryMethod(Method mappingMethod, Type target, List<TypeMirror> qualifiers,
TypeMirror resultType);
List<String> qualifyingNames, TypeMirror resultType);
Set<VirtualMappingMethod> getUsedVirtualMappings();
}

View File

@ -169,6 +169,7 @@ public class PropertyMapping extends ModelElement {
private String dateFormat;
private String defaultValue;
private List<TypeMirror> qualifiers;
private List<String> qualifyingNames;
private TypeMirror resultType;
private SourceReference sourceReference;
@ -182,6 +183,11 @@ public class PropertyMapping extends ModelElement {
return this;
}
public PropertyMappingBuilder qualifyingNames(List<String> qualifyingNames) {
this.qualifyingNames = qualifyingNames;
return this;
}
public PropertyMappingBuilder resultType(TypeMirror resultType) {
this.resultType = resultType;
return this;
@ -229,6 +235,7 @@ public class PropertyMapping extends ModelElement {
targetPropertyName,
dateFormat,
qualifiers,
qualifyingNames,
resultType,
sourceRefStr,
preferUpdateMethods
@ -316,7 +323,7 @@ public class PropertyMapping extends ModelElement {
targetPropertyName );
}
Assignment factoryMethod =
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null, null );
result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod,
targetType );
}
@ -397,7 +404,7 @@ public class PropertyMapping extends ModelElement {
targetPropertyName );
}
Assignment factoryMethod
= ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
= ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null, null );
result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod,
targetType );
}
@ -605,6 +612,7 @@ public class PropertyMapping extends ModelElement {
private String constantExpression;
private String dateFormat;
private List<TypeMirror> qualifiers;
private List<String> qualifyingNames;
private TypeMirror resultType;
public ConstantMappingBuilder constantExpression(String constantExpression) {
@ -622,6 +630,11 @@ public class PropertyMapping extends ModelElement {
return this;
}
public ConstantMappingBuilder qualifyingNames(List<String> qualifyingNames) {
this.qualifyingNames = qualifyingNames;
return this;
}
public ConstantMappingBuilder resultType(TypeMirror resultType) {
this.resultType = resultType;
return this;
@ -640,6 +653,7 @@ public class PropertyMapping extends ModelElement {
targetPropertyName,
dateFormat,
qualifiers,
qualifyingNames,
resultType,
constantExpression,
method.getMappingTargetParameter() != null
@ -657,7 +671,7 @@ public class PropertyMapping extends ModelElement {
targetPropertyName );
}
Assignment factoryMethod =
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null );
ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null, null );
assignment = new UpdateWrapper( assignment, method.getThrownTypes(), factoryMethod,
targetType );
}

View File

@ -38,6 +38,7 @@ import org.mapstruct.ap.internal.util.Message;
public class BeanMapping {
private final List<TypeMirror> qualifiers;
private final List<String> qualifyingNames;
private final TypeMirror resultType;
private final NullValueMappingStrategyPrism nullValueMappingStrategy;
@ -55,7 +56,7 @@ public class BeanMapping {
? null
: NullValueMappingStrategyPrism.valueOf( beanMapping.nullValueMappingStrategy() );
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty()
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() && beanMapping.qualifiedByName().isEmpty()
&& ( nullValueMappingStrategy == null ) ) {
messager.printMessage( method, Message.BEANMAPPING_NO_ELEMENTS );
@ -63,14 +64,17 @@ public class BeanMapping {
return new BeanMapping(
beanMapping.qualifiedBy(),
beanMapping.qualifiedByName(),
resultTypeIsDefined ? beanMapping.resultType() : null,
nullValueMappingStrategy
);
}
private BeanMapping(List<TypeMirror> qualifiers, TypeMirror mirror, NullValueMappingStrategyPrism nvms) {
private BeanMapping(List<TypeMirror> qualifiers, List<String> qualyfyingNames, TypeMirror mirror,
NullValueMappingStrategyPrism nvms) {
this.qualifiers = qualifiers;
this.qualifyingNames = qualyfyingNames;
this.resultType = mirror;
this.nullValueMappingStrategy = nvms;
}
@ -79,6 +83,10 @@ public class BeanMapping {
return qualifiers;
}
public List<String> getQualifyingNames() {
return qualifyingNames;
}
public TypeMirror getResultType() {
return resultType;
}

View File

@ -40,6 +40,7 @@ public class IterableMapping {
private final String dateFormat;
private final List<TypeMirror> qualifiers;
private final List<String> qualifyingNames;
private final TypeMirror qualifyingElementTargetType;
private final AnnotationMirror mirror;
private final AnnotationValue dateFormatAnnotationValue;
@ -61,6 +62,7 @@ public class IterableMapping {
if ( !elementTargetTypeIsDefined
&& iterableMapping.dateFormat().isEmpty()
&& iterableMapping.qualifiedBy().isEmpty()
&& iterableMapping.qualifiedByName().isEmpty()
&& ( nullValueMappingStrategy == null ) ) {
messager.printMessage( method, Message.ITERABLEMAPPING_NO_ELEMENTS );
@ -68,6 +70,7 @@ public class IterableMapping {
return new IterableMapping(iterableMapping.dateFormat(),
iterableMapping.qualifiedBy(),
iterableMapping.qualifiedByName(),
elementTargetTypeIsDefined ? iterableMapping.elementTargetType() : null,
iterableMapping.mirror,
iterableMapping.values.dateFormat(),
@ -75,11 +78,13 @@ public class IterableMapping {
);
}
private IterableMapping(String dateFormat, List<TypeMirror> qualifiers, TypeMirror resultType,
AnnotationMirror mirror, AnnotationValue dateFormatAnnotationValue, NullValueMappingStrategyPrism nvms) {
private IterableMapping(String dateFormat, List<TypeMirror> qualifiers, List<String> qualifyingNames,
TypeMirror resultType, AnnotationMirror mirror, AnnotationValue dateFormatAnnotationValue,
NullValueMappingStrategyPrism nvms) {
this.dateFormat = dateFormat;
this.qualifiers = qualifiers;
this.qualifyingNames = qualifyingNames;
this.qualifyingElementTargetType = resultType;
this.mirror = mirror;
this.dateFormatAnnotationValue = dateFormatAnnotationValue;
@ -94,6 +99,10 @@ public class IterableMapping {
return qualifiers;
}
public List<String> getQualifyingNames() {
return qualifyingNames;
}
public TypeMirror getQualifyingElementTargetType() {
return qualifyingElementTargetType;
}

View File

@ -39,8 +39,10 @@ public class MapMapping {
private final String keyFormat;
private final List<TypeMirror> keyQualifiers;
private final List<String> keyQualifyingNames;
private final String valueFormat;
private final List<TypeMirror> valueQualifiers;
private final List<String> valueQualifyingNames;
private final AnnotationMirror mirror;
private final TypeMirror keyQualifyingTargetType;
private final TypeMirror valueQualifyingTargetType;
@ -62,8 +64,10 @@ public class MapMapping {
boolean valueTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.valueTargetType().getKind() );
if ( mapMapping.keyDateFormat().isEmpty()
&& mapMapping.keyQualifiedBy().isEmpty()
&& mapMapping.keyQualifiedByName().isEmpty()
&& mapMapping.valueDateFormat().isEmpty()
&& mapMapping.valueQualifiedBy().isEmpty()
&& mapMapping.valueQualifiedByName().isEmpty()
&& !keyTargetTypeIsDefined
&& !valueTargetTypeIsDefined
&& ( nullValueMappingStrategy == null ) ) {
@ -75,23 +79,28 @@ public class MapMapping {
return new MapMapping(
mapMapping.keyDateFormat(),
mapMapping.keyQualifiedBy(),
mapMapping.keyQualifiedByName(),
keyTargetTypeIsDefined ? mapMapping.keyTargetType() : null,
mapMapping.valueDateFormat(),
mapMapping.valueQualifiedBy(),
mapMapping.valueQualifiedByName(),
valueTargetTypeIsDefined ? mapMapping.valueTargetType() : null,
mapMapping.mirror,
nullValueMappingStrategy
);
}
private MapMapping(String keyFormat, List<TypeMirror> keyQualifiers, TypeMirror keyResultType, String valueFormat,
List<TypeMirror> valueQualifiers, TypeMirror valueResultType, AnnotationMirror mirror,
private MapMapping(String keyFormat, List<TypeMirror> keyQualifiers, List<String> keyQualifyingNames,
TypeMirror keyResultType, String valueFormat, List<TypeMirror> valueQualifiers,
List<String> valueQualifyingNames, TypeMirror valueResultType, AnnotationMirror mirror,
NullValueMappingStrategyPrism nvms ) {
this.keyFormat = keyFormat;
this.keyQualifiers = keyQualifiers;
this.keyQualifyingNames = keyQualifyingNames;
this.keyQualifyingTargetType = keyResultType;
this.valueFormat = valueFormat;
this.valueQualifiers = valueQualifiers;
this.valueQualifyingNames = valueQualifyingNames;
this.valueQualifyingTargetType = valueResultType;
this.mirror = mirror;
this.nullValueMappingStrategy = nvms;
@ -105,6 +114,10 @@ public class MapMapping {
return keyQualifiers;
}
public List<String> getKeyQualifyingNames() {
return keyQualifyingNames;
}
public TypeMirror getKeyQualifyingTargetType() {
return keyQualifyingTargetType;
}
@ -117,6 +130,10 @@ public class MapMapping {
return valueQualifiers;
}
public List<String> getValueQualifyingNames() {
return valueQualifyingNames;
}
public TypeMirror getValueQualifyingTargetType() {
return valueQualifyingTargetType;
}

View File

@ -57,6 +57,7 @@ public class Mapping {
private final String dateFormat;
private final String defaultValue;
private final List<TypeMirror> qualifiers;
private final List<String> qualifyingNames;
private final TypeMirror resultType;
private final boolean isIgnored;
private final List<String> dependsOn;
@ -147,6 +148,7 @@ public class Mapping {
dateFormat,
defaultValue,
mappingPrism.qualifiedBy(),
mappingPrism.qualifiedByName(),
mappingPrism.ignore(),
mappingPrism.mirror,
mappingPrism.values.source(),
@ -160,7 +162,7 @@ public class Mapping {
@SuppressWarnings("checkstyle:parameternumber")
private Mapping(String sourceName, String constant, String javaExpression, String targetName,
String dateFormat, String defaultValue, List<TypeMirror> qualifiers,
boolean isIgnored, AnnotationMirror mirror,
List<String> qualifyingNames, boolean isIgnored, AnnotationMirror mirror,
AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue,
AnnotationValue dependsOnAnnotationValue,
TypeMirror resultType, List<String> dependsOn) {
@ -171,6 +173,7 @@ public class Mapping {
this.dateFormat = dateFormat;
this.defaultValue = defaultValue;
this.qualifiers = qualifiers;
this.qualifyingNames = qualifyingNames;
this.isIgnored = isIgnored;
this.mirror = mirror;
this.sourceAnnotationValue = sourceAnnotationValue;
@ -250,6 +253,10 @@ public class Mapping {
return qualifiers;
}
public List<String> getQualifyingNames() {
return qualifyingNames;
}
public boolean isIgnored() {
return isIgnored;
}
@ -325,6 +332,7 @@ public class Mapping {
dateFormat,
null,
qualifiers,
qualifyingNames,
isIgnored,
mirror,
sourceAnnotationValue,
@ -353,6 +361,7 @@ public class Mapping {
dateFormat,
defaultValue,
qualifiers,
qualifyingNames,
isIgnored,
mirror,
sourceAnnotationValue,

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
@ -31,6 +32,7 @@ import javax.lang.model.util.Types;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SourceMethod;
import org.mapstruct.ap.internal.prism.NamedPrism;
import org.mapstruct.ap.internal.prism.QualifierPrism;
/**
@ -53,10 +55,11 @@ import org.mapstruct.ap.internal.prism.QualifierPrism;
public class QualifierSelector implements MethodSelector {
private final Types typeUtils;
private final TypeMirror namedAnnotationTypeMirror;
public QualifierSelector( Types typeUtils, Elements elementUtils ) {
this.typeUtils = typeUtils;
namedAnnotationTypeMirror = elementUtils.getTypeElement( "org.mapstruct.Named" ).asType();
}
@Override
@ -64,14 +67,33 @@ public class QualifierSelector implements MethodSelector {
Type sourceType, Type targetType,
SelectionCriteria criteria) {
List<TypeMirror> qualifiers = criteria.getQualifiers();
if ( qualifiers == null || qualifiers.isEmpty() ) {
// remove the method marked as qualifier from the list
int numberOfQualifiersToMatch = 0;
// Define some local collections and make sure that they are defined.
List<TypeMirror> qualifierTypes = new ArrayList<TypeMirror>();
if ( criteria.getQualifiers() != null ) {
qualifierTypes.addAll( criteria.getQualifiers() );
numberOfQualifiersToMatch += criteria.getQualifiers().size();
}
List<String> qualfiedByNames = new ArrayList<String>();
if ( criteria.getQualifiedByNames() != null ) {
qualfiedByNames.addAll( criteria.getQualifiedByNames() );
numberOfQualifiersToMatch += criteria.getQualifiedByNames().size();
}
// add the mapstruct @Named annotation as annotation to look for
if ( !qualfiedByNames.isEmpty() ) {
qualifierTypes.add( namedAnnotationTypeMirror );
}
// Check there are qualfiers for this mapping: Mapping#qualifier or Mapping#qualfiedByName
if ( qualifierTypes.isEmpty() ) {
// When no qualifiers, disqualify all methods marked with a qualifier by removing them from the candidates
List<T> nonQualiferAnnotatedMethods = new ArrayList<T>();
for ( T candidate : methods ) {
if ( candidate instanceof SourceMethod ) {
Set<TypeMirror> qualifierAnnotations = getQualifierAnnotations( candidate );
Set<AnnotationMirror> qualifierAnnotations = getQualifierAnnotationMirrors( candidate );
if ( qualifierAnnotations.isEmpty() ) {
nonQualiferAnnotatedMethods.add( candidate );
}
@ -84,7 +106,7 @@ public class QualifierSelector implements MethodSelector {
return nonQualiferAnnotatedMethods;
}
else {
// Check all methods marked with qualfier (or methods in Mappers marked wiht a qualfier) for matches.
List<T> matches = new ArrayList<T>();
for ( T candidate : methods ) {
@ -93,21 +115,37 @@ public class QualifierSelector implements MethodSelector {
}
// retrieve annotations
Set<TypeMirror> qualifierAnnotations = getQualifierAnnotations( candidate );
Set<AnnotationMirror> qualifierAnnotationMirrors = getQualifierAnnotationMirrors( candidate );
// now count if all qualifiers are matched
int matchingQualifierCounter = 0;
for ( TypeMirror qualifier : qualifiers ) {
for ( TypeMirror annotationType : qualifierAnnotations ) {
if ( typeUtils.isSameType( qualifier, annotationType ) ) {
matchingQualifierCounter++;
for ( AnnotationMirror qualifierAnnotationMirror : qualifierAnnotationMirrors ) {
for ( TypeMirror qualifierType : qualifierTypes ) {
// get the type of the annotation mirror.
DeclaredType qualifierAnnotationType = qualifierAnnotationMirror.getAnnotationType();
if ( typeUtils.isSameType( qualifierType, qualifierAnnotationType ) ) {
// Match! we have an annotation which has the @Qualifer marker ( could be @Named as well )
if ( typeUtils.isSameType( qualifierAnnotationType, namedAnnotationTypeMirror ) ) {
// Match! its an @Named, so do the additional check on name.
NamedPrism namedPrism = NamedPrism.getInstance( qualifierAnnotationMirror );
if ( namedPrism.value() != null && qualfiedByNames.contains( namedPrism.value() ) ) {
// Match! its an @Name and the value matches as well. Oh boy.
matchingQualifierCounter++;
}
}
else {
// Match! its a self declared qualifer annoation (marked with @Qualifier)
matchingQualifierCounter++;
}
break;
}
}
}
if ( matchingQualifierCounter == qualifiers.size() ) {
// all qualifiers are matched with a qualifying annotation, add candidate
if ( matchingQualifierCounter == numberOfQualifiersToMatch ) {
// Only if all qualifiers are matched with a qualifying annotation, add candidate
matches.add( candidate );
}
}
@ -120,10 +158,10 @@ public class QualifierSelector implements MethodSelector {
}
}
private Set<TypeMirror> getQualifierAnnotations( Method candidate ) {
private Set<AnnotationMirror> getQualifierAnnotationMirrors( Method candidate ) {
// retrieve annotations
Set<TypeMirror> qualiferAnnotations = new HashSet<TypeMirror>();
Set<AnnotationMirror> qualiferAnnotations = new HashSet<AnnotationMirror>();
// first from the method itself
SourceMethod candidateSM = (SourceMethod) candidate;
@ -144,12 +182,11 @@ public class QualifierSelector implements MethodSelector {
return qualiferAnnotations;
}
private void addOnlyWhenQualifier( Set<TypeMirror> annotationSet, AnnotationMirror candidate ) {
private void addOnlyWhenQualifier( Set<AnnotationMirror> annotationSet, AnnotationMirror candidate ) {
// only add the candidate annotation when the candidate itself has the annotation 'Qualifier'
if ( QualifierPrism.getInstanceOn( candidate.getAnnotationType().asElement() ) != null ) {
annotationSet.add( candidate.getAnnotationType() );
annotationSet.add( candidate );
}
}
}

View File

@ -30,13 +30,15 @@ import javax.lang.model.type.TypeMirror;
public class SelectionCriteria {
private final List<TypeMirror> qualifiers;
private final List<String> qualifiedByNames;
private final String targetPropertyName;
private final TypeMirror qualifyingResultType;
private boolean preferUpdateMapping;
public SelectionCriteria(List<TypeMirror> qualifiers, String targetPropertyName, TypeMirror qualifyingResultType,
boolean preferUpdateMapping ) {
public SelectionCriteria(List<TypeMirror> qualifiers, List<String> qualifiedByNames, String targetPropertyName,
TypeMirror qualifyingResultType, boolean preferUpdateMapping ) {
this.qualifiers = qualifiers;
this.qualifiedByNames = qualifiedByNames;
this.targetPropertyName = targetPropertyName;
this.qualifyingResultType = qualifyingResultType;
this.preferUpdateMapping = preferUpdateMapping;
@ -46,6 +48,10 @@ public class SelectionCriteria {
return qualifiers;
}
public List<String> getQualifiedByNames() {
return qualifiedByNames;
}
public String getTargetPropertyName() {
return targetPropertyName;
}

View File

@ -39,6 +39,7 @@ import org.mapstruct.TargetType;
import net.java.dev.hickory.prism.GeneratePrism;
import net.java.dev.hickory.prism.GeneratePrisms;
import org.mapstruct.Named;
/**
* Triggers the generation of prism types using <a href="https://java.net/projects/hickory">Hickory</a>.
@ -59,6 +60,7 @@ import net.java.dev.hickory.prism.GeneratePrisms;
@GeneratePrism(value = InheritConfiguration.class, publicAccess = true),
@GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true),
@GeneratePrism(value = Qualifier.class, publicAccess = true),
@GeneratePrism(value = Named.class, publicAccess = true),
@GeneratePrism(value = AfterMapping.class, publicAccess = true),
@GeneratePrism(value = BeforeMapping.class, publicAccess = true),

View File

@ -269,12 +269,14 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
String dateFormat = null;
List<TypeMirror> qualifiers = null;
List<String> qualifyingNames = null;
TypeMirror qualifyingElementTargetType = null;
NullValueMappingStrategyPrism nullValueMappingStrategy = null;
if ( mappingOptions.getIterableMapping() != null ) {
dateFormat = mappingOptions.getIterableMapping().getDateFormat();
qualifiers = mappingOptions.getIterableMapping().getQualifiers();
qualifyingNames = mappingOptions.getIterableMapping().getQualifyingNames();
qualifyingElementTargetType = mappingOptions.getIterableMapping().getQualifyingElementTargetType();
nullValueMappingStrategy = mappingOptions.getIterableMapping().getNullValueMappingStrategy();
}
@ -284,6 +286,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
.method( method )
.dateFormat( dateFormat )
.qualifiers( qualifiers )
.qualifyingNames( qualifyingNames )
.qualifyingElementTargetType( qualifyingElementTargetType )
.nullValueMappingStrategy( nullValueMappingStrategy )
.build();
@ -298,7 +301,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
String keyDateFormat = null;
String valueDateFormat = null;
List<TypeMirror> keyQualifiers = null;
List<String> keyQualifyingNames = null;
List<TypeMirror> valueQualifiers = null;
List<String> valueQualifyingNames = null;
TypeMirror keyQualifyingTargetType = null;
TypeMirror valueQualifyingTargetType = null;
NullValueMappingStrategyPrism nullValueMappingStrategy = null;
@ -307,7 +312,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
keyDateFormat = mappingOptions.getMapMapping().getKeyFormat();
valueDateFormat = mappingOptions.getMapMapping().getValueFormat();
keyQualifiers = mappingOptions.getMapMapping().getKeyQualifiers();
keyQualifyingNames = mappingOptions.getMapMapping().getKeyQualifyingNames();
valueQualifiers = mappingOptions.getMapMapping().getValueQualifiers();
valueQualifyingNames = mappingOptions.getMapMapping().getValueQualifyingNames();
keyQualifyingTargetType = mappingOptions.getMapMapping().getKeyQualifyingTargetType();
valueQualifyingTargetType = mappingOptions.getMapMapping().getValueQualifyingTargetType();
nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy();
@ -319,7 +326,9 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
.keyDateFormat( keyDateFormat )
.valueDateFormat( valueDateFormat )
.keyQualifiers( keyQualifiers )
.keyQualifyingNames( keyQualifyingNames )
.valueQualifiers( valueQualifiers )
.valueQualifyingNames( valueQualifyingNames )
.keyQualifyingTargetType( keyQualifyingTargetType )
.valueQualifyingTargetType( valueQualifyingTargetType )
.nullValueMappingStrategy( nullValueMappingStrategy )
@ -345,11 +354,13 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
NullValueMappingStrategyPrism nullValueMappingStrategy = null;
TypeMirror resultType = null;
List<TypeMirror> qualifiers = null;
List<String> qualifyingNames = null;
if ( mappingOptions.getBeanMapping() != null ) {
nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy();
resultType = mappingOptions.getBeanMapping().getResultType();
qualifiers = mappingOptions.getBeanMapping().getQualifiers();
qualifyingNames = mappingOptions.getBeanMapping().getQualifyingNames();
}
BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder();
BeanMappingMethod beanMappingMethod = builder
@ -357,6 +368,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
.souceMethod( method )
.nullValueMappingStrategy( nullValueMappingStrategy )
.qualifiers( qualifiers )
.qualifyingNames( qualifyingNames )
.resultType( resultType )
.build();