Use presence checks for checking source parameter presence

Instead of explicitly doing a null check use a PresenceCheck mechanism for
* BeanMappingMethod
* ContainerMappingMethod
* MapMappingMethod
This commit is contained in:
Filip Hrisafov 2023-08-01 09:53:58 +02:00
parent b2dc64136d
commit 812faeef51
18 changed files with 216 additions and 43 deletions

View File

@ -46,11 +46,13 @@ import org.mapstruct.ap.internal.model.common.BuilderType;
import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.FormattingParameters;
import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.ParameterBinding;
import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.SourceRHS;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.common.TypeFactory;
import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer; import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer;
import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer.GraphAnalyzerBuilder; import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer.GraphAnalyzerBuilder;
import org.mapstruct.ap.internal.model.presence.NullPresenceCheck;
import org.mapstruct.ap.internal.model.source.BeanMappingOptions; import org.mapstruct.ap.internal.model.source.BeanMappingOptions;
import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.MappingOptions;
import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.Method;
@ -88,6 +90,7 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
private final List<PropertyMapping> propertyMappings; private final List<PropertyMapping> propertyMappings;
private final Map<String, List<PropertyMapping>> mappingsByParameter; private final Map<String, List<PropertyMapping>> mappingsByParameter;
private final Map<String, List<PropertyMapping>> constructorMappingsByParameter; private final Map<String, List<PropertyMapping>> constructorMappingsByParameter;
private final Map<String, PresenceCheck> presenceChecksByParameter;
private final List<PropertyMapping> constantMappings; private final List<PropertyMapping> constantMappings;
private final List<PropertyMapping> constructorConstantMappings; private final List<PropertyMapping> constructorConstantMappings;
private final List<SubclassMapping> subclassMappings; private final List<SubclassMapping> subclassMappings;
@ -1869,11 +1872,19 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
// parameter mapping. // parameter mapping.
this.mappingsByParameter = new HashMap<>(); this.mappingsByParameter = new HashMap<>();
this.constantMappings = new ArrayList<>( propertyMappings.size() ); this.constantMappings = new ArrayList<>( propertyMappings.size() );
this.presenceChecksByParameter = new LinkedHashMap<>();
this.constructorMappingsByParameter = new LinkedHashMap<>(); this.constructorMappingsByParameter = new LinkedHashMap<>();
this.constructorConstantMappings = new ArrayList<>(); this.constructorConstantMappings = new ArrayList<>();
Set<String> sourceParameterNames = getSourceParameters().stream() Set<String> sourceParameterNames = new HashSet<>();
.map( Parameter::getName ) for ( Parameter sourceParameter : getSourceParameters() ) {
.collect( Collectors.toSet() ); sourceParameterNames.add( sourceParameter.getName() );
if ( !sourceParameter.getType().isPrimitive() ) {
presenceChecksByParameter.put(
sourceParameter.getName(),
new NullPresenceCheck( sourceParameter.getName() )
);
}
}
for ( PropertyMapping mapping : propertyMappings ) { for ( PropertyMapping mapping : propertyMappings ) {
if ( mapping.isConstructorMapping() ) { if ( mapping.isConstructorMapping() ) {
if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) {
@ -1984,44 +1995,50 @@ public class BeanMappingMethod extends NormalTypeMappingMethod {
return types; return types;
} }
public List<Parameter> getSourceParametersExcludingPrimitives() { public Collection<PresenceCheck> getSourcePresenceChecks() {
return presenceChecksByParameter.values();
}
public Map<String, PresenceCheck> getPresenceChecksByParameter() {
return presenceChecksByParameter;
}
public PresenceCheck getPresenceCheckByParameter(Parameter parameter) {
return presenceChecksByParameter.get( parameter.getName() );
}
public List<Parameter> getSourceParametersNeedingPresenceCheck() {
return getSourceParameters().stream() return getSourceParameters().stream()
.filter( parameter -> !parameter.getType().isPrimitive() ) .filter( this::needsPresenceCheck )
.collect( Collectors.toList() ); .collect( Collectors.toList() );
} }
public List<Parameter> getSourceParametersNeedingNullCheck() { public List<Parameter> getSourceParametersNotNeedingPresenceCheck() {
return getSourceParameters().stream() return getSourceParameters().stream()
.filter( this::needsNullCheck ) .filter( parameter -> !needsPresenceCheck( parameter ) )
.collect( Collectors.toList() ); .collect( Collectors.toList() );
} }
public List<Parameter> getSourceParametersNotNeedingNullCheck() { private boolean needsPresenceCheck(Parameter parameter) {
return getSourceParameters().stream() if ( !presenceChecksByParameter.containsKey( parameter.getName() ) ) {
.filter( parameter -> !needsNullCheck( parameter ) )
.collect( Collectors.toList() );
}
private boolean needsNullCheck(Parameter parameter) {
if ( parameter.getType().isPrimitive() ) {
return false; return false;
} }
List<PropertyMapping> mappings = propertyMappingsByParameter( parameter ); List<PropertyMapping> mappings = propertyMappingsByParameter( parameter );
if ( mappings.size() == 1 && doesNotNeedNullCheckForSourceParameter( mappings.get( 0 ) ) ) { if ( mappings.size() == 1 && doesNotNeedPresenceCheckForSourceParameter( mappings.get( 0 ) ) ) {
return false; return false;
} }
mappings = constructorPropertyMappingsByParameter( parameter ); mappings = constructorPropertyMappingsByParameter( parameter );
if ( mappings.size() == 1 && doesNotNeedNullCheckForSourceParameter( mappings.get( 0 ) ) ) { if ( mappings.size() == 1 && doesNotNeedPresenceCheckForSourceParameter( mappings.get( 0 ) ) ) {
return false; return false;
} }
return true; return true;
} }
private boolean doesNotNeedNullCheckForSourceParameter(PropertyMapping mapping) { private boolean doesNotNeedPresenceCheckForSourceParameter(PropertyMapping mapping) {
if ( mapping.getAssignment().isCallingUpdateMethod() ) { if ( mapping.getAssignment().isCallingUpdateMethod() ) {
// If the mapping assignment is calling an update method then we should do a null check // If the mapping assignment is calling an update method then we should do a null check
// in the bean mapping // in the bean mapping

View File

@ -12,7 +12,9 @@ import java.util.Set;
import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Assignment;
import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.presence.NullPresenceCheck;
import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.util.Strings;
@ -30,6 +32,8 @@ public abstract class ContainerMappingMethod extends NormalTypeMappingMethod {
private final SelectionParameters selectionParameters; private final SelectionParameters selectionParameters;
private final String index1Name; private final String index1Name;
private final String index2Name; private final String index2Name;
private final Parameter sourceParameter;
private final PresenceCheck sourceParameterPresenceCheck;
private IterableCreation iterableCreation; private IterableCreation iterableCreation;
ContainerMappingMethod(Method method, List<Annotation> annotations, ContainerMappingMethod(Method method, List<Annotation> annotations,
@ -45,16 +49,30 @@ public abstract class ContainerMappingMethod extends NormalTypeMappingMethod {
this.selectionParameters = selectionParameters; this.selectionParameters = selectionParameters;
this.index1Name = Strings.getSafeVariableName( "i", existingVariables ); this.index1Name = Strings.getSafeVariableName( "i", existingVariables );
this.index2Name = Strings.getSafeVariableName( "j", existingVariables ); this.index2Name = Strings.getSafeVariableName( "j", existingVariables );
}
public Parameter getSourceParameter() { Parameter sourceParameter = null;
for ( Parameter parameter : getParameters() ) { for ( Parameter parameter : getParameters() ) {
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
return parameter; sourceParameter = parameter;
break;
} }
} }
throw new IllegalStateException( "Method " + this + " has no source parameter." ); if ( sourceParameter == null ) {
throw new IllegalStateException( "Method " + this + " has no source parameter." );
}
this.sourceParameter = sourceParameter;
this.sourceParameterPresenceCheck = new NullPresenceCheck( this.sourceParameter.getName() );
}
public Parameter getSourceParameter() {
return sourceParameter;
}
public PresenceCheck getSourceParameterPresenceCheck() {
return sourceParameterPresenceCheck;
} }
public IterableCreation getIterableCreation() { public IterableCreation getIterableCreation() {

View File

@ -15,8 +15,10 @@ import org.mapstruct.ap.internal.model.assignment.LocalVarWrapper;
import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Assignment;
import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.FormattingParameters;
import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Parameter;
import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.SourceRHS;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.presence.NullPresenceCheck;
import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.Method;
import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.SelectionParameters;
import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria;
@ -35,6 +37,8 @@ public class MapMappingMethod extends NormalTypeMappingMethod {
private final Assignment keyAssignment; private final Assignment keyAssignment;
private final Assignment valueAssignment; private final Assignment valueAssignment;
private final Parameter sourceParameter;
private final PresenceCheck sourceParameterPresenceCheck;
private IterableCreation iterableCreation; private IterableCreation iterableCreation;
public static class Builder extends AbstractMappingMethodBuilder<Builder, MapMappingMethod> { public static class Builder extends AbstractMappingMethodBuilder<Builder, MapMappingMethod> {
@ -235,16 +239,28 @@ public class MapMappingMethod extends NormalTypeMappingMethod {
this.keyAssignment = keyAssignment; this.keyAssignment = keyAssignment;
this.valueAssignment = valueAssignment; this.valueAssignment = valueAssignment;
} Parameter sourceParameter = null;
public Parameter getSourceParameter() {
for ( Parameter parameter : getParameters() ) { for ( Parameter parameter : getParameters() ) {
if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) {
return parameter; sourceParameter = parameter;
break;
} }
} }
throw new IllegalStateException( "Method " + this + " has no source parameter." ); if ( sourceParameter == null ) {
throw new IllegalStateException( "Method " + this + " has no source parameter." );
}
this.sourceParameter = sourceParameter;
this.sourceParameterPresenceCheck = new NullPresenceCheck( this.sourceParameter.getName() );
}
public Parameter getSourceParameter() {
return sourceParameter;
}
public PresenceCheck getSourceParameterPresenceCheck() {
return sourceParameterPresenceCheck;
} }
public List<Type> getSourceElementTypes() { public List<Type> getSourceElementTypes() {

View File

@ -18,9 +18,15 @@ import org.mapstruct.ap.internal.model.common.Type;
public class MethodReferencePresenceCheck extends ModelElement implements PresenceCheck { public class MethodReferencePresenceCheck extends ModelElement implements PresenceCheck {
protected final MethodReference methodReference; protected final MethodReference methodReference;
protected final boolean negate;
public MethodReferencePresenceCheck(MethodReference methodReference) { public MethodReferencePresenceCheck(MethodReference methodReference) {
this( methodReference, false );
}
public MethodReferencePresenceCheck(MethodReference methodReference, boolean negate) {
this.methodReference = methodReference; this.methodReference = methodReference;
this.negate = negate;
} }
@Override @Override
@ -32,6 +38,15 @@ public class MethodReferencePresenceCheck extends ModelElement implements Presen
return methodReference; return methodReference;
} }
public boolean isNegate() {
return negate;
}
@Override
public PresenceCheck negate() {
return new MethodReferencePresenceCheck( methodReference, true );
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if ( this == o ) { if ( this == o ) {

View File

@ -0,0 +1,52 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.internal.model.common;
import java.util.Objects;
import java.util.Set;
/**
* @author Filip Hrisafov
*/
public class NegatePresenceCheck extends ModelElement implements PresenceCheck {
private final PresenceCheck presenceCheck;
public NegatePresenceCheck(PresenceCheck presenceCheck) {
this.presenceCheck = presenceCheck;
}
public PresenceCheck getPresenceCheck() {
return presenceCheck;
}
@Override
public Set<Type> getImportTypes() {
return presenceCheck.getImportTypes();
}
@Override
public PresenceCheck negate() {
return presenceCheck;
}
@Override
public boolean equals(Object o) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
NegatePresenceCheck that = (NegatePresenceCheck) o;
return Objects.equals( presenceCheck, that.presenceCheck );
}
@Override
public int hashCode() {
return Objects.hash( presenceCheck );
}
}

View File

@ -21,4 +21,6 @@ public interface PresenceCheck {
*/ */
Set<Type> getImportTypes(); Set<Type> getImportTypes();
PresenceCheck negate();
} }

View File

@ -11,6 +11,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.ModelElement;
import org.mapstruct.ap.internal.model.common.NegatePresenceCheck;
import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
@ -29,6 +30,11 @@ public class AllPresenceChecksPresenceCheck extends ModelElement implements Pres
return presenceChecks; return presenceChecks;
} }
@Override
public PresenceCheck negate() {
return new NegatePresenceCheck( this );
}
@Override @Override
public Set<Type> getImportTypes() { public Set<Type> getImportTypes() {
Set<Type> importTypes = new HashSet<>(); Set<Type> importTypes = new HashSet<>();

View File

@ -10,6 +10,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.ModelElement;
import org.mapstruct.ap.internal.model.common.NegatePresenceCheck;
import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
@ -28,6 +29,11 @@ public class JavaExpressionPresenceCheck extends ModelElement implements Presenc
return javaExpression; return javaExpression;
} }
@Override
public PresenceCheck negate() {
return new NegatePresenceCheck( this );
}
@Override @Override
public Set<Type> getImportTypes() { public Set<Type> getImportTypes() {
return Collections.emptySet(); return Collections.emptySet();

View File

@ -19,20 +19,36 @@ import org.mapstruct.ap.internal.model.common.Type;
public class NullPresenceCheck extends ModelElement implements PresenceCheck { public class NullPresenceCheck extends ModelElement implements PresenceCheck {
private final String sourceReference; private final String sourceReference;
private final boolean negate;
public NullPresenceCheck(String sourceReference) { public NullPresenceCheck(String sourceReference) {
this.sourceReference = sourceReference; this.sourceReference = sourceReference;
this.negate = false;
}
public NullPresenceCheck(String sourceReference, boolean negate) {
this.sourceReference = sourceReference;
this.negate = negate;
} }
public String getSourceReference() { public String getSourceReference() {
return sourceReference; return sourceReference;
} }
public boolean isNegate() {
return negate;
}
@Override @Override
public Set<Type> getImportTypes() { public Set<Type> getImportTypes() {
return Collections.emptySet(); return Collections.emptySet();
} }
@Override
public PresenceCheck negate() {
return new NullPresenceCheck( sourceReference, !negate );
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if ( this == o ) { if ( this == o ) {

View File

@ -10,6 +10,7 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.ModelElement;
import org.mapstruct.ap.internal.model.common.NegatePresenceCheck;
import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.PresenceCheck;
import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.Type;
@ -20,10 +21,16 @@ public class SuffixPresenceCheck extends ModelElement implements PresenceCheck {
private final String sourceReference; private final String sourceReference;
private final String suffix; private final String suffix;
private final boolean negate;
public SuffixPresenceCheck(String sourceReference, String suffix) { public SuffixPresenceCheck(String sourceReference, String suffix) {
this( sourceReference, suffix, false );
}
public SuffixPresenceCheck(String sourceReference, String suffix, boolean negate) {
this.sourceReference = sourceReference; this.sourceReference = sourceReference;
this.suffix = suffix; this.suffix = suffix;
this.negate = negate;
} }
public String getSourceReference() { public String getSourceReference() {
@ -34,6 +41,15 @@ public class SuffixPresenceCheck extends ModelElement implements PresenceCheck {
return suffix; return suffix;
} }
public boolean isNegate() {
return negate;
}
@Override
public PresenceCheck negate() {
return new NegatePresenceCheck( this );
}
@Override @Override
public Set<Type> getImportTypes() { public Set<Type> getImportTypes() {
return Collections.emptySet(); return Collections.emptySet();

View File

@ -27,8 +27,8 @@
</#if> </#if>
</#list> </#list>
<#if !mapNullToDefault && !sourceParametersExcludingPrimitives.empty> <#if !mapNullToDefault && !sourcePresenceChecks.empty>
if ( <#list sourceParametersExcludingPrimitives as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && </#if></#list> ) { if ( <#list sourcePresenceChecks as sourcePresenceCheck><@includeModel object=sourcePresenceCheck.negate() /><#if sourcePresenceCheck_has_next> && </#if></#list> ) {
return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#if finalizerMethod??>.<@includeModel object=finalizerMethod /></#if><#else>null</#if></#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#if finalizerMethod??>.<@includeModel object=finalizerMethod /></#if><#else>null</#if></#if>;
} }
</#if> </#if>
@ -47,19 +47,19 @@
<#if !existingInstanceMapping> <#if !existingInstanceMapping>
<#if hasConstructorMappings()> <#if hasConstructorMappings()>
<#if (sourceParameters?size > 1)> <#if (sourceParameters?size > 1)>
<#list sourceParametersNeedingNullCheck as sourceParam> <#list sourceParametersNeedingPresenceCheck as sourceParam>
<#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)> <#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)>
<#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping>
<@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null};
</#list> </#list>
if ( ${sourceParam.name} != null ) { if ( <@includeModel object=getPresenceCheckByParameter(sourceParam) /> ) {
<#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping>
<@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> <@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
</#list> </#list>
} }
</#if> </#if>
</#list> </#list>
<#list sourceParametersNotNeedingNullCheck as sourceParam> <#list sourceParametersNotNeedingPresenceCheck as sourceParam>
<#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)> <#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)>
<#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping>
<@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null};
@ -71,7 +71,7 @@
<#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping> <#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping>
<@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null};
</#list> </#list>
<#if mapNullToDefault>if ( ${sourceParameters[0].name} != null ) {</#if> <#if mapNullToDefault>if ( <@includeModel object=getPresenceCheckByParameter(sourceParameters[0]) /> ) {</#if>
<#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping> <#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping>
<@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> <@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
</#list> </#list>
@ -100,16 +100,16 @@
</#if> </#if>
</#list> </#list>
<#if (sourceParameters?size > 1)> <#if (sourceParameters?size > 1)>
<#list sourceParametersNeedingNullCheck as sourceParam> <#list sourceParametersNeedingPresenceCheck as sourceParam>
<#if (propertyMappingsByParameter(sourceParam)?size > 0)> <#if (propertyMappingsByParameter(sourceParam)?size > 0)>
if ( ${sourceParam.name} != null ) { if ( <@includeModel object=getPresenceCheckByParameter(sourceParam) /> ) {
<#list propertyMappingsByParameter(sourceParam) as propertyMapping> <#list propertyMappingsByParameter(sourceParam) as propertyMapping>
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
</#list> </#list>
} }
</#if> </#if>
</#list> </#list>
<#list sourceParametersNotNeedingNullCheck as sourceParam> <#list sourceParametersNotNeedingPresenceCheck as sourceParam>
<#if (propertyMappingsByParameter(sourceParam)?size > 0)> <#if (propertyMappingsByParameter(sourceParam)?size > 0)>
<#list propertyMappingsByParameter(sourceParam) as propertyMapping> <#list propertyMappingsByParameter(sourceParam) as propertyMapping>
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
@ -117,7 +117,7 @@
</#if> </#if>
</#list> </#list>
<#else> <#else>
<#if mapNullToDefault>if ( ${sourceParameters[0].name} != null ) {</#if> <#if mapNullToDefault>if ( <@includeModel object=getPresenceCheckByParameter(sourceParameters[0]) /> ) {</#if>
<#list propertyMappingsByParameter(sourceParameters[0]) as propertyMapping> <#list propertyMappingsByParameter(sourceParameters[0]) as propertyMapping>
<@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/>
</#list> </#list>

View File

@ -17,7 +17,7 @@
</#if> </#if>
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
<#else> <#else>

View File

@ -17,7 +17,7 @@
</#if> </#if>
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
<#else> <#else>

View File

@ -6,7 +6,7 @@
--> -->
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MethodReferencePresenceCheck" --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MethodReferencePresenceCheck" -->
<@includeModel object=methodReference <#if isNegate()>!</#if><@includeModel object=methodReference
presenceCheck=true presenceCheck=true
targetPropertyName=ext.targetPropertyName targetPropertyName=ext.targetPropertyName
targetType=ext.targetType/> targetType=ext.targetType/>

View File

@ -18,7 +18,7 @@
</#if> </#if>
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
<#else> <#else>

View File

@ -0,0 +1,9 @@
<#--
Copyright MapStruct Authors.
Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
-->
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.NegatePresenceCheck" -->
!( <@includeModel object=presenceCheck /> )

View File

@ -6,4 +6,4 @@
--> -->
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.NullPresenceCheck" --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.NullPresenceCheck" -->
${sourceReference} != null ${sourceReference} <#if isNegate()>==<#else>!=</#if> null

View File

@ -6,4 +6,4 @@
--> -->
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.SuffixPresenceCheck" --> <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.SuffixPresenceCheck" -->
${sourceReference}${suffix} <#if isNegate()>!</#if>${sourceReference}${suffix}