#268 introduction of qualifiers

This commit is contained in:
sjaakd 2014-08-17 12:06:21 +02:00
parent 6d7a4da067
commit 69beb9a6b4
32 changed files with 1130 additions and 47 deletions

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -41,4 +42,14 @@ public @interface IterableMapping {
* @return A date format string as processable by {@link SimpleDateFormat}.
*/
String dateFormat();
/**
* A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple
* mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] qualifiedBy() default { };
}

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -50,4 +51,26 @@ public @interface MapMapping {
* @return A date format string as processable by {@link SimpleDateFormat}.
*/
String valueDateFormat() default "";
/**
* A key value qualifier can be specified to aid the selection process of a suitable mapper. This is useful in
* case multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found'
* error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] keyQualifiedBy() default { };
/**
* A value qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case
* multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] valueQualifiedBy() default { };
}

View File

@ -0,0 +1,52 @@
/**
* Copyright 2012-2014 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;
/**
* Declares a target annotation to be a qualifier.
*
* <p>
* For more info see:
* <ol>
* <li>{@link Mapping#qualifiedBy() }</li>
* <li>{@link IterableMapping#qualifiedBy() }</li>
* <li>{@link MapMapping#keyQualifiedBy() }</li>
* <li>{@link MapMapping#valueQualifiedBy() }</li>
* </p>
* <p>
* <code>
* @Qualifier
* @Target(ElementType.METHOD)
* @Retention(RetentionPolicy.SOURCE)
* public @interface EnglishToGerman {
* }
* </code>
* </p>
*
* @author Sjaak Derksen
*/
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface Qualifier {
}

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
@ -31,9 +32,9 @@ import java.util.Date;
*
* @author Gunnar Morling
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
@Repeatable(Mappings.class)
@Retention( RetentionPolicy.SOURCE )
@Target( ElementType.METHOD )
@Repeatable( Mappings.class )
public @interface Mapping {
/**
@ -42,8 +43,8 @@ public @interface Mapping {
* <li>The source name of the configured property as defined by the JavaBeans specification.</li>
* <li>When used to map an enum constant, the name of the constant member is to be given.</li>
* </ol>
* Either this attribute or {@link #constant()} or {@link #expression()} may be specified for a given mapping,
* but not two at the same time. If this attribute is given, the target property must be specified via
* Either this attribute or {@link #constant()} or {@link #expression()} may be specified for a given mapping, but
* not two at the same time. If this attribute is given, the target property must be specified via
* {@link #target()}.
*
* @return The source name of the configured property or enum constant.
@ -67,13 +68,12 @@ public @interface Mapping {
String dateFormat() default "";
/**
* A constant {@link String} based on which the specified target property is to be set. If the designated
* target property is not of type {@code String}, the value will be converted by applying a matching conversion
* method or built-in conversion.
* A constant {@link String} based on which the specified target property is to be set. If the designated target
* property is not of type {@code String}, the value will be converted by applying a matching conversion method or
* built-in conversion.
* <p>
* Either this attribute or {@link #source()} or {@link #expression()} may be specified for a given mapping,
* but not two at the same time. If this attribute is given, the target property must be specified via
* {@link #target()}.
* Either this attribute or {@link #source()} or {@link #expression()} may be specified for a given mapping, but not
* two at the same time. If this attribute is given, the target property must be specified via {@link #target()}.
*
* @return A constant {@code String} constant specifying the value for the designated target property
*/
@ -86,9 +86,8 @@ public @interface Mapping {
* {@code expression = "java(new org.example.TimeAndFormat( s.getTime(), s.getFormat() ))")} will insert the java
* expression in the designated {@link #target()} property.
* <p>
* Either this attribute or {@link #source()} or {@link #constant()} may be specified for a given mapping,
* but not two at the same time. If this attribute is given, the target property must be specified via
* {@link #target()}.
* Either this attribute or {@link #source()} or {@link #constant()} may be specified for a given mapping, but not
* two at the same time. If this attribute is given, the target property must be specified via {@link #target()}.
*
* @return A constant {@code String} constant specifying the value for the designated target property
*/
@ -103,4 +102,14 @@ public @interface Mapping {
* @return {@code true} if the given property should be ignored, {@code false} otherwise
*/
boolean ignore() default false;
/**
* A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple
* mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] qualifiedBy() default { };
}

View File

@ -18,6 +18,7 @@
*/
package org.mapstruct;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -101,4 +102,14 @@ public @interface Mapping {
* @return {@code true} if the given property should be ignored, {@code false} otherwise
*/
boolean ignore() default false;
/**
* A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple
* mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error.
*
* A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method.
*
* @return the qualifiers
*/
Class<? extends Annotation>[] qualifiedBy() default { };
}

View File

@ -18,8 +18,10 @@
*/
package org.mapstruct.ap.model.source;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.IterableMappingPrism;
@ -31,6 +33,7 @@ import org.mapstruct.ap.prism.IterableMappingPrism;
public class IterableMapping {
private final String dateFormat;
private final List<TypeMirror> qualifiers;
private final AnnotationMirror mirror;
private final AnnotationValue dateFormatAnnotationValue;
@ -41,13 +44,19 @@ public class IterableMapping {
return new IterableMapping(
iterableMapping.dateFormat(),
iterableMapping.qualifiedBy(),
iterableMapping.mirror,
iterableMapping.values.dateFormat()
);
}
private IterableMapping(String dateFormat, AnnotationMirror mirror, AnnotationValue dateFormatAnnotationValue) {
private IterableMapping(
String dateFormat,
List<TypeMirror> qualifiers,
AnnotationMirror mirror,
AnnotationValue dateFormatAnnotationValue) {
this.dateFormat = dateFormat;
this.qualifiers = qualifiers;
this.mirror = mirror;
this.dateFormatAnnotationValue = dateFormatAnnotationValue;
}
@ -56,6 +65,10 @@ public class IterableMapping {
return dateFormat;
}
public List<TypeMirror> getQualifiers() {
return qualifiers;
}
public AnnotationMirror getMirror() {
return mirror;
}

View File

@ -18,7 +18,9 @@
*/
package org.mapstruct.ap.model.source;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.prism.MapMappingPrism;
@ -30,7 +32,9 @@ import org.mapstruct.ap.prism.MapMappingPrism;
public class MapMapping {
private final String keyFormat;
private final List<TypeMirror> keyQualifiers;
private final String valueFormat;
private final List<TypeMirror> valueQualifiers;
private final AnnotationMirror mirror;
public static MapMapping fromPrism(MapMappingPrism mapMapping) {
@ -40,14 +44,23 @@ public class MapMapping {
return new MapMapping(
mapMapping.keyDateFormat(),
mapMapping.keyQualifiedBy(),
mapMapping.valueDateFormat(),
mapMapping.valueQualifiedBy(),
mapMapping.mirror
);
}
private MapMapping(String keyFormat, String valueFormat, AnnotationMirror mirror) {
private MapMapping(
String keyFormat,
List<TypeMirror> keyQualifiers,
String valueFormat,
List<TypeMirror> valueQualifiers,
AnnotationMirror mirror) {
this.keyFormat = keyFormat;
this.keyQualifiers = keyQualifiers;
this.valueFormat = valueFormat;
this.valueQualifiers = valueQualifiers;
this.mirror = mirror;
}
@ -55,10 +68,18 @@ public class MapMapping {
return keyFormat;
}
public List<TypeMirror> getKeyQualifiers() {
return keyQualifiers;
}
public String getValueFormat() {
return valueFormat;
}
public List<TypeMirror> getValueQualifiers() {
return valueQualifiers;
}
public AnnotationMirror getMirror() {
return mirror;
}

View File

@ -29,6 +29,7 @@ import javax.annotation.processing.Messager;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import org.mapstruct.ap.prism.MappingPrism;
@ -52,6 +53,7 @@ public class Mapping {
private final String javaExpression;
private final String targetName;
private final String dateFormat;
private final List<TypeMirror> qualifiers;
private final boolean isIgnored;
private final AnnotationMirror mirror;
private final AnnotationValue sourceAnnotationValue;
@ -126,6 +128,7 @@ public class Mapping {
mappingPrism.expression(),
mappingPrism.target(),
mappingPrism.dateFormat(),
mappingPrism.qualifiedBy(),
mappingPrism.ignore(),
mappingPrism.mirror,
mappingPrism.values.source(),
@ -153,9 +156,10 @@ public class Mapping {
}
//CHECKSTYLE:OFF
private Mapping(String sourceName, String sourceParameterName, String sourcePropertyName, String constant,
String expression, String targetName, String dateFormat, boolean isIgnored, AnnotationMirror mirror,
AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue) {
private Mapping( String sourceName, String sourceParameterName, String sourcePropertyName, String constant,
String expression, String targetName, String dateFormat, List<TypeMirror> qualifiers,
boolean isIgnored, AnnotationMirror mirror, AnnotationValue sourceAnnotationValue,
AnnotationValue targetAnnotationValue) {
this.sourceName = sourceName;
this.sourceParameterName = sourceParameterName;
this.sourcePropertyName = sourcePropertyName;
@ -165,6 +169,7 @@ public class Mapping {
this.javaExpression = javaExpressionMatcher.matches() ? javaExpressionMatcher.group( 1 ).trim() : "";
this.targetName = targetName.equals( "" ) ? sourceName : targetName;
this.dateFormat = dateFormat;
this.qualifiers = qualifiers;
this.isIgnored = isIgnored;
this.mirror = mirror;
this.sourceAnnotationValue = sourceAnnotationValue;
@ -216,6 +221,10 @@ public class Mapping {
return dateFormat;
}
public List<TypeMirror> getQualifiers() {
return qualifiers;
}
public boolean isIgnored() {
return isIgnored;
}
@ -244,6 +253,7 @@ public class Mapping {
expression,
sourceName,
dateFormat,
qualifiers,
isIgnored,
mirror,
sourceAnnotationValue,

View File

@ -20,6 +20,7 @@ package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.model.common.Parameter;
import org.mapstruct.ap.model.common.Type;
@ -33,8 +34,14 @@ import org.mapstruct.ap.model.source.Method;
public class InheritanceSelector implements MethodSelector {
@Override
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
Type returnType, String targetPropertyName) {
public <T extends Method> List<T> getMatchingMethods(
Method mappingMethod,
List<T> methods,
Type parameterType,
Type returnType,
List<TypeMirror> qualifiers,
String targetPropertyName
) {
List<T> candidatesWithBestMatchingSourceType = new ArrayList<T>();
int bestMatchingSourceTypeDistance = Integer.MAX_VALUE;

View File

@ -19,6 +19,7 @@
package org.mapstruct.ap.model.source.selector;
import java.util.List;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method;
@ -40,10 +41,12 @@ public interface MethodSelector {
* @param methods list of available methods
* @param parameterType parameter type that should be matched
* @param returnType return type that should be matched
* @param qualifiers list of custom annotations, used in the qualifying process
* @param targetPropertyName some information can be derived from the target property
*
* @return list of methods that passes the matching process
*/
<T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
Type returnType, String targetPropertyName);
Type returnType, List<TypeMirror> qualifiers,
String targetPropertyName);
}

View File

@ -21,6 +21,8 @@ package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import org.mapstruct.ap.model.common.Parameter;
@ -37,18 +39,21 @@ public class MethodSelectors implements MethodSelector {
private final List<MethodSelector> selectors;
public MethodSelectors(Types typeUtils, TypeFactory typeFactory) {
public MethodSelectors(Types typeUtils, Elements elementUtils, TypeFactory typeFactory) {
selectors =
Arrays.<MethodSelector>asList(
new TypeSelector( typeFactory ),
new InheritanceSelector(),
new XmlElementDeclSelector( typeUtils )
new XmlElementDeclSelector( typeUtils ),
new QualifierSelector( typeUtils, elementUtils )
);
}
@Override
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
Type returnType, String targetPropertyName) {
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
Type parameterType, Type returnType,
List<TypeMirror> qualifiers,
String targetPropertyName) {
List<T> candidates = new ArrayList<T>( methods );
@ -58,6 +63,7 @@ public class MethodSelectors implements MethodSelector {
candidates,
parameterType,
returnType,
qualifiers,
targetPropertyName
);
}

View File

@ -0,0 +1,125 @@
/**
* Copyright 2012-2014 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.model.source.selector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import org.mapstruct.Qualifier;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.source.Method;
import org.mapstruct.ap.model.source.SourceMethod;
/**
* This selector selects a best match based on qualifiers name.
*
* @author Sjaak Derksen
*/
public class QualifierSelector implements MethodSelector {
private final Types typeUtils;
private final TypeMirror qualifierType;
public QualifierSelector( Types typeUtils, Elements elementUtils ) {
this.typeUtils = typeUtils;
qualifierType = elementUtils.getTypeElement( Qualifier.class.getCanonicalName() ).asType();
}
@Override
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
Type parameterType, Type returnType,
List<TypeMirror> qualifiers,
String targetPropertyName) {
List<T> matches = new ArrayList<T>();
if ( qualifiers == null || qualifiers.isEmpty() ) {
return methods;
}
for ( T candidate : methods ) {
if ( !( candidate instanceof SourceMethod ) ) {
continue;
}
// retrieve annotations
Set<TypeMirror> combinedAnnotations = new HashSet<TypeMirror>();
// first from the method itself
SourceMethod candidateSM = (SourceMethod) candidate;
List<? extends AnnotationMirror> methodAnnotations = candidateSM.getExecutable().getAnnotationMirrors();
for ( AnnotationMirror methodAnnotation : methodAnnotations ) {
addOnlyWhenQualifier( combinedAnnotations, methodAnnotation );
}
// then from the mapper (if declared)
Type mapper = candidate.getDeclaringMapper();
if ( mapper != null ) {
List<? extends AnnotationMirror> mapperAnnotations = mapper.getTypeElement().getAnnotationMirrors();
for ( AnnotationMirror mapperAnnotation : mapperAnnotations ) {
addOnlyWhenQualifier( combinedAnnotations, mapperAnnotation );
}
}
// now count if all qualifiers are machted
int matchingQualifierCounter = 0;
for ( TypeMirror qualifier : qualifiers) {
for ( TypeMirror annotationType : combinedAnnotations ) {
if ( typeUtils.isSameType( qualifier, annotationType ) ) {
matchingQualifierCounter++;
break;
}
}
}
if ( matchingQualifierCounter == qualifiers.size() ) {
// all qualifiers are matched with a qualifying annotation, add candidate
matches.add( candidate );
}
}
if ( !matches.isEmpty() ) {
return matches;
}
else {
return methods;
}
}
private void addOnlyWhenQualifier( Set<TypeMirror> annotationSet, AnnotationMirror candidate ) {
// get all the annotations of the candidate annotation
List<? extends AnnotationMirror> annotationsOfCandidate
= candidate.getAnnotationType().asElement().getAnnotationMirrors();
// only add the candidate annotation when the candidate itself has the annotation 'Qualifier'
for ( AnnotationMirror annotationOfCandidate : annotationsOfCandidate ) {
if ( typeUtils.isSameType( annotationOfCandidate.getAnnotationType(), qualifierType ) ) {
annotationSet.add( candidate.getAnnotationType() );
break;
}
}
}
}

View File

@ -20,6 +20,7 @@ package org.mapstruct.ap.model.source.selector;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.model.common.Type;
import org.mapstruct.ap.model.common.TypeFactory;
@ -41,8 +42,10 @@ public class TypeSelector implements MethodSelector {
}
@Override
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
Type returnType, String targetPropertyName) {
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
Type parameterType, Type returnType,
List<TypeMirror> qualifiers,
String targetPropertyName) {
List<T> result = new ArrayList<T>();
for ( T method : methods ) {

View File

@ -51,13 +51,16 @@ public class XmlElementDeclSelector implements MethodSelector {
}
@Override
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods, Type parameterType,
Type returnType, String targetPropertyName) {
public <T extends Method> List<T> getMatchingMethods(Method mappingMethod, List<T> methods,
Type parameterType, Type returnType,
List<TypeMirror> qualifiers,
String targetPropertyName) {
// only true source methods are qualifying
if ( !(mappingMethod instanceof SourceMethod) ) {
return methods;
}
SourceMethod sourceMappingMethod = (SourceMethod) mappingMethod;
List<T> nameMatches = new ArrayList<T>();

View File

@ -297,11 +297,21 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
reverseMappingMethod.getIterableMapping() != null ) {
method.setIterableMapping( reverseMappingMethod.getIterableMapping() );
}
String dateFormat
= method.getIterableMapping() != null ? method.getIterableMapping().getDateFormat() : null;
IterableMappingMethod iterableMappingMethod
= getIterableMappingMethod( mapperReferences, methods, method, dateFormat );
String dateFormat = null;
List<TypeMirror> qualifiers = null;
if ( method.getIterableMapping() != null ) {
dateFormat = method.getIterableMapping().getDateFormat();
qualifiers = method.getIterableMapping().getQualifiers();
}
IterableMappingMethod iterableMappingMethod = getIterableMappingMethod(
mapperReferences,
methods,
method,
dateFormat,
qualifiers
);
hasFactoryMethod = iterableMappingMethod.getFactoryMethod() != null;
mappingMethods.add( iterableMappingMethod );
}
@ -312,13 +322,24 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
}
String keyDateFormat = null;
String valueDateFormat = null;
List<TypeMirror> keyQualifiers = null;
List<TypeMirror> valueQualifiers = null;
if ( method.getMapMapping() != null ) {
keyDateFormat = method.getMapMapping().getKeyFormat();
valueDateFormat = method.getMapMapping().getValueFormat();
keyQualifiers = method.getMapMapping().getKeyQualifiers();
valueQualifiers = method.getMapMapping().getValueQualifiers();
}
MapMappingMethod mapMappingMethod
= getMapMappingMethod( mapperReferences, methods, method, keyDateFormat, valueDateFormat );
MapMappingMethod mapMappingMethod = getMapMappingMethod(
mapperReferences,
methods,
method,
keyDateFormat,
valueDateFormat,
keyQualifiers,
valueQualifiers
);
hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null;
mappingMethods.add( mapMappingMethod );
}
@ -438,9 +459,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
// check if there's a mapping defined
Mapping mapping = method.getMappingByTargetPropertyName( targetPropertyName );
String dateFormat = null;
List<TypeMirror> qualifiers = null;
String sourcePropertyName;
if ( mapping != null ) {
dateFormat = mapping.getDateFormat();
qualifiers = mapping.getQualifiers();
sourcePropertyName = mapping.getSourcePropertyName();
}
else {
@ -466,7 +489,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
sourceAccessor,
targetAccessor,
targetPropertyName,
dateFormat
dateFormat,
qualifiers
);
}
}
@ -480,7 +504,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
sourceAccessor,
targetAccessor,
targetPropertyName,
dateFormat
dateFormat,
qualifiers
);
}
}
@ -569,7 +594,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
method,
"\"" + mapping.getConstant() + "\"",
targetAccessor,
mapping.getDateFormat()
mapping.getDateFormat(),
mapping.getQualifiers()
);
}
@ -775,7 +801,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
ExecutableElement sourceAccessor,
ExecutableElement targetAccessor,
String targetPropertyName,
String dateFormat) {
String dateFormat,
List<TypeMirror> qualifiers) {
Type sourceType;
Type targetType;
@ -815,6 +842,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
targetType,
targetPropertyName,
dateFormat,
qualifiers,
iteratorReference != null ? iteratorReference : sourceReference
);
@ -925,7 +953,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
SourceMethod method,
String constantExpression,
ExecutableElement targetAccessor,
String dateFormat) {
String dateFormat,
List<TypeMirror> qualifiers) {
// source
String mappedElement = "constant '" + constantExpression + "'";
@ -944,6 +973,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
targetType,
targetPropertyName,
dateFormat,
qualifiers,
constantExpression
);
@ -986,7 +1016,8 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
private IterableMappingMethod getIterableMappingMethod(List<MapperReference> mapperReferences,
List<SourceMethod> methods,
Method method,
String dateFormat ) {
String dateFormat,
List<TypeMirror> qualifiers) {
Type sourceElementType = method.getSourceParameters().iterator().next().getType().getTypeParameters().get( 0 );
Type targetElementType = method.getResultType().getTypeParameters().get( 0 );
String conversionStr = Strings.getSaveVariableName( sourceElementType.getName(), method.getParameterNames() );
@ -1000,6 +1031,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
targetElementType,
null, // there is no targetPropertyName
dateFormat,
qualifiers,
conversionStr
);
@ -1019,8 +1051,13 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
return new IterableMappingMethod( method, assignment, factoryMethod );
}
private MapMappingMethod getMapMappingMethod(List<MapperReference> mapperReferences, List<SourceMethod> methods,
Method method, String keyDateFormat, String valueDateFormat ) {
private MapMappingMethod getMapMappingMethod(List<MapperReference> mapperReferences,
List<SourceMethod> methods,
Method method,
String keyDateFormat,
String valueDateFormat,
List<TypeMirror> keyQualifiers,
List<TypeMirror> valueQualifiers ) {
List<Type> sourceTypeParams = method.getSourceParameters().iterator().next().getType().getTypeParameters();
List<Type> resultTypeParams = method.getResultType().getTypeParameters();
@ -1037,6 +1074,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
keyTargetType,
null, // there is no targetPropertyName
keyDateFormat,
keyQualifiers,
"entry.getKey()"
);
@ -1059,6 +1097,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
valueTargetType,
null, // there is no targetPropertyName
valueDateFormat,
valueQualifiers,
"entry.getValue()"
);
@ -1233,7 +1272,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
ForgedMethod methodToGenerate
= new ForgedMethod( sourceType, targetType, element );
IterableMappingMethod iterableMappingMethod
= getIterableMappingMethod( mapperReferences, methods, methodToGenerate, null );
= getIterableMappingMethod( mapperReferences, methods, methodToGenerate, null, null );
if ( !mappingsToGenerate.contains( iterableMappingMethod ) ) {
mappingsToGenerate.add( iterableMappingMethod );
}
@ -1246,7 +1285,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
ForgedMethod methodToGenerate
= new ForgedMethod( sourceType, targetType, element );
MapMappingMethod mapMappingMethod
= getMapMappingMethod( mapperReferences, methods, methodToGenerate, null, null );
= getMapMappingMethod( mapperReferences, methods, methodToGenerate, null, null, null, null );
if ( !mappingsToGenerate.contains( mapMappingMethod ) ) {
mappingsToGenerate.add( mapMappingMethod );
}

View File

@ -89,7 +89,7 @@ public class MappingResolver {
this.conversions = new Conversions( elementUtils, typeFactory );
this.builtInMethods = new BuiltInMappingMethods( typeFactory );
this.virtualMethods = new HashSet<VirtualMappingMethod>();
this.methodSelectors = new MethodSelectors( typeUtils, typeFactory );
this.methodSelectors = new MethodSelectors( typeUtils, elementUtils, typeFactory );
this.typeUtils = typeUtils;
}
@ -105,6 +105,7 @@ public class MappingResolver {
* @param targetType return type to match
* @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 sourceReference call to source type as string
*
* @return an assignment to a method parameter, which can either be:
@ -123,6 +124,7 @@ public class MappingResolver {
Type targetType,
String targetPropertyName,
String dateFormat,
List<TypeMirror> qualifiers,
String sourceReference ) {
ResolvingAttempt attempt = new ResolvingAttempt( mappingMethod,
@ -131,6 +133,7 @@ public class MappingResolver {
methods,
targetPropertyName,
dateFormat,
qualifiers,
sourceReference,
this
);
@ -151,6 +154,7 @@ public class MappingResolver {
private final List<SourceMethod> methods;
private final String targetPropertyName;
private final String dateFormat;
private final List<TypeMirror> qualifiers;
private final String sourceReference;
private final MappingResolver context;
@ -165,6 +169,7 @@ public class MappingResolver {
List<SourceMethod> methods,
String targetPropertyName,
String dateFormat,
List<TypeMirror> qualifiers,
String sourceReference,
MappingResolver context ) {
this.mappingMethod = mappingMethod;
@ -173,6 +178,7 @@ public class MappingResolver {
this.methods = methods;
this.targetPropertyName = targetPropertyName;
this.dateFormat = dateFormat;
this.qualifiers = qualifiers;
this.sourceReference = sourceReference;
this.context = context;
this.virtualMethodCandidates = new HashSet<VirtualMappingMethod>();
@ -403,6 +409,7 @@ public class MappingResolver {
methods,
sourceType,
returnType,
qualifiers,
targetPropertyName
);

View File

@ -0,0 +1,44 @@
/**
* Copyright 2012-2014 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.selection.qualifier;
import org.mapstruct.ap.test.selection.qualifier.bean.GermanRelease;
import org.mapstruct.ap.test.selection.qualifier.bean.OriginalRelease;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.ap.test.selection.qualifier.annotation.NonQualifierAnnotated;
import org.mapstruct.ap.test.selection.qualifier.handwritten.SomeOtherMapper;
import org.mapstruct.ap.test.selection.qualifier.handwritten.YetAnotherMapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Sjaak Derksen
*/
@Mapper( uses = { SomeOtherMapper.class, YetAnotherMapper.class } )
public interface ErroneousMapper {
ErroneousMapper INSTANCE = Mappers.getMapper( ErroneousMapper.class );
@Mappings( {
@Mapping( source = "title", qualifiedBy = { NonQualifierAnnotated.class } ), } )
GermanRelease toGerman( OriginalRelease movies );
}

View File

@ -0,0 +1,42 @@
/**
* Copyright 2012-2014 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.selection.qualifier;
import java.util.List;
import java.util.Map;
import org.mapstruct.MapMapping;
import org.mapstruct.Mapper;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
import org.mapstruct.ap.test.selection.qualifier.handwritten.Facts;
import org.mapstruct.ap.test.selection.qualifier.handwritten.PlotWords;
import org.mapstruct.factory.Mappers;
/**
*
* @author Sjaak Derksen
*/
@Mapper( uses = { Facts.class, PlotWords.class } )
public interface FactMapper {
FactMapper INSTANCE = Mappers.getMapper( FactMapper.class );
@MapMapping( keyQualifiedBy = { EnglishToGerman.class }, valueQualifiedBy = { EnglishToGerman.class } )
Map<String, List<String>> mapFacts( Map<String, List<String>> keyWords );
}

View File

@ -0,0 +1,54 @@
/**
* Copyright 2012-2014 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.selection.qualifier;
import com.google.common.collect.ImmutableMap;
import java.util.List;
import java.util.Map;
import org.mapstruct.IterableMapping;
import org.mapstruct.Mapper;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
import org.mapstruct.ap.test.selection.qualifier.handwritten.SomeOtherMapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Sjaak Derksen
*/
@Mapper( uses = { SomeOtherMapper.class } )
public abstract class KeyWordMapper {
private static final Map<String, String> EN_GER = ImmutableMap.<String, String>builder()
.put( "magnificent", "Großartig" )
.put( "evergreen", "Evergreen" )
.put( "classic", "Klassiker" )
.put( "box office flop", "Kasse Flop" )
.build();
public static final KeyWordMapper INSTANCE = Mappers.getMapper( KeyWordMapper.class );
@IterableMapping( dateFormat = "", qualifiedBy = { EnglishToGerman.class } )
abstract List<String> mapKeyWords( List<String> keyWords );
@EnglishToGerman
public String mapKeyWord( String keyword ) {
return EN_GER.get( keyword );
}
}

View File

@ -0,0 +1,46 @@
/**
* Copyright 2012-2014 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.selection.qualifier;
import org.mapstruct.ap.test.selection.qualifier.bean.GermanRelease;
import org.mapstruct.ap.test.selection.qualifier.bean.OriginalRelease;
import org.mapstruct.ap.test.selection.qualifier.handwritten.Titles;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
import org.mapstruct.ap.test.selection.qualifier.annotation.TitleTranslator;
import org.mapstruct.ap.test.selection.qualifier.handwritten.SomeOtherMapper;
import org.mapstruct.factory.Mappers;
/**
*
* @author Sjaak Derksen
*/
@Mapper( uses = { Titles.class, SomeOtherMapper.class, KeyWordMapper.class, FactMapper.class } )
public interface MovieMapper {
MovieMapper INSTANCE = Mappers.getMapper( MovieMapper.class );
@Mappings( {
@Mapping( source = "title", qualifiedBy = { TitleTranslator.class, EnglishToGerman.class } ),
} )
GermanRelease toGerman( OriginalRelease movies );
}

View File

@ -0,0 +1,119 @@
/**
* Copyright 2012-2014 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.selection.qualifier;
import org.mapstruct.ap.test.selection.qualifier.bean.GermanRelease;
import org.mapstruct.ap.test.selection.qualifier.bean.OriginalRelease;
import org.mapstruct.ap.test.selection.qualifier.bean.AbstractEntry;
import org.mapstruct.ap.test.selection.qualifier.handwritten.Titles;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.tools.Diagnostic.Kind;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.MapAssert.entry;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
import org.mapstruct.ap.test.selection.qualifier.annotation.NonQualifierAnnotated;
import org.mapstruct.ap.test.selection.qualifier.annotation.TitleTranslator;
import org.mapstruct.ap.test.selection.qualifier.handwritten.Facts;
import org.mapstruct.ap.test.selection.qualifier.handwritten.PlotWords;
import org.mapstruct.ap.test.selection.qualifier.handwritten.SomeOtherMapper;
import org.mapstruct.ap.test.selection.qualifier.handwritten.YetAnotherMapper;
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;
/**
*
* @author Sjaak Derksen
*/
@IssueKey( "268" )
@WithClasses( {
OriginalRelease.class,
GermanRelease.class,
AbstractEntry.class,
SomeOtherMapper.class,
NonQualifierAnnotated.class
} )
@RunWith( AnnotationProcessorTestRunner.class )
public class QualifierTest {
@Test
@WithClasses( {
Titles.class,
Facts.class,
PlotWords.class,
OriginalRelease.class,
EnglishToGerman.class,
TitleTranslator.class,
MovieMapper.class,
KeyWordMapper.class,
FactMapper.class } )
public void shouldMatchClassAndMethod() {
OriginalRelease foreignMovies = new OriginalRelease();
foreignMovies.setTitle( "Sixth Sense, The" );
foreignMovies.setKeyWords( Arrays.asList( "evergreen", "magnificent" ) );
Map<String, List<String>> facts = new HashMap<String, List<String>>();
facts.put( "director", Arrays.asList( "M. Night Shyamalan" ) );
facts.put( "cast", Arrays.asList( "Bruce Willis", "Haley Joel Osment", "Toni Collette" ) );
facts.put( "plot keywords", Arrays.asList( "boy", "child psychologist", "I see dead people" ) );
foreignMovies.setFacts( facts );
GermanRelease germanMovies = MovieMapper.INSTANCE.toGerman( foreignMovies );
assertThat( germanMovies ).isNotNull();
assertThat( germanMovies.getTitle() ).isEqualTo( "Der sechste Sinn" );
assertThat( germanMovies.getKeyWords() ).isNotNull();
assertThat( germanMovies.getKeyWords().size() ).isEqualTo( 2 );
assertThat( germanMovies.getKeyWords() ).containsSequence( "Evergreen", "Großartig" );
assertThat( germanMovies.getFacts() ).isNotNull();
assertThat( germanMovies.getFacts() ).hasSize( 3 );
assertThat( germanMovies.getFacts() ).includes(
entry( "Regisseur", Arrays.asList( "M. Night Shyamalan" ) ),
entry( "Besetzung", Arrays.asList( "Bruce Willis", "Haley Joel Osment", "Toni Collette" ) ),
entry( "Handlungstichwörter", Arrays.asList( "Jungen", "Kinderpsychologe", "Ich sehe tote Menschen" ) )
);
}
@Test
@WithClasses( {
YetAnotherMapper.class,
ErroneousMapper.class
} )
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic( type = ErroneousMapper.class,
kind = Kind.ERROR,
line = 42,
messageRegExp = "Ambiguous mapping methods found for mapping property 'title' "
+ "from java.lang.String to java.lang.String.*" )
}
)
public void shouldNotProduceMatchingMethod() {
}
}

View File

@ -0,0 +1,35 @@
/**
* Copyright 2012-2014 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.selection.qualifier.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.mapstruct.Qualifier;
/**
*
* @author Sjaak Derksen
*/
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface EnglishToGerman {
}

View File

@ -0,0 +1,33 @@
/**
* Copyright 2012-2014 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.selection.qualifier.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @author Sjaak Derksen
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface NonQualifierAnnotated {
}

View File

@ -0,0 +1,35 @@
/**
* Copyright 2012-2014 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.selection.qualifier.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.mapstruct.Qualifier;
/**
*
* @author Sjaak Derksen
*/
@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface TitleTranslator {
}

View File

@ -0,0 +1,61 @@
/**
* Copyright 2012-2014 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.selection.qualifier.bean;
import java.util.List;
import java.util.Map;
/**
*
* @author Sjaak Derksen
*/
public abstract class AbstractEntry {
private String title;
private List<String> keyWords;
private Map<String, List<String>> facts;
public String getTitle() {
return title;
}
public void setTitle( String title ) {
this.title = title;
}
public List<String> getKeyWords() {
return keyWords;
}
public void setKeyWords( List<String> keyWords ) {
this.keyWords = keyWords;
}
public Map<String, List<String> > getFacts() {
return facts;
}
public void setFacts( Map<String, List<String> > facts ) {
this.facts = facts;
}
}

View File

@ -0,0 +1,27 @@
/**
* Copyright 2012-2014 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.selection.qualifier.bean;
/**
*
* @author Sjaak Derksen
*/
public class GermanRelease extends AbstractEntry {
}

View File

@ -0,0 +1,27 @@
/**
* Copyright 2012-2014 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.selection.qualifier.bean;
/**
*
* @author Sjaak Derksen
*/
public class OriginalRelease extends AbstractEntry {
}

View File

@ -0,0 +1,45 @@
/**
* Copyright 2012-2014 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.selection.qualifier.handwritten;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
/**
*
* @author Sjaak Derksen
*/
public class Facts {
private static final Map<String, String> EN_GER = ImmutableMap.<String, String>builder()
.put( "director", "Regisseur" )
.put( "cast", "Besetzung" )
.put( "cameo", "Kurzauftritt" )
.put( "soundtrack", "Filmmusik" )
.put( "plot keywords", "Handlungstichwörter" )
.build();
@EnglishToGerman
public String translateFactName( String fact ) {
String result = EN_GER.get( fact );
return result != null ? result : fact;
}
}

View File

@ -0,0 +1,57 @@
/**
* Copyright 2012-2014 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.selection.qualifier.handwritten;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
/**
*
* @author Sjaak Derksen
*/
public class PlotWords {
private static final Map<String, String> EN_GER = ImmutableMap.<String, String>builder()
.put( "boy", "Jungen" )
.put( "child psychologist", "Kinderpsychologe" )
.put( "I see dead people", "Ich sehe tote Menschen" )
.build();
@EnglishToGerman
public List<String> translate( List<String> keywords ) {
List<String> result = new ArrayList<String>();
for ( String keyword : keywords ) {
if ( EN_GER.containsKey( keyword ) ) {
result.add( EN_GER.get( keyword ) );
}
else {
result.add( keyword );
}
}
return result;
}
public List<String> methodNotToSelect( List<String> title ) {
throw new AssertionError( "method should not be called" );
}
}

View File

@ -0,0 +1,33 @@
/**
* Copyright 2012-2014 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.selection.qualifier.handwritten;
import org.mapstruct.ap.test.selection.qualifier.annotation.NonQualifierAnnotated;
/**
*
* @author Sjaak Derksen
*/
public class SomeOtherMapper {
@NonQualifierAnnotated
public String methodNotToSelect( String title ) {
throw new AssertionError( "method should not be called" );
}
}

View File

@ -0,0 +1,52 @@
/**
* Copyright 2012-2014 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.selection.qualifier.handwritten;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import org.mapstruct.ap.test.selection.qualifier.annotation.EnglishToGerman;
import org.mapstruct.ap.test.selection.qualifier.annotation.TitleTranslator;
//import org.mapstruct.ap.test.selection.qualifier.annotation.TitleTranslator;
/**
*
* @author Sjaak Derksen
*/
@TitleTranslator
public class Titles {
private static final Map<String, String> EN_GER = ImmutableMap.<String, String>builder()
.put( "Star Wars", "Krieg der Sterne" )
.put( "Sixth Sense, The", "Der sechste Sinn" )
.put( "Shawshank Redemption, The", "Die Verurteilten" )
.put( "Trainspotting", "Neue Helden" )
.put( "Never Say Never", "Sag niemals nie" )
.build();
@EnglishToGerman
public String translateTitle(String title) {
return EN_GER.get( title );
}
public String methodNotToSelect( String title ) {
throw new AssertionError( "method should not be called" );
}
}

View File

@ -0,0 +1,30 @@
/**
* Copyright 2012-2014 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.selection.qualifier.handwritten;
/**
*
* @author Sjaak Derksen
*/
public class YetAnotherMapper {
public String methodNotToSelect( String title ) {
throw new AssertionError( "method should not be called" );
}
}