mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#600 added defaultValue feature
This commit is contained in:
parent
b0b2f51331
commit
964f676af6
@ -154,4 +154,16 @@ public @interface Mapping {
|
||||
* @return the dependencies of the mapped property
|
||||
*/
|
||||
String[] dependsOn() default { };
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In case the source property is null the provided default {@link String} value is set.
|
||||
* If the designated target
|
||||
* property is not of type {@code String}, the value will be converted by applying a matching conversion method or
|
||||
* built-in conversion.
|
||||
* </p>
|
||||
* Either this attribute or {@link #constant()} or {@link #expression()} may be specified for a given mapping.
|
||||
* @return Default value to set in case the source property is null.
|
||||
*/
|
||||
String defaultValue() default "";
|
||||
}
|
||||
|
@ -151,4 +151,16 @@ public @interface Mapping {
|
||||
* @return the dependencies of the mapped property
|
||||
*/
|
||||
String[] dependsOn() default { };
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* In case the source property is null the provided default {@link String} value is set.
|
||||
* If the designated target
|
||||
* property is not of type {@code String}, the value will be converted by applying a matching conversion method or
|
||||
* built-in conversion.
|
||||
* </p>
|
||||
* Either this attribute or {@link #constant()} or {@link #expression()} may be specified for a given mapping.
|
||||
* @return Default value to set in case the source property is null.
|
||||
*/
|
||||
String defaultValue() default "";
|
||||
}
|
||||
|
@ -302,6 +302,7 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
.dateFormat( mapping.getDateFormat() )
|
||||
.existingVariableNames( existingVariableNames )
|
||||
.dependsOn( mapping.getDependsOn() )
|
||||
.defaultValue( mapping.getDefaultValue() )
|
||||
.build();
|
||||
handledTargets.add( mapping.getTargetName() );
|
||||
unprocessedSourceParameters.remove( sourceRef.getParameter() );
|
||||
@ -424,6 +425,7 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
.qualifiers( mapping != null ? mapping.getQualifiers() : null )
|
||||
.resultType( mapping != null ? mapping.getResultType() : null )
|
||||
.dateFormat( mapping != null ? mapping.getDateFormat() : null )
|
||||
.defaultValue( mapping != null ? mapping.getDefaultValue() : null )
|
||||
.existingVariableNames( existingVariableNames )
|
||||
.dependsOn( mapping != null ? mapping.getDependsOn() : Collections.<String>emptyList() )
|
||||
.build();
|
||||
|
@ -18,20 +18,6 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.model;
|
||||
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.DIRECT;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.MAPPED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.MAPPED_TYPE_CONVERTED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED_MAPPED;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import org.mapstruct.ap.internal.model.assignment.AdderWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.Assignment;
|
||||
@ -53,6 +39,19 @@ import org.mapstruct.ap.internal.util.Executables;
|
||||
import org.mapstruct.ap.internal.util.Message;
|
||||
import org.mapstruct.ap.internal.util.Strings;
|
||||
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.DIRECT;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.MAPPED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.MAPPED_TYPE_CONVERTED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED;
|
||||
import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentType.TYPE_CONVERTED_MAPPED;
|
||||
|
||||
/**
|
||||
* Represents the mapping between a source and target property, e.g. from {@code String Source#foo} to
|
||||
* {@code int Target#bar}. Name and type of source and target property can differ. If they have different types, the
|
||||
@ -69,6 +68,8 @@ public class PropertyMapping extends ModelElement {
|
||||
private final Type targetType;
|
||||
private final Assignment assignment;
|
||||
private final List<String> dependsOn;
|
||||
private String defaultValue;
|
||||
private Assignment defaultValueAssignment;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static class MappingBuilderBase<T extends MappingBuilderBase<T>> {
|
||||
@ -121,6 +122,7 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
// initial properties
|
||||
private String dateFormat;
|
||||
private String defaultValue;
|
||||
private List<TypeMirror> qualifiers;
|
||||
private TypeMirror resultType;
|
||||
private SourceReference sourceReference;
|
||||
@ -145,6 +147,11 @@ public class PropertyMapping extends ModelElement {
|
||||
return this;
|
||||
}
|
||||
|
||||
public PropertyMappingBuilder defaultValue(String defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
private enum TargetWriteAccessorType {
|
||||
GETTER,
|
||||
SETTER,
|
||||
@ -237,10 +244,31 @@ public class PropertyMapping extends ModelElement {
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
dependsOn,
|
||||
getDefaultValueAssignment()
|
||||
);
|
||||
}
|
||||
|
||||
private Assignment getDefaultValueAssignment() {
|
||||
if ( defaultValue != null && !getSourceType().isPrimitive() ) {
|
||||
PropertyMapping build = new ConstantMappingBuilder()
|
||||
.constantExpression( '"' + defaultValue + '"' )
|
||||
.dateFormat( dateFormat )
|
||||
.qualifiers( qualifiers )
|
||||
.resultType( resultType )
|
||||
.dependsOn( dependsOn )
|
||||
.existingVariableNames( existingVariableNames )
|
||||
.mappingContext( ctx )
|
||||
.sourceMethod( method )
|
||||
.targetPropertyName( targetPropertyName )
|
||||
.targetReadAccessor( targetReadAccessor )
|
||||
.targetWriteAccessor( targetWriteAccessor )
|
||||
.build();
|
||||
return build.getAssignment();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Assignment assignObject(Type sourceType, Type targetType, TargetWriteAccessorType targetAccessorType,
|
||||
Assignment rhs) {
|
||||
|
||||
@ -657,7 +685,8 @@ public class PropertyMapping extends ModelElement {
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
dependsOn,
|
||||
null
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -702,7 +731,8 @@ public class PropertyMapping extends ModelElement {
|
||||
targetReadAccessor != null ? targetReadAccessor.getSimpleName().toString() : null,
|
||||
targetType,
|
||||
assignment,
|
||||
dependsOn
|
||||
dependsOn,
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@ -710,13 +740,14 @@ public class PropertyMapping extends ModelElement {
|
||||
|
||||
// Constructor for creating mappings of constant expressions.
|
||||
private PropertyMapping(String name, String targetWriteAccessorName, String targetReadAccessorName, Type targetType,
|
||||
Assignment propertyAssignment, List<String> dependsOn) {
|
||||
this( name, null, targetWriteAccessorName, targetReadAccessorName, targetType, propertyAssignment, dependsOn );
|
||||
Assignment propertyAssignment, List<String> dependsOn, Assignment defaultValueAssignment ) {
|
||||
this( name, null, targetWriteAccessorName, targetReadAccessorName,
|
||||
targetType, propertyAssignment, dependsOn, defaultValueAssignment );
|
||||
}
|
||||
|
||||
private PropertyMapping(String name, String sourceBeanName, String targetWriteAccessorName,
|
||||
String targetReadAccessorName, Type targetType, Assignment assignment,
|
||||
List<String> dependsOn) {
|
||||
List<String> dependsOn, Assignment defaultValueAssignment ) {
|
||||
this.name = name;
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
this.targetWriteAccessorName = targetWriteAccessorName;
|
||||
@ -724,6 +755,7 @@ public class PropertyMapping extends ModelElement {
|
||||
this.targetType = targetType;
|
||||
this.assignment = assignment;
|
||||
this.dependsOn = dependsOn != null ? dependsOn : Collections.<String>emptyList();
|
||||
this.defaultValueAssignment = defaultValueAssignment;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -753,6 +785,10 @@ public class PropertyMapping extends ModelElement {
|
||||
return assignment;
|
||||
}
|
||||
|
||||
public Assignment getDefaultValueAssignment() {
|
||||
return defaultValueAssignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Type> getImportTypes() {
|
||||
return assignment.getImportTypes();
|
||||
@ -762,6 +798,10 @@ public class PropertyMapping extends ModelElement {
|
||||
return dependsOn;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PropertyMapping {"
|
||||
@ -770,6 +810,7 @@ public class PropertyMapping extends ModelElement {
|
||||
+ "\n targetReadAccessorName='" + targetReadAccessorName + "\',"
|
||||
+ "\n targetType=" + targetType + ","
|
||||
+ "\n propertyAssignment=" + assignment + ","
|
||||
+ "\n defaultValueAssignment=" + defaultValueAssignment + ","
|
||||
+ "\n dependsOn=" + dependsOn
|
||||
+ "\n}";
|
||||
}
|
||||
|
@ -18,13 +18,12 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.model.source;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
||||
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingsPrism;
|
||||
import org.mapstruct.ap.internal.util.FormattingMessager;
|
||||
import org.mapstruct.ap.internal.util.Message;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
@ -33,13 +32,13 @@ import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import org.mapstruct.ap.internal.model.common.TypeFactory;
|
||||
import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingsPrism;
|
||||
import org.mapstruct.ap.internal.util.FormattingMessager;
|
||||
import org.mapstruct.ap.internal.util.Message;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represents a property mapping as configured via {@code @Mapping}.
|
||||
@ -55,6 +54,7 @@ public class Mapping {
|
||||
private final String javaExpression;
|
||||
private final String targetName;
|
||||
private final String dateFormat;
|
||||
private final String defaultValue;
|
||||
private final List<TypeMirror> qualifiers;
|
||||
private final TypeMirror resultType;
|
||||
private final boolean isIgnored;
|
||||
@ -95,6 +95,7 @@ public class Mapping {
|
||||
public static Mapping fromMappingPrism(MappingPrism mappingPrism, ExecutableElement element,
|
||||
FormattingMessager messager) {
|
||||
|
||||
|
||||
if ( mappingPrism.target().isEmpty() ) {
|
||||
messager.printMessage(
|
||||
element,
|
||||
@ -117,11 +118,20 @@ public class Mapping {
|
||||
messager.printMessage( element, Message.PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED );
|
||||
return null;
|
||||
}
|
||||
else if ( !mappingPrism.expression().isEmpty() && !mappingPrism.defaultValue().isEmpty() ) {
|
||||
messager.printMessage( element, Message.PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED );
|
||||
return null;
|
||||
}
|
||||
else if ( !mappingPrism.constant().isEmpty() && !mappingPrism.defaultValue().isEmpty() ) {
|
||||
messager.printMessage( element, Message.PROPERTYMAPPING_CONSTANT_AND_DEFAULT_VALUE_BOTH_DEFINED );
|
||||
return null;
|
||||
}
|
||||
|
||||
String source = mappingPrism.source().isEmpty() ? null : mappingPrism.source();
|
||||
String constant = mappingPrism.constant().isEmpty() ? null : mappingPrism.constant();
|
||||
String expression = getExpression( mappingPrism, element, messager );
|
||||
String dateFormat = mappingPrism.dateFormat().isEmpty() ? null : mappingPrism.dateFormat();
|
||||
String defaultValue = mappingPrism.defaultValue().isEmpty() ? null : mappingPrism.defaultValue();
|
||||
|
||||
boolean resultTypeIsDefined = !TypeKind.VOID.equals( mappingPrism.resultType().getKind() );
|
||||
TypeMirror resultType = resultTypeIsDefined ? mappingPrism.resultType() : null;
|
||||
@ -134,6 +144,7 @@ public class Mapping {
|
||||
expression,
|
||||
mappingPrism.target(),
|
||||
dateFormat,
|
||||
defaultValue,
|
||||
mappingPrism.qualifiedBy(),
|
||||
mappingPrism.ignore(),
|
||||
mappingPrism.mirror,
|
||||
@ -147,7 +158,7 @@ public class Mapping {
|
||||
|
||||
@SuppressWarnings("checkstyle:parameternumber")
|
||||
private Mapping(String sourceName, String constant, String javaExpression, String targetName,
|
||||
String dateFormat, List<TypeMirror> qualifiers,
|
||||
String dateFormat, String defaultValue, List<TypeMirror> qualifiers,
|
||||
boolean isIgnored, AnnotationMirror mirror,
|
||||
AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue,
|
||||
AnnotationValue dependsOnAnnotationValue,
|
||||
@ -157,6 +168,7 @@ public class Mapping {
|
||||
this.javaExpression = javaExpression;
|
||||
this.targetName = targetName;
|
||||
this.dateFormat = dateFormat;
|
||||
this.defaultValue = defaultValue;
|
||||
this.qualifiers = qualifiers;
|
||||
this.isIgnored = isIgnored;
|
||||
this.mirror = mirror;
|
||||
@ -229,6 +241,10 @@ public class Mapping {
|
||||
return dateFormat;
|
||||
}
|
||||
|
||||
public String getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public List<TypeMirror> getQualifiers() {
|
||||
return qualifiers;
|
||||
}
|
||||
@ -306,6 +322,7 @@ public class Mapping {
|
||||
null, // expression
|
||||
sourceName != null ? sourceName : targetName,
|
||||
dateFormat,
|
||||
null,
|
||||
qualifiers,
|
||||
isIgnored,
|
||||
mirror,
|
||||
@ -333,6 +350,7 @@ public class Mapping {
|
||||
javaExpression,
|
||||
targetName,
|
||||
dateFormat,
|
||||
defaultValue,
|
||||
qualifiers,
|
||||
isIgnored,
|
||||
mirror,
|
||||
|
@ -44,6 +44,8 @@ public enum Message {
|
||||
PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED( "Source and constant are both defined in @Mapping, either define a source or a constant." ),
|
||||
PROPERTYMAPPING_SOURCE_AND_EXPRESSION_BOTH_DEFINED( "Source and expression are both defined in @Mapping, either define a source or an expression." ),
|
||||
PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED( "Expression and constant are both defined in @Mapping, either define an expression or a constant." ),
|
||||
PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED( "Expression and default value are both defined in @Mapping, either define a defaultValue or an expression." ),
|
||||
PROPERTYMAPPING_CONSTANT_AND_DEFAULT_VALUE_BOTH_DEFINED( "Constant and default value are both defined in @Mapping, either define a defaultValue or a constant." ),
|
||||
PROPERTYMAPPING_INVALID_EXPRESSION( "Value must be given in the form \"java(<EXPRESSION>)\"." ),
|
||||
PROPERTYMAPPING_REVERSAL_PROBLEM( "Parameter %s cannot be reversed." ),
|
||||
PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no parameter named \"%s\"." ),
|
||||
|
@ -47,7 +47,7 @@
|
||||
<#if (propertyMappingsByParameter[sourceParam.name]?size > 0)>
|
||||
if ( ${sourceParam.name} != null ) {
|
||||
<#list propertyMappingsByParameter[sourceParam.name] as propertyMapping>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping/>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
|
||||
</#list>
|
||||
}
|
||||
</#if>
|
||||
@ -55,14 +55,14 @@
|
||||
<#list sourcePrimitiveParameters as sourceParam>
|
||||
<#if (propertyMappingsByParameter[sourceParam.name]?size > 0)>
|
||||
<#list propertyMappingsByParameter[sourceParam.name] as propertyMapping>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping/>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
|
||||
</#list>
|
||||
</#if>
|
||||
</#list>
|
||||
<#else>
|
||||
<#if mapNullToDefault>if ( ${sourceParameters[0].name} != null ) {</#if>
|
||||
<#list propertyMappingsByParameter[sourceParameters[0].name] as propertyMapping>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping/>
|
||||
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
|
||||
</#list>
|
||||
<#if mapNullToDefault>}</#if>
|
||||
</#if>
|
||||
|
@ -23,4 +23,5 @@
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=targetReadAccessorName
|
||||
targetWriteAccessorName=targetWriteAccessorName
|
||||
targetType=targetType/>
|
||||
targetType=targetType
|
||||
defaultValueAssignment=defaultValueAssignment />
|
||||
|
@ -20,9 +20,20 @@
|
||||
-->
|
||||
if ( ${sourceReference} != null ) {
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType
|
||||
defaultValue=ext.defaultValueAssignment/>
|
||||
}
|
||||
<#if ext.defaultValueAssignment?? >
|
||||
else {
|
||||
<@includeModel object=ext.defaultValueAssignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
}
|
||||
</#if>
|
@ -19,10 +19,10 @@
|
||||
|
||||
-->
|
||||
<#if (thrownTypes?size == 0) >
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_assignment/> );
|
||||
<@assignment_w_defaultValue/>
|
||||
<#else>
|
||||
try {
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_assignment/> );
|
||||
<@assignment_w_defaultValue/>
|
||||
}
|
||||
<#list thrownTypes as exceptionType>
|
||||
catch ( <@includeModel object=exceptionType/> e ) {
|
||||
@ -30,11 +30,31 @@
|
||||
}
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType
|
||||
defaultValueAssignment=ext.defaultValueAssignment/>
|
||||
</#macro>
|
||||
|
||||
<#macro _defaultValueAssignment>
|
||||
<@includeModel object=ext.defaultValueAssignment.assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
||||
|
||||
<#macro assignment_w_defaultValue>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_assignment/> );
|
||||
<#-- if the assignee property is a primitive, defaulValueAssignment will not be set -->
|
||||
<#if ext.defaultValueAssignment?? >
|
||||
if ( ${sourceReference} == null ) {
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}( <@_defaultValueAssignment/> );
|
||||
}
|
||||
</#if>
|
||||
</#macro>
|
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
public class CountryDts {
|
||||
private String code;
|
||||
private int id;
|
||||
private long zipcode;
|
||||
private String region;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getZipcode() {
|
||||
return zipcode;
|
||||
}
|
||||
|
||||
public void setZipcode(long zipcode) {
|
||||
this.zipcode = zipcode;
|
||||
}
|
||||
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(String region) {
|
||||
this.region = region;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
public class CountryEntity {
|
||||
private String code;
|
||||
private Integer id;
|
||||
private long zipcode;
|
||||
private Region region;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public long getZipcode() {
|
||||
return zipcode;
|
||||
}
|
||||
|
||||
public void setZipcode(long zipcode) {
|
||||
this.zipcode = zipcode;
|
||||
}
|
||||
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(Region region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public abstract class CountryMapper {
|
||||
public static final CountryMapper INSTANCE = Mappers.getMapper( CountryMapper.class );
|
||||
|
||||
@Mappings( {
|
||||
@Mapping( target = "code", defaultValue = "DE" ),
|
||||
@Mapping( target = "id", defaultValue = "42" ),
|
||||
@Mapping( target = "zipcode", defaultValue = "1337" ),
|
||||
@Mapping( target = "region", defaultValue = "someRegion" ),
|
||||
} )
|
||||
public abstract CountryDts mapToCountryDts(CountryEntity country);
|
||||
|
||||
@Mappings( {
|
||||
@Mapping( target = "code", defaultValue = "DE" ),
|
||||
@Mapping( target = "id", defaultValue = "42" ),
|
||||
@Mapping( target = "zipcode", defaultValue = "1337" ),
|
||||
@Mapping( target = "region", ignore = true )
|
||||
|
||||
} )
|
||||
public abstract void mapToCountryDts(CountryDts countryDts, @MappingTarget CountryEntity country);
|
||||
|
||||
@Mappings( {
|
||||
@Mapping( target = "code", defaultValue = "DE" ),
|
||||
@Mapping( target = "id", defaultValue = "42" ),
|
||||
@Mapping( target = "zipcode", defaultValue = "1337" ),
|
||||
@Mapping( target = "region", ignore = true )
|
||||
|
||||
} )
|
||||
public abstract void mapToCountryDts(CountryEntity source, @MappingTarget CountryEntity target);
|
||||
|
||||
protected String mapToString(Region region) {
|
||||
return ( region != null ) ? region.getCode() : null;
|
||||
}
|
||||
}
|
@ -0,0 +1,162 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.ap.testutil.IssueKey;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import static org.fest.assertions.Assertions.assertThat;
|
||||
|
||||
@IssueKey( "600" )
|
||||
@RunWith( AnnotationProcessorTestRunner.class )
|
||||
@WithClasses( {
|
||||
CountryEntity.class,
|
||||
CountryDts.class
|
||||
} )
|
||||
public class DefaultValueTest {
|
||||
@Test
|
||||
@WithClasses( {
|
||||
Region.class,
|
||||
CountryMapper.class
|
||||
} )
|
||||
/**
|
||||
* Checks:
|
||||
* <ul>
|
||||
* <li>On code: Using defaultValue without type conversion</li>
|
||||
* <li>On id: Type conversion of the defaultValue (string expr to int)</li>
|
||||
* <li>On name: Using ConstantExpression instead of defaultValue</li>
|
||||
* <li>On zipcode: Ignoring defaultValue on primitive target types</li>
|
||||
* <li>On region: Using defaultValue before the assignment by an intern method (mapToString)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public void shouldDefaultValueAndUseConstantExpression() {
|
||||
CountryEntity countryEntity = new CountryEntity();
|
||||
|
||||
CountryDts countryDts = CountryMapper.INSTANCE.mapToCountryDts( countryEntity );
|
||||
|
||||
// id is null so it should fall back to the default value
|
||||
assertThat( countryDts.getId() ).isEqualTo( 42 );
|
||||
|
||||
// code is null so it should fall back to the default value
|
||||
assertThat( countryDts.getCode() ).isEqualTo( "DE" );
|
||||
|
||||
assertThat( countryDts.getZipcode() ).isEqualTo( 0 );
|
||||
|
||||
assertThat( countryDts.getRegion() ).isEqualTo( "someRegion" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( {
|
||||
Region.class,
|
||||
CountryMapper.class
|
||||
} )
|
||||
public void shouldIgnoreDefaultValue() {
|
||||
CountryEntity countryEntity = new CountryEntity();
|
||||
countryEntity.setCode( "US" );
|
||||
Region region = new Region();
|
||||
region.setCode( "foobar" );
|
||||
countryEntity.setRegion( region );
|
||||
|
||||
CountryDts countryDts = CountryMapper.INSTANCE.mapToCountryDts( countryEntity );
|
||||
|
||||
// the source entity had a code set, so the default value shouldn't be used
|
||||
assertThat( countryDts.getCode() ).isEqualTo( "US" );
|
||||
assertThat( countryDts.getRegion() ).isEqualTo( "foobar" );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( {
|
||||
Region.class,
|
||||
CountryMapper.class
|
||||
} )
|
||||
public void shouldHandleUpdateMethodsFromDtsToEntity() {
|
||||
CountryEntity countryEntity = new CountryEntity();
|
||||
CountryDts countryDts = new CountryDts();
|
||||
|
||||
CountryMapper.INSTANCE.mapToCountryDts( countryDts, countryEntity );
|
||||
|
||||
assertThat( countryEntity.getId() ).isEqualTo( 0 );
|
||||
// no code is set, so fall back to default value
|
||||
assertThat( countryEntity.getCode() ).isEqualTo( "DE" );
|
||||
assertThat( countryEntity.getZipcode() ).isEqualTo( 0 );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( {
|
||||
Region.class,
|
||||
CountryMapper.class
|
||||
} )
|
||||
public void shouldHandleUpdateMethodsFromEntityToEntity() {
|
||||
CountryEntity source = new CountryEntity();
|
||||
CountryEntity target = new CountryEntity();
|
||||
|
||||
CountryMapper.INSTANCE.mapToCountryDts( source, target );
|
||||
|
||||
// no id is set, so fall back to default value
|
||||
assertThat( target.getId() ).isEqualTo( 42 );
|
||||
// no code is set, so fall back to default value
|
||||
assertThat( target.getCode() ).isEqualTo( "DE" );
|
||||
assertThat( target.getZipcode() ).isEqualTo( 0 );
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( {
|
||||
ErroneousMapper.class,
|
||||
Region.class,
|
||||
} )
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic( type = ErroneousMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 33,
|
||||
messageRegExp = "Constant and default value are both defined in @Mapping,"
|
||||
+ " either define a defaultValue or a constant." ),
|
||||
}
|
||||
)
|
||||
public void errorOnDefaultValueAndConstant() throws ParseException {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses( {
|
||||
ErroneousMapper2.class,
|
||||
Region.class,
|
||||
} )
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic( type = ErroneousMapper2.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 33,
|
||||
messageRegExp = "Expression and default value are both defined in @Mapping,"
|
||||
+ " either define a defaultValue or an expression." ),
|
||||
}
|
||||
)
|
||||
public void errorOnDefaultValueAndExpression() throws ParseException {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public abstract class ErroneousMapper {
|
||||
public static final ErroneousMapper INSTANCE = Mappers.getMapper( ErroneousMapper.class );
|
||||
|
||||
@Mappings( {
|
||||
@Mapping( target = "code", defaultValue = "DE", constant = "FOOBAR" ),
|
||||
} )
|
||||
public abstract CountryDts mapToCountryDts(CountryEntity country);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public abstract class ErroneousMapper2 {
|
||||
public static final ErroneousMapper2 INSTANCE = Mappers.getMapper( ErroneousMapper2.class );
|
||||
|
||||
@Mappings( {
|
||||
@Mapping( target = "code", defaultValue = "DE", expression = "java(;)" ),
|
||||
} )
|
||||
public abstract CountryDts mapToCountryDts(CountryEntity country);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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.test.defaultvalue;
|
||||
|
||||
public class Region {
|
||||
private String code;
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user