mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#339 introduce centralized enum for messages
This commit is contained in:
parent
31d2151b7b
commit
d61ca26652
@ -43,6 +43,7 @@ import org.mapstruct.ap.option.ReportingPolicy;
|
|||||||
import org.mapstruct.ap.prism.BeanMappingPrism;
|
import org.mapstruct.ap.prism.BeanMappingPrism;
|
||||||
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
|
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.Executables;
|
import org.mapstruct.ap.util.Executables;
|
||||||
import org.mapstruct.ap.util.MapperConfig;
|
import org.mapstruct.ap.util.MapperConfig;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
@ -119,11 +120,10 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
if ( beanMapping != null && beanMapping.getResultType() != null ) {
|
if ( beanMapping != null && beanMapping.getResultType() != null ) {
|
||||||
resultType = ctx.getTypeFactory().getType( beanMapping.getResultType() );
|
resultType = ctx.getTypeFactory().getType( beanMapping.getResultType() );
|
||||||
if ( !resultType.isAssignableTo( method.getResultType() ) ) {
|
if ( !resultType.isAssignableTo( method.getResultType() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format( "%s not assignable to: %s.", resultType, method.getResultType() ),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
beanMappingPrism.mirror );
|
beanMappingPrism.mirror,
|
||||||
|
Message.beanmapping_notassignable, resultType, method.getResultType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,15 +154,12 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
// fetch the target property
|
// fetch the target property
|
||||||
ExecutableElement targetProperty = unprocessedTargetProperties.get( mapping.getTargetName() );
|
ExecutableElement targetProperty = unprocessedTargetProperties.get( mapping.getTargetName() );
|
||||||
if ( targetProperty == null ) {
|
if ( targetProperty == null ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Unknown property \"%s\" in return type.",
|
|
||||||
mapping.getTargetName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mapping.getMirror(),
|
mapping.getMirror(),
|
||||||
mapping.getSourceAnnotationValue()
|
mapping.getSourceAnnotationValue(),
|
||||||
|
Message.beanmapping_unknownpropertyinreturntype,
|
||||||
|
mapping.getTargetName()
|
||||||
);
|
);
|
||||||
errorOccurred = true;
|
errorOccurred = true;
|
||||||
}
|
}
|
||||||
@ -313,12 +310,10 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
if ( propertyMapping != null && newPropertyMapping != null ) {
|
if ( propertyMapping != null && newPropertyMapping != null ) {
|
||||||
// TODO improve error message
|
// TODO improve error message
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
"Several possible source properties for target property \""
|
Message.beanmapping_severalpossiblesources,
|
||||||
+ targetProperty.getKey()
|
targetProperty.getKey()
|
||||||
+ "\".",
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -394,10 +389,10 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
// Should never really happen
|
// Should never really happen
|
||||||
else {
|
else {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format( "Found several matching getters for property \"%s\"", sourcePropertyName ),
|
Message.beanmapping_severalpossibletargetaccessors,
|
||||||
method.getExecutable()
|
sourcePropertyName
|
||||||
);
|
);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -435,14 +430,14 @@ public class BeanMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) {
|
if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) {
|
||||||
|
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( unmappedTargetPolicy.getDiagnosticKind(),
|
||||||
unmappedTargetPolicy.getDiagnosticKind(),
|
method.getExecutable(),
|
||||||
|
Message.beanmapping_unmappedtargets,
|
||||||
MessageFormat.format(
|
MessageFormat.format(
|
||||||
"Unmapped target {0,choice,1#property|1<properties}: \"{1}\"",
|
"{0,choice,1#property|1<properties}: \"{1}\"",
|
||||||
unprocessedTargetProperties.size(),
|
unprocessedTargetProperties.size(),
|
||||||
Strings.join( unprocessedTargetProperties.keySet(), ", " )
|
Strings.join( unprocessedTargetProperties.keySet(), ", " )
|
||||||
),
|
)
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import org.mapstruct.ap.model.source.EnumMapping;
|
|||||||
import org.mapstruct.ap.model.source.Mapping;
|
import org.mapstruct.ap.model.source.Mapping;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.model.source.SourceMethod;
|
import org.mapstruct.ap.model.source.SourceMethod;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -84,15 +85,11 @@ public class EnumMappingMethod extends MappingMethod {
|
|||||||
for ( Mapping mapping : mappedConstants ) {
|
for ( Mapping mapping : mappedConstants ) {
|
||||||
targetConstants.add( mapping.getTargetName() );
|
targetConstants.add( mapping.getTargetName() );
|
||||||
}
|
}
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format(
|
Message.enummapping_multipletargets,
|
||||||
"One enum constant must not be mapped to more than one target constant, "
|
enumConstant,
|
||||||
+ "but constant %s is mapped to %s.",
|
Strings.join( targetConstants, ", " )
|
||||||
enumConstant,
|
|
||||||
Strings.join( targetConstants, ", " )
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,48 +108,40 @@ public class EnumMappingMethod extends MappingMethod {
|
|||||||
for ( Mapping mappedConstant : mappedConstants ) {
|
for ( Mapping mappedConstant : mappedConstants ) {
|
||||||
|
|
||||||
if ( mappedConstant.getSourceName() == null ) {
|
if ( mappedConstant.getSourceName() == null ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"A source constant must be specified for mappings of an enum mapping method.",
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mappedConstant.getMirror()
|
mappedConstant.getMirror(),
|
||||||
|
Message.enummapping_undefinedsource
|
||||||
);
|
);
|
||||||
foundIncorrectMapping = true;
|
foundIncorrectMapping = true;
|
||||||
}
|
}
|
||||||
else if ( !sourceEnumConstants.contains( mappedConstant.getSourceName() ) ) {
|
else if ( !sourceEnumConstants.contains( mappedConstant.getSourceName() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Constant %s doesn't exist in enum type %s.",
|
|
||||||
mappedConstant.getSourceName(),
|
|
||||||
method.getSourceParameters().iterator().next().getType()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mappedConstant.getMirror(),
|
mappedConstant.getMirror(),
|
||||||
mappedConstant.getSourceAnnotationValue()
|
mappedConstant.getSourceAnnotationValue(),
|
||||||
|
Message.enummapping_nonexistingconstant,
|
||||||
|
mappedConstant.getSourceName(),
|
||||||
|
method.getSourceParameters().iterator().next().getType()
|
||||||
);
|
);
|
||||||
foundIncorrectMapping = true;
|
foundIncorrectMapping = true;
|
||||||
}
|
}
|
||||||
if ( mappedConstant.getTargetName() == null ) {
|
if ( mappedConstant.getTargetName() == null ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"A target constant must be specified for mappings of an enum mapping method.",
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mappedConstant.getMirror()
|
mappedConstant.getMirror(),
|
||||||
|
Message.enummapping_undefinedtarget
|
||||||
);
|
);
|
||||||
foundIncorrectMapping = true;
|
foundIncorrectMapping = true;
|
||||||
}
|
}
|
||||||
else if ( !targetEnumConstants.contains( mappedConstant.getTargetName() ) ) {
|
else if ( !targetEnumConstants.contains( mappedConstant.getTargetName() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Constant %s doesn't exist in enum type %s.",
|
|
||||||
mappedConstant.getTargetName(),
|
|
||||||
method.getReturnType()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mappedConstant.getMirror(),
|
mappedConstant.getMirror(),
|
||||||
mappedConstant.getTargetAnnotationValue()
|
mappedConstant.getTargetAnnotationValue(),
|
||||||
|
Message.enummapping_nonexistingconstant,
|
||||||
|
mappedConstant.getTargetName(),
|
||||||
|
method.getReturnType()
|
||||||
);
|
);
|
||||||
foundIncorrectMapping = true;
|
foundIncorrectMapping = true;
|
||||||
}
|
}
|
||||||
@ -178,14 +167,10 @@ public class EnumMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !unmappedSourceEnumConstants.isEmpty() ) {
|
if ( !unmappedSourceEnumConstants.isEmpty() ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format(
|
Message.enummapping_unmappedtargets,
|
||||||
"The following constants from the source enum have no corresponding constant in the "
|
Strings.join( unmappedSourceEnumConstants, ", " )
|
||||||
+ "target enum and must be be mapped via @Mapping: %s",
|
|
||||||
Strings.join( unmappedSourceEnumConstants, ", " )
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ import org.mapstruct.ap.model.common.Parameter;
|
|||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.MapperConfig;
|
import org.mapstruct.ap.util.MapperConfig;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
@ -111,12 +112,8 @@ public class IterableMappingMethod extends MappingMethod {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( assignment == null ) {
|
if ( assignment == null ) {
|
||||||
String message = String.format(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, method.getExecutable(),
|
||||||
"Can't create implementation of method %s. Found no method nor built-in conversion for mapping "
|
Message.iterablemapping_mappingnotfound );
|
||||||
+ "source element type into target element type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, message, method.getExecutable() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// target accessor is setter, so decorate assignment as setter
|
// target accessor is setter, so decorate assignment as setter
|
||||||
|
@ -29,6 +29,7 @@ import org.mapstruct.ap.model.common.Parameter;
|
|||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.source.Method;
|
import org.mapstruct.ap.model.source.Method;
|
||||||
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
import org.mapstruct.ap.prism.NullValueMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.MapperConfig;
|
import org.mapstruct.ap.util.MapperConfig;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
@ -119,11 +120,8 @@ public class MapMappingMethod extends MappingMethod {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( keyAssignment == null ) {
|
if ( keyAssignment == null ) {
|
||||||
String message = String.format(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, method.getExecutable(),
|
||||||
"Can't create implementation of method %s. Found no method nor "
|
Message.mapmapping_key_mappingnotfound );
|
||||||
+ "built-in conversion for mapping source key type to target key type.", method
|
|
||||||
);
|
|
||||||
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, message, method.getExecutable() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// find mapping method or conversion for value
|
// find mapping method or conversion for value
|
||||||
@ -143,11 +141,8 @@ public class MapMappingMethod extends MappingMethod {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( valueAssignment == null ) {
|
if ( valueAssignment == null ) {
|
||||||
String message = String.format(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, method.getExecutable(),
|
||||||
"Can't create implementation of method %s. Found no method nor "
|
Message.mapmapping_value_mappingnotfound );
|
||||||
+ "built-in conversion for mapping source value type to target value type.", method
|
|
||||||
);
|
|
||||||
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR, message, method.getExecutable() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapNullToDefault
|
// mapNullToDefault
|
||||||
|
@ -22,7 +22,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
@ -112,7 +112,7 @@ public class MappingBuilderContext {
|
|||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
private final Elements elementUtils;
|
private final Elements elementUtils;
|
||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private final Messager messager;
|
private final FormattingMessager messager;
|
||||||
private final Options options;
|
private final Options options;
|
||||||
private final TypeElement mapperTypeElement;
|
private final TypeElement mapperTypeElement;
|
||||||
private final List<SourceMethod> sourceModel;
|
private final List<SourceMethod> sourceModel;
|
||||||
@ -123,7 +123,7 @@ public class MappingBuilderContext {
|
|||||||
public MappingBuilderContext(TypeFactory typeFactory,
|
public MappingBuilderContext(TypeFactory typeFactory,
|
||||||
Elements elementUtils,
|
Elements elementUtils,
|
||||||
Types typeUtils,
|
Types typeUtils,
|
||||||
Messager messager,
|
FormattingMessager messager,
|
||||||
Options options,
|
Options options,
|
||||||
MappingResolver mappingResolver,
|
MappingResolver mappingResolver,
|
||||||
TypeElement mapper,
|
TypeElement mapper,
|
||||||
@ -164,7 +164,7 @@ public class MappingBuilderContext {
|
|||||||
return typeUtils;
|
return typeUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Messager getMessager() {
|
public FormattingMessager getMessager() {
|
||||||
return messager;
|
return messager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ import org.mapstruct.ap.util.Strings;
|
|||||||
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.DIRECT;
|
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.DIRECT;
|
||||||
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED;
|
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED;
|
||||||
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED_MAPPED;
|
import static org.mapstruct.ap.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED_MAPPED;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the mapping between a source and target property, e.g. from {@code String Source#foo} to
|
* Represents the mapping between a source and target property, e.g. from {@code String Source#foo} to
|
||||||
@ -171,18 +172,14 @@ public class PropertyMapping extends ModelElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format(
|
Message.propertymapping_mappingnotfound,
|
||||||
"Can't map %s to \"%s %s\". "
|
sourceElement,
|
||||||
+ "Consider to declare/implement a mapping method: \"%s map(%s value)\".",
|
targetType,
|
||||||
sourceElement,
|
targetPropertyName,
|
||||||
targetType,
|
targetType,
|
||||||
targetPropertyName,
|
getSourceType() /* original source type */
|
||||||
targetType,
|
|
||||||
getSourceType() /* original source type */
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,16 +531,13 @@ public class PropertyMapping extends ModelElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format(
|
Message.constantmapping_mappingnotfound,
|
||||||
"Can't map \"%s %s\" to \"%s %s\".",
|
sourceType,
|
||||||
sourceType,
|
constantExpression,
|
||||||
constantExpression,
|
targetType,
|
||||||
targetType,
|
targetPropertyName
|
||||||
targetPropertyName
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,13 +18,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.model.common;
|
package org.mapstruct.ap.model.common;
|
||||||
|
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reflects the result of a date format validation
|
* Reflects the result of a date format validation
|
||||||
*/
|
*/
|
||||||
final class DateFormatValidationResult {
|
final class DateFormatValidationResult {
|
||||||
|
|
||||||
private final boolean isValid;
|
private final boolean isValid;
|
||||||
private final String validationInformation;
|
private final Message validationInfo;
|
||||||
|
private final Object[] validationInfoArgs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
@ -32,18 +37,19 @@ final class DateFormatValidationResult {
|
|||||||
* @param isValid determines of the validation was successful.
|
* @param isValid determines of the validation was successful.
|
||||||
* @param validationInformation a string representing the validation result
|
* @param validationInformation a string representing the validation result
|
||||||
*/
|
*/
|
||||||
DateFormatValidationResult(boolean isValid, String validationInformation) {
|
DateFormatValidationResult(boolean isValid, Message validationInformation, Object... infoArgs) {
|
||||||
|
|
||||||
this.isValid = isValid;
|
this.isValid = isValid;
|
||||||
this.validationInformation = validationInformation;
|
this.validationInfo = validationInformation;
|
||||||
|
this.validationInfoArgs = infoArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String validationInformation() {
|
public void printErrorMessage(FormattingMessager messager) {
|
||||||
return validationInformation;
|
messager.printMessage( Diagnostic.Kind.ERROR, validationInfo, validationInfoArgs );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import org.mapstruct.ap.util.JodaTimeConstants;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for {@link DateFormatValidator}. <p> Based on the types of source / target type a specific {@link
|
* Factory for {@link DateFormatValidator}. <p> Based on the types of source / target type a specific {@link
|
||||||
@ -73,9 +74,8 @@ final class DateFormatValidatorFactory {
|
|||||||
dateFormatValidator = new DateFormatValidator() {
|
dateFormatValidator = new DateFormatValidator() {
|
||||||
@Override
|
@Override
|
||||||
public DateFormatValidationResult validate(String dateFormat) {
|
public DateFormatValidationResult validate(String dateFormat) {
|
||||||
return new DateFormatValidationResult(
|
return new DateFormatValidationResult( true, Message.general_unsupporteddateformatcheck,
|
||||||
true, String.format(
|
sourceType, targetType );
|
||||||
"No dateFormat cheeck is supported for types %s, %s", sourceType, targetType ) );
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -179,14 +179,10 @@ final class DateFormatValidatorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static DateFormatValidationResult validDateFormat(String dateFormat) {
|
private static DateFormatValidationResult validDateFormat(String dateFormat) {
|
||||||
return new DateFormatValidationResult(
|
return new DateFormatValidationResult( true, Message.general_validdate, dateFormat );
|
||||||
true, String.format(
|
|
||||||
"given date format \"%s\" is valid.", dateFormat ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DateFormatValidationResult invalidDateFormat(String dateFormat, Throwable e) {
|
private static DateFormatValidationResult invalidDateFormat(String dateFormat, Throwable e) {
|
||||||
return new DateFormatValidationResult(
|
return new DateFormatValidationResult( false, Message.general_invaliddate, dateFormat, e.getMessage() );
|
||||||
false, String.format(
|
|
||||||
"given date format \"%s\" is invalid. Message: \"%s\"", dateFormat, e.getMessage() ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@ package org.mapstruct.ap.model.common;
|
|||||||
|
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.tools.Diagnostic;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the {@link ConversionContext} passed to conversion providers.
|
* Default implementation of the {@link ConversionContext} passed to conversion providers.
|
||||||
@ -30,14 +29,14 @@ import javax.tools.Diagnostic;
|
|||||||
*/
|
*/
|
||||||
public class DefaultConversionContext implements ConversionContext {
|
public class DefaultConversionContext implements ConversionContext {
|
||||||
|
|
||||||
private final Messager messager;
|
private final FormattingMessager messager;
|
||||||
private final Type sourceType;
|
private final Type sourceType;
|
||||||
private final Type targetType;
|
private final Type targetType;
|
||||||
private final String dateFormat;
|
private final String dateFormat;
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
|
|
||||||
public DefaultConversionContext(TypeFactory typeFactory, Messager messager, Type sourceType, Type targetType,
|
public DefaultConversionContext(TypeFactory typeFactory, FormattingMessager messager, Type sourceType,
|
||||||
String dateFormat) {
|
Type targetType, String dateFormat) {
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
this.messager = messager;
|
this.messager = messager;
|
||||||
this.sourceType = sourceType;
|
this.sourceType = sourceType;
|
||||||
@ -55,7 +54,7 @@ public class DefaultConversionContext implements ConversionContext {
|
|||||||
DateFormatValidationResult validationResult = dateFormatValidator.validate( dateFormat );
|
DateFormatValidationResult validationResult = dateFormatValidator.validate( dateFormat );
|
||||||
|
|
||||||
if ( !validationResult.isValid() ) {
|
if ( !validationResult.isValid() ) {
|
||||||
messager.printMessage( Diagnostic.Kind.ERROR, validationResult.validationInformation() );
|
validationResult.printErrorMessage( messager );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +74,7 @@ public class DefaultConversionContext implements ConversionContext {
|
|||||||
return typeFactory;
|
return typeFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Messager getMessager() {
|
protected FormattingMessager getMessager() {
|
||||||
return messager;
|
return messager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
package org.mapstruct.ap.model.source;
|
package org.mapstruct.ap.model.source;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
import org.mapstruct.ap.prism.BeanMappingPrism;
|
import org.mapstruct.ap.prism.BeanMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,19 +38,15 @@ public class BeanMapping {
|
|||||||
private final List<TypeMirror> qualifiers;
|
private final List<TypeMirror> qualifiers;
|
||||||
private final TypeMirror resultType;
|
private final TypeMirror resultType;
|
||||||
|
|
||||||
public static BeanMapping fromPrism( BeanMappingPrism beanMapping, ExecutableElement method, Messager messager ) {
|
public static BeanMapping fromPrism( BeanMappingPrism beanMapping, ExecutableElement method,
|
||||||
|
FormattingMessager messager ) {
|
||||||
if ( beanMapping == null ) {
|
if ( beanMapping == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() );
|
boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() );
|
||||||
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() ) {
|
if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR, method, Message.beanmapping_noelements );
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"'resultType' and 'qualifiedBy' are undefined in @BeanMapping, "
|
|
||||||
+ "define at least one of them.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BeanMapping(
|
return new BeanMapping(
|
||||||
@ -58,9 +55,7 @@ public class BeanMapping {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private BeanMapping(
|
private BeanMapping( List<TypeMirror> qualifiers, TypeMirror mirror) {
|
||||||
List<TypeMirror> qualifiers,
|
|
||||||
TypeMirror mirror) {
|
|
||||||
this.qualifiers = qualifiers;
|
this.qualifiers = qualifiers;
|
||||||
this.resultType = mirror;
|
this.resultType = mirror;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package org.mapstruct.ap.model.source;
|
package org.mapstruct.ap.model.source;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.AnnotationValue;
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
@ -28,6 +28,7 @@ import javax.lang.model.type.TypeMirror;
|
|||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.mapstruct.ap.prism.IterableMappingPrism;
|
import org.mapstruct.ap.prism.IterableMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an iterable mapping as configured via {@code @IterableMapping}.
|
* Represents an iterable mapping as configured via {@code @IterableMapping}.
|
||||||
@ -43,7 +44,7 @@ public class IterableMapping {
|
|||||||
private final AnnotationValue dateFormatAnnotationValue;
|
private final AnnotationValue dateFormatAnnotationValue;
|
||||||
|
|
||||||
public static IterableMapping fromPrism(IterableMappingPrism iterableMapping, ExecutableElement method,
|
public static IterableMapping fromPrism(IterableMappingPrism iterableMapping, ExecutableElement method,
|
||||||
Messager messager) {
|
FormattingMessager messager) {
|
||||||
if ( iterableMapping == null ) {
|
if ( iterableMapping == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -52,12 +53,7 @@ public class IterableMapping {
|
|||||||
if ( !elementTargetTypeIsDefined
|
if ( !elementTargetTypeIsDefined
|
||||||
&& iterableMapping.dateFormat().isEmpty()
|
&& iterableMapping.dateFormat().isEmpty()
|
||||||
&& iterableMapping.qualifiedBy().isEmpty() ) {
|
&& iterableMapping.qualifiedBy().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR, method, Message.iterablemapping_noelements );
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"'dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in @IterableMapping, "
|
|
||||||
+ "define at least one of them.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new IterableMapping(
|
return new IterableMapping(
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package org.mapstruct.ap.model.source;
|
package org.mapstruct.ap.model.source;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
@ -27,6 +27,7 @@ import javax.lang.model.type.TypeMirror;
|
|||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.mapstruct.ap.prism.MapMappingPrism;
|
import org.mapstruct.ap.prism.MapMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a map mapping as configured via {@code @MapMapping}.
|
* Represents a map mapping as configured via {@code @MapMapping}.
|
||||||
@ -43,7 +44,8 @@ public class MapMapping {
|
|||||||
private final TypeMirror keyQualifyingTargetType;
|
private final TypeMirror keyQualifyingTargetType;
|
||||||
private final TypeMirror valueQualifyingTargetType;
|
private final TypeMirror valueQualifyingTargetType;
|
||||||
|
|
||||||
public static MapMapping fromPrism(MapMappingPrism mapMapping, ExecutableElement method, Messager messager) {
|
public static MapMapping fromPrism(MapMappingPrism mapMapping, ExecutableElement method,
|
||||||
|
FormattingMessager messager) {
|
||||||
if ( mapMapping == null ) {
|
if ( mapMapping == null ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -56,12 +58,7 @@ public class MapMapping {
|
|||||||
&& mapMapping.valueQualifiedBy().isEmpty()
|
&& mapMapping.valueQualifiedBy().isEmpty()
|
||||||
&& !keyTargetTypeIsDefined
|
&& !keyTargetTypeIsDefined
|
||||||
&& !valueTargetTypeIsDefined ) {
|
&& !valueTargetTypeIsDefined ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR, method, Message.mapmapping_noelements );
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', 'valueQualfiedBy' and "
|
|
||||||
+ "'valueTargetType' are all undefined in @MapMapping, define at least one of them.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.AnnotationValue;
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.ElementKind;
|
import javax.lang.model.element.ElementKind;
|
||||||
@ -39,6 +39,7 @@ import org.mapstruct.ap.model.common.TypeFactory;
|
|||||||
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
|
import org.mapstruct.ap.prism.CollectionMappingStrategyPrism;
|
||||||
import org.mapstruct.ap.prism.MappingPrism;
|
import org.mapstruct.ap.prism.MappingPrism;
|
||||||
import org.mapstruct.ap.prism.MappingsPrism;
|
import org.mapstruct.ap.prism.MappingsPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a property mapping as configured via {@code @Mapping}.
|
* Represents a property mapping as configured via {@code @Mapping}.
|
||||||
@ -66,7 +67,7 @@ public class Mapping {
|
|||||||
|
|
||||||
public static Map<String, List<Mapping>> fromMappingsPrism(MappingsPrism mappingsAnnotation,
|
public static Map<String, List<Mapping>> fromMappingsPrism(MappingsPrism mappingsAnnotation,
|
||||||
ExecutableElement method,
|
ExecutableElement method,
|
||||||
Messager messager) {
|
FormattingMessager messager) {
|
||||||
Map<String, List<Mapping>> mappings = new HashMap<String, List<Mapping>>();
|
Map<String, List<Mapping>> mappings = new HashMap<String, List<Mapping>>();
|
||||||
|
|
||||||
for ( MappingPrism mappingPrism : mappingsAnnotation.value() ) {
|
for ( MappingPrism mappingPrism : mappingsAnnotation.value() ) {
|
||||||
@ -81,10 +82,10 @@ public class Mapping {
|
|||||||
mappingsOfProperty.add( mapping );
|
mappingsOfProperty.add( mapping );
|
||||||
|
|
||||||
if ( mappingsOfProperty.size() > 1 && !isEnumType( method.getReturnType() ) ) {
|
if ( mappingsOfProperty.size() > 1 && !isEnumType( method.getReturnType() ) ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR,
|
||||||
Kind.ERROR,
|
method,
|
||||||
"Target property \"" + mappingPrism.target() + "\" must not be mapped more than once.",
|
Message.propertymapping_duplicatetargets,
|
||||||
method
|
mappingPrism.target()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,40 +94,37 @@ public class Mapping {
|
|||||||
return mappings;
|
return mappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mapping fromMappingPrism(MappingPrism mappingPrism, ExecutableElement element, Messager messager) {
|
public static Mapping fromMappingPrism(MappingPrism mappingPrism, ExecutableElement element,
|
||||||
|
FormattingMessager messager) {
|
||||||
|
|
||||||
if ( mappingPrism.target().isEmpty() ) {
|
if ( mappingPrism.target().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"Target must not be empty in @Mapping",
|
|
||||||
element,
|
element,
|
||||||
mappingPrism.mirror,
|
mappingPrism.mirror,
|
||||||
mappingPrism.values.target()
|
mappingPrism.values.target(),
|
||||||
|
Message.propertymapping_emptytarget
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !mappingPrism.source().isEmpty() && !mappingPrism.constant().isEmpty() ) {
|
if ( !mappingPrism.source().isEmpty() && !mappingPrism.constant().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
element,
|
||||||
"Source and constant are both defined in @Mapping, either define a source or a constant",
|
Message.propertymapping_sourceandconstantbothdefined
|
||||||
element
|
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if ( !mappingPrism.source().isEmpty() && !mappingPrism.expression().isEmpty() ) {
|
else if ( !mappingPrism.source().isEmpty() && !mappingPrism.expression().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
element,
|
||||||
"Source and expression are both defined in @Mapping, either define a source or an expression",
|
Message.propertymapping_sourceandexpressionbothdefined
|
||||||
element
|
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if ( !mappingPrism.expression().isEmpty() && !mappingPrism.constant().isEmpty() ) {
|
else if ( !mappingPrism.expression().isEmpty() && !mappingPrism.constant().isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
element,
|
||||||
"Expression and constant are both defined in @Mapping, either define an expression or a constant",
|
Message.propertymapping_expressionandconstantbothdefined
|
||||||
element
|
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -173,7 +171,8 @@ public class Mapping {
|
|||||||
this.resultType = resultType;
|
this.resultType = resultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getExpression(MappingPrism mappingPrism, ExecutableElement element, Messager messager) {
|
private static String getExpression(MappingPrism mappingPrism, ExecutableElement element,
|
||||||
|
FormattingMessager messager) {
|
||||||
if ( mappingPrism.expression().isEmpty() ) {
|
if ( mappingPrism.expression().isEmpty() ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -181,12 +180,11 @@ public class Mapping {
|
|||||||
Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mappingPrism.expression() );
|
Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mappingPrism.expression() );
|
||||||
|
|
||||||
if ( !javaExpressionMatcher.matches() ) {
|
if ( !javaExpressionMatcher.matches() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"Value must be given in the form \"java(<EXPRESSION>)\"",
|
|
||||||
element,
|
element,
|
||||||
mappingPrism.mirror,
|
mappingPrism.mirror,
|
||||||
mappingPrism.values.expression()
|
mappingPrism.values.expression(),
|
||||||
|
Message.propertymapping_invalidexpression
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -199,7 +197,7 @@ public class Mapping {
|
|||||||
( (DeclaredType) mirror ).asElement().getKind() == ElementKind.ENUM;
|
( (DeclaredType) mirror ).asElement().getKind() == ElementKind.ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init(SourceMethod method, Messager messager, TypeFactory typeFactory) {
|
public void init(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory) {
|
||||||
|
|
||||||
if ( !method.isEnumMapping() ) {
|
if ( !method.isEnumMapping() ) {
|
||||||
sourceReference = new SourceReference.BuilderFromMapping()
|
sourceReference = new SourceReference.BuilderFromMapping()
|
||||||
@ -274,7 +272,7 @@ public class Mapping {
|
|||||||
return method.getResultType().getTargetAccessors( cms ).containsKey( name );
|
return method.getResultType().getTargetAccessors( cms ).containsKey( name );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mapping reverse(SourceMethod method, Messager messager, TypeFactory typeFactory) {
|
public Mapping reverse(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory) {
|
||||||
|
|
||||||
// mapping can only be reversed if the source was not a constant nor an expression nor a nested property
|
// mapping can only be reversed if the source was not a constant nor an expression nor a nested property
|
||||||
if ( constant != null || javaExpression != null ) {
|
if ( constant != null || javaExpression != null ) {
|
||||||
@ -297,10 +295,10 @@ public class Mapping {
|
|||||||
if ( sourceReference != null && sourceReference.getPropertyEntries().isEmpty() ) {
|
if ( sourceReference != null && sourceReference.getPropertyEntries().isEmpty() ) {
|
||||||
// parameter mapping only, apparently the @InheritReverseConfiguration is intentional
|
// parameter mapping only, apparently the @InheritReverseConfiguration is intentional
|
||||||
// but erroneous. Lets raise an error to warn.
|
// but erroneous. Lets raise an error to warn.
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format( "Parameter %s cannot be reversed", sourceReference.getParameter() ),
|
Message.propertymapping_reversalproblem,
|
||||||
method.getExecutable()
|
sourceReference.getParameter()
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
@ -50,7 +50,7 @@ public class SourceMethod implements Method {
|
|||||||
|
|
||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
private final Messager messager;
|
private final FormattingMessager messager;
|
||||||
|
|
||||||
private final Type declaringMapper;
|
private final Type declaringMapper;
|
||||||
private final ExecutableElement executable;
|
private final ExecutableElement executable;
|
||||||
@ -77,7 +77,7 @@ public class SourceMethod implements Method {
|
|||||||
private MapMapping mapMapping = null;
|
private MapMapping mapMapping = null;
|
||||||
private Types typeUtils;
|
private Types typeUtils;
|
||||||
private TypeFactory typeFactory = null;
|
private TypeFactory typeFactory = null;
|
||||||
private Messager messager = null;
|
private FormattingMessager messager = null;
|
||||||
private MapperConfig mapperConfig = null;
|
private MapperConfig mapperConfig = null;
|
||||||
|
|
||||||
public Builder() {
|
public Builder() {
|
||||||
@ -133,7 +133,7 @@ public class SourceMethod implements Method {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setMessager(Messager messager) {
|
public Builder setMessager(FormattingMessager messager) {
|
||||||
this.messager = messager;
|
this.messager = messager;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ public class SourceMethod implements Method {
|
|||||||
private SourceMethod( Type declaringMapper, ExecutableElement executable, List<Parameter> parameters,
|
private SourceMethod( Type declaringMapper, ExecutableElement executable, List<Parameter> parameters,
|
||||||
Type returnType, List<Type> exceptionTypes, Map<String, List<Mapping>> mappings,
|
Type returnType, List<Type> exceptionTypes, Map<String, List<Mapping>> mappings,
|
||||||
IterableMapping iterableMapping, MapMapping mapMapping, Types typeUtils,
|
IterableMapping iterableMapping, MapMapping mapMapping, Types typeUtils,
|
||||||
TypeFactory typeFactory, Messager messager, MapperConfig config) {
|
TypeFactory typeFactory, FormattingMessager messager, MapperConfig config) {
|
||||||
this.declaringMapper = declaringMapper;
|
this.declaringMapper = declaringMapper;
|
||||||
this.executable = executable;
|
this.executable = executable;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
|
@ -22,13 +22,14 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
import org.mapstruct.ap.model.common.Parameter;
|
import org.mapstruct.ap.model.common.Parameter;
|
||||||
import org.mapstruct.ap.model.common.Type;
|
import org.mapstruct.ap.model.common.Type;
|
||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.Executables;
|
import org.mapstruct.ap.util.Executables;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
@ -67,10 +68,10 @@ public class SourceReference {
|
|||||||
|
|
||||||
private Mapping mapping;
|
private Mapping mapping;
|
||||||
private SourceMethod method;
|
private SourceMethod method;
|
||||||
private Messager messager;
|
private FormattingMessager messager;
|
||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
|
|
||||||
public BuilderFromMapping messager(Messager messager) {
|
public BuilderFromMapping messager(FormattingMessager messager) {
|
||||||
this.messager = messager;
|
this.messager = messager;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -114,7 +115,7 @@ public class SourceReference {
|
|||||||
String sourceParameterName = segments[0];
|
String sourceParameterName = segments[0];
|
||||||
parameter = method.getSourceParameter( sourceParameterName );
|
parameter = method.getSourceParameter( sourceParameterName );
|
||||||
if ( parameter == null ) {
|
if ( parameter == null ) {
|
||||||
reportMappingError( "Method has no parameter named \"%s\".", sourceParameterName );
|
reportMappingError( Message.propertymapping_invalidparametername, sourceParameterName );
|
||||||
isValid = false;
|
isValid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,15 +155,13 @@ public class SourceReference {
|
|||||||
if ( !foundEntryMatch ) {
|
if ( !foundEntryMatch ) {
|
||||||
|
|
||||||
if ( parameter != null ) {
|
if ( parameter != null ) {
|
||||||
reportMappingError(
|
reportMappingError( Message.propertymapping_nopropertyinparameter,
|
||||||
"The type of parameter \"%s\" has no property named \"%s\".",
|
|
||||||
parameter.getName(),
|
parameter.getName(),
|
||||||
Strings.join( Arrays.asList( sourcePropertyNames ), "." )
|
Strings.join( Arrays.asList( sourcePropertyNames ), "." )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reportMappingError(
|
reportMappingError( Message.propertymapping_invalidpropertyname,
|
||||||
"No property named \"%s\" exists in source parameter(s).",
|
|
||||||
mapping.getSourceName()
|
mapping.getSourceName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -193,12 +192,14 @@ public class SourceReference {
|
|||||||
return sourceEntries;
|
return sourceEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportMappingError(String message, Object... objects) {
|
private void reportMappingError(Message msg, Object... objects) {
|
||||||
messager.printMessage(
|
messager.printMessage(
|
||||||
Diagnostic.Kind.ERROR,
|
Diagnostic.Kind.ERROR,
|
||||||
String.format( message, objects ),
|
method.getExecutable(),
|
||||||
method.getExecutable(), mapping.getMirror(),
|
mapping.getMirror(),
|
||||||
mapping.getSourceAnnotationValue()
|
mapping.getSourceAnnotationValue(),
|
||||||
|
msg,
|
||||||
|
objects
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.processor;
|
package org.mapstruct.ap.processor;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.annotation.processing.Filer;
|
import javax.annotation.processing.Filer;
|
||||||
import javax.annotation.processing.Messager;
|
import javax.annotation.processing.Messager;
|
||||||
import javax.annotation.processing.ProcessingEnvironment;
|
import javax.annotation.processing.ProcessingEnvironment;
|
||||||
@ -31,6 +32,7 @@ import javax.tools.Diagnostic.Kind;
|
|||||||
import org.mapstruct.ap.model.common.TypeFactory;
|
import org.mapstruct.ap.model.common.TypeFactory;
|
||||||
import org.mapstruct.ap.option.Options;
|
import org.mapstruct.ap.option.Options;
|
||||||
import org.mapstruct.ap.processor.ModelElementProcessor.ProcessorContext;
|
import org.mapstruct.ap.processor.ModelElementProcessor.ProcessorContext;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.version.VersionInformation;
|
import org.mapstruct.ap.version.VersionInformation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,7 +80,7 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Messager getMessager() {
|
public FormattingMessager getMessager() {
|
||||||
return messager;
|
return messager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +99,7 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
|
|||||||
return messager.isErroneous();
|
return messager.isErroneous();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DelegatingMessager implements Messager {
|
private static class DelegatingMessager implements FormattingMessager {
|
||||||
|
|
||||||
private final Messager delegate;
|
private final Messager delegate;
|
||||||
private boolean isErroneous = false;
|
private boolean isErroneous = false;
|
||||||
@ -107,32 +109,37 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Kind kind, CharSequence msg) {
|
public void printMessage( Kind kind, Message msg, Object... args) {
|
||||||
delegate.printMessage( kind, msg );
|
String message = String.format( msg.getDescription(), args );
|
||||||
|
delegate.printMessage( kind, message);
|
||||||
if ( kind == Kind.ERROR ) {
|
if ( kind == Kind.ERROR ) {
|
||||||
isErroneous = true;
|
isErroneous = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Kind kind, CharSequence msg, Element e) {
|
public void printMessage( Kind kind, Element e, Message msg, Object... args) {
|
||||||
delegate.printMessage( kind, msg, e );
|
String message = String.format( msg.getDescription(), args );
|
||||||
|
delegate.printMessage( kind, message, e );
|
||||||
if ( kind == Kind.ERROR ) {
|
if ( kind == Kind.ERROR ) {
|
||||||
isErroneous = true;
|
isErroneous = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a) {
|
public void printMessage( Kind kind, Element e, AnnotationMirror a, Message msg, Object... args) {
|
||||||
delegate.printMessage( kind, msg, e, a );
|
String message = String.format( msg.getDescription(), args );
|
||||||
|
delegate.printMessage( kind, message, e, a );
|
||||||
if ( kind == Kind.ERROR ) {
|
if ( kind == Kind.ERROR ) {
|
||||||
isErroneous = true;
|
isErroneous = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Kind kind, CharSequence msg, Element e, AnnotationMirror a, AnnotationValue v) {
|
public void printMessage( Kind kind, Element e, AnnotationMirror a, AnnotationValue v, Message msg,
|
||||||
delegate.printMessage( kind, msg, e, a, v );
|
Object... args) {
|
||||||
|
String message = String.format( msg.getDescription(), args );
|
||||||
|
delegate.printMessage( kind, message, e, a, v );
|
||||||
if ( kind == Kind.ERROR ) {
|
if ( kind == Kind.ERROR ) {
|
||||||
isErroneous = true;
|
isErroneous = true;
|
||||||
}
|
}
|
||||||
@ -141,5 +148,6 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
|
|||||||
public boolean isErroneous() {
|
public boolean isErroneous() {
|
||||||
return isErroneous;
|
return isErroneous;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import java.util.List;
|
|||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.type.TypeKind;
|
import javax.lang.model.type.TypeKind;
|
||||||
@ -55,6 +55,7 @@ import org.mapstruct.ap.prism.InheritConfigurationPrism;
|
|||||||
import org.mapstruct.ap.prism.InheritInverseConfigurationPrism;
|
import org.mapstruct.ap.prism.InheritInverseConfigurationPrism;
|
||||||
import org.mapstruct.ap.prism.MapperPrism;
|
import org.mapstruct.ap.prism.MapperPrism;
|
||||||
import org.mapstruct.ap.processor.creation.MappingResolverImpl;
|
import org.mapstruct.ap.processor.creation.MappingResolverImpl;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.MapperConfig;
|
import org.mapstruct.ap.util.MapperConfig;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
import org.mapstruct.ap.version.VersionInformation;
|
import org.mapstruct.ap.version.VersionInformation;
|
||||||
@ -69,7 +70,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
|
|
||||||
private Elements elementUtils;
|
private Elements elementUtils;
|
||||||
private Types typeUtils;
|
private Types typeUtils;
|
||||||
private Messager messager;
|
private FormattingMessager messager;
|
||||||
private Options options;
|
private Options options;
|
||||||
private VersionInformation versionInformation;
|
private VersionInformation versionInformation;
|
||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
@ -93,7 +94,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
messager,
|
messager,
|
||||||
options,
|
options,
|
||||||
new MappingResolverImpl(
|
new MappingResolverImpl(
|
||||||
context.getMessager(),
|
messager,
|
||||||
elementUtils,
|
elementUtils,
|
||||||
typeUtils,
|
typeUtils,
|
||||||
typeFactory,
|
typeFactory,
|
||||||
@ -165,12 +166,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
TypeElement decoratorElement = (TypeElement) typeUtils.asElement( decoratorPrism.value() );
|
TypeElement decoratorElement = (TypeElement) typeUtils.asElement( decoratorPrism.value() );
|
||||||
|
|
||||||
if ( !typeUtils.isAssignable( decoratorElement.asType(), element.asType() ) ) {
|
if ( !typeUtils.isAssignable( decoratorElement.asType(), element.asType() ) ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, element, decoratorPrism.mirror, Message.decorator_nosubtype);
|
||||||
Kind.ERROR,
|
|
||||||
String.format( "Specified decorator type is no subtype of the annotated mapper type." ),
|
|
||||||
element,
|
|
||||||
decoratorPrism.mirror
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>( methods.size() );
|
List<MappingMethod> mappingMethods = new ArrayList<MappingMethod>( methods.size() );
|
||||||
@ -208,15 +204,7 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( !hasDelegateConstructor && !hasDefaultConstructor ) {
|
if ( !hasDelegateConstructor && !hasDefaultConstructor ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, element, decoratorPrism.mirror, Message.decorator_constructor );
|
||||||
Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Specified decorator type has no default constructor nor a constructor with a single " +
|
|
||||||
"parameter accepting the decorated mapper type."
|
|
||||||
),
|
|
||||||
element,
|
|
||||||
decoratorPrism.mirror
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Decorator.getInstance(
|
return Decorator.getInstance(
|
||||||
@ -372,13 +360,10 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
if ( method.getReturnType().getTypeMirror().getKind() != TypeKind.VOID &&
|
if ( method.getReturnType().getTypeMirror().getKind() != TypeKind.VOID &&
|
||||||
method.getReturnType().isInterface() &&
|
method.getReturnType().isInterface() &&
|
||||||
method.getReturnType().getImplementationType() == null ) {
|
method.getReturnType().getImplementationType() == null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR,
|
||||||
Kind.ERROR,
|
method.getExecutable(),
|
||||||
String.format(
|
Message.general_noimplementation,
|
||||||
"No implementation type is registered for return type %s.",
|
method.getReturnType()
|
||||||
method.getReturnType()
|
|
||||||
),
|
|
||||||
method.getExecutable()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,11 +506,10 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
method.getExecutable()
|
method.getExecutable()
|
||||||
);
|
);
|
||||||
if ( reversePrism != null ) {
|
if ( reversePrism != null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
"Method cannot be annotated with both a @InheritConfiguration and @InheritInverseConfiguration",
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritconfiguration_both
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,15 +524,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( candidatePrism != null ) {
|
if ( candidatePrism != null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Resolved inverse mapping method %s() should not carry the "
|
|
||||||
+ "@InheritInverseConfiguration annotation itself.",
|
|
||||||
candidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_referencehasinverse,
|
||||||
|
candidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -556,14 +536,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
candidate.getExecutable()
|
candidate.getExecutable()
|
||||||
);
|
);
|
||||||
if ( candidateTemplatePrism != null ) {
|
if ( candidateTemplatePrism != null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Resolved inverse mapping method %s() should not carry the @InheritConfiguration annotation.",
|
|
||||||
candidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_referencehasforward,
|
||||||
|
candidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -578,25 +555,22 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
|
|
||||||
String name = reversePrism.name();
|
String name = reversePrism.name();
|
||||||
if ( name.isEmpty() ) {
|
if ( name.isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Several matching inverse methods exist: %s(). Specify a name explicitly.",
|
|
||||||
Strings.join( candidateNames, "(), " )
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_duplicates,
|
||||||
|
Strings.join( candidateNames, "(), " )
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"None of the candidates %s() matches given name: \"%s\".",
|
|
||||||
Strings.join( candidateNames, "(), " ), name
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_invalidname,
|
||||||
|
Strings.join( candidateNames, "(), " ),
|
||||||
|
name
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -604,28 +578,25 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
private void reportErrorWhenSeveralNamesMatch(List<SourceMethod> candidates, SourceMethod method,
|
private void reportErrorWhenSeveralNamesMatch(List<SourceMethod> candidates, SourceMethod method,
|
||||||
InheritInverseConfigurationPrism reversePrism) {
|
InheritInverseConfigurationPrism reversePrism) {
|
||||||
|
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Given name \"%s\" matches several candidate methods: %s().",
|
|
||||||
reversePrism.name(), Strings.join( candidates, "(), " )
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_duplicatematches,
|
||||||
|
reversePrism.name(),
|
||||||
|
Strings.join( candidates, "(), " )
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method,
|
private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method,
|
||||||
InheritInverseConfigurationPrism reversePrism) {
|
InheritInverseConfigurationPrism reversePrism) {
|
||||||
|
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Given name \"%s\" does not match the only candidate. Did you mean: \"%s\".",
|
|
||||||
reversePrism.name(), onlyCandidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
reversePrism.mirror
|
reversePrism.mirror,
|
||||||
|
Message.inheritinverseconfiguration_nonamematch,
|
||||||
|
reversePrism.name(),
|
||||||
|
onlyCandidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,14 +609,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( candidatePrism != null ) {
|
if ( candidatePrism != null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Resolved mapping method %s() should not carry the @InheritConfiguration annotation itself.",
|
|
||||||
candidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prism.mirror
|
prism.mirror,
|
||||||
|
Message.inheritconfiguration_referencehasforward,
|
||||||
|
candidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,14 +622,11 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
);
|
);
|
||||||
|
|
||||||
if ( candidateInversePrism != null ) {
|
if ( candidateInversePrism != null ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Resolved mapping method %s() should not carry the @InheritInverseConfiguration annotation.",
|
|
||||||
candidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prism.mirror
|
prism.mirror,
|
||||||
|
Message.inheritconfiguration_referencehasinverse,
|
||||||
|
candidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,25 +641,20 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
|
|
||||||
String name = prism.name();
|
String name = prism.name();
|
||||||
if ( name.isEmpty() ) {
|
if ( name.isEmpty() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Several matching methods exist: %s(). Specify a name explicitly.",
|
|
||||||
Strings.join( candidateNames, "(), " )
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prism.mirror
|
prism.mirror,
|
||||||
|
Message.inheritconfiguration_duplicates,
|
||||||
|
Strings.join( candidateNames, "(), " )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"None of the candidates %s() matches given name: \"%s\".",
|
|
||||||
Strings.join( candidateNames, "(), " ), name
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prism.mirror
|
prism.mirror,
|
||||||
|
Message.inheritconfiguration_invalidname,
|
||||||
|
Strings.join( candidateNames, "(), " ),
|
||||||
|
name
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -702,30 +662,24 @@ public class MapperCreationProcessor implements ModelElementProcessor<List<Sourc
|
|||||||
private void reportErrorWhenSeveralNamesMatch(List<SourceMethod> candidates, SourceMethod method,
|
private void reportErrorWhenSeveralNamesMatch(List<SourceMethod> candidates, SourceMethod method,
|
||||||
InheritConfigurationPrism prism) {
|
InheritConfigurationPrism prism) {
|
||||||
|
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Given name \"%s\" matches several candidate methods: %s().",
|
|
||||||
prism.name(), Strings.join( candidates, "(), " )
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prism.mirror
|
prism.mirror,
|
||||||
|
Message.inheritconfiguration_duplicatematches,
|
||||||
|
prism.name(),
|
||||||
|
Strings.join( candidates, "(), " )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method,
|
private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method,
|
||||||
InheritConfigurationPrism prims) {
|
InheritConfigurationPrism prims) {
|
||||||
|
|
||||||
messager.printMessage(
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
Diagnostic.Kind.ERROR,
|
|
||||||
String.format(
|
|
||||||
"Given name \"%s\" does not match the only candidate. Did you mean: \"%s\".",
|
|
||||||
prims.name(), onlyCandidate.getName()
|
|
||||||
),
|
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
prims.mirror
|
prims.mirror,
|
||||||
|
Message.inheritconfiguration_nonamematch,
|
||||||
|
prims.name(),
|
||||||
|
onlyCandidate.getName()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.ExecutableElement;
|
import javax.lang.model.element.ExecutableElement;
|
||||||
import javax.lang.model.element.Modifier;
|
import javax.lang.model.element.Modifier;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
@ -49,6 +49,7 @@ import org.mapstruct.ap.prism.MapMappingPrism;
|
|||||||
import org.mapstruct.ap.prism.MappingPrism;
|
import org.mapstruct.ap.prism.MappingPrism;
|
||||||
import org.mapstruct.ap.prism.MappingsPrism;
|
import org.mapstruct.ap.prism.MappingsPrism;
|
||||||
import org.mapstruct.ap.util.AnnotationProcessingException;
|
import org.mapstruct.ap.util.AnnotationProcessingException;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.MapperConfig;
|
import org.mapstruct.ap.util.MapperConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,7 +62,7 @@ import org.mapstruct.ap.util.MapperConfig;
|
|||||||
*/
|
*/
|
||||||
public class MethodRetrievalProcessor implements ModelElementProcessor<Void, List<SourceMethod>> {
|
public class MethodRetrievalProcessor implements ModelElementProcessor<Void, List<SourceMethod>> {
|
||||||
|
|
||||||
private Messager messager;
|
private FormattingMessager messager;
|
||||||
private TypeFactory typeFactory;
|
private TypeFactory typeFactory;
|
||||||
private Types typeUtils;
|
private Types typeUtils;
|
||||||
private Elements elementUtils;
|
private Elements elementUtils;
|
||||||
@ -271,88 +272,60 @@ public class MethodRetrievalProcessor implements ModelElementProcessor<Void, Lis
|
|||||||
Parameter targetParameter, Type resultType, Type returnType,
|
Parameter targetParameter, Type resultType, Type returnType,
|
||||||
boolean containsTargetTypeParameter) {
|
boolean containsTargetTypeParameter) {
|
||||||
if ( sourceParameters.isEmpty() ) {
|
if ( sourceParameters.isEmpty() ) {
|
||||||
messager.printMessage( Kind.ERROR, "Can't generate mapping method with no input arguments.", method );
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_noinputargs );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( targetParameter != null && ( sourceParameters.size() + 1 != method.getParameters().size() ) ) {
|
if ( targetParameter != null && ( sourceParameters.size() + 1 != method.getParameters().size() ) ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_duplicatemappingtargets );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method with more than one @MappingTarget parameter.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( resultType.getTypeMirror().getKind() == TypeKind.VOID ) {
|
if ( resultType.getTypeMirror().getKind() == TypeKind.VOID ) {
|
||||||
messager.printMessage( Kind.ERROR, "Can't generate mapping method with return type void.", method );
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_voidmappingmethod );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( returnType.getTypeMirror().getKind() != TypeKind.VOID &&
|
if ( returnType.getTypeMirror().getKind() != TypeKind.VOID &&
|
||||||
!resultType.isAssignableTo( returnType ) ) {
|
!resultType.isAssignableTo( returnType ) ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_nonassignableresulttype );
|
||||||
Kind.ERROR,
|
|
||||||
"The result type is not assignable to the the return type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type parameterType = sourceParameters.get( 0 ).getType();
|
Type parameterType = sourceParameters.get( 0 ).getType();
|
||||||
|
|
||||||
if ( parameterType.isIterableType() && !resultType.isIterableType() ) {
|
if ( parameterType.isIterableType() && !resultType.isIterableType() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_iterabletononiterable );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method from iterable type to non-iterable type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( containsTargetTypeParameter ) {
|
if ( containsTargetTypeParameter ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_mappinghastargettypeparameter );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method that has a parameter annotated with @TargetType.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !parameterType.isIterableType() && resultType.isIterableType() ) {
|
if ( !parameterType.isIterableType() && resultType.isIterableType() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_noniterabletoiterable );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method from non-iterable type to iterable type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parameterType.isPrimitive() ) {
|
if ( parameterType.isPrimitive() ) {
|
||||||
messager.printMessage( Kind.ERROR, "Can't generate mapping method with primitive parameter type.", method );
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_primitiveparameter );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( resultType.isPrimitive() ) {
|
if ( resultType.isPrimitive() ) {
|
||||||
messager.printMessage( Kind.ERROR, "Can't generate mapping method with primitive return type.", method );
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_primitivereturn );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parameterType.isEnumType() && !resultType.isEnumType() ) {
|
if ( parameterType.isEnumType() && !resultType.isEnumType() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_enumtononenum );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method from enum type to non-enum type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !parameterType.isEnumType() && resultType.isEnumType() ) {
|
if ( !parameterType.isEnumType() && resultType.isEnumType() ) {
|
||||||
messager.printMessage(
|
messager.printMessage( Kind.ERROR, method, Message.retrieval_nonenumtoenum );
|
||||||
Kind.ERROR,
|
|
||||||
"Can't generate mapping method from non-enum type to enum type.",
|
|
||||||
method
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package org.mapstruct.ap.processor;
|
package org.mapstruct.ap.processor;
|
||||||
|
|
||||||
import javax.annotation.processing.Filer;
|
import javax.annotation.processing.Filer;
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
@ -59,7 +59,7 @@ public interface ModelElementProcessor<P, R> {
|
|||||||
|
|
||||||
TypeFactory getTypeFactory();
|
TypeFactory getTypeFactory();
|
||||||
|
|
||||||
Messager getMessager();
|
FormattingMessager getMessager();
|
||||||
|
|
||||||
Options getOptions();
|
Options getOptions();
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.lang.model.util.Elements;
|
import javax.lang.model.util.Elements;
|
||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
@ -49,6 +49,7 @@ import org.mapstruct.ap.model.source.builtin.BuiltInMethod;
|
|||||||
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
import org.mapstruct.ap.model.source.selector.MethodSelectors;
|
||||||
import org.mapstruct.ap.model.source.selector.SelectionCriteria;
|
import org.mapstruct.ap.model.source.selector.SelectionCriteria;
|
||||||
import org.mapstruct.ap.prism.BeanMappingPrism;
|
import org.mapstruct.ap.prism.BeanMappingPrism;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
import org.mapstruct.ap.util.Strings;
|
import org.mapstruct.ap.util.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +61,7 @@ import org.mapstruct.ap.util.Strings;
|
|||||||
*/
|
*/
|
||||||
public class MappingResolverImpl implements MappingResolver {
|
public class MappingResolverImpl implements MappingResolver {
|
||||||
|
|
||||||
private final Messager messager;
|
private final FormattingMessager messager;
|
||||||
private final Types typeUtils;
|
private final Types typeUtils;
|
||||||
private final TypeFactory typeFactory;
|
private final TypeFactory typeFactory;
|
||||||
|
|
||||||
@ -77,8 +78,9 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
*/
|
*/
|
||||||
private final Set<VirtualMappingMethod> usedVirtualMappings = new HashSet<VirtualMappingMethod>();
|
private final Set<VirtualMappingMethod> usedVirtualMappings = new HashSet<VirtualMappingMethod>();
|
||||||
|
|
||||||
public MappingResolverImpl(Messager messager, Elements elementUtils, Types typeUtils, TypeFactory typeFactory,
|
public MappingResolverImpl(FormattingMessager messager, Elements elementUtils, Types typeUtils,
|
||||||
List<SourceMethod> sourceModel, List<MapperReference> mapperReferences) {
|
TypeFactory typeFactory, List<SourceMethod> sourceModel,
|
||||||
|
List<MapperReference> mapperReferences) {
|
||||||
this.messager = messager;
|
this.messager = messager;
|
||||||
this.typeUtils = typeUtils;
|
this.typeUtils = typeUtils;
|
||||||
this.typeFactory = typeFactory;
|
this.typeFactory = typeFactory;
|
||||||
@ -462,14 +464,23 @@ public class MappingResolverImpl implements MappingResolver {
|
|||||||
// into the target type
|
// into the target type
|
||||||
if ( candidates.size() > 1 ) {
|
if ( candidates.size() > 1 ) {
|
||||||
|
|
||||||
String errorMsg = String.format(
|
if ( mappedElement != null ) {
|
||||||
"Ambiguous mapping methods found for %s %s: %s.",
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
mappedElement != null ? "mapping " + mappedElement + " to" : "factorizing",
|
mappingMethod.getExecutable(),
|
||||||
returnType,
|
Message.general_ambigiousmappingmethod,
|
||||||
Strings.join( candidates, ", " )
|
mappedElement,
|
||||||
);
|
returnType,
|
||||||
|
Strings.join( candidates, ", " )
|
||||||
messager.printMessage( Diagnostic.Kind.ERROR, errorMsg, mappingMethod.getExecutable() );
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
messager.printMessage( Diagnostic.Kind.ERROR,
|
||||||
|
mappingMethod.getExecutable(),
|
||||||
|
Message.general_ambigiousfactorymethod,
|
||||||
|
returnType,
|
||||||
|
Strings.join( candidates, ", " )
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !candidates.isEmpty() ) {
|
if ( !candidates.isEmpty() ) {
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.util;
|
package org.mapstruct.ap.util;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.AnnotationValue;
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
@ -26,7 +25,7 @@ import javax.lang.model.element.Element;
|
|||||||
/**
|
/**
|
||||||
* Indicates an error during annotation processing. Should only be thrown in non-recoverable situations such as errors
|
* Indicates an error during annotation processing. Should only be thrown in non-recoverable situations such as errors
|
||||||
* due to incomplete compilations etc. Expected errors to be propagated to the user of the annotation processor should
|
* due to incomplete compilations etc. Expected errors to be propagated to the user of the annotation processor should
|
||||||
* be raised using the {@link Messager} API instead.
|
* be raised using the {@link FormattingMessager} API instead.
|
||||||
*
|
*
|
||||||
* @author Gunnar Morling
|
* @author Gunnar Morling
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.util;
|
||||||
|
|
||||||
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
|
import javax.lang.model.element.AnnotationValue;
|
||||||
|
import javax.lang.model.element.Element;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
|
||||||
|
public interface FormattingMessager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message of the specified kind.
|
||||||
|
*
|
||||||
|
* @param kind the kind of message
|
||||||
|
* @param msg the message
|
||||||
|
* @param args Arguments referenced by the format specifiers in the format string. If there are more arguments
|
||||||
|
* than format specifiers, the extra arguments are ignored
|
||||||
|
*/
|
||||||
|
void printMessage( Diagnostic.Kind kind, Message msg, Object... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message of the specified kind at the location of the
|
||||||
|
* element.
|
||||||
|
*
|
||||||
|
* @param kind the kind of message
|
||||||
|
* @param e the element to use as a position hint
|
||||||
|
* @param msg the message
|
||||||
|
* @param args Arguments referenced by the format specifiers in the format string. If there are more arguments
|
||||||
|
* than format specifiers, the extra arguments are ignored
|
||||||
|
*/
|
||||||
|
void printMessage( Diagnostic.Kind kind, Element e, Message msg, Object... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message of the specified kind at the location of the
|
||||||
|
* annotation mirror of the annotated element.
|
||||||
|
*
|
||||||
|
* @param kind the kind of message
|
||||||
|
* @param e the annotated element
|
||||||
|
* @param a the annotation to use as a position hint
|
||||||
|
* @param msg the message
|
||||||
|
* @param args Arguments referenced by the format specifiers in the format string. If there are more arguments
|
||||||
|
* than format specifiers, the extra arguments are ignored
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void printMessage( Diagnostic.Kind kind, Element e, AnnotationMirror a, Message msg, Object... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints a message of the specified kind at the location of the
|
||||||
|
* annotation value inside the annotation mirror of the annotated
|
||||||
|
* element.
|
||||||
|
*
|
||||||
|
* @param kind the kind of message
|
||||||
|
* @param e the annotated element
|
||||||
|
* @param a the annotation containing the annotation value
|
||||||
|
* @param v the annotation value to use as a position hint
|
||||||
|
* @param msg the message
|
||||||
|
* @param args Arguments referenced by the format specifiers in the format string. If there are more arguments
|
||||||
|
* than format specifiers, the extra arguments are ignored
|
||||||
|
*/
|
||||||
|
void printMessage( Diagnostic.Kind kind,
|
||||||
|
Element e,
|
||||||
|
AnnotationMirror a,
|
||||||
|
AnnotationValue v,
|
||||||
|
Message msg,
|
||||||
|
Object... args);
|
||||||
|
}
|
100
processor/src/main/java/org/mapstruct/ap/util/Message.java
Normal file
100
processor/src/main/java/org/mapstruct/ap/util/Message.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2012-2015 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.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sjaak Derksen
|
||||||
|
*/
|
||||||
|
public enum Message {
|
||||||
|
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
beanmapping_noelements( "'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ),
|
||||||
|
beanmapping_notassignable( "%s not assignable to: %s." ),
|
||||||
|
beanmapping_unknownpropertyinreturntype( "Unknown property \"%s\" in return type." ),
|
||||||
|
beanmapping_severalpossiblesources( "Several possible source properties for target property \"%s\"." ),
|
||||||
|
beanmapping_severalpossibletargetaccessors( "Found several matching getters for property \"%s\"" ),
|
||||||
|
beanmapping_unmappedtargets( "Unmapped target %s" ),
|
||||||
|
propertymapping_mappingnotfound( "Can't map %s to \"%s %s\". Consider to declare/implement a mapping method: \"%s map(%s value)\"." ),
|
||||||
|
propertymapping_duplicatetargets( "Target property \"%s\" must not be mapped more than once." ),
|
||||||
|
propertymapping_emptytarget( "Target must not be empty in @Mapping" ),
|
||||||
|
propertymapping_sourceandconstantbothdefined( "Source and constant are both defined in @Mapping, either define a source or a constant" ),
|
||||||
|
propertymapping_sourceandexpressionbothdefined( "Source and expression are both defined in @Mapping, either define a source or an expression" ),
|
||||||
|
propertymapping_expressionandconstantbothdefined( "Expression and constant are both defined in @Mapping, either define an expression or a constant" ),
|
||||||
|
propertymapping_invalidexpression( "Value must be given in the form \"java(<EXPRESSION>)\"" ),
|
||||||
|
propertymapping_reversalproblem( "Parameter %s cannot be reversed" ),
|
||||||
|
propertymapping_invalidparametername( "Method has no parameter named \"%s\"." ),
|
||||||
|
propertymapping_nopropertyinparameter( "The type of parameter \"%s\" has no property named \"%s\"." ),
|
||||||
|
propertymapping_invalidpropertyname( "No property named \"%s\" exists in source parameter(s)." ),
|
||||||
|
constantmapping_mappingnotfound( "Can't map \"%s %s\" to \"%s %s\"." ),
|
||||||
|
mapmapping_key_mappingnotfound( "Can't create implementation of method %s. Found no method nor built-in conversion for mapping source key type to target key type." ),
|
||||||
|
mapmapping_value_mappingnotfound( "Can't create implementation of method %s. Found no method nor built-in conversion for mapping source value type to target value type." ),
|
||||||
|
mapmapping_noelements( "'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, define at least one of them." ),
|
||||||
|
iterablemapping_mappingnotfound( "Can't create implementation of method %s. Found no method nor built-in conversion for mapping source element type into target element type." ),
|
||||||
|
iterablemapping_noelements( "'dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in @IterableMapping, define at least one of them." ),
|
||||||
|
enummapping_multipletargets( "One enum constant must not be mapped to more than one target constant, but constant %s is mapped to %s." ),
|
||||||
|
enummapping_undefinedsource( "A source constant must be specified for mappings of an enum mapping method." ),
|
||||||
|
enummapping_nonexistingconstant( "Constant %s doesn't exist in enum type %s." ),
|
||||||
|
enummapping_undefinedtarget( "A target constant must be specified for mappings of an enum mapping method." ),
|
||||||
|
enummapping_unmappedtargets( "The following constants from the source enum have no corresponding constant in the target enum and must be be mapped via @Mapping: %s" ),
|
||||||
|
decorator_nosubtype( "Specified decorator type is no subtype of the annotated mapper type." ),
|
||||||
|
decorator_constructor( "Specified decorator type has no default constructor nor a constructor with a single parameter accepting the decorated mapper type." ),
|
||||||
|
general_noimplementation( "No implementation type is registered for return type %s." ),
|
||||||
|
general_ambigiousmappingmethod( "Ambiguous mapping methods found for mapping %s to %s: %s." ),
|
||||||
|
general_ambigiousfactorymethod( "Ambiguous mapping methods found for factorizing %s: %s." ),
|
||||||
|
general_unsupporteddateformatcheck( "No dateFormat cheeck is supported for types %s, %s" ),
|
||||||
|
general_validdate( "given date format \"%s\" is valid." ),
|
||||||
|
general_invaliddate( "given date format \"%s\" is invalid. Message: \"%s\"" ),
|
||||||
|
retrieval_noinputargs( "Can't generate mapping method with no input arguments." ),
|
||||||
|
retrieval_duplicatemappingtargets( "Can't generate mapping method with more than one @MappingTarget parameter." ),
|
||||||
|
retrieval_voidmappingmethod( "Can't generate mapping method with return type void." ),
|
||||||
|
retrieval_nonassignableresulttype( "The result type is not assignable to the the return type." ),
|
||||||
|
retrieval_iterabletononiterable( "Can't generate mapping method from iterable type to non-iterable type." ),
|
||||||
|
retrieval_mappinghastargettypeparameter( "Can't generate mapping method that has a parameter annotated with @TargetType." ),
|
||||||
|
retrieval_noniterabletoiterable( "Can't generate mapping method from non-iterable type to iterable type." ),
|
||||||
|
retrieval_primitiveparameter( "Can't generate mapping method with primitive parameter type." ),
|
||||||
|
retrieval_primitivereturn( "Can't generate mapping method with primitive return type." ),
|
||||||
|
retrieval_enumtononenum( "Can't generate mapping method from enum type to non-enum type." ),
|
||||||
|
retrieval_nonenumtoenum( "Can't generate mapping method from non-enum type to enum type." ),
|
||||||
|
inheritconfiguration_both( "Method cannot be annotated with both a @InheritConfiguration and @InheritInverseConfiguration" ),
|
||||||
|
inheritinverseconfiguration_referencehasinverse( "Resolved inverse mapping method %s() should not carry the @InheritInverseConfiguration annotation itself." ),
|
||||||
|
inheritinverseconfiguration_referencehasforward( "Resolved inverse mapping method %s() should not carry the @InheritConfiguration annotation." ),
|
||||||
|
inheritinverseconfiguration_duplicates( "Several matching inverse methods exist: %s(). Specify a name explicitly." ),
|
||||||
|
inheritinverseconfiguration_invalidname( "None of the candidates %s() matches given name: \"%s\"." ),
|
||||||
|
inheritinverseconfiguration_duplicatematches( "Given name \"%s\" matches several candidate methods: %s()." ),
|
||||||
|
inheritinverseconfiguration_nonamematch( "Given name \"%s\" does not match the only candidate. Did you mean: \"%s\"." ),
|
||||||
|
inheritconfiguration_referencehasforward( "Resolved mapping method %s() should not carry the @InheritConfiguration annotation itself." ),
|
||||||
|
inheritconfiguration_referencehasinverse( "Resolved mapping method %s() should not carry the @InheritInverseConfiguration annotation." ),
|
||||||
|
inheritconfiguration_duplicates( "Several matching methods exist: %s(). Specify a name explicitly." ),
|
||||||
|
inheritconfiguration_invalidname( "None of the candidates %s() matches given name: \"%s\"." ),
|
||||||
|
inheritconfiguration_duplicatematches( "Given name \"%s\" matches several candidate methods: %s()." ),
|
||||||
|
inheritconfiguration_nonamematch( "Given name \"%s\" does not match the only candidate. Did you mean: \"%s\"." );
|
||||||
|
// CHECKSTYLE:ON
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
private Message(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,7 +22,6 @@ import org.junit.Test;
|
|||||||
import org.mapstruct.ap.testutil.IssueKey;
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
import org.mapstruct.ap.util.JavaTimeConstants;
|
import org.mapstruct.ap.util.JavaTimeConstants;
|
||||||
|
|
||||||
import javax.annotation.processing.Messager;
|
|
||||||
import javax.lang.model.element.AnnotationMirror;
|
import javax.lang.model.element.AnnotationMirror;
|
||||||
import javax.lang.model.element.AnnotationValue;
|
import javax.lang.model.element.AnnotationValue;
|
||||||
import javax.lang.model.element.Element;
|
import javax.lang.model.element.Element;
|
||||||
@ -34,6 +33,8 @@ import java.lang.annotation.Annotation;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.fest.assertions.Assertions.assertThat;
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
import org.mapstruct.ap.util.Message;
|
||||||
|
import org.mapstruct.ap.util.FormattingMessager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing DefaultConversionContext for dateFormat
|
* Testing DefaultConversionContext for dateFormat
|
||||||
@ -119,26 +120,26 @@ public class DefaultConversionContextTest {
|
|||||||
false );
|
false );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class StatefulMessagerMock implements Messager {
|
private static class StatefulMessagerMock implements FormattingMessager {
|
||||||
|
|
||||||
private Diagnostic.Kind lastKindPrinted;
|
private Diagnostic.Kind lastKindPrinted;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Diagnostic.Kind kind, CharSequence msg) {
|
public void printMessage( Diagnostic.Kind kind, Message msg, Object... arg) {
|
||||||
lastKindPrinted = kind;
|
lastKindPrinted = kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e) {
|
public void printMessage( Diagnostic.Kind kind, Element e, Message msg, Object... arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a) {
|
public void printMessage( Diagnostic.Kind kind, Element e, AnnotationMirror a, Message msg, Object... arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void printMessage(Diagnostic.Kind kind, CharSequence msg, Element e, AnnotationMirror a,
|
public void printMessage( Diagnostic.Kind kind, Element e, AnnotationMirror a, AnnotationValue v,
|
||||||
AnnotationValue v) {
|
Message msg, Object... arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Diagnostic.Kind getLastKindPrinted() {
|
public Diagnostic.Kind getLastKindPrinted() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user