mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#669 ispresentcheck and NULL check implementation
This commit is contained in:
parent
c47fd95d04
commit
1af4441d2d
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.mapstruct;
|
||||
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL_INLINE;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -148,4 +150,12 @@ public @interface Mapper {
|
||||
* specified with {@link #config()}.
|
||||
*/
|
||||
MappingInheritanceStrategy mappingInheritanceStrategy() default MappingInheritanceStrategy.EXPLICIT;
|
||||
|
||||
/**
|
||||
* Decide how to do presence check, such as checking null or calling hasX method, before mapping.
|
||||
* Can be overridden by the one on {@link MapperConfig} or {@link Mapping}.
|
||||
*
|
||||
* @return strategy about how to do null or presence check
|
||||
*/
|
||||
SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL_INLINE;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.mapstruct;
|
||||
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL_INLINE;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@ -135,4 +137,12 @@ public @interface MapperConfig {
|
||||
*/
|
||||
MappingInheritanceStrategy mappingInheritanceStrategy()
|
||||
default MappingInheritanceStrategy.EXPLICIT;
|
||||
|
||||
/**
|
||||
* Decide how to do presence check, such as checking null or calling hasXXX method, before mapping.
|
||||
* Can be overridden by the one on {@link Mapper} or {@link Mapping}.
|
||||
*
|
||||
* @return strategy about how to do null or presence check
|
||||
*/
|
||||
SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL_INLINE;
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct;
|
||||
|
||||
/**
|
||||
* Strategy to decide how to check null or hasX method before mapping
|
||||
*
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public enum SourceValuePresenceCheckStrategy {
|
||||
|
||||
/**
|
||||
* Only check != null for inline conversions
|
||||
*
|
||||
*/
|
||||
IS_NULL_INLINE,
|
||||
|
||||
/**
|
||||
* Always check != null, no matter whether it's an inline or method conversion
|
||||
*
|
||||
*/
|
||||
IS_NULL,
|
||||
|
||||
/**
|
||||
* Will invoke custom hasX() method, before mapping,
|
||||
* name to be given through the accessor naming strategy
|
||||
*/
|
||||
CUSTOM;
|
||||
}
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.mapstruct;
|
||||
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
@ -191,4 +193,12 @@ public @interface Mapping {
|
||||
* @return Default value to set in case the source property is {@code null}.
|
||||
*/
|
||||
String defaultValue() default "";
|
||||
|
||||
/**
|
||||
* Decide whether we should check null or hasX method before mapping.
|
||||
* The value on {@link Mapper} can override this one.
|
||||
*
|
||||
* @return strategy about how to do null or has value check
|
||||
*/
|
||||
SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.mapstruct;
|
||||
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL_INLINE;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@ -190,4 +192,12 @@ public @interface Mapping {
|
||||
* @return Default value to set in case the source property is {@code null}.
|
||||
*/
|
||||
String defaultValue() default "";
|
||||
|
||||
/**
|
||||
* Decide how to do presence check, such as checking null or calling hasXXX method, before mapping.
|
||||
* If it is set to default, it can be overridden by the one on {@link MapperConfig} or {@link Mapper}.
|
||||
*
|
||||
* @return strategy about how to do null or presence check
|
||||
*/
|
||||
SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL_INLINE;
|
||||
}
|
||||
|
@ -367,9 +367,6 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
Iterator<Entry<String, ExecutableElement>> targetPropertiesIterator =
|
||||
unprocessedTargetProperties.entrySet().iterator();
|
||||
|
||||
// usually there should be only one getter; only for Boolean there may be two: isFoo() and getFoo()
|
||||
List<ExecutableElement> candidates = new ArrayList<ExecutableElement>( 2 );
|
||||
|
||||
while ( targetPropertiesIterator.hasNext() ) {
|
||||
|
||||
Entry<String, ExecutableElement> targetProperty = targetPropertiesIterator.next();
|
||||
@ -387,18 +384,24 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
PropertyMapping newPropertyMapping = null;
|
||||
ExecutableElement sourceAccessor = sourceType.getPropertyReadAccessors().get( propertyName );
|
||||
if ( sourceAccessor != null ) {
|
||||
Mapping mapping = method.getSingleMappingByTargetPropertyName( propertyName );
|
||||
|
||||
ExecutableElement sourceReadAccessor =
|
||||
sourceParameter.getType().getPropertyReadAccessors().get( propertyName );
|
||||
|
||||
ExecutableElement sourcePresenceChecker =
|
||||
sourceParameter.getType().getPropertyPresenceCheckers().get( propertyName );
|
||||
|
||||
if ( sourceReadAccessor != null ) {
|
||||
Mapping mapping = method.getSingleMappingByTargetPropertyName( targetProperty.getKey() );
|
||||
DeclaredType declaredSourceType = (DeclaredType) sourceParameter.getType().getTypeMirror();
|
||||
|
||||
SourceReference sourceRef = new SourceReference.BuilderFromProperty()
|
||||
.sourceParameter( sourceParameter )
|
||||
.type( ctx.getTypeFactory().getReturnType( declaredSourceType, sourceAccessor ) )
|
||||
.accessor( sourceAccessor )
|
||||
.name( propertyName )
|
||||
.type( ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ) )
|
||||
.readAccessor( sourceReadAccessor )
|
||||
.presenceChecker( sourcePresenceChecker )
|
||||
.name( targetProperty.getKey() )
|
||||
.build();
|
||||
|
||||
newPropertyMapping = new PropertyMappingBuilder()
|
||||
@ -416,10 +419,7 @@ public class BeanMappingMethod extends MappingMethod {
|
||||
.build();
|
||||
|
||||
unprocessedSourceParameters.remove( sourceParameter );
|
||||
|
||||
}
|
||||
// candidates are handled
|
||||
candidates.clear();
|
||||
|
||||
if ( propertyMapping != null && newPropertyMapping != null ) {
|
||||
// TODO improve error message
|
||||
|
@ -145,7 +145,7 @@ public class NestedPropertyMappingMethod extends MappingMethod {
|
||||
private final String safeName;
|
||||
|
||||
public SafePropertyEntry( PropertyEntry entry, String safeName ) {
|
||||
super( entry.getName(), entry.getAccessor(), entry.getType() );
|
||||
super( entry.getName(), entry.getAccessor(), entry.getPresenceChecker(), entry.getType() );
|
||||
this.safeName = safeName;
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,7 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
private final List<String> enumConstants;
|
||||
|
||||
private Map<String, ExecutableElement> getters = null;
|
||||
private Map<String, ExecutableElement> presenceCheckers = null;
|
||||
|
||||
private List<ExecutableElement> allExecutables = null;
|
||||
private List<ExecutableElement> setters = null;
|
||||
@ -380,6 +381,23 @@ public class Type extends ModelElement implements Comparable<Type> {
|
||||
return getters;
|
||||
}
|
||||
|
||||
/**
|
||||
* getPropertyPresenceCheckers
|
||||
*
|
||||
* @return an unmodifiable map of all presence checkers, indexed by property name
|
||||
*/
|
||||
public Map<String, ExecutableElement> getPropertyPresenceCheckers() {
|
||||
if ( presenceCheckers == null ) {
|
||||
List<ExecutableElement> checkerList = Filters.presenceCheckMethodsIn( getAllExecutables() );
|
||||
Map<String, ExecutableElement> modifiableCheckers = new LinkedHashMap<String, ExecutableElement>();
|
||||
for (ExecutableElement checker : checkerList) {
|
||||
modifiableCheckers.put( Executables.getPropertyName( checker ), checker );
|
||||
}
|
||||
presenceCheckers = Collections.unmodifiableMap( modifiableCheckers );
|
||||
}
|
||||
return presenceCheckers;
|
||||
}
|
||||
|
||||
/**
|
||||
* getPropertyWriteAccessors returns a map of the write accessors according to the CollectionMappingStrategy. These
|
||||
* accessors include:
|
||||
|
@ -38,6 +38,7 @@ 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.prism.SourceValuePresenceCheckStrategy;
|
||||
import org.mapstruct.ap.internal.util.FormattingMessager;
|
||||
import org.mapstruct.ap.internal.util.Message;
|
||||
|
||||
@ -61,6 +62,9 @@ public class Mapping {
|
||||
private final boolean isIgnored;
|
||||
private final List<String> dependsOn;
|
||||
|
||||
private final SourceValuePresenceCheckStrategy valuePresenceCheckStrategy;
|
||||
private final boolean isSetValuePresenceCheckStrategy;
|
||||
|
||||
private final AnnotationMirror mirror;
|
||||
private final AnnotationValue sourceAnnotationValue;
|
||||
private final AnnotationValue targetAnnotationValue;
|
||||
@ -96,7 +100,6 @@ public class Mapping {
|
||||
public static Mapping fromMappingPrism(MappingPrism mappingPrism, ExecutableElement element,
|
||||
FormattingMessager messager) {
|
||||
|
||||
|
||||
if ( mappingPrism.target().isEmpty() ) {
|
||||
messager.printMessage(
|
||||
element,
|
||||
@ -139,13 +142,14 @@ public class Mapping {
|
||||
List<String> dependsOn =
|
||||
mappingPrism.dependsOn() != null ? mappingPrism.dependsOn() : Collections.<String>emptyList();
|
||||
|
||||
boolean isSetValuePresenceCheckStrategy = mappingPrism.values.sourceValuePresenceCheckStrategy() != null;
|
||||
|
||||
FormattingParameters formattingParam = new FormattingParameters( dateFormat, numberFormat );
|
||||
SelectionParameters selectionParams = new SelectionParameters(
|
||||
mappingPrism.qualifiedBy(),
|
||||
mappingPrism.qualifiedByName(),
|
||||
resultTypeIsDefined ? mappingPrism.resultType() : null);
|
||||
|
||||
FormattingParameters formattingParam = new FormattingParameters( dateFormat, numberFormat );
|
||||
|
||||
return new Mapping(
|
||||
source,
|
||||
constant,
|
||||
@ -159,16 +163,20 @@ public class Mapping {
|
||||
formattingParam,
|
||||
selectionParams,
|
||||
mappingPrism.values.dependsOn(),
|
||||
dependsOn
|
||||
dependsOn,
|
||||
SourceValuePresenceCheckStrategy.valueOf( mappingPrism.sourceValuePresenceCheckStrategy() ),
|
||||
isSetValuePresenceCheckStrategy
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("checkstyle:parameternumber")
|
||||
private Mapping(String sourceName, String constant, String javaExpression, String targetName,
|
||||
private Mapping( String sourceName, String constant, String javaExpression, String targetName,
|
||||
String defaultValue, boolean isIgnored, AnnotationMirror mirror,
|
||||
AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue,
|
||||
FormattingParameters formattingParameters, SelectionParameters selectionParameters,
|
||||
AnnotationValue dependsOnAnnotationValue, List<String> dependsOn) {
|
||||
AnnotationValue dependsOnAnnotationValue, List<String> dependsOn,
|
||||
SourceValuePresenceCheckStrategy valuePresenceCheckStrategy,
|
||||
boolean isSetValuePresenceCheckStrategy ) {
|
||||
this.sourceName = sourceName;
|
||||
this.constant = constant;
|
||||
this.javaExpression = javaExpression;
|
||||
@ -182,6 +190,8 @@ public class Mapping {
|
||||
this.selectionParameters = selectionParameters;
|
||||
this.dependsOnAnnotationValue = dependsOnAnnotationValue;
|
||||
this.dependsOn = dependsOn;
|
||||
this.valuePresenceCheckStrategy = valuePresenceCheckStrategy;
|
||||
this.isSetValuePresenceCheckStrategy = isSetValuePresenceCheckStrategy;
|
||||
}
|
||||
|
||||
private static String getExpression(MappingPrism mappingPrism, ExecutableElement element,
|
||||
@ -282,6 +292,14 @@ public class Mapping {
|
||||
return dependsOn;
|
||||
}
|
||||
|
||||
public SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() {
|
||||
return valuePresenceCheckStrategy;
|
||||
}
|
||||
|
||||
public boolean isSetSourceValuePresenceCheckStrategy() {
|
||||
return isSetValuePresenceCheckStrategy;
|
||||
}
|
||||
|
||||
private boolean hasPropertyInReverseMethod(String name, SourceMethod method) {
|
||||
CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy();
|
||||
return method.getResultType().getPropertyWriteAccessors( cms ).containsKey( name );
|
||||
@ -330,7 +348,9 @@ public class Mapping {
|
||||
formattingParameters,
|
||||
selectionParameters,
|
||||
dependsOnAnnotationValue,
|
||||
Collections.<String>emptyList()
|
||||
Collections.<String>emptyList(),
|
||||
valuePresenceCheckStrategy,
|
||||
isSetValuePresenceCheckStrategy
|
||||
);
|
||||
|
||||
reverse.init( method, messager, typeFactory );
|
||||
@ -357,7 +377,9 @@ public class Mapping {
|
||||
formattingParameters,
|
||||
selectionParameters,
|
||||
dependsOnAnnotationValue,
|
||||
dependsOn
|
||||
dependsOn,
|
||||
valuePresenceCheckStrategy,
|
||||
isSetValuePresenceCheckStrategy
|
||||
);
|
||||
|
||||
if ( sourceReference != null ) {
|
||||
@ -375,3 +397,4 @@ public class Mapping {
|
||||
"\n}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,12 +175,14 @@ public class SourceReference {
|
||||
for ( String entryName : entryNames ) {
|
||||
boolean matchFound = false;
|
||||
Map<String, ExecutableElement> sourceReadAccessors = newType.getPropertyReadAccessors();
|
||||
Map<String, ExecutableElement> sourcePresenceCheckers = newType.getPropertyPresenceCheckers();
|
||||
|
||||
for ( Map.Entry<String, ExecutableElement> getter : sourceReadAccessors.entrySet() ) {
|
||||
if ( getter.getKey().equals( entryName ) ) {
|
||||
newType = typeFactory.getReturnType(
|
||||
(DeclaredType) newType.getTypeMirror(), getter.getValue()
|
||||
);
|
||||
sourceEntries.add( new PropertyEntry( entryName, getter.getValue(), newType ) );
|
||||
newType = typeFactory.getReturnType( (DeclaredType) newType.getTypeMirror(),
|
||||
getter.getValue() );
|
||||
sourceEntries.add( new PropertyEntry( entryName, getter.getValue(),
|
||||
sourcePresenceCheckers.get( entryName ), newType ) );
|
||||
matchFound = true;
|
||||
break;
|
||||
}
|
||||
@ -204,7 +206,8 @@ public class SourceReference {
|
||||
public static class BuilderFromProperty {
|
||||
|
||||
private String name;
|
||||
private ExecutableElement accessor;
|
||||
private ExecutableElement readAccessor;
|
||||
private ExecutableElement presenceChecker;
|
||||
private Type type;
|
||||
private Parameter sourceParameter;
|
||||
|
||||
@ -213,8 +216,13 @@ public class SourceReference {
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuilderFromProperty accessor(ExecutableElement accessor) {
|
||||
this.accessor = accessor;
|
||||
public BuilderFromProperty readAccessor(ExecutableElement readAccessor) {
|
||||
this.readAccessor = readAccessor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuilderFromProperty presenceChecker(ExecutableElement presenceChecker) {
|
||||
this.presenceChecker = presenceChecker;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -230,8 +238,8 @@ public class SourceReference {
|
||||
|
||||
public SourceReference build() {
|
||||
List<PropertyEntry> sourcePropertyEntries = new ArrayList<PropertyEntry>();
|
||||
if ( accessor != null ) {
|
||||
sourcePropertyEntries.add( new PropertyEntry( name, accessor, type ) );
|
||||
if ( readAccessor != null ) {
|
||||
sourcePropertyEntries.add( new PropertyEntry( name, readAccessor, presenceChecker, type ) );
|
||||
}
|
||||
return new SourceReference( sourceParameter, sourcePropertyEntries, true );
|
||||
}
|
||||
@ -271,11 +279,14 @@ public class SourceReference {
|
||||
|
||||
private final String name;
|
||||
private final ExecutableElement accessor;
|
||||
private final ExecutableElement presenceChecker;
|
||||
private final Type type;
|
||||
|
||||
public PropertyEntry(String name, ExecutableElement accessor, Type type) {
|
||||
public PropertyEntry(String name, ExecutableElement readAccessor,
|
||||
ExecutableElement presenceChecker, Type type) {
|
||||
this.name = name;
|
||||
this.accessor = accessor;
|
||||
this.accessor = readAccessor;
|
||||
this.presenceChecker = presenceChecker;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@ -287,6 +298,10 @@ public class SourceReference {
|
||||
return accessor;
|
||||
}
|
||||
|
||||
public ExecutableElement getPresenceChecker() {
|
||||
return presenceChecker;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -43,6 +43,9 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
|
||||
if ( isGetterMethod( method ) ) {
|
||||
return MethodType.GETTER;
|
||||
}
|
||||
else if ( isPresenceCheckMethod( method ) ) {
|
||||
return MethodType.PRESENCE_CHECKER;
|
||||
}
|
||||
else if ( isSetterMethod( method ) ) {
|
||||
return MethodType.SETTER;
|
||||
}
|
||||
@ -67,6 +70,14 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
|
||||
return isNonBooleanGetterName || ( isBooleanGetterName && returnTypeIsBoolean );
|
||||
}
|
||||
|
||||
private boolean isPresenceCheckMethod(ExecutableElement method) {
|
||||
String methodName = method.getSimpleName().toString();
|
||||
|
||||
return methodName.startsWith( "has" ) && methodName.length() > 3 &&
|
||||
( method.getReturnType().getKind() == TypeKind.BOOLEAN ||
|
||||
"java.lang.Boolean".equals( getQualifiedName( method.getReturnType() ) ) );
|
||||
}
|
||||
|
||||
public boolean isSetterMethod(ExecutableElement method) {
|
||||
String methodName = method.getSimpleName().toString();
|
||||
|
||||
@ -81,8 +92,8 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
|
||||
|
||||
|
||||
@Override
|
||||
public String getPropertyName(ExecutableElement getterOrSetterMethod) {
|
||||
String methodName = getterOrSetterMethod.getSimpleName().toString();
|
||||
public String getPropertyName(ExecutableElement getterOrHasserOrSetterMethod) {
|
||||
String methodName = getterOrHasserOrSetterMethod.getSimpleName().toString();
|
||||
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.internal.prism;
|
||||
|
||||
|
||||
/**
|
||||
* Prism for the enum {@link org.mapstruct.SourceValuePresenceCheckStrategy}
|
||||
*
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public enum SourceValuePresenceCheckStrategy {
|
||||
/**
|
||||
* Only check != null for inline conversions
|
||||
*
|
||||
*/
|
||||
IS_NULL_INLINE,
|
||||
|
||||
/**
|
||||
* Always check != null, no matter whether it's an inline or method conversion
|
||||
*
|
||||
*/
|
||||
IS_NULL,
|
||||
|
||||
/**
|
||||
* Will invoke custom hasX() method, before mapping,
|
||||
* name to be given through the accessor naming strategy
|
||||
*/
|
||||
CUSTOM;
|
||||
}
|
@ -76,6 +76,12 @@ public class Executables {
|
||||
ACCESSOR_NAMING_STRATEGY.getMethodType( method ) == MethodType.GETTER;
|
||||
}
|
||||
|
||||
public static boolean isPresenceCheckMethod(ExecutableElement method) {
|
||||
return isPublic( method ) &&
|
||||
method.getParameters().isEmpty() &&
|
||||
ACCESSOR_NAMING_STRATEGY.getMethodType( method ) == MethodType.PRESENCE_CHECKER;
|
||||
}
|
||||
|
||||
public static boolean isSetterMethod(ExecutableElement method) {
|
||||
return isPublic( method )
|
||||
&& method.getParameters().size() == 1
|
||||
@ -92,8 +98,8 @@ public class Executables {
|
||||
return method.getModifiers().contains( Modifier.PUBLIC );
|
||||
}
|
||||
|
||||
public static String getPropertyName(ExecutableElement getterOrSetterMethod) {
|
||||
return ACCESSOR_NAMING_STRATEGY.getPropertyName( getterOrSetterMethod );
|
||||
public static String getPropertyName(ExecutableElement getterOrHasserOrSetterMethod) {
|
||||
return ACCESSOR_NAMING_STRATEGY.getPropertyName( getterOrHasserOrSetterMethod );
|
||||
}
|
||||
|
||||
public static boolean isDefaultMethod(ExecutableElement method) {
|
||||
|
@ -46,6 +46,18 @@ public class Filters {
|
||||
return getterMethods;
|
||||
}
|
||||
|
||||
public static List<ExecutableElement> presenceCheckMethodsIn(Iterable<ExecutableElement> elements) {
|
||||
List<ExecutableElement> presenceCheckMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
for ( ExecutableElement method : elements ) {
|
||||
if ( Executables.isPresenceCheckMethod( method ) ) {
|
||||
presenceCheckMethods.add( method );
|
||||
}
|
||||
}
|
||||
|
||||
return presenceCheckMethods;
|
||||
}
|
||||
|
||||
public static List<ExecutableElement> setterMethodsIn(Iterable<ExecutableElement> elements) {
|
||||
List<ExecutableElement> setterMethods = new LinkedList<ExecutableElement>();
|
||||
|
||||
|
@ -32,6 +32,7 @@ import org.mapstruct.ap.internal.prism.MapperConfigPrism;
|
||||
import org.mapstruct.ap.internal.prism.MapperPrism;
|
||||
import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism;
|
||||
import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism;
|
||||
import org.mapstruct.ap.internal.prism.SourceValuePresenceCheckStrategy;
|
||||
|
||||
/**
|
||||
* Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and
|
||||
@ -183,4 +184,22 @@ public class MapperConfiguration {
|
||||
public AnnotationMirror getAnnotationMirror() {
|
||||
return mapperPrism.mirror;
|
||||
}
|
||||
|
||||
public SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() {
|
||||
if ( mapperConfigPrism != null && mapperPrism.values.sourceValuePresenceCheckStrategy() == null ) {
|
||||
return SourceValuePresenceCheckStrategy.valueOf( mapperConfigPrism.sourceValuePresenceCheckStrategy() );
|
||||
}
|
||||
else {
|
||||
return SourceValuePresenceCheckStrategy.valueOf( mapperPrism.sourceValuePresenceCheckStrategy() );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSetSourceValuePresenceCheckStrategy() {
|
||||
if ( mapperConfigPrism != null && mapperPrism.values.sourceValuePresenceCheckStrategy() == null ) {
|
||||
return mapperConfigPrism.values.sourceValuePresenceCheckStrategy() != null;
|
||||
}
|
||||
else {
|
||||
return mapperPrism.values.sourceValuePresenceCheckStrategy() != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ public enum Message {
|
||||
PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no parameter named \"%s\"." ),
|
||||
PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER( "The type of parameter \"%s\" has no property named \"%s\"." ),
|
||||
PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s)." ),
|
||||
PROPERTYMAPPING_NO_PRESENCE_CHECKER_FOR_SOURCE_TYPE( "Using custom source value presence checking strategy, but no presence checker found for %s in source type." ),
|
||||
PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
||||
|
||||
CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ),
|
||||
|
@ -43,5 +43,10 @@ public enum MethodType {
|
||||
/**
|
||||
* Any method which is neither a JavaBeans getter, setter nor an adder method.
|
||||
*/
|
||||
OTHER;
|
||||
OTHER,
|
||||
|
||||
/**
|
||||
* A method to check whether a property is present, e.g. {@code public String hasName()}.
|
||||
*/
|
||||
PRESENCE_CHECKER;
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.SourceValuePresenceCheckStrategy;
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
@Mapper( sourceValuePresenceCheckStrategy = SourceValuePresenceCheckStrategy.IS_NULL_INLINE )
|
||||
public class CustomMapper {
|
||||
|
||||
public MyLongWrapper toMyLongWrapperViaPrimitive(Long primitive) {
|
||||
MyLongWrapper wrapper = new MyLongWrapper();
|
||||
wrapper.setMyLong( primitive );
|
||||
return wrapper;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
|
||||
/**
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class MyLongWrapper {
|
||||
|
||||
private Long myLong;
|
||||
|
||||
public Long getMyLong() {
|
||||
return myLong;
|
||||
}
|
||||
|
||||
public void setMyLong(Long myLong) {
|
||||
myLong.longValue();
|
||||
this.myLong = myLong;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public class MyObject {
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return this == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.fest.assertions.Assertions;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
/**
|
||||
* Test for correct handling of source presence checks.
|
||||
*
|
||||
* @author Sean Huang
|
||||
*/
|
||||
@WithClasses({
|
||||
SourceTargetMapper.class,
|
||||
MyObject.class,
|
||||
CustomMapper.class,
|
||||
MyLongWrapper.class,
|
||||
Source.class,
|
||||
Target.class,
|
||||
SourceWtCheck.class,
|
||||
TargetWtCheck.class
|
||||
})
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
public class PresenceCheckTest {
|
||||
|
||||
@Test
|
||||
public void testSourceNoPresenceCheckWithIsNullheck() {
|
||||
SourceWtCheck source = new SourceWtCheck();
|
||||
source.setHasSomeList( false );
|
||||
source.setHasSomeLong2( false );
|
||||
|
||||
TargetWtCheck target = SourceTargetMapper.INSTANCE.sourceToTargetWithIsNullCheck( source );
|
||||
|
||||
//No null check for primitive type
|
||||
Assert.assertEquals( 0, target.getSomePrimitiveDouble(), 0.01 );
|
||||
Assert.assertEquals( null, target.getSomeInteger() );
|
||||
Assert.assertEquals( null, target.getNoCheckObject() );
|
||||
Assert.assertEquals( 0, target.getNoCheckPrimitive() );
|
||||
Assert.assertEquals( null, target.getSomeLong1() );
|
||||
Assert.assertEquals( null, target.getSomeLong2() );
|
||||
}
|
||||
|
||||
@Test( expected = NullPointerException.class )
|
||||
public void testSourceNoPresenceCheckWithIsNullInlineCheck() {
|
||||
SourceWtCheck source = new SourceWtCheck();
|
||||
source.setHasSomeList( false );
|
||||
|
||||
//No null check for Mapper, if sourceValuePresenceCheckStrategy = IS_NULL_INLINE
|
||||
TargetWtCheck target = SourceTargetMapper.INSTANCE.sourceToTargetWithIsNullInlineCheck( source );
|
||||
|
||||
Assert.assertEquals( null, target.getSomeLong2() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSourcePresenceCheckWithCustom() {
|
||||
MyObject object = new MyObject();
|
||||
MyLongWrapper longWrapper = new MyLongWrapper();
|
||||
longWrapper.setMyLong( 2L );
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add( "first" );
|
||||
list.add( "second" );
|
||||
|
||||
Source source = new Source();
|
||||
|
||||
source.setSomeObject( object );
|
||||
source.setSomePrimitiveDouble( 5.0 );
|
||||
source.setSomeInteger( 7 );
|
||||
source.setSomeLong1( 2L );
|
||||
source.setHasSomeLong2( false );
|
||||
source.setSomeList( list );
|
||||
|
||||
Target target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustom( source );
|
||||
|
||||
Assert.assertEquals( object, target.getSomeObject() );
|
||||
Assert.assertEquals( 5.0, target.getSomePrimitiveDouble(), 0.01 );
|
||||
Assert.assertEquals( (Integer) 7, target.getSomeInteger() );
|
||||
Assert.assertEquals( longWrapper.getMyLong(), target.getSomeLong1().getMyLong() );
|
||||
Assert.assertEquals( null, target.getSomeLong2() );
|
||||
|
||||
Assertions.assertThat( target.getSomeList() ).containsExactly( "first", "second" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithCustom() {
|
||||
MyObject object = new MyObject();
|
||||
MyLongWrapper longWrapper = new MyLongWrapper();
|
||||
longWrapper.setMyLong( 2L );
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add( "first" );
|
||||
list.add( "second" );
|
||||
|
||||
Source source = new Source();
|
||||
|
||||
source.setSomeObject( object );
|
||||
|
||||
source.setSomePrimitiveDouble( 5.0 );
|
||||
source.setHasSomePrimitiveDouble( false );
|
||||
|
||||
source.setSomeInteger( 7 );
|
||||
source.setSomeLong1( 2L );
|
||||
|
||||
source.setSomeLong2( 4L );
|
||||
source.setHasSomeLong2( false );
|
||||
|
||||
source.setSomeList( list );
|
||||
|
||||
Target target = new Target();
|
||||
|
||||
SourceTargetMapper.INSTANCE.sourceToTargetWithCustom( source, target );
|
||||
|
||||
Assert.assertEquals( object, target.getSomeObject() );
|
||||
Assert.assertEquals( 0, target.getSomePrimitiveDouble(), 0.01 );
|
||||
Assert.assertEquals( (Integer) 7, target.getSomeInteger() );
|
||||
Assert.assertEquals( longWrapper.getMyLong(), target.getSomeLong1().getMyLong() );
|
||||
Assert.assertEquals( null, target.getSomeLong2() );
|
||||
|
||||
Assertions.assertThat( target.getSomeList() ).containsExactly( "first", "second" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSourcePresenceCheckWithCustomAndDefaultValue() {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add( "first" );
|
||||
list.add( "second" );
|
||||
|
||||
Source source = new Source();
|
||||
source.setSomeList( list );
|
||||
|
||||
source.setHasSomePrimitiveDouble( false );
|
||||
source.setHasSomeInteger( false );
|
||||
source.setHasSomeLong1( false );
|
||||
source.setHasSomeLong2( false );
|
||||
|
||||
Target target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustomAndDefault( source );
|
||||
|
||||
Assert.assertEquals( null, target.getSomeObject() );
|
||||
|
||||
//Support default value for primitive type if there is hasX method and config is on
|
||||
Assert.assertEquals( 111.1, target.getSomePrimitiveDouble(), 0.01 );
|
||||
Assert.assertEquals( (Integer) 222, target.getSomeInteger() );
|
||||
Assert.assertEquals( (Long) 333L, target.getSomeLong1().getMyLong() );
|
||||
Assert.assertEquals( (Long) 444L, target.getSomeLong2().getMyLong() );
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
Assert.assertEquals( list.get( i ), target.getSomeList().get( i ) );
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public class Source {
|
||||
|
||||
private MyObject someObject;
|
||||
private boolean hasSomeObject = true;
|
||||
|
||||
private double somePrimitiveDouble;
|
||||
private boolean hasPrimitiveSomeDouble = true;
|
||||
|
||||
private Integer someInteger;
|
||||
private boolean hasSomeInteger = true;
|
||||
|
||||
private Long someLong1;
|
||||
private boolean hasSomeLong1 = true;
|
||||
|
||||
private Long someLong2;
|
||||
private boolean hasSomeLong2 = true;
|
||||
|
||||
private List<String> someList;
|
||||
private boolean hasSomeList = true;
|
||||
|
||||
public boolean hasSomeObject() {
|
||||
return hasSomeObject;
|
||||
}
|
||||
|
||||
public void setHasSomeObject(boolean has) {
|
||||
this.hasSomeObject = has;
|
||||
}
|
||||
|
||||
public MyObject getSomeObject() {
|
||||
return someObject;
|
||||
}
|
||||
|
||||
public void setSomeObject(MyObject someObject) {
|
||||
this.someObject = someObject;
|
||||
}
|
||||
|
||||
public boolean hasSomePrimitiveDouble() {
|
||||
return hasPrimitiveSomeDouble;
|
||||
}
|
||||
|
||||
public void setHasSomePrimitiveDouble(boolean has) {
|
||||
this.hasPrimitiveSomeDouble = has;
|
||||
}
|
||||
|
||||
public double getSomePrimitiveDouble() {
|
||||
return somePrimitiveDouble;
|
||||
}
|
||||
|
||||
public void setSomePrimitiveDouble(double someDouble) {
|
||||
this.somePrimitiveDouble = someDouble;
|
||||
}
|
||||
|
||||
public boolean hasSomeInteger() {
|
||||
return hasSomeInteger;
|
||||
}
|
||||
|
||||
public void setHasSomeInteger(boolean hasSomeInteger) {
|
||||
this.hasSomeInteger = hasSomeInteger;
|
||||
}
|
||||
|
||||
public Integer getSomeInteger() {
|
||||
return someInteger;
|
||||
}
|
||||
|
||||
public void setSomeInteger(Integer someInteger) {
|
||||
this.someInteger = someInteger;
|
||||
}
|
||||
|
||||
public boolean hasSomeLong1() {
|
||||
return hasSomeLong1;
|
||||
}
|
||||
|
||||
public void setHasSomeLong1(boolean hasSomeInLong) {
|
||||
this.hasSomeLong1 = hasSomeInLong;
|
||||
}
|
||||
|
||||
public boolean hasSomeLong2() {
|
||||
return hasSomeLong2;
|
||||
}
|
||||
|
||||
public void setHasSomeLong2(boolean hasSomeInLong) {
|
||||
this.hasSomeLong2 = hasSomeInLong;
|
||||
}
|
||||
|
||||
public Long getSomeLong1() {
|
||||
return someLong1;
|
||||
}
|
||||
|
||||
public Long getSomeLong2() {
|
||||
return someLong2;
|
||||
}
|
||||
|
||||
public void setSomeLong1(Long someLong) {
|
||||
this.someLong1 = someLong;
|
||||
}
|
||||
|
||||
public void setSomeLong2(Long someLong) {
|
||||
this.someLong2 = someLong;
|
||||
}
|
||||
|
||||
public boolean hasSomeList() {
|
||||
return hasSomeList;
|
||||
}
|
||||
|
||||
public void setHasSomeList(boolean has) {
|
||||
this.hasSomeList = has;
|
||||
}
|
||||
|
||||
public List<String> getSomeList() {
|
||||
return someList;
|
||||
}
|
||||
|
||||
public void setSomeList(List<String> someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.CUSTOM;
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL;
|
||||
import static org.mapstruct.SourceValuePresenceCheckStrategy.IS_NULL_INLINE;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.Mappings;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
@Mapper(uses = { CustomMapper.class }, sourceValuePresenceCheckStrategy = CUSTOM)
|
||||
public interface SourceTargetMapper {
|
||||
|
||||
SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
||||
|
||||
Target sourceToTargetWithCustom(Source source);
|
||||
|
||||
void sourceToTargetWithCustom(Source source, @MappingTarget Target target);
|
||||
|
||||
@Mappings( {
|
||||
@Mapping(target = "somePrimitiveDouble", defaultValue = "111.1"),
|
||||
@Mapping(target = "someInteger", defaultValue = "222"),
|
||||
@Mapping(target = "someLong1", defaultValue = "333"),
|
||||
@Mapping(target = "someLong2", defaultValue = "444"),
|
||||
} )
|
||||
Target sourceToTargetWithCustomAndDefault(Source source);
|
||||
|
||||
@Mappings( {
|
||||
@Mapping(target = "somePrimitiveDouble", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "someInteger", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "noCheckObject", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "noCheckPrimitive", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "someLong1", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
} )
|
||||
TargetWtCheck sourceToTargetWithIsNullCheck(SourceWtCheck source);
|
||||
|
||||
@Mappings( {
|
||||
@Mapping(target = "noCheckObject", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "noCheckPrimitive", sourceValuePresenceCheckStrategy = IS_NULL),
|
||||
@Mapping(target = "someLong2", sourceValuePresenceCheckStrategy = IS_NULL_INLINE),
|
||||
} )
|
||||
TargetWtCheck sourceToTargetWithIsNullInlineCheck(SourceWtCheck source);
|
||||
|
||||
/*
|
||||
* Seeing exception below since there is no presence check method on source.
|
||||
*
|
||||
* org.junit.ComparisonFailure: [Compilation failed. Diagnostics: [DiagnosticDescriptor:
|
||||
* ERROR SourceTargetPresenceCheckMapper.java:53 Using custom source value presence checking strategy,
|
||||
* but no presence checker found for property "int noCheckPrimitive" in source type.]]
|
||||
* expected:<[SUCCEED]ED> but was:<[FAIL]ED>
|
||||
*
|
||||
@Mappings( {
|
||||
@Mapping(target = "someDouble", defaultValue = "111.1"),
|
||||
@Mapping(target = "someInteger", defaultValue = "222"),
|
||||
@Mapping(target = "someLong", defaultValue = "333"),
|
||||
} )
|
||||
TargetWtCheck sourceToTargetWithConfigOn(SourceWtCheck source);
|
||||
*/
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public class SourceWtCheck extends Source {
|
||||
|
||||
private int noCheckPrimitive;
|
||||
private String noCheckObject;
|
||||
|
||||
public int getNoCheckPrimitive() {
|
||||
return noCheckPrimitive;
|
||||
}
|
||||
|
||||
public void setNoCheckPrimitive(int noCheckPrimitive) {
|
||||
this.noCheckPrimitive = noCheckPrimitive;
|
||||
}
|
||||
|
||||
public String getNoCheckObject() {
|
||||
return noCheckObject;
|
||||
}
|
||||
|
||||
public void setNoCheckObject(String noCheckObject) {
|
||||
this.noCheckObject = noCheckObject;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public class Target {
|
||||
|
||||
private MyObject someObject;
|
||||
private double somePrimitiveDouble;
|
||||
private Integer someInteger;
|
||||
private MyLongWrapper someLong1;
|
||||
private MyLongWrapper someLong2;
|
||||
private List<String> someList;
|
||||
|
||||
public MyObject getSomeObject() {
|
||||
return someObject;
|
||||
}
|
||||
|
||||
public void setSomeObject(MyObject someObject) {
|
||||
this.someObject = someObject;
|
||||
}
|
||||
|
||||
public double getSomePrimitiveDouble() {
|
||||
return somePrimitiveDouble;
|
||||
}
|
||||
|
||||
public void setSomePrimitiveDouble(double someDouble) {
|
||||
this.somePrimitiveDouble = someDouble;
|
||||
}
|
||||
|
||||
public Integer getSomeInteger() {
|
||||
return someInteger;
|
||||
}
|
||||
|
||||
public void setSomeInteger(Integer someInteger) {
|
||||
this.someInteger = someInteger;
|
||||
}
|
||||
|
||||
public MyLongWrapper getSomeLong1() {
|
||||
return someLong1;
|
||||
}
|
||||
|
||||
public void setSomeLong1(MyLongWrapper someLong) {
|
||||
this.someLong1 = someLong;
|
||||
}
|
||||
|
||||
public MyLongWrapper getSomeLong2() {
|
||||
return someLong2;
|
||||
}
|
||||
|
||||
public void setSomeLong2(MyLongWrapper someLong) {
|
||||
this.someLong2 = someLong;
|
||||
}
|
||||
|
||||
public List<String> getSomeList() {
|
||||
return someList;
|
||||
}
|
||||
|
||||
public void setSomeList(List<String> someList) {
|
||||
this.someList = someList;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Copyright 2012-2016 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.mapstruct.ap.test.presencecheck;
|
||||
|
||||
|
||||
/**
|
||||
* @author Sean Huang
|
||||
*/
|
||||
public class TargetWtCheck extends Target {
|
||||
|
||||
private int noCheckPrimitive;
|
||||
private String noCheckObject;
|
||||
|
||||
public int getNoCheckPrimitive() {
|
||||
return noCheckPrimitive;
|
||||
}
|
||||
|
||||
public void setNoCheckPrimitive(int noCheckPrimitive) {
|
||||
this.noCheckPrimitive = noCheckPrimitive;
|
||||
}
|
||||
|
||||
public String getNoCheckObject() {
|
||||
return noCheckObject;
|
||||
}
|
||||
|
||||
public void setNoCheckObject(String noCheckObject) {
|
||||
this.noCheckObject = noCheckObject;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user