mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#996 refactor ArrayCopyWrapper
This commit is contained in:
parent
fc0f13a7a1
commit
1f0533ca94
@ -151,17 +151,7 @@ public class MapMappingMethod extends MappingMethod {
|
||||
}
|
||||
|
||||
if ( valueAssignment == null ) {
|
||||
|
||||
valueAssignment = forgeMapping( valueSourceRHS, valueSourceType, valueTargetType );
|
||||
|
||||
// if ( method instanceof ForgedMethod ) {
|
||||
// // leave messaging to calling property mapping
|
||||
// return null;
|
||||
// }
|
||||
// else {
|
||||
// ctx.getMessager().printMessage( method.getExecutable(),
|
||||
// Message.MAPMAPPING_VALUE_MAPPING_NOT_FOUND );
|
||||
// }
|
||||
}
|
||||
|
||||
// mapNullToDefault
|
||||
|
@ -37,7 +37,6 @@ import org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.Assignment;
|
||||
import org.mapstruct.ap.internal.model.assignment.EnumConstantWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps;
|
||||
import org.mapstruct.ap.internal.model.assignment.NullCheckWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.SetterWrapper;
|
||||
import org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMaps;
|
||||
import org.mapstruct.ap.internal.model.assignment.UpdateWrapper;
|
||||
@ -435,10 +434,9 @@ public class PropertyMapping extends ModelElement {
|
||||
targetPropertyName,
|
||||
arrayType,
|
||||
targetType,
|
||||
existingVariableNames,
|
||||
isFieldAssignment()
|
||||
);
|
||||
return new NullCheckWrapper( assignment );
|
||||
return assignment;
|
||||
}
|
||||
|
||||
private SourceRHS getSourceRHS( SourceReference sourceReference ) {
|
||||
|
@ -18,16 +18,10 @@
|
||||
*/
|
||||
package org.mapstruct.ap.internal.model.assignment;
|
||||
|
||||
import static org.mapstruct.ap.internal.util.Strings.decapitalize;
|
||||
import static org.mapstruct.ap.internal.util.Strings.getSaveVariableName;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.mapstruct.ap.internal.model.common.Type;
|
||||
import org.mapstruct.ap.internal.util.Strings;
|
||||
|
||||
/**
|
||||
* Decorates the assignment as a Map or Collection constructor
|
||||
@ -36,16 +30,18 @@ import org.mapstruct.ap.internal.util.Strings;
|
||||
*/
|
||||
public class ArrayCopyWrapper extends AssignmentWrapper {
|
||||
|
||||
private final String targetPropertyName;
|
||||
private final Type arraysType;
|
||||
private final Type targetType;
|
||||
|
||||
public ArrayCopyWrapper(Assignment decoratedAssignment, String targetPropertyName, Type arraysType,
|
||||
Type targetType, Collection<String> existingVariableNames, boolean fieldAssignment) {
|
||||
super( decoratedAssignment, fieldAssignment );
|
||||
this.targetPropertyName = Strings.getSaveVariableName( targetPropertyName, existingVariableNames );
|
||||
public ArrayCopyWrapper(Assignment rhs,
|
||||
String targetPropertyName,
|
||||
Type arraysType,
|
||||
Type targetType,
|
||||
boolean fieldAssignment) {
|
||||
super( rhs, fieldAssignment );
|
||||
this.arraysType = arraysType;
|
||||
this.targetType = targetType;
|
||||
rhs.setSourceLocalVarName( rhs.createLocalVarName( targetPropertyName ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -57,7 +53,7 @@ public class ArrayCopyWrapper extends AssignmentWrapper {
|
||||
return imported;
|
||||
}
|
||||
|
||||
public String getLocalVarName() {
|
||||
return getSaveVariableName( decapitalize( targetPropertyName ), Collections.<String>emptyList() );
|
||||
public boolean isIncludeSourceNullCheck() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -109,17 +109,18 @@ public interface Assignment {
|
||||
Type getSourceType();
|
||||
|
||||
/**
|
||||
* safe (local) element variable name when dealing with collections.
|
||||
* Creates an unique safe (local) variable name.
|
||||
*
|
||||
* @param desiredName the desired name
|
||||
* @return the desired name, made unique
|
||||
*
|
||||
* @return the desired name, made unique in the scope of the bean mapping.
|
||||
*/
|
||||
String createLocalVarName( String desiredName );
|
||||
|
||||
/**
|
||||
* a local variable name for supporting a null check and avoiding executing a nested method forged method twice
|
||||
* See {@link #setSourceLocalVarName(java.lang.String) }
|
||||
*
|
||||
* @return local variable name (can be null)
|
||||
* @return local variable name (can be null if not set)
|
||||
*/
|
||||
String getSourceLocalVarName();
|
||||
|
||||
@ -132,7 +133,9 @@ public interface Assignment {
|
||||
String getSourceParameterName();
|
||||
|
||||
/**
|
||||
* Use sourceLocalVarName iso sourceReference
|
||||
* Replaces the sourceReference at the call site in the assignment in the template with this sourceLocalVarName.
|
||||
* The sourceLocalVarName can subsequently be used for e.g. null checking.
|
||||
*
|
||||
* @param sourceLocalVarName source local variable name
|
||||
*/
|
||||
void setSourceLocalVarName(String sourceLocalVarName);
|
||||
|
@ -1,32 +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.model.assignment;
|
||||
|
||||
/**
|
||||
* Wraps the assignment in a null check.
|
||||
*
|
||||
* @author Sjaak Derksen
|
||||
*/
|
||||
public class NullCheckWrapper extends AssignmentWrapper {
|
||||
|
||||
public NullCheckWrapper( Assignment decoratedAssignment ) {
|
||||
super( decoratedAssignment, false );
|
||||
}
|
||||
|
||||
}
|
@ -1,33 +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.model.assignment;
|
||||
|
||||
/**
|
||||
* Wraps an update-assignment in a null check and sets the target property to {@code null}, if the source is
|
||||
* {@code null}.
|
||||
*
|
||||
* @author Andreas Gudian
|
||||
*/
|
||||
public class UpdateNullCheckWrapper extends AssignmentWrapper {
|
||||
|
||||
public UpdateNullCheckWrapper(Assignment decoratedAssignment, boolean fieldAssignment) {
|
||||
super( decoratedAssignment, fieldAssignment );
|
||||
}
|
||||
|
||||
}
|
@ -19,25 +19,9 @@
|
||||
|
||||
-->
|
||||
<#import "../macro/CommonMacros.ftl" as lib>
|
||||
<#if (thrownTypes?size == 0) >
|
||||
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>Arrays.copyOf( ${localVarName}, ${localVarName}.length )</@lib.handleWrite>;
|
||||
<#else>
|
||||
try {
|
||||
<@includeModel object=ext.targetType/> ${localVarName} = <@_assignment/>;
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>Arrays.copyOf(>Arrays.copyOf( ${localVarName}, ${localVarName}.length )</@lib.handleWrite>;
|
||||
}
|
||||
<#list thrownTypes as exceptionType>
|
||||
catch ( <@includeModel object=exceptionType/> e ) {
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
</#list>
|
||||
</#if>
|
||||
<#macro _assignment>
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
</#macro>
|
||||
<@lib.handleExceptions>
|
||||
<@lib.sourceLocalVarAssignment/>
|
||||
<@lib.handleSourceReferenceNullCheck>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>Arrays.copyOf( ${sourceLocalVarName}, ${sourceLocalVarName}.length )</@lib.handleWrite>;
|
||||
</@lib.handleSourceReferenceNullCheck>
|
||||
</@lib.handleExceptions>
|
@ -25,8 +25,8 @@ if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesi
|
||||
<#if ext.existingInstanceMapping>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear();
|
||||
</#if>
|
||||
<@lib.handleNullCheck>
|
||||
<@lib.handleLocalVarNullCheck>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.<#if ext.targetType.collectionType>addAll<#else>putAll</#if>( ${nullCheckLocalVarName} );
|
||||
</@lib.handleNullCheck>
|
||||
</@lib.handleLocalVarNullCheck>
|
||||
</@lib.handleExceptions>
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.NullCheckWrapper" -->
|
||||
<#--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<#if sourceLocalVarName??>
|
||||
<@includeModel object=sourceType/> ${sourceLocalVarName} = ${sourceReference};
|
||||
if ( ${sourceLocalVarName} != null ) {
|
||||
<@_assignment object=assignment defaultValue=ext.defaultValueAssignment/>
|
||||
}
|
||||
<#else>
|
||||
if ( <#if sourcePresenceCheckerReference?? >${sourcePresenceCheckerReference}<#else>${sourceReference} != null</#if> ) {
|
||||
<@_assignment object=assignment defaultValue=ext.defaultValueAssignment/>
|
||||
}
|
||||
</#if>
|
||||
<#if ext.defaultValueAssignment?? >
|
||||
else {
|
||||
<@_assignment object=ext.defaultValueAssignment/>
|
||||
}
|
||||
</#if>
|
||||
<#macro _assignment object defaultValue="">
|
||||
<@includeModel object=object
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType
|
||||
defaultValue=defaultValue/>
|
||||
</#macro>
|
@ -21,31 +21,7 @@
|
||||
<#import "../macro/CommonMacros.ftl" as lib>
|
||||
<@lib.handleExceptions>
|
||||
<@lib.sourceLocalVarAssignment/>
|
||||
<#if sourcePresenceCheckerReference??>
|
||||
if ( ${sourcePresenceCheckerReference} ) {
|
||||
<@assignment/>;
|
||||
}
|
||||
<@elseDefaultAssignment/>
|
||||
<#elseif includeSourceNullCheck || ext.defaultValueAssignment??>
|
||||
if ( <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference}</#if> != null ) {
|
||||
<@assignment/>;
|
||||
}
|
||||
<@elseDefaultAssignment/>
|
||||
<#else>
|
||||
<@assignment/>;
|
||||
</#if>
|
||||
</@lib.handleExceptions>
|
||||
<#--
|
||||
standard assignment
|
||||
-->
|
||||
<#macro assignment>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/></@lib.handleWrite></#macro>
|
||||
<#--
|
||||
add default assignment when required
|
||||
-->
|
||||
<#macro elseDefaultAssignment>
|
||||
<#if ext.defaultValueAssignment?? >
|
||||
else {
|
||||
<@lib.handeDefaultAssigment/>
|
||||
}
|
||||
</#if>
|
||||
</#macro>
|
||||
<@lib.handleSourceReferenceNullCheck>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/></@lib.handleWrite>;
|
||||
</@lib.handleSourceReferenceNullCheck>
|
||||
</@lib.handleExceptions>
|
@ -23,11 +23,11 @@
|
||||
<@lib.handleExceptions>
|
||||
<#if ext.existingInstanceMapping>
|
||||
if ( ${ext.targetBeanName}.${ext.targetReadAccessorName} != null ) {
|
||||
<@lib.handleNullCheck>
|
||||
<@lib.handleLocalVarNullCheck>
|
||||
${ext.targetBeanName}.${ext.targetReadAccessorName}.clear();
|
||||
${ext.targetBeanName}.${ext.targetReadAccessorName}.<#if ext.targetType.collectionType>addAll<#else>putAll</#if>( ${nullCheckLocalVarName} );
|
||||
</@lib.handleNullCheck>
|
||||
<#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && !includeSourceNullCheck>else {<#-- the opposite (defaultValueAssignment) case is handeld inside lib.handleNullCheck -->
|
||||
</@lib.handleLocalVarNullCheck>
|
||||
<#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && !includeSourceNullCheck>else {<#-- the opposite (defaultValueAssignment) case is handeld inside lib.handleLocalVarNullCheck -->
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>null</@lib.handleWrite>;
|
||||
}
|
||||
</#if>
|
||||
@ -43,9 +43,9 @@
|
||||
assigns the target via the regular target write accessor (usually the setter)
|
||||
-->
|
||||
<#macro callTargetWriteAccessor>
|
||||
<@lib.handleNullCheck>
|
||||
<@lib.handleLocalVarNullCheck>
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else>${nullCheckLocalVarName}</#if></@lib.handleWrite>;
|
||||
</@lib.handleNullCheck>
|
||||
</@lib.handleLocalVarNullCheck>
|
||||
</#macro>
|
||||
<#--
|
||||
wraps the local variable in a collection initializer (new collection, or EnumSet.copyOf)
|
||||
|
@ -1,32 +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.
|
||||
|
||||
-->
|
||||
<#import '../macro/CommonMacros.ftl' as lib>
|
||||
if ( <#if sourcePresenceCheckerReference?? >${sourcePresenceCheckerReference}<#else>${sourceReference} != null</#if> ) {
|
||||
<@includeModel object=assignment
|
||||
targetBeanName=ext.targetBeanName
|
||||
existingInstanceMapping=ext.existingInstanceMapping
|
||||
targetReadAccessorName=ext.targetReadAccessorName
|
||||
targetWriteAccessorName=ext.targetWriteAccessorName
|
||||
targetType=ext.targetType/>
|
||||
}
|
||||
else {
|
||||
${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>null</@lib.handleWrite>;
|
||||
}
|
@ -18,18 +18,51 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
|
||||
<#--
|
||||
macro: handleNullCheck
|
||||
macro: handleSourceReferenceNullCheck
|
||||
|
||||
purpose: macro surrounds nested with either a source presence checker or a null check. It acts directly on the
|
||||
source reference. It adds an else clause with the default assigment when applicable.
|
||||
|
||||
requires: caller to implement boolean:getIncludeSourceNullCheck()
|
||||
-->
|
||||
<#macro handleSourceReferenceNullCheck>
|
||||
<#if sourcePresenceCheckerReference??>
|
||||
if ( ${sourcePresenceCheckerReference} ) {
|
||||
<#nested>
|
||||
}
|
||||
<@elseDefaultAssignment/>
|
||||
<#elseif includeSourceNullCheck || ext.defaultValueAssignment??>
|
||||
if ( <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference}</#if> != null ) {
|
||||
<#nested>
|
||||
}
|
||||
<@elseDefaultAssignment/>
|
||||
<#else>
|
||||
<#nested>
|
||||
</#if>
|
||||
</#macro>
|
||||
<#--
|
||||
local macro related to handleSourceReferenceNullCheck
|
||||
-->
|
||||
<#macro elseDefaultAssignment>
|
||||
<#if ext.defaultValueAssignment?? >
|
||||
else {
|
||||
<@handeDefaultAssigment/>
|
||||
}
|
||||
</#if>
|
||||
</#macro>
|
||||
<#--
|
||||
macro: handleLocalVarNullCheck
|
||||
|
||||
purpose: macro surrounds nested with either a source presence checker or a null check. It always uses
|
||||
a local variable. Note that the local variable assignemnt is inside the IF statement for the
|
||||
source presence check. Note also, that the else clause contains the default variable assignment if
|
||||
present.
|
||||
|
||||
TODO: is only used by collection mapping currently.. should perhas be moved to there and not in common
|
||||
requires: caller to implement String:getNullCheckLocalVarName()
|
||||
caller to implement Type:getNullCheckLocalVarType()
|
||||
-->
|
||||
<#macro handleNullCheck>
|
||||
<#macro handleLocalVarNullCheck>
|
||||
<#if sourcePresenceCheckerReference??>
|
||||
if ( ${sourcePresenceCheckerReference} ) {
|
||||
<@includeModel object=nullCheckLocalVarType/> ${nullCheckLocalVarName} = <@lib.handleAssignment/>;
|
||||
@ -47,7 +80,6 @@
|
||||
}
|
||||
</#if>
|
||||
</#macro>
|
||||
|
||||
<#--
|
||||
macro: handleExceptions
|
||||
|
||||
@ -130,10 +162,11 @@ Performs a default assignment with a default value.
|
||||
<#--
|
||||
macro: sourceLocalVarAssignment
|
||||
|
||||
purpose: assigment for source local variables
|
||||
purpose: assignment for source local variables. The sourceLocalVarName replaces the sourceReference in the
|
||||
assignmentcall.
|
||||
-->
|
||||
<#macro sourceLocalVarAssignment>
|
||||
<#if sourceLocalVarName??>
|
||||
<@includeModel object=sourceType/> ${sourceLocalVarName} = ${sourceReference};
|
||||
</#if>
|
||||
</#macro>
|
||||
</#macro>
|
Loading…
x
Reference in New Issue
Block a user