diff --git a/copyright.txt b/copyright.txt
index 4f1c07002..46dc97558 100644
--- a/copyright.txt
+++ b/copyright.txt
@@ -17,6 +17,7 @@ Remko Plantenga
Samuel Wright
Sebastian Hasait
Sjaak Derksen
+Sean Huang
Timo Eckhardt
Tomek Gubala
Vincent Alexander Beelte
diff --git a/core-common/src/main/java/org/mapstruct/Mapper.java b/core-common/src/main/java/org/mapstruct/Mapper.java
index d90636a0e..bbc3f669f 100644
--- a/core-common/src/main/java/org/mapstruct/Mapper.java
+++ b/core-common/src/main/java/org/mapstruct/Mapper.java
@@ -18,14 +18,13 @@
*/
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;
import java.lang.annotation.Target;
import org.mapstruct.factory.Mappers;
+import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION;
/**
* Marks an interface or abstract class as a mapper and activates the generation of a implementation of that type via
@@ -152,10 +151,11 @@ public @interface Mapper {
MappingInheritanceStrategy mappingInheritanceStrategy() default MappingInheritanceStrategy.EXPLICIT;
/**
- * Decide how to do presence check, such as checking null or calling hasX method, before mapping.
+ * Determines when to include a null check on the source property value of a bean mapping.
+ *
* Can be overridden by the one on {@link MapperConfig} or {@link Mapping}.
*
- * @return strategy about how to do null or presence check
+ * @return strategy how to do null checking
*/
- SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL_INLINE;
+ NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION;
}
diff --git a/core-common/src/main/java/org/mapstruct/MapperConfig.java b/core-common/src/main/java/org/mapstruct/MapperConfig.java
index 96e2c93bb..08e710df7 100644
--- a/core-common/src/main/java/org/mapstruct/MapperConfig.java
+++ b/core-common/src/main/java/org/mapstruct/MapperConfig.java
@@ -18,14 +18,13 @@
*/
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;
import java.lang.annotation.Target;
import org.mapstruct.factory.Mappers;
+import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION;
/**
* Marks a class or interface as configuration source for generated mappers. This allows to share common configurations
@@ -139,10 +138,11 @@ public @interface MapperConfig {
default MappingInheritanceStrategy.EXPLICIT;
/**
- * Decide how to do presence check, such as checking null or calling hasXXX method, before mapping.
+ * Determines when to include a null check on the source property value of a bean mapping.
+ *
* Can be overridden by the one on {@link Mapper} or {@link Mapping}.
*
- * @return strategy about how to do null or presence check
+ * @return strategy how to do null checking
*/
- SourceValuePresenceCheckStrategy sourceValuePresenceCheckStrategy() default IS_NULL_INLINE;
+ NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION;
}
diff --git a/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java b/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java
new file mode 100644
index 000000000..9f698633c
--- /dev/null
+++ b/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java
@@ -0,0 +1,61 @@
+/**
+ * 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 for dealing with null source values.
+ *
+ * Note: This strategy is not in effect when the a specific source presence check method is defined
+ * in the service provider interface (SPI).
+ *
+ * @author Sean Huang
+ */
+public enum NullValueCheckStrategy {
+
+ /**
+ * This option includes a null check. When:
+ *
+ *
+ * - a source value is directly assigned to a target
+ * - a source value assigned to a target by calling a type conversion on the target first
+ *
+ *
+ * NOTE: mapping methods (generated or hand written) are excluded from this null check. They are intended to
+ * handle a null source value as 'valid' input.
+ *
+ *//**
+ * This option includes a null check. When:
+ *
+ *
+ * - a source value is directly assigned to a target
+ * - a source value assigned to a target by calling a type conversion on the target first
+ *
+ *
+ * NOTE: mapping methods (generated or hand written) are excluded from this null check. They are intended to
+ * handle a null source value as 'valid' input.
+ *
+ */
+ ON_IMPLICIT_CONVERSION,
+
+ /**
+ * This option always includes a null check.
+ */
+ ALLWAYS,
+
+}
diff --git a/core-jdk8/src/main/java/org/mapstruct/Mapping.java b/core-jdk8/src/main/java/org/mapstruct/Mapping.java
index e02146ace..ff217389c 100644
--- a/core-jdk8/src/main/java/org/mapstruct/Mapping.java
+++ b/core-jdk8/src/main/java/org/mapstruct/Mapping.java
@@ -18,8 +18,6 @@
*/
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;
@@ -193,12 +191,4 @@ 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;
}
diff --git a/core/src/main/java/org/mapstruct/Mapping.java b/core/src/main/java/org/mapstruct/Mapping.java
index 430d5d345..4a902fe70 100644
--- a/core/src/main/java/org/mapstruct/Mapping.java
+++ b/core/src/main/java/org/mapstruct/Mapping.java
@@ -18,8 +18,6 @@
*/
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;
@@ -192,12 +190,4 @@ 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;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java
index 3f7efde85..70298270b 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java
@@ -370,7 +370,7 @@ public class BeanMappingMethod extends MappingMethod {
while ( targetPropertiesIterator.hasNext() ) {
Entry targetProperty = targetPropertiesIterator.next();
- String propertyName = targetProperty.getKey();
+ String targetPropertyName = targetProperty.getKey();
PropertyMapping propertyMapping = null;
@@ -387,10 +387,10 @@ public class BeanMappingMethod extends MappingMethod {
PropertyMapping newPropertyMapping = null;
ExecutableElement sourceReadAccessor =
- sourceParameter.getType().getPropertyReadAccessors().get( propertyName );
+ sourceParameter.getType().getPropertyReadAccessors().get( targetPropertyName );
ExecutableElement sourcePresenceChecker =
- sourceParameter.getType().getPropertyPresenceCheckers().get( propertyName );
+ sourceParameter.getType().getPropertyPresenceCheckers().get( targetPropertyName );
if ( sourceReadAccessor != null ) {
Mapping mapping = method.getSingleMappingByTargetPropertyName( targetProperty.getKey() );
@@ -408,8 +408,8 @@ public class BeanMappingMethod extends MappingMethod {
.mappingContext( ctx )
.sourceMethod( method )
.targetWriteAccessor( targetProperty.getValue() )
- .targetReadAccessor( getTargetPropertyReadAccessor( propertyName ) )
- .targetPropertyName( propertyName )
+ .targetReadAccessor( getTargetPropertyReadAccessor( targetPropertyName ) )
+ .targetPropertyName( targetPropertyName )
.sourceReference( sourceRef )
.formattingParameters( mapping != null ? mapping.getFormattingParameters() : null )
.selectionParameters( mapping != null ? mapping.getSelectionParameters() : null )
@@ -426,7 +426,7 @@ public class BeanMappingMethod extends MappingMethod {
ctx.getMessager().printMessage(
method.getExecutable(),
Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES,
- propertyName
+ targetPropertyName
);
break;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
index e0bc63626..b13753571 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java
@@ -23,6 +23,7 @@ import static org.mapstruct.ap.internal.model.assignment.Assignment.AssignmentTy
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 static org.mapstruct.ap.internal.prism.NullValueCheckStrategy.ALLWAYS;
import java.util.Arrays;
import java.util.Collections;
@@ -52,6 +53,7 @@ import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.model.source.SourceMethod;
import org.mapstruct.ap.internal.model.source.SourceReference;
import org.mapstruct.ap.internal.model.source.SourceReference.PropertyEntry;
+import static org.mapstruct.ap.internal.util.Collections.first;
import org.mapstruct.ap.internal.util.Executables;
import org.mapstruct.ap.internal.util.MapperConfiguration;
import org.mapstruct.ap.internal.util.Message;
@@ -235,23 +237,14 @@ public class PropertyMapping extends ModelElement {
if ( assignment != null ) {
if ( targetType.isCollectionOrMapType() ) {
- assignment = assignCollection( targetType, targetWriteAccessorType, assignment );
+ assignment = assignToCollection( targetType, targetWriteAccessorType, assignment );
}
else if ( targetType.isArrayType() && sourceType.isArrayType() && assignment.getType() == DIRECT ) {
- Type arrayType = ctx.getTypeFactory().getType( Arrays.class );
- assignment = new ArrayCopyWrapper(
- assignment,
- targetPropertyName,
- arrayType,
- targetType,
- existingVariableNames
- );
- assignment = new NullCheckWrapper( assignment );
+ assignment = assignToArray( targetType, assignment );
}
else {
- assignment = assignObject( sourceType, targetType, targetWriteAccessorType, assignment );
+ assignment = assignToPlain( sourceType, targetType, targetWriteAccessorType, assignment );
}
-
}
else {
ctx.getMessager().printMessage(
@@ -278,7 +271,9 @@ public class PropertyMapping extends ModelElement {
}
private Assignment getDefaultValueAssignment() {
- if ( defaultValue != null && !getSourceType().isPrimitive() ) {
+ if ( defaultValue != null
+ && ( !getSourceType().isPrimitive() || getSourcePresenceCheckerRef() != null) ) {
+ // cannot check on null source if source is primitive unless it has a presenche checker
PropertyMapping build = new ConstantMappingBuilder()
.constantExpression( '"' + defaultValue + '"' )
.formattingParameters( formattingParameters )
@@ -296,63 +291,98 @@ public class PropertyMapping extends ModelElement {
return null;
}
- private Assignment assignObject(Type sourceType, Type targetType, TargetWriteAccessorType targetAccessorType,
- Assignment rhs) {
+ private Assignment assignToPlain(Type sourceType, Type targetType, TargetWriteAccessorType targetAccessorType,
+ Assignment rightHandSide) {
- Assignment result = rhs;
+ Assignment result;
if ( targetAccessorType == TargetWriteAccessorType.SETTER ) {
- if ( result.isUpdateMethod() ) {
- if ( targetReadAccessor == null ) {
- ctx.getMessager().printMessage( method.getExecutable(),
- Message.PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE,
- targetPropertyName );
- }
- Assignment factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, targetType, null );
- result = new UpdateWrapper( result, method.getThrownTypes(), factoryMethod,
- targetType );
- }
- else {
- result = new SetterWrapper( result, method.getThrownTypes() );
- }
- if ( !sourceType.isPrimitive()
- && !sourceReference.getPropertyEntries().isEmpty() ) { // parameter null taken care of by beanmapper
-
- if ( result.isUpdateMethod() ) {
- result = new UpdateNullCheckWrapper( result );
- }
- else if ( result.getType() == TYPE_CONVERTED
- || result.getType() == TYPE_CONVERTED_MAPPED
- || result.getType() == MAPPED_TYPE_CONVERTED
- || ( result.getType() == DIRECT && targetType.isPrimitive() ) ) {
- // for primitive types null check is not possible at all, but a conversion needs
- // a null check.
- result = new NullCheckWrapper( result );
- }
- }
+ result = assignToPlainViaSetter( sourceType, targetType, rightHandSide );
}
else {
- // TargetAccessorType must be ADDER
- if ( getSourceType().isCollectionType() ) {
- result = new AdderWrapper(
- result,
- method.getThrownTypes(),
- getSourceRef(),
- sourceType
- );
- result = new NullCheckWrapper( result );
- }
- else {
- // Possibly adding null to a target collection. So should be surrounded by an null check.
- result = new SetterWrapper( result, method.getThrownTypes() );
- result = new NullCheckWrapper( result );
- }
+ result = assignToPlainViaAdder( sourceType, rightHandSide );
}
return result;
}
- private Assignment assignCollection(Type targetType,
+ private Assignment assignToPlainViaSetter(Type sourceType, Type targetType, Assignment rightHandSide) {
+
+ Assignment result;
+
+ if ( rightHandSide.isUpdateMethod() ) {
+ if ( targetReadAccessor == null ) {
+ ctx.getMessager().printMessage( method.getExecutable(),
+ Message.PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE,
+ targetPropertyName );
+ }
+ Assignment factoryMethod = ctx.getMappingResolver().getFactoryMethod( method, targetType, null );
+ result = new UpdateWrapper( rightHandSide, method.getThrownTypes(), factoryMethod,
+ targetType );
+ }
+ else {
+ result = new SetterWrapper( rightHandSide, method.getThrownTypes() );
+ }
+
+ // if the sourceReference is the bean mapping method parameter itself, no null check is required
+ // since this is handled by the BeanMapping
+ if ( sourceReference.getPropertyEntries().isEmpty() ) {
+ return result;
+ }
+
+ // add a null / presence checked when required
+ if ( sourceType.isPrimitive() ) {
+ if ( getSourcePresenceCheckerRef() != null ) {
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ }
+ else {
+
+ if ( result.isUpdateMethod() ) {
+ result = new UpdateNullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ else if ( getSourcePresenceCheckerRef() != null ) {
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ else if ( ALLWAYS.equals( method.getMapperConfiguration().getNullValueCheckStrategy() ) ) {
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ else if ( result.getType() == TYPE_CONVERTED
+ || result.getType() == TYPE_CONVERTED_MAPPED
+ || result.getType() == MAPPED_TYPE_CONVERTED
+ || (result.getType() == DIRECT && targetType.isPrimitive()) ) {
+ // for primitive types null check is not possible at all, but a conversion needs
+ // a null check.
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ }
+
+ return result;
+ }
+
+
+ private Assignment assignToPlainViaAdder(Type sourceType, Assignment rightHandSide) {
+
+ Assignment result = rightHandSide;
+
+ if ( getSourceType().isCollectionType() ) {
+ result = new AdderWrapper(
+ result,
+ method.getThrownTypes(),
+ getSourceRef(),
+ sourceType
+ );
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ else {
+ // Possibly adding null to a target collection. So should be surrounded by an null check.
+ result = new SetterWrapper( result, method.getThrownTypes() );
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
+ }
+ return result;
+ }
+
+ private Assignment assignToCollection(Type targetType,
TargetWriteAccessorType targetAccessorType,
Assignment rhs) {
@@ -419,15 +449,28 @@ public class PropertyMapping extends ModelElement {
// for mapping methods (builtin / custom), the mapping method is responsible for the
// null check. Typeconversions do not apply to collections and maps.
if ( result.getType() == DIRECT ) {
- result = new NullCheckWrapper( result );
+ result = new NullCheckWrapper( result, getSourcePresenceCheckerRef() );
}
else if ( result.getType() == MAPPED && result.isUpdateMethod() ) {
- result = new UpdateNullCheckWrapper( result );
+ result = new UpdateNullCheckWrapper( result, getSourcePresenceCheckerRef() );
}
return result;
}
+ private Assignment assignToArray(Type targetType, Assignment rightHandSide) {
+
+ Type arrayType = ctx.getTypeFactory().getType( Arrays.class );
+ Assignment assignment = new ArrayCopyWrapper(
+ rightHandSide,
+ targetPropertyName,
+ arrayType,
+ targetType,
+ existingVariableNames
+ );
+ return new NullCheckWrapper( assignment, getSourcePresenceCheckerRef() );
+ }
+
private Type getSourceType() {
Parameter sourceParam = sourceReference.getParameter();
@@ -514,6 +557,19 @@ public class PropertyMapping extends ModelElement {
}
}
+ private String getSourcePresenceCheckerRef() {
+ String sourcePresenceChecker = null;
+ if ( !sourceReference.getPropertyEntries().isEmpty() ) {
+ Parameter sourceParam = sourceReference.getParameter();
+ PropertyEntry propertyEntry = first( sourceReference.getPropertyEntries() );
+ if ( propertyEntry.getPresenceChecker() != null ) {
+ sourcePresenceChecker = sourceParam.getName()
+ + "." + propertyEntry.getPresenceChecker().getSimpleName() + "()";
+ }
+ }
+ return sourcePresenceChecker;
+ }
+
private Assignment forgeMapOrIterableMapping(Type sourceType, Type targetType, String sourceReference,
ExecutableElement element) {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.java
index 51a667f4a..003877892 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.java
@@ -25,7 +25,15 @@ package org.mapstruct.ap.internal.model.assignment;
*/
public class NullCheckWrapper extends AssignmentWrapper {
- public NullCheckWrapper( Assignment decoratedAssignment ) {
+ private final String sourcePresenceChecker;
+
+
+ public NullCheckWrapper( Assignment decoratedAssignment, String sourcePresenceChecker ) {
super( decoratedAssignment );
+ this.sourcePresenceChecker = sourcePresenceChecker;
+ }
+
+ public String getSourcePresenceChecker() {
+ return sourcePresenceChecker;
}
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.java
index 491d7ee7a..20ab7ec75 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.java
@@ -26,7 +26,15 @@ package org.mapstruct.ap.internal.model.assignment;
*/
public class UpdateNullCheckWrapper extends AssignmentWrapper {
- public UpdateNullCheckWrapper( Assignment decoratedAssignment ) {
+ private final String sourcePresenceChecker;
+
+ public UpdateNullCheckWrapper( Assignment decoratedAssignment, String sourcePresenceChecker ) {
super( decoratedAssignment );
+ this.sourcePresenceChecker = sourcePresenceChecker;
}
+
+ public String getSourcePresenceChecker() {
+ return sourcePresenceChecker;
+ }
+
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java
index 7f15a6241..471f04346 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java
@@ -38,7 +38,6 @@ 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;
@@ -62,9 +61,6 @@ public class Mapping {
private final boolean isIgnored;
private final List dependsOn;
- private final SourceValuePresenceCheckStrategy valuePresenceCheckStrategy;
- private final boolean isSetValuePresenceCheckStrategy;
-
private final AnnotationMirror mirror;
private final AnnotationValue sourceAnnotationValue;
private final AnnotationValue targetAnnotationValue;
@@ -142,7 +138,6 @@ public class Mapping {
List dependsOn =
mappingPrism.dependsOn() != null ? mappingPrism.dependsOn() : Collections.emptyList();
- boolean isSetValuePresenceCheckStrategy = mappingPrism.values.sourceValuePresenceCheckStrategy() != null;
FormattingParameters formattingParam = new FormattingParameters( dateFormat, numberFormat );
SelectionParameters selectionParams = new SelectionParameters(
@@ -163,9 +158,7 @@ public class Mapping {
formattingParam,
selectionParams,
mappingPrism.values.dependsOn(),
- dependsOn,
- SourceValuePresenceCheckStrategy.valueOf( mappingPrism.sourceValuePresenceCheckStrategy() ),
- isSetValuePresenceCheckStrategy
+ dependsOn
);
}
@@ -174,9 +167,7 @@ public class Mapping {
String defaultValue, boolean isIgnored, AnnotationMirror mirror,
AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue,
FormattingParameters formattingParameters, SelectionParameters selectionParameters,
- AnnotationValue dependsOnAnnotationValue, List dependsOn,
- SourceValuePresenceCheckStrategy valuePresenceCheckStrategy,
- boolean isSetValuePresenceCheckStrategy ) {
+ AnnotationValue dependsOnAnnotationValue, List dependsOn ) {
this.sourceName = sourceName;
this.constant = constant;
this.javaExpression = javaExpression;
@@ -190,8 +181,6 @@ 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,
@@ -292,14 +281,6 @@ 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 );
@@ -348,9 +329,7 @@ public class Mapping {
formattingParameters,
selectionParameters,
dependsOnAnnotationValue,
- Collections.emptyList(),
- valuePresenceCheckStrategy,
- isSetValuePresenceCheckStrategy
+ Collections.emptyList()
);
reverse.init( method, messager, typeFactory );
@@ -377,9 +356,7 @@ public class Mapping {
formattingParameters,
selectionParameters,
dependsOnAnnotationValue,
- dependsOn,
- valuePresenceCheckStrategy,
- isSetValuePresenceCheckStrategy
+ dependsOn
);
if ( sourceReference != null ) {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java
index eb0a9597c..74aa42f4d 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java
@@ -283,7 +283,7 @@ public class SourceReference {
private final Type type;
public PropertyEntry(String name, ExecutableElement readAccessor,
- ExecutableElement presenceChecker, Type type) {
+ ExecutableElement presenceChecker, Type type) {
this.name = name;
this.accessor = readAccessor;
this.presenceChecker = presenceChecker;
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyObject.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java
similarity index 77%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyObject.java
rename to processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java
index 1f035b671..b9917b8f8 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyObject.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategy.java
@@ -16,19 +16,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
+package org.mapstruct.ap.internal.prism;
+
/**
+ * Prism for the enum {@link org.mapstruct.SourceValuePresenceCheckStrategy}
+ *
* @author Sean Huang
*/
-public class MyObject {
- @Override
- public boolean equals(Object object) {
- return this == object;
- }
+public enum NullValueCheckStrategy {
- @Override
- public int hashCode() {
- return super.hashCode();
- }
+ ON_IMPLICIT_CONVERSION,
+ ALLWAYS;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/services/Services.java b/processor/src/main/java/org/mapstruct/ap/internal/services/Services.java
deleted file mode 100644
index d4552e6ea..000000000
--- a/processor/src/main/java/org/mapstruct/ap/internal/services/Services.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * 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.services;
-
-import java.util.ServiceLoader;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-/**
- * A simple locator for SPI implementations.
- *
- * @author Christian Schuster
- */
-public class Services {
-
- private static final ConcurrentMap, Object> SERVICES = new ConcurrentHashMap, Object>();
-
- private Services() {
- }
-
- public static T get(Class serviceType, T defaultValue) {
- @SuppressWarnings("unchecked")
- T service = (T) SERVICES.get( serviceType );
-
- if ( service == null ) {
- service = loadAndCache( serviceType, defaultValue );
- }
-
- return service;
- }
-
- private static T loadAndCache(Class serviceType, T defaultValue) {
- T service = find( serviceType );
- if ( service == null ) {
- service = defaultValue;
- }
-
- @SuppressWarnings("unchecked")
- T cached = (T) SERVICES.putIfAbsent( serviceType, service );
- if ( cached != null ) {
- service = (T) cached;
- }
-
- return service;
- }
-
- private static T find(Class spi) {
- T matchingImplementation = null;
-
- for ( T implementation : ServiceLoader.load( spi, spi.getClassLoader() ) ) {
- if ( matchingImplementation == null ) {
- matchingImplementation = implementation;
- }
- else {
- throw new IllegalStateException(
- "Multiple implementations have been found for the service provider interface "
- + spi.getCanonicalName() + ": " + matchingImplementation.getClass().getCanonicalName() + ", "
- + implementation.getClass().getCanonicalName() + "."
- );
- }
- }
-
- return matchingImplementation;
- }
-}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java
index 14a5d8e5d..ed0ac11f1 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java
@@ -35,11 +35,10 @@ import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
-import org.mapstruct.ap.internal.naming.DefaultAccessorNamingStrategy;
import org.mapstruct.ap.internal.prism.AfterMappingPrism;
import org.mapstruct.ap.internal.prism.BeforeMappingPrism;
-import org.mapstruct.ap.internal.services.Services;
import org.mapstruct.ap.spi.AccessorNamingStrategy;
+import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy;
import org.mapstruct.ap.spi.MethodType;
/**
@@ -63,8 +62,7 @@ public class Executables {
}
private static final AccessorNamingStrategy ACCESSOR_NAMING_STRATEGY = Services.get(
- AccessorNamingStrategy.class,
- new DefaultAccessorNamingStrategy()
+ AccessorNamingStrategy.class, new DefaultAccessorNamingStrategy()
);
private Executables() {
@@ -98,8 +96,8 @@ public class Executables {
return method.getModifiers().contains( Modifier.PUBLIC );
}
- public static String getPropertyName(ExecutableElement getterOrHasserOrSetterMethod) {
- return ACCESSOR_NAMING_STRATEGY.getPropertyName( getterOrHasserOrSetterMethod );
+ public static String getPropertyName(ExecutableElement getterOrPresenceCheckerOrSetterMethod) {
+ return ACCESSOR_NAMING_STRATEGY.getPropertyName( getterOrPresenceCheckerOrSetterMethod );
}
public static boolean isDefaultMethod(ExecutableElement method) {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java b/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
index e4420b02a..5bf917a98 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java
@@ -32,7 +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;
+import org.mapstruct.ap.internal.prism.NullValueCheckStrategy;
/**
* Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and
@@ -136,6 +136,15 @@ public class MapperConfiguration {
}
}
+ public NullValueCheckStrategy getNullValueCheckStrategy() {
+ if ( mapperConfigPrism != null && mapperPrism.values.nullValueCheckStrategy() == null ) {
+ return NullValueCheckStrategy.valueOf( mapperConfigPrism.nullValueCheckStrategy() );
+ }
+ else {
+ return NullValueCheckStrategy.valueOf( mapperPrism.nullValueCheckStrategy() );
+ }
+ }
+
public boolean isMapToDefault(NullValueMappingStrategyPrism mapNullToDefault) {
// check on method level
@@ -185,21 +194,4 @@ public class MapperConfiguration {
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;
- }
- }
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java
new file mode 100644
index 000000000..cc3c98c72
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java
@@ -0,0 +1,51 @@
+/**
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+/**
+ * A simple locator for SPI implementations.
+ *
+ * @author Christian Schuster
+ */
+public class Services {
+
+ private Services() {
+ }
+
+ public static T get(Class serviceType, T defaultValue) {
+
+ Iterator services = ServiceLoader.load( serviceType, Services.class.getClassLoader() ).iterator();
+
+ T result;
+ if ( services.hasNext() ) {
+ result = services.next();
+ }
+ else {
+ result = defaultValue;
+ }
+ if ( services.hasNext() ) {
+ throw new IllegalStateException(
+ "Multiple implementations have been found for the service provider interface" );
+ }
+ return result;
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/naming/DefaultAccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java
similarity index 83%
rename from processor/src/main/java/org/mapstruct/ap/internal/naming/DefaultAccessorNamingStrategy.java
rename to processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java
index c04e703da..c587af52b 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/naming/DefaultAccessorNamingStrategy.java
+++ b/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.internal.naming;
+package org.mapstruct.ap.spi;
import java.beans.Introspector;
@@ -28,8 +28,6 @@ import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleElementVisitor6;
import javax.lang.model.util.SimpleTypeVisitor6;
-import org.mapstruct.ap.spi.AccessorNamingStrategy;
-import org.mapstruct.ap.spi.MethodType;
/**
* The default JavaBeans-compliant implementation of the {@link AccessorNamingStrategy} service provider interface.
@@ -43,9 +41,6 @@ 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;
}
@@ -70,14 +65,6 @@ 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();
@@ -92,8 +79,8 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
@Override
- public String getPropertyName(ExecutableElement getterOrHasserOrSetterMethod) {
- String methodName = getterOrHasserOrSetterMethod.getSimpleName().toString();
+ public String getPropertyName(ExecutableElement getterOrSetterMethod) {
+ String methodName = getterOrSetterMethod.getSimpleName().toString();
return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) );
}
@@ -108,7 +95,7 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy {
return "get" + property.substring( 0, 1 ).toUpperCase() + property.substring( 1 );
}
- private static String getQualifiedName(TypeMirror type) {
+ protected static String getQualifiedName(TypeMirror type) {
DeclaredType declaredType = type.accept(
new SimpleTypeVisitor6() {
@Override
diff --git a/processor/src/main/java/org/mapstruct/ap/spi/PresenceCheckAccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/PresenceCheckAccessorNamingStrategy.java
new file mode 100644
index 000000000..c533292f9
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/spi/PresenceCheckAccessorNamingStrategy.java
@@ -0,0 +1,53 @@
+/**
+ * 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.spi;
+
+
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.type.TypeKind;
+
+/**
+ * The default JavaBeans-compliant implementation of the {@link AccessorNamingStrategy} service provider interface.
+ *
+ * @author Sjaak Derksen
+ */
+public class PresenceCheckAccessorNamingStrategy
+ extends DefaultAccessorNamingStrategy
+ implements AccessorNamingStrategy {
+
+ @Override
+ public MethodType getMethodType(ExecutableElement method) {
+ if ( isPresenceCheckMethod( method ) ) {
+ return MethodType.PRESENCE_CHECKER;
+ }
+ else {
+ return super.getMethodType( method );
+ }
+ }
+
+
+ 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() ) ) );
+ }
+
+}
diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl
index 96e3bfcdc..675b5533f 100644
--- a/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl
+++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl
@@ -23,15 +23,23 @@
if ( ${sourceParameter.name} == null ) {
return ${returnType.null};
}
- <#list propertyEntries as entry>
- <@includeModel object=entry.type/> ${entry.name} = <#if entry_index == 0>${sourceParameter.name}.${entry.accessorName}()<#else>${propertyEntries[entry_index-1].name}.${entry.accessorName}()#if>;
+<#list propertyEntries as entry>
+ <#if entry.presenceChecker?? >
+ if ( !<@localVarName index=entry_index/>.${entry.presenceChecker.simpleName}() ) {
+ return ${returnType.null};
+ }
+ #if>
+ <@includeModel object=entry.type/> ${entry.name} = <@localVarName index=entry_index/>.${entry.accessorName}();
+ <#if !entry.presenceChecker?? >
<#if !entry.type.primitive>
if ( ${entry.name} == null ) {
return ${returnType.null};
}
#if>
+ #if>
<#if !entry_has_next>
return ${entry.name};
#if>
- #list>
+#list>
}
+<#macro localVarName index><#if index == 0>${sourceParameter.name}<#else>${propertyEntries[index-1].name}#if>#macro>
\ No newline at end of file
diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.ftl
index 18336e6ec..c92d8eb29 100644
--- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.ftl
+++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NullCheckWrapper.ftl
@@ -18,7 +18,7 @@
limitations under the License.
-->
-if ( ${sourceReference} != null ) {
+if ( <#if sourcePresenceChecker?? >${sourcePresenceChecker}<#else>${sourceReference} != null#if> ) {
<@includeModel object=assignment
targetBeanName=ext.targetBeanName
existingInstanceMapping=ext.existingInstanceMapping
diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.ftl
index fbd9ad604..067c525e5 100644
--- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.ftl
+++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateNullCheckWrapper.ftl
@@ -18,7 +18,7 @@
limitations under the License.
-->
-if ( ${sourceReference} != null ) {
+if ( <#if sourcePresenceChecker?? >${sourcePresenceChecker}<#else>${sourceReference} != null#if> ) {
<@includeModel object=assignment
targetBeanName=ext.targetBeanName
existingInstanceMapping=ext.existingInstanceMapping
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/PresenceCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/presencecheck/PresenceCheckTest.java
deleted file mode 100644
index 62204c863..000000000
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/PresenceCheckTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/**
- * 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 list = new ArrayList();
- 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 list = new ArrayList();
- 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 list = new ArrayList();
- 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 ) );
- }
- }
-}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceTargetMapper.java
deleted file mode 100644
index 2febd1f0e..000000000
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceTargetMapper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * 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);
- */
-}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/PresenceCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/PresenceCheckTest.java
new file mode 100644
index 000000000..d038491cf
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/PresenceCheckTest.java
@@ -0,0 +1,76 @@
+/**
+ * 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.source.nullvaluecheckstrategy;
+
+
+import static org.fest.assertions.Assertions.assertThat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mapstruct.ap.testutil.WithClasses;
+import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@WithClasses({
+ RockFestivalMapper.class,
+ RockFestivalSource.class,
+ RockFestivalTarget.class,
+ RockFestivalMapperConfig.class,
+ RockFestivalMapperWithConfig.class,
+ RockFestivalMapperOveridingConfig.class,
+ Stage.class
+})
+@RunWith(AnnotationProcessorTestRunner.class)
+public class PresenceCheckTest {
+
+ @Test
+ public void testCallingMappingMethodWithNullSource() {
+
+ RockFestivalSource source = new RockFestivalSource();
+ RockFestivalTarget target = RockFestivalMapper.INSTANCE.map( source );
+ assertThat( target.getStage() ).isNull();
+
+ source.setArtistName( "New Order" );
+ target = RockFestivalMapper.INSTANCE.map( source );
+ assertThat( target.getStage() ).isEqualTo( Stage.THE_BARN );
+
+ }
+
+ @Test
+ public void testCallingMappingMethodWithNullSourceWithConfig() {
+
+ RockFestivalSource source = new RockFestivalSource();
+ RockFestivalTarget target = RockFestivalMapperWithConfig.INSTANCE.map( source );
+ assertThat( target.getStage() ).isNull();
+
+ source.setArtistName( "New Order" );
+ target = RockFestivalMapperWithConfig.INSTANCE.map( source );
+ assertThat( target.getStage() ).isEqualTo( Stage.THE_BARN );
+
+ }
+
+ @Test( expected = IllegalArgumentException.class )
+ public void testCallingMappingMethodWithNullSourceOveridingConfig() {
+
+ RockFestivalSource source = new RockFestivalSource();
+ RockFestivalMapperOveridingConfig.INSTANCE.map( source );
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java
new file mode 100644
index 000000000..cee061e00
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapper.java
@@ -0,0 +1,43 @@
+/**
+ * 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.source.nullvaluecheckstrategy;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.NullValueCheckStrategy;
+import org.mapstruct.factory.Mappers;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@Mapper( nullValueCheckStrategy = NullValueCheckStrategy.ALLWAYS )
+public abstract class RockFestivalMapper {
+
+ public static final RockFestivalMapper INSTANCE = Mappers.getMapper( RockFestivalMapper.class );
+
+ @Mapping( target = "stage", source = "artistName" )
+ public abstract RockFestivalTarget map( RockFestivalSource in );
+
+ public Stage artistToStage( String name ) {
+ return Stage.forArtist( name );
+ }
+
+
+}
diff --git a/core-common/src/main/java/org/mapstruct/SourceValuePresenceCheckStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
similarity index 61%
rename from core-common/src/main/java/org/mapstruct/SourceValuePresenceCheckStrategy.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
index 6bf0092f3..9cb829432 100644
--- a/core-common/src/main/java/org/mapstruct/SourceValuePresenceCheckStrategy.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperConfig.java
@@ -16,30 +16,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct;
+package org.mapstruct.ap.test.source.nullvaluecheckstrategy;
+import org.mapstruct.MapperConfig;
+import org.mapstruct.NullValueCheckStrategy;
/**
- * Strategy to decide how to check null or hasX method before mapping
*
- * @author Sean Huang
+ * @author Sjaak Derksen
*/
-public enum SourceValuePresenceCheckStrategy {
+@MapperConfig( nullValueCheckStrategy = NullValueCheckStrategy.ALLWAYS )
+public interface RockFestivalMapperConfig {
- /**
- * 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;
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperOveridingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperOveridingConfig.java
new file mode 100644
index 000000000..18d3f5811
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperOveridingConfig.java
@@ -0,0 +1,44 @@
+/**
+ * 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.source.nullvaluecheckstrategy;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
+import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+@Mapper( config = RockFestivalMapperConfig.class, nullValueCheckStrategy = ON_IMPLICIT_CONVERSION )
+public abstract class RockFestivalMapperOveridingConfig {
+
+ public static final RockFestivalMapperOveridingConfig INSTANCE =
+ Mappers.getMapper( RockFestivalMapperOveridingConfig.class );
+
+ @Mapping( target = "stage", source = "artistName" )
+ public abstract RockFestivalTarget map( RockFestivalSource in );
+
+ public Stage artistToStage( String name ) {
+ return Stage.forArtist( name );
+ }
+
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/TargetWtCheck.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperWithConfig.java
similarity index 56%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/TargetWtCheck.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperWithConfig.java
index c644e221d..e6921c3ad 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/TargetWtCheck.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalMapperWithConfig.java
@@ -16,30 +16,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
+package org.mapstruct.ap.test.source.nullvaluecheckstrategy;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.factory.Mappers;
/**
- * @author Sean Huang
+ *
+ * @author Sjaak Derksen
*/
-public class TargetWtCheck extends Target {
+@Mapper( config = RockFestivalMapperConfig.class )
+public abstract class RockFestivalMapperWithConfig {
- private int noCheckPrimitive;
- private String noCheckObject;
+ public static final RockFestivalMapperWithConfig INSTANCE =
+ Mappers.getMapper( RockFestivalMapperWithConfig.class );
- public int getNoCheckPrimitive() {
- return noCheckPrimitive;
+ @Mapping( target = "stage", source = "artistName" )
+ public abstract RockFestivalTarget map( RockFestivalSource in );
+
+ public Stage artistToStage( String name ) {
+ return Stage.forArtist( name );
}
- public void setNoCheckPrimitive(int noCheckPrimitive) {
- this.noCheckPrimitive = noCheckPrimitive;
- }
- public String getNoCheckObject() {
- return noCheckObject;
- }
-
- public void setNoCheckObject(String noCheckObject) {
- this.noCheckObject = noCheckObject;
- }
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/CustomMapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalSource.java
similarity index 64%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/CustomMapper.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalSource.java
index 33b5fd04c..0cc04c9ac 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/CustomMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalSource.java
@@ -16,20 +16,22 @@
* 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;
+package org.mapstruct.ap.test.source.nullvaluecheckstrategy;
/**
- * @author Sean Huang
+ *
+ * @author Sjaak Derksen
*/
-@Mapper( sourceValuePresenceCheckStrategy = SourceValuePresenceCheckStrategy.IS_NULL_INLINE )
-public class CustomMapper {
+public class RockFestivalSource {
- public MyLongWrapper toMyLongWrapperViaPrimitive(Long primitive) {
- MyLongWrapper wrapper = new MyLongWrapper();
- wrapper.setMyLong( primitive );
- return wrapper;
+ private String artistName;
+
+ public String getArtistName() {
+ return artistName;
}
+
+ public void setArtistName(String artistName) {
+ this.artistName = artistName;
+ }
+
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyLongWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalTarget.java
similarity index 77%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyLongWrapper.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalTarget.java
index 8e28a9e7d..4638036f1 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/MyLongWrapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/RockFestivalTarget.java
@@ -16,23 +16,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
-
+package org.mapstruct.ap.test.source.nullvaluecheckstrategy;
/**
+ *
* @author Sjaak Derksen
*/
-public class MyLongWrapper {
+public class RockFestivalTarget {
- private Long myLong;
+ private Stage stage;
- public Long getMyLong() {
- return myLong;
+ public Stage getStage() {
+ return stage;
}
- public void setMyLong(Long myLong) {
- myLong.longValue();
- this.myLong = myLong;
+ public void setStage(Stage stage) {
+ this.stage = stage;
}
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/Stage.java b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/Stage.java
new file mode 100644
index 000000000..686a89daf
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/nullvaluecheckstrategy/Stage.java
@@ -0,0 +1,53 @@
+/**
+ * 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.source.nullvaluecheckstrategy;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ *
+ * @author Sjaak Derksen
+ */
+public enum Stage {
+
+ MAIN("Paul McCartney", "Ellie Goulding", "Disclosure", "Kaiser Chiefs", "Rammstein"),
+ KLUB_C("James Blake", "Lost Frequencies"),
+ THE_BARN("New Order", "Year and Years");
+
+ private final List artists;
+
+ Stage(String... artist) {
+ this.artists = Arrays.asList( artist );
+ }
+
+ public static Stage forArtist( String name ) {
+
+ if ( name == null ) {
+ throw new IllegalArgumentException();
+ }
+
+ for ( Stage value : Stage.values() ) {
+ if ( value.artists.contains( name ) ) {
+ return value;
+ }
+ }
+ return null;
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceWtCheck.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/GoalKeeper.java
similarity index 61%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceWtCheck.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/GoalKeeper.java
index f21de82ff..1b08ecdb4 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/SourceWtCheck.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/GoalKeeper.java
@@ -16,30 +16,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
-
+package org.mapstruct.ap.test.source.presencecheck.spi;
/**
- * @author Sean Huang
+ *
+ * @author Sjaak Derksen
*/
-public class SourceWtCheck extends Source {
+public class GoalKeeper {
- private int noCheckPrimitive;
- private String noCheckObject;
+ private String name;
+ private boolean hasName = true;
- public int getNoCheckPrimitive() {
- return noCheckPrimitive;
+ public String getName() {
+ return name;
}
- public void setNoCheckPrimitive(int noCheckPrimitive) {
- this.noCheckPrimitive = noCheckPrimitive;
+ public void setName(String name) {
+ this.name = name;
}
- public String getNoCheckObject() {
- return noCheckObject;
+ public boolean hasName() {
+ return hasName;
}
- public void setNoCheckObject(String noCheckObject) {
- this.noCheckObject = noCheckObject;
+ public void setHasName(boolean hasName) {
+ this.hasName = hasName;
}
+
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/PresenceCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/PresenceCheckTest.java
new file mode 100644
index 000000000..2b4a25e1d
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/PresenceCheckTest.java
@@ -0,0 +1,217 @@
+/**
+ * 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.source.presencecheck.spi;
+
+import java.util.Arrays;
+import static org.fest.assertions.Assertions.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mapstruct.ap.spi.PresenceCheckAccessorNamingStrategy;
+import org.mapstruct.ap.testutil.WithClasses;
+import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
+import org.mapstruct.ap.testutil.WithServiceImplementation;
+
+/**
+ * Test for correct handling of source presence checks.
+ *
+ * @author Sean Huang
+ */
+@WithClasses({
+ SourceTargetMapper.class,
+ Source.class,
+ Target.class,
+ SoccerTeamMapper.class,
+ SoccerTeamSource.class,
+ GoalKeeper.class,
+ SoccerTeamTarget.class
+})
+@WithServiceImplementation( PresenceCheckAccessorNamingStrategy.class )
+@RunWith(AnnotationProcessorTestRunner.class)
+public class PresenceCheckTest {
+
+ @Test
+ public void testWithSourcesPresent() {
+
+ Source source = new Source();
+
+ source.setSomePrimitiveDouble( 5.0 );
+ source.setSomeInteger( 7 );
+ source.setSomeList( Arrays.asList( "first", "second" ) );
+ source.setSomeArray( new String[]{ "x", "y" } );
+
+ Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 5.0 );
+ assertThat( target.getSomeInteger() ).isEqualTo( 7 );
+ assertThat( target.getSomeList() ).containsExactly( "first", "second" );
+ assertThat( target.getSomeArray() ).isEqualTo( new String[]{ "x", "y"} );
+ }
+
+ @Test
+ public void testWithSourcesAbsent() {
+
+ Source source = new Source();
+
+ source.setHasSomePrimitiveDouble( false );
+ source.setHasSomeInteger( false );
+ source.setHasSomeList( false );
+ source.setHasSomeArray( false );
+
+ Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 0d );
+ assertThat( target.getSomeInteger() ).isNull();
+ assertThat( target.getSomeList() ).isNull();
+ assertThat( target.getSomeArray() ).isNull();
+ }
+
+ @Test
+ public void testUpdateMethodWithSourcesPresent() {
+
+ Source source = new Source();
+
+ source.setSomePrimitiveDouble( 5.0 );
+ source.setSomeInteger( 7 );
+ source.setSomeList( Arrays.asList( "first", "second" ) );
+ source.setSomeArray( new String[]{ "x", "y" } );
+
+ Target target = new Target();
+ SourceTargetMapper.INSTANCE.sourceToTarget( source, target );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 5.0 );
+ assertThat( target.getSomeInteger() ).isEqualTo( 7 );
+ assertThat( target.getSomeList() ).containsExactly( "first", "second" );
+ assertThat( target.getSomeArray() ).isEqualTo( new String[]{ "x", "y"} );
+ }
+
+ @Test
+ public void testUpdateMethodWithSourcesAbsent() {
+
+ Source source = new Source();
+
+ source.setHasSomePrimitiveDouble( false );
+ source.setHasSomeInteger( false );
+ source.setHasSomeList( false );
+ source.setHasSomeArray( false );
+
+ Target target = new Target();
+ SourceTargetMapper.INSTANCE.sourceToTarget( source, target );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 0d );
+ assertThat( target.getSomeInteger() ).isNull();
+ assertThat( target.getSomeList() ).isNull();
+ assertThat( target.getSomeArray() ).isNull();
+ }
+
+ @Test
+ public void testWithSourcesPresentAndDefault() {
+
+ Source source = new Source();
+
+ source.setSomePrimitiveDouble( 5.0 );
+ source.setSomeInteger( 7 );
+ source.setSomeList( Arrays.asList( "first", "second" ) );
+ source.setSomeArray( new String[]{ "x", "y" } );
+
+ Target target = SourceTargetMapper.INSTANCE.sourceToTargetWitDefaults( source );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 5.0 );
+ assertThat( target.getSomeInteger() ).isEqualTo( 7 );
+ assertThat( target.getSomeList() ).containsExactly( "first", "second" );
+ assertThat( target.getSomeArray() ).isEqualTo( new String[]{ "x", "y"} );
+ }
+
+ @Test
+ public void testWithSourcesAbsentAndDefault() {
+
+ Source source = new Source();
+
+ source.setHasSomePrimitiveDouble( false );
+ source.setHasSomeInteger( false );
+ source.setHasSomeList( false );
+ source.setHasSomeArray( false );
+
+ Target target = SourceTargetMapper.INSTANCE.sourceToTargetWitDefaults( source );
+
+ assertThat( target.getSomePrimitiveDouble() ).isEqualTo( 111.1d );
+ assertThat( target.getSomeInteger() ).isEqualTo( 222 );
+ assertThat( target.getSomeList() ).containsExactly( "a", "b" );
+ assertThat( target.getSomeArray() ).isEqualTo( new String[]{ "u", "v"} );
+ }
+
+ @Test
+ public void testAdderWithSourcesPresent() {
+
+ SoccerTeamSource soccerTeamSource = new SoccerTeamSource();
+ soccerTeamSource.setPlayers( Arrays.asList( "pele", "cruyf" ) );
+
+ SoccerTeamTarget target = SoccerTeamMapper.INSTANCE.mapAdder( soccerTeamSource );
+
+ assertThat( target.getPlayers() ).containsExactly( "pele", "cruyf" );
+ }
+
+ @Test
+ public void testAdderWithSourcesAbsent() {
+
+ SoccerTeamSource soccerTeamSource = new SoccerTeamSource();
+ soccerTeamSource.setHasPlayers( false );
+
+ SoccerTeamTarget target = SoccerTeamMapper.INSTANCE.mapAdder( soccerTeamSource );
+
+ assertThat( target.getPlayers() ).isNull();
+ }
+
+ @Test
+ public void testNestedWithSourcesPresent() {
+
+ SoccerTeamSource soccerTeamSource = new SoccerTeamSource();
+ GoalKeeper goalKeeper = new GoalKeeper();
+ goalKeeper.setName( "Buffon" );
+ soccerTeamSource.setGoalKeeper( goalKeeper );
+
+ SoccerTeamTarget target = SoccerTeamMapper.INSTANCE.mapNested( soccerTeamSource );
+
+ assertThat( target.getGoalKeeperName() ).isEqualTo( "Buffon" );
+ }
+
+ @Test
+ public void testNestedWithSourcesAbsentOnRootLevel() {
+
+ SoccerTeamSource soccerTeamSource = new SoccerTeamSource();
+ soccerTeamSource.setHasGoalKeeper( false );
+
+ SoccerTeamTarget target = SoccerTeamMapper.INSTANCE.mapNested( soccerTeamSource );
+
+ assertThat( target.getGoalKeeperName() ).isNull();
+ }
+
+ @Test
+ public void testNestedWithSourcesAbsentOnNestingLevel() {
+
+ SoccerTeamSource soccerTeamSource = new SoccerTeamSource();
+ GoalKeeper goalKeeper = new GoalKeeper();
+ goalKeeper.setHasName( false );
+ soccerTeamSource.setGoalKeeper( goalKeeper );
+
+ SoccerTeamTarget target = SoccerTeamMapper.INSTANCE.mapNested( soccerTeamSource );
+
+ assertThat( target.getGoalKeeperName() ).isNull();
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/SourceValuePresenceCheckStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamMapper.java
similarity index 51%
rename from processor/src/main/java/org/mapstruct/ap/internal/prism/SourceValuePresenceCheckStrategy.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamMapper.java
index 5f2425d89..e1b906c2c 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/prism/SourceValuePresenceCheckStrategy.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamMapper.java
@@ -16,30 +16,31 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.internal.prism;
+package org.mapstruct.ap.test.source.presencecheck.spi;
+import org.mapstruct.CollectionMappingStrategy;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
/**
- * Prism for the enum {@link org.mapstruct.SourceValuePresenceCheckStrategy}
*
- * @author Sean Huang
+ * @author Sjaak Derksen
*/
-public enum SourceValuePresenceCheckStrategy {
- /**
- * Only check != null for inline conversions
- *
- */
- IS_NULL_INLINE,
+@Mapper( collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED )
+public interface SoccerTeamMapper {
- /**
- * Always check != null, no matter whether it's an inline or method conversion
- *
- */
- IS_NULL,
+ SoccerTeamMapper INSTANCE = Mappers.getMapper( SoccerTeamMapper.class );
+
+ @Mapping( target = "goalKeeperName", ignore = true )
+ SoccerTeamTarget mapAdder( SoccerTeamSource in );
+
+
+ @Mappings({
+ @Mapping(target = "players", ignore = true),
+ @Mapping(target = "goalKeeperName", source = "goalKeeper.name")
+ })
+ SoccerTeamTarget mapNested( SoccerTeamSource in );
- /**
- * Will invoke custom hasX() method, before mapping,
- * name to be given through the accessor naming strategy
- */
- CUSTOM;
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamSource.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamSource.java
new file mode 100644
index 000000000..a7e794293
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamSource.java
@@ -0,0 +1,66 @@
+/**
+ * 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.source.presencecheck.spi;
+
+import java.util.List;
+
+/**
+ * @author Sjaak Derksen
+ */
+public class SoccerTeamSource {
+
+ private List players;
+ private boolean hasPlayers = true;
+
+ private GoalKeeper goalKeeper;
+ private boolean hasGoalKeeper = true;
+
+ public boolean hasPlayers() {
+ return hasPlayers;
+ }
+
+ public void setHasPlayers(boolean has) {
+ this.hasPlayers = has;
+ }
+
+ public List getPlayers() {
+ return players;
+ }
+
+ public void setPlayers(List players) {
+ this.players = players;
+ }
+
+ public GoalKeeper getGoalKeeper() {
+ return goalKeeper;
+ }
+
+ public void setGoalKeeper(GoalKeeper goalKeeper) {
+ this.goalKeeper = goalKeeper;
+ }
+
+ public boolean hasGoalKeeper() {
+ return hasGoalKeeper;
+ }
+
+ public void setHasGoalKeeper(boolean hasGoalKeeper) {
+ this.hasGoalKeeper = hasGoalKeeper;
+ }
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamTarget.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamTarget.java
new file mode 100644
index 000000000..2ecb92d4e
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SoccerTeamTarget.java
@@ -0,0 +1,52 @@
+/**
+ * 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.source.presencecheck.spi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Sjaak Derksen
+ */
+public class SoccerTeamTarget {
+
+ private List players;
+ private String goalKeeperName;
+
+
+ public List getPlayers() {
+ return players;
+ }
+
+ public void addPlayer(String player) {
+ if ( this.players == null ) {
+ this.players = new ArrayList();
+ }
+ this.players.add( player );
+ }
+
+ public String getGoalKeeperName() {
+ return goalKeeperName;
+ }
+
+ public void setGoalKeeperName(String goalKeeperName) {
+ this.goalKeeperName = goalKeeperName;
+ }
+
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/Source.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Source.java
similarity index 64%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/Source.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Source.java
index 00e52ef03..34f325afb 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/Source.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Source.java
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
+package org.mapstruct.ap.test.source.presencecheck.spi;
import java.util.List;
@@ -25,39 +25,17 @@ import java.util.List;
*/
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 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;
- }
+ private String[] someArray;
+ private boolean hasSomeArray = true;
public boolean hasSomePrimitiveDouble() {
return hasPrimitiveSomeDouble;
@@ -91,38 +69,6 @@ public class Source {
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;
}
@@ -138,4 +84,21 @@ public class Source {
public void setSomeList(List someList) {
this.someList = someList;
}
+
+ public String[] getSomeArray() {
+ return someArray;
+ }
+
+ public void setSomeArray(String[] someArray) {
+ this.someArray = someArray;
+ }
+
+ public boolean hasSomeArray() {
+ return hasSomeArray;
+ }
+
+ public void setHasSomeArray(boolean hasSomeArray) {
+ this.hasSomeArray = hasSomeArray;
+ }
+
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SourceTargetMapper.java
new file mode 100644
index 000000000..c6d933079
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/SourceTargetMapper.java
@@ -0,0 +1,59 @@
+/**
+ * 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.source.presencecheck.spi;
+
+import java.util.Arrays;
+import java.util.List;
+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
+public abstract class SourceTargetMapper {
+
+ public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
+
+ //@Mapping( target = "someInteger2", source = "someNested.someInteger2" )
+ abstract Target sourceToTarget(Source source);
+
+ abstract void sourceToTarget(Source source, @MappingTarget Target target);
+
+ @Mappings( {
+ @Mapping(target = "somePrimitiveDouble", defaultValue = "111.1"),
+ @Mapping(target = "someInteger", defaultValue = "222"),
+ @Mapping(target = "someList", defaultValue = "a,b"),
+ @Mapping(target = "someArray", defaultValue = "u,v")
+ } )
+ abstract Target sourceToTargetWitDefaults(Source source);
+
+
+ protected List toList( String in ) {
+ return Arrays.asList( in.split( "," ) );
+ }
+
+ protected String[] toArray( String in ) {
+ return in.split( "," );
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/Target.java b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Target.java
similarity index 70%
rename from processor/src/test/java/org/mapstruct/ap/test/presencecheck/Target.java
rename to processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Target.java
index 9d54e6d42..2a2ccaab5 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/presencecheck/Target.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/source/presencecheck/spi/Target.java
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.presencecheck;
+package org.mapstruct.ap.test.source.presencecheck.spi;
import java.util.List;
@@ -25,20 +25,10 @@ import java.util.List;
*/
public class Target {
- private MyObject someObject;
private double somePrimitiveDouble;
private Integer someInteger;
- private MyLongWrapper someLong1;
- private MyLongWrapper someLong2;
private List someList;
-
- public MyObject getSomeObject() {
- return someObject;
- }
-
- public void setSomeObject(MyObject someObject) {
- this.someObject = someObject;
- }
+ private String[] someArray;
public double getSomePrimitiveDouble() {
return somePrimitiveDouble;
@@ -56,22 +46,6 @@ public class Target {
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 getSomeList() {
return someList;
}
@@ -79,4 +53,13 @@ public class Target {
public void setSomeList(List someList) {
this.someList = someList;
}
+
+ public String[] getSomeArray() {
+ return someArray;
+ }
+
+ public void setSomeArray(String[] someArray) {
+ this.someArray = someArray;
+ }
+
}