From c69a56c138b54b8a7fd6a6c1ac53009f8c8a75f9 Mon Sep 17 00:00:00 2001 From: sjaakd Date: Sat, 7 Feb 2015 20:03:01 +0100 Subject: [PATCH] #160 Using update method, basic behavior. Single mapping methods on non collection / array properties. --- .../java/org/mapstruct/ap/model/Direct.java | 6 + .../ap/model/IterableMappingMethod.java | 3 +- .../mapstruct/ap/model/MapMappingMethod.java | 6 +- .../ap/model/MappingBuilderContext.java | 3 +- .../mapstruct/ap/model/MethodReference.java | 8 + .../mapstruct/ap/model/PropertyMapping.java | 52 ++++- .../mapstruct/ap/model/TypeConversion.java | 6 + .../ap/model/assignment/Assignment.java | 2 + .../model/assignment/AssignmentWrapper.java | 5 + .../ap/model/assignment/UpdateWrapper.java | 72 ++++++ .../selector/CreateOrUpdateSelector.java | 26 ++- .../source/selector/SelectionCriteria.java | 14 +- .../processor/MethodRetrievalProcessor.java | 30 ++- .../creation/MappingResolverImpl.java | 14 +- .../java/org/mapstruct/ap/util/Message.java | 2 + ...ruct.ap.model.assignment.UpdateWrapper.ftl | 44 ++++ .../ap/test/updatemethods/CompanyDto.java | 46 ++++ .../ap/test/updatemethods/CompanyEntity.java | 46 ++++ .../ap/test/updatemethods/CompanyMapper.java | 40 ++++ .../ap/test/updatemethods/DepartmentDto.java | 37 ++++ .../test/updatemethods/DepartmentEntity.java | 40 ++++ .../DepartmentEntityFactory.java | 32 +++ .../updatemethods/DepartmentInBetween.java | 37 ++++ .../ErroneousCompanyMapper1.java | 39 ++++ .../ErroneousOrganizationMapper1.java | 45 ++++ .../ErroneousOrganizationMapper2.java | 45 ++++ .../test/updatemethods/OrganizationDto.java | 37 ++++ .../updatemethods/OrganizationEntity.java | 55 +++++ .../updatemethods/OrganizationMapper.java | 51 +++++ .../updatemethods/OrganizationTypeEntity.java | 37 ++++ .../OrganizationTypeNrEntity.java | 37 ++++ ...rganizationWithoutCompanyGetterEntity.java | 41 ++++ .../OrganizationWithoutTypeGetterEntity.java | 41 ++++ .../test/updatemethods/UpdateMethodsTest.java | 207 ++++++++++++++++++ .../selection/ExternalHandWrittenMapper.java | 38 ++++ .../selection/ExternalMapper.java | 38 ++++ .../selection/ExternalSelectionTest.java | 74 +++++++ .../selection/OrganizationMapper1.java | 39 ++++ .../selection/OrganizationMapper2.java | 39 ++++ 39 files changed, 1410 insertions(+), 24 deletions(-) create mode 100644 processor/src/main/java/org/mapstruct/ap/model/assignment/UpdateWrapper.java create mode 100644 processor/src/main/resources/org.mapstruct.ap.model.assignment.UpdateWrapper.ftl create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntityFactory.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentInBetween.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousCompanyMapper1.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper1.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper2.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeNrEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutCompanyGetterEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutTypeGetterEntity.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/UpdateMethodsTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalHandWrittenMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalSelectionTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper1.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper2.java diff --git a/processor/src/main/java/org/mapstruct/ap/model/Direct.java b/processor/src/main/java/org/mapstruct/ap/model/Direct.java index dc19a10db..3b934b184 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/Direct.java +++ b/processor/src/main/java/org/mapstruct/ap/model/Direct.java @@ -62,4 +62,10 @@ public class Direct extends ModelElement implements Assignment { public AssignmentType getType() { return AssignmentType.DIRECT; } + + @Override + public boolean isUpdateMethod() { + return false; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java index a7af652b5..e836a5fd7 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java @@ -115,7 +115,8 @@ public class IterableMappingMethod extends MappingMethod { dateFormat, qualifiers, qualifyingElementTargetType, - loopVariableName + loopVariableName, + false ); if ( assignment == null ) { diff --git a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java index de99183f9..494809c5d 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java @@ -125,7 +125,8 @@ public class MapMappingMethod extends MappingMethod { keyDateFormat, keyQualifiers, keyQualifyingTargetType, - "entry.getKey()" + "entry.getKey()", + false ); if ( keyAssignment == null ) { @@ -145,7 +146,8 @@ public class MapMappingMethod extends MappingMethod { valueDateFormat, valueQualifiers, valueQualifyingTargetType, - "entry.getValue()" + "entry.getValue()", + false ); if ( valueAssignment == null ) { diff --git a/processor/src/main/java/org/mapstruct/ap/model/MappingBuilderContext.java b/processor/src/main/java/org/mapstruct/ap/model/MappingBuilderContext.java index cd9bf29af..61f424bc2 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MappingBuilderContext.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MappingBuilderContext.java @@ -83,6 +83,7 @@ public class MappingBuilderContext { * @param resultType used for further select the appropriate mapping method based on resultType (bean mapping) * targetType (Iterable- and MapMapping) * @param sourceReference call to source type as string + * @param preferUpdateMethods selection should prefer update methods when present. * * @return an assignment to a method parameter, which can either be: *
    @@ -94,7 +95,7 @@ public class MappingBuilderContext { */ Assignment getTargetAssignment(Method mappingMethod, String mappedElement, Type sourceType, Type targetType, String targetPropertyName, String dateFormat, List qualifiers, - TypeMirror resultType, String sourceReference); + TypeMirror resultType, String sourceReference, boolean preferUpdateMethods); /** * returns a no arg factory method diff --git a/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java b/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java index 6c1badbb4..3a72a100b 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java @@ -42,6 +42,7 @@ public class MethodReference extends MappingMethod implements Assignment { private final MapperReference declaringMapper; private final Set importTypes; private final List exceptionTypes; + private final boolean isUpdateMethod; /** * In case this reference targets a built-in method, allows to pass specific context information to the invoked @@ -78,6 +79,7 @@ public class MethodReference extends MappingMethod implements Assignment { } this.importTypes = Collections.unmodifiableSet( imported ); this.exceptionTypes = method.getThrownTypes(); + this.isUpdateMethod = method.getMappingTargetParameter() != null; } public MethodReference(BuiltInMethod method, ConversionContext contextParam) { @@ -86,6 +88,7 @@ public class MethodReference extends MappingMethod implements Assignment { this.contextParam = method.getContextParameter( contextParam ); this.importTypes = Collections.emptySet(); this.exceptionTypes = Collections.emptyList(); + this.isUpdateMethod = method.getMappingTargetParameter() != null; } public MapperReference getDeclaringMapper() { @@ -159,4 +162,9 @@ public class MethodReference extends MappingMethod implements Assignment { return null; } } + + @Override + public boolean isUpdateMethod() { + return isUpdateMethod; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java index f1bd587e7..57ae69699 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java @@ -35,6 +35,7 @@ import org.mapstruct.ap.model.assignment.NewCollectionOrMapWrapper; import org.mapstruct.ap.model.assignment.NullCheckWrapper; import org.mapstruct.ap.model.assignment.SetterWrapper; import org.mapstruct.ap.model.assignment.SetterWrapperForCollectionsAndMaps; +import org.mapstruct.ap.model.assignment.UpdateWrapper; import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.Parameter; import org.mapstruct.ap.model.common.Type; @@ -163,6 +164,16 @@ public class PropertyMapping extends ModelElement { sourceRefStr = getSourceRef(); } + // all the tricky cases will be excluded for the time being. + boolean preferUpdateMethods; + if ( targetType.isCollectionOrMapType() || targetType.isArrayType() || + targetAccessorType == TargetWriteAccessorType.ADDER ) { + preferUpdateMethods = false; + } + else { + preferUpdateMethods = method.getMappingTargetParameter() != null; + } + Assignment assignment = ctx.getMappingResolver().getTargetAssignment( method, sourceElement, @@ -172,7 +183,8 @@ public class PropertyMapping extends ModelElement { dateFormat, qualifiers, resultType, - sourceRefStr + sourceRefStr, + preferUpdateMethods ); // No mapping found. Try to forge a mapping @@ -198,6 +210,7 @@ public class PropertyMapping extends ModelElement { else { assignment = assignObject( sourceType, targetType, targetAccessorType, assignment ); } + } else { ctx.getMessager().printMessage( @@ -228,8 +241,19 @@ public class PropertyMapping extends ModelElement { Assignment result = rhs; if ( targetAccessorType == TargetWriteAccessorType.SETTER ) { - - result = new SetterWrapper( result, method.getThrownTypes() ); + 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, null ); + result = new UpdateWrapper( result, method.getThrownTypes(), targetType, factoryMethod ); + } + else { + result = new SetterWrapper( result, method.getThrownTypes() ); + } if ( !sourceType.isPrimitive() && !sourceReference.getPropertyEntries().isEmpty() /* parameter null taken care of by beanmapper */ && ( result.getType() == TYPE_CONVERTED @@ -575,17 +599,33 @@ public class PropertyMapping extends ModelElement { dateFormat, qualifiers, resultType, - constantExpression + constantExpression, + method.getMappingTargetParameter() != null ); if ( assignment != null ) { if ( Executables.isSetterMethod( targetWriteAccessor ) ) { + // target accessor is setter, so decorate assignment as setter - assignment = new SetterWrapper( assignment, method.getThrownTypes() ); + if ( assignment.isUpdateMethod() ) { + if ( targetReadAccessor == null ) { + ctx.getMessager().printMessage( method.getExecutable(), + Message.CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE, + targetPropertyName ); + } + Assignment factoryMethod = + ctx.getMappingResolver().getFactoryMethod( method, targetType, null, null ); + assignment = + new UpdateWrapper( assignment, method.getThrownTypes(), targetType, factoryMethod ); + } + else { + assignment = new SetterWrapper( assignment, method.getThrownTypes() ); + } } else { - // wrap when dealing with getter only on target + + // target accessor is getter, so getter map/ collection handling assignment = new GetterWrapperForCollectionsAndMaps( assignment, method.getThrownTypes(), diff --git a/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java b/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java index cda8d4722..0132b7fd5 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java @@ -103,4 +103,10 @@ public class TypeConversion extends ModelElement implements Assignment { return null; } } + + @Override + public boolean isUpdateMethod() { + return false; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/Assignment.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/Assignment.java index 1bc8a325d..00f43d2eb 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/assignment/Assignment.java +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/Assignment.java @@ -83,4 +83,6 @@ public interface Assignment { */ AssignmentType getType(); + + boolean isUpdateMethod(); } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentWrapper.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentWrapper.java index 520e3cc21..3470c419f 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentWrapper.java @@ -64,4 +64,9 @@ public abstract class AssignmentWrapper extends ModelElement implements Assignme public AssignmentType getType() { return decoratedAssignment.getType(); } + + @Override + public boolean isUpdateMethod() { + return decoratedAssignment.isUpdateMethod(); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/UpdateWrapper.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/UpdateWrapper.java new file mode 100644 index 000000000..a31e78a60 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/UpdateWrapper.java @@ -0,0 +1,72 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.model.assignment; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.mapstruct.ap.model.common.Type; + +/** + * Wraps the assignment in a target setter. + * + * @author Sjaak Derksen + */ +public class UpdateWrapper extends AssignmentWrapper { + + private final List exceptionTypesToExclude; + private final Type targetType; + private final Assignment factoryMethod; + + public UpdateWrapper(Assignment decoratedAssignment, List exceptionTypesToExclude, Type targetType, + Assignment factoryMethod ) { + super( decoratedAssignment ); + this.exceptionTypesToExclude = exceptionTypesToExclude; + this.targetType = targetType; + this.factoryMethod = factoryMethod; + } + + @Override + public List getExceptionTypes() { + List parentExceptionTypes = super.getExceptionTypes(); + List result = new ArrayList( parentExceptionTypes ); + for ( Type exceptionTypeToExclude : exceptionTypesToExclude ) { + for ( Type parentExceptionType : parentExceptionTypes ) { + if ( parentExceptionType.isAssignableTo( exceptionTypeToExclude ) ) { + result.remove( parentExceptionType ); + } + } + } + return result; + } + + @Override + public Set getImportTypes() { + Set imported = new HashSet(); + imported.addAll( super.getImportTypes() ); + imported.add( targetType ); /* is a new target type */ + return imported; + } + + public Assignment getFactoryMethod() { + return factoryMethod; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/CreateOrUpdateSelector.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/CreateOrUpdateSelector.java index f9b08880f..fe7287922 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/selector/CreateOrUpdateSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/CreateOrUpdateSelector.java @@ -23,12 +23,21 @@ import java.util.List; import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.source.Method; -import org.mapstruct.ap.model.source.MethodMatcher; /** - * Selects only create method candidates (so methods not containing {@link @MappingTarget} ) - * {@link MethodMatcher}). + * Selection based on type of method (create - or update method). * + *

    + * Prefers (when present): + *

      + *
    1. create method candidates (methods not containing {@link @MappingTarget} ) when mapping method is + * a create method
    2. + *
    3. update method candidates (methods containing {@link @MappingTarget} ) when mapping method is + * an update method
    4. + *
    + * When not present, the remaining (createCandidates when mapping method is update method, updateCandidates when mapping + * method is a create method) candidates are selected. + *

    * @author Sjaak Derksen */ public class CreateOrUpdateSelector implements MethodSelector { @@ -38,14 +47,23 @@ public class CreateOrUpdateSelector implements MethodSelector { Type sourceType, Type targetType, SelectionCriteria criteria) { + boolean isCreateMethod = mappingMethod.getMappingTargetParameter() == null; List createCandidates = new ArrayList(); + List updateCandidates = new ArrayList(); for ( T method : methods ) { boolean isCreateCandidate = method.getMappingTargetParameter() == null; if ( isCreateCandidate ) { createCandidates.add( method ); } + else { + updateCandidates.add( method ); + } + } + if ( criteria.isPreferUpdateMapping() ) { + if ( !updateCandidates.isEmpty() ) { + return updateCandidates; + } } return createCandidates; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java index 36330c4fb..588368f4c 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java @@ -31,11 +31,14 @@ public class SelectionCriteria { private final List qualifiers; private final String targetPropertyName; private final TypeMirror qualifyingResultType; + private boolean preferUpdateMapping; - public SelectionCriteria(List qualifiers, String targetPropertyName, TypeMirror qualifyingResultType) { + public SelectionCriteria(List qualifiers, String targetPropertyName, TypeMirror qualifyingResultType, + boolean preferUpdateMapping ) { this.qualifiers = qualifiers; this.targetPropertyName = targetPropertyName; this.qualifyingResultType = qualifyingResultType; + this.preferUpdateMapping = preferUpdateMapping; } public List getQualifiers() { @@ -49,4 +52,13 @@ public class SelectionCriteria { public TypeMirror getQualifyingResultType() { return qualifyingResultType; } + + public boolean isPreferUpdateMapping() { + return preferUpdateMapping; + } + + public void setPreferUpdateMapping(boolean preferUpdateMapping) { + this.preferUpdateMapping = preferUpdateMapping; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java index f3cc86767..7ca9ebe80 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/MethodRetrievalProcessor.java @@ -272,14 +272,30 @@ public class MethodRetrievalProcessor implements ModelElementProcessor parameters) { - return isValidReferencedOrFactoryMethod( 1, parameters ); + int validSourceParameters = 0; + int targetParameters = 0; + int targetTypeParameters = 0; + + for ( Parameter param : parameters ) { + if ( param.isMappingTarget() ) { + targetParameters++; + } + + if ( param.isTargetType() ) { + targetTypeParameters++; + } + + if ( !param.isMappingTarget() && !param.isTargetType() ) { + validSourceParameters++; + } + } + return validSourceParameters == 1 + && targetParameters <= 1 + && targetTypeParameters <= 1 + && parameters.size() == validSourceParameters + targetParameters + targetTypeParameters; } private boolean isValidFactoryMethod(List parameters) { - return isValidReferencedOrFactoryMethod( 0, parameters ); - } - - private boolean isValidReferencedOrFactoryMethod(int sourceParamCount, List parameters) { int validSourceParameters = 0; int targetParameters = 0; int targetTypeParameters = 0; @@ -297,7 +313,9 @@ public class MethodRetrievalProcessor implements ModelElementProcessor qualifiers, - TypeMirror resultType, String sourceReference) { + TypeMirror resultType, String sourceReference, boolean preferUpdateMapping) { - SelectionCriteria criteria = new SelectionCriteria(qualifiers, targetPropertyName, resultType ); + SelectionCriteria criteria = + new SelectionCriteria(qualifiers, targetPropertyName, resultType, preferUpdateMapping ); ResolvingAttempt attempt = new ResolvingAttempt( sourceModel, @@ -122,7 +123,7 @@ public class MappingResolverImpl implements MappingResolver { public MethodReference getFactoryMethod( Method mappingMethod, Type targetType, List qualifiers, TypeMirror resultType ) { - SelectionCriteria criteria = new SelectionCriteria(qualifiers, null, resultType ); + SelectionCriteria criteria = new SelectionCriteria( qualifiers, null, resultType, false ); ResolvingAttempt attempt = new ResolvingAttempt( sourceModel, @@ -150,6 +151,7 @@ public class MappingResolverImpl implements MappingResolver { private final String dateFormat; private final SelectionCriteria selectionCriteria; private final String sourceReference; + private final boolean savedPreferUpdateMapping; // resolving via 2 steps creates the possibillity of wrong matches, first builtin method matches, // second doesn't. In that case, the first builtin method should not lead to a virtual method @@ -166,6 +168,7 @@ public class MappingResolverImpl implements MappingResolver { this.sourceReference = sourceReference; this.virtualMethodCandidates = new HashSet(); this.selectionCriteria = criteria; + this.savedPreferUpdateMapping = criteria.isPreferUpdateMapping(); } private List filterPossibleCandidateMethods(List candidateMethods) { @@ -223,6 +226,9 @@ public class MappingResolverImpl implements MappingResolver { return referencedMethod; } + // stop here when looking for update methods. + selectionCriteria.setPreferUpdateMapping( false ); + // 2 step method, finally: conversion(method(source)) conversion = resolveViaMethodAndConversion( sourceType, targetType ); if ( conversion != null ) { @@ -311,8 +317,10 @@ public class MappingResolverImpl implements MappingResolver { resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType, true ); if ( methodRefY != null ) { + selectionCriteria.setPreferUpdateMapping( false ); Assignment methodRefX = resolveViaMethod( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType(), true ); + selectionCriteria.setPreferUpdateMapping( savedPreferUpdateMapping ); if ( methodRefX != null ) { methodRefY.setAssignment( methodRefX ); methodRefX.setAssignment( AssignmentFactory.createDirect( sourceReference ) ); diff --git a/processor/src/main/java/org/mapstruct/ap/util/Message.java b/processor/src/main/java/org/mapstruct/ap/util/Message.java index 1a9541c5c..715b454e2 100644 --- a/processor/src/main/java/org/mapstruct/ap/util/Message.java +++ b/processor/src/main/java/org/mapstruct/ap/util/Message.java @@ -49,8 +49,10 @@ public enum Message { PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no parameter named \"%s\"." ), PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER( "The type of parameter \"%s\" has no property named \"%s\"." ), PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s)." ), + PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ), CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ), + CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ), MAPMAPPING_KEY_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source key type to target key type." ), MAPMAPPING_VALUE_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source value type to target value type." ), diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.UpdateWrapper.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.UpdateWrapper.ftl new file mode 100644 index 000000000..be93df2b4 --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.UpdateWrapper.ftl @@ -0,0 +1,44 @@ +<#-- + + Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + and/or other contributors as indicated by the @authors tag. See the + copyright.txt file in the distribution for a full listing of all + contributors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<#if (exceptionTypes?size == 0) > + <@_assignment/>; +<#else> + try { + <@_assignment/>; + } + <#list exceptionTypes as exceptionType> + catch ( <@includeModel object=exceptionType/> e ) { + throw new RuntimeException( e ); + } + + +<#macro _assignment> + if ( ${ext.targetBeanName}.${ext.targetReadAccessorName}() == null ) { + ${ext.targetBeanName}.${ext.targetWriteAccessorName}( <#if factoryMethod??><@includeModel object=factoryMethod targetType=ext.targetType raw=true/><#else>new <@includeModel object=ext.targetType/>() ); + } + <@includeModel object=assignment + targetBeanName=ext.targetBeanName + raw=ext.raw + existingInstanceMapping=ext.existingInstanceMapping + targetReadAccessorName=ext.targetReadAccessorName + targetWriteAccessorName=ext.targetWriteAccessorName + targetType=ext.targetType/> + \ No newline at end of file diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyDto.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyDto.java new file mode 100644 index 000000000..f12fd58c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyDto.java @@ -0,0 +1,46 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class CompanyDto { + + private String name; + private DepartmentDto department; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public DepartmentDto getDepartment() { + return department; + } + + public void setDepartment(DepartmentDto department) { + this.department = department; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyEntity.java new file mode 100644 index 000000000..ad22c4fb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyEntity.java @@ -0,0 +1,46 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class CompanyEntity { + + private String name; + private DepartmentEntity department; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public DepartmentEntity getDepartment() { + return department; + } + + public void setDepartment(DepartmentEntity department) { + this.department = department; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyMapper.java new file mode 100644 index 000000000..69936bc9a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/CompanyMapper.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( uses = DepartmentEntityFactory.class ) +public interface CompanyMapper { + + CompanyMapper INSTANCE = Mappers.getMapper( CompanyMapper.class ); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + + DepartmentInBetween toInBetween(DepartmentDto dto); + + void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentDto.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentDto.java new file mode 100644 index 000000000..193032ae2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentDto.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class DepartmentDto { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntity.java new file mode 100644 index 000000000..b0b70b075 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntity.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class DepartmentEntity { + + private String name; + + public DepartmentEntity(Integer justAnArgToAvoidConstruction) { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntityFactory.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntityFactory.java new file mode 100644 index 000000000..ecd57ca08 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentEntityFactory.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class DepartmentEntityFactory { + + + public DepartmentEntity createDepartmentEntity() { + return new DepartmentEntity(5); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentInBetween.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentInBetween.java new file mode 100644 index 000000000..aa60da103 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/DepartmentInBetween.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class DepartmentInBetween { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousCompanyMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousCompanyMapper1.java new file mode 100644 index 000000000..375382a15 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousCompanyMapper1.java @@ -0,0 +1,39 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( uses = DepartmentEntityFactory.class ) +public interface ErroneousCompanyMapper1 { + + ErroneousCompanyMapper1 INSTANCE = Mappers.getMapper( ErroneousCompanyMapper1.class ); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + + void toInBetween(DepartmentDto dto, @MappingTarget DepartmentInBetween entity); + + void toDepartmentEntity(DepartmentInBetween dto, @MappingTarget DepartmentEntity entity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper1.java new file mode 100644 index 000000000..cea30a75b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper1.java @@ -0,0 +1,45 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( uses = DepartmentEntityFactory.class ) +public interface ErroneousOrganizationMapper1 { + + ErroneousOrganizationMapper1 INSTANCE = Mappers.getMapper( ErroneousOrganizationMapper1.class ); + + @Mapping(target = "type", constant = "commercial") + void toOrganizationEntity(OrganizationDto dto, @MappingTarget OrganizationWithoutCompanyGetterEntity entity); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + + @Mapping(source = "type", target = "type") + void toName(String type, @MappingTarget OrganizationTypeEntity entity); + + DepartmentEntity toDepartmentEntity(DepartmentDto dto); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper2.java new file mode 100644 index 000000000..b9d7cce7a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/ErroneousOrganizationMapper2.java @@ -0,0 +1,45 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper +public interface ErroneousOrganizationMapper2 { + + ErroneousOrganizationMapper2 INSTANCE = Mappers.getMapper( ErroneousOrganizationMapper2.class ); + + @Mapping(target = "type", constant = "commercial") + void toOrganizationEntity(OrganizationDto dto, @MappingTarget OrganizationWithoutTypeGetterEntity entity); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + + @Mapping(source = "type", target = "type") + void toName(String type, @MappingTarget OrganizationTypeEntity entity); + + DepartmentEntity toDepartmentEntity(DepartmentDto dto); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationDto.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationDto.java new file mode 100644 index 000000000..0fb59bc4e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationDto.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationDto { + + private CompanyDto company; + + public CompanyDto getCompany() { + return company; + } + + public void setCompany(CompanyDto company) { + this.company = company; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationEntity.java new file mode 100644 index 000000000..8b845e0ba --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationEntity.java @@ -0,0 +1,55 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationEntity { + + private CompanyEntity company; + private OrganizationTypeEntity type; + private OrganizationTypeNrEntity typeNr; + + public CompanyEntity getCompany() { + return company; + } + + public void setCompany(CompanyEntity company) { + this.company = company; + } + + public OrganizationTypeEntity getType() { + return type; + } + + public void setType(OrganizationTypeEntity type) { + this.type = type; + } + + public OrganizationTypeNrEntity getTypeNr() { + return typeNr; + } + + public void setTypeNr(OrganizationTypeNrEntity typeNr) { + this.typeNr = typeNr; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationMapper.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationMapper.java new file mode 100644 index 000000000..3ea35e82c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationMapper.java @@ -0,0 +1,51 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( uses = DepartmentEntityFactory.class ) +public interface OrganizationMapper { + + OrganizationMapper INSTANCE = Mappers.getMapper( OrganizationMapper.class ); + + @Mappings({ + @Mapping(target = "type", constant = "commercial"), + @Mapping(target = "typeNr", constant = "5") + }) + void toOrganizationEntity(OrganizationDto dto, @MappingTarget OrganizationEntity entity); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + + DepartmentEntity toDepartmentEntity(DepartmentDto dto); + + @Mapping(source = "type", target = "type") + void toName(String type, @MappingTarget OrganizationTypeEntity entity); + + @Mapping(source = "number", target = "number") + void toNumber(Integer number, @MappingTarget OrganizationTypeNrEntity entity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeEntity.java new file mode 100644 index 000000000..c3fa9d0c7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationTypeEntity { + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeNrEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeNrEntity.java new file mode 100644 index 000000000..30f8606a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationTypeNrEntity.java @@ -0,0 +1,37 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationTypeNrEntity { + + private Integer number; + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutCompanyGetterEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutCompanyGetterEntity.java new file mode 100644 index 000000000..500e4268a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutCompanyGetterEntity.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationWithoutCompanyGetterEntity { + + private CompanyEntity company; + private OrganizationTypeEntity type; + + public void setCompany(CompanyEntity company) { + this.company = company; + } + + public OrganizationTypeEntity getType() { + return type; + } + + public void setType(OrganizationTypeEntity type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutTypeGetterEntity.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutTypeGetterEntity.java new file mode 100644 index 000000000..fe7cc4e81 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/OrganizationWithoutTypeGetterEntity.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +/** + * + * @author Sjaak Derksen + */ +public class OrganizationWithoutTypeGetterEntity { + + private CompanyEntity company; + private OrganizationTypeEntity type; + + public CompanyEntity getCompany() { + return company; + } + + public void setCompany(CompanyEntity company) { + this.company = company; + } + + public void setType(OrganizationTypeEntity type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/UpdateMethodsTest.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/UpdateMethodsTest.java new file mode 100644 index 000000000..68809ecaf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/UpdateMethodsTest.java @@ -0,0 +1,207 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.fest.assertions.Assertions.assertThat; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +/** + * + * @author Sjaak Derksen + */ +@IssueKey("160") +@RunWith(AnnotationProcessorTestRunner.class) +public class UpdateMethodsTest { + + @Test + @WithClasses( { + OrganizationMapper.class, + OrganizationDto.class, + OrganizationEntity.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class, + OrganizationTypeNrEntity.class + } ) + public void testPreferUpdateMethod() { + + OrganizationEntity organizationEntity = new OrganizationEntity(); + CompanyEntity companyEntity = new CompanyEntity(); + organizationEntity.setCompany( companyEntity ); + companyEntity.setName( "CocaCola" ); + + OrganizationDto organizationDto = new OrganizationDto(); + CompanyDto companyDto = new CompanyDto(); + organizationDto.setCompany( companyDto ); + companyDto.setName( "PepsiCo" ); + DepartmentDto departmentDto = new DepartmentDto(); + departmentDto.setName( "finance" ); + companyDto.setDepartment( departmentDto ); + + OrganizationMapper.INSTANCE.toOrganizationEntity( organizationDto, organizationEntity ); + + assertThat( organizationEntity.getCompany() ).isEqualTo( companyEntity ); + assertThat( organizationEntity.getCompany().getName() ).isEqualTo( "PepsiCo" ); + assertThat( organizationEntity.getType().getType() ).isEqualTo( "commercial" ); + assertThat( organizationEntity.getTypeNr().getNumber()).isEqualTo( 5 ); + assertThat( organizationEntity.getCompany().getDepartment().getName() ).isEqualTo( "finance" ); + } + + @Test + @WithClasses( { + OrganizationMapper.class, + OrganizationDto.class, + OrganizationEntity.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class, + OrganizationTypeNrEntity.class + } ) + public void testPreferUpdateMethodSourceObjectNotDefined() { + + OrganizationEntity organizationEntity = new OrganizationEntity(); + + OrganizationDto organizationDto = new OrganizationDto(); + CompanyDto companyDto = new CompanyDto(); + organizationDto.setCompany( companyDto ); + companyDto.setName( "PepsiCo" ); + DepartmentDto departmentDto = new DepartmentDto(); + departmentDto.setName( "finance" ); + companyDto.setDepartment( departmentDto ); + + OrganizationMapper.INSTANCE.toOrganizationEntity( organizationDto, organizationEntity ); + + assertThat( organizationEntity.getCompany().getName() ).isEqualTo( "PepsiCo" ); + assertThat( organizationEntity.getType().getType() ).isEqualTo( "commercial" ); + assertThat( organizationEntity.getTypeNr().getNumber()).isEqualTo( 5 ); + assertThat( organizationEntity.getCompany().getDepartment().getName() ).isEqualTo( "finance" ); + } + + @Test + @WithClasses( { + CompanyMapper.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentInBetween.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class, + OrganizationTypeNrEntity.class + } ) + public void testPreferUpdateMethodEncapsulatingCreateMethod() { + + CompanyEntity companyEntity = new CompanyEntity(); + + CompanyDto companyDto = new CompanyDto(); + DepartmentDto departmentDto = new DepartmentDto(); + departmentDto.setName( "finance" ); + companyDto.setDepartment( departmentDto ); + + CompanyMapper.INSTANCE.toCompanyEntity( companyDto, companyEntity ); + + assertThat( companyEntity.getDepartment().getName() ).isEqualTo( "finance" ); + + } + + @Test + @WithClasses( { + ErroneousOrganizationMapper1.class, + OrganizationDto.class, + OrganizationWithoutCompanyGetterEntity.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class + } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousOrganizationMapper1.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 36, + messageRegExp = "No read accessor found for property \"company\" in target type.") + } + ) + public void testShouldFailOnPropertyMappingNoPropertyGetter() { } + + @Test + @WithClasses( { + ErroneousOrganizationMapper2.class, + OrganizationDto.class, + OrganizationWithoutTypeGetterEntity.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class + } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousOrganizationMapper2.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 36, + messageRegExp = "No read accessor found for property \"type\" in target type.") + } + ) + public void testShouldFailOnConstantMappingNoPropertyGetter() { } + + @Test + @WithClasses( { + ErroneousCompanyMapper1.class, + OrganizationDto.class, + OrganizationWithoutTypeGetterEntity.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentInBetween.class, + DepartmentEntity.class, + DepartmentEntityFactory.class, + OrganizationTypeEntity.class + } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCompanyMapper1.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 34, + messageRegExp = "Can't map property \".*DepartmentDto department\" to \".*DepartmentEntity department.") + } + ) + public void testShouldFailOnTwoNestedUpdateMethods() { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalHandWrittenMapper.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalHandWrittenMapper.java new file mode 100644 index 000000000..44f38c561 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalHandWrittenMapper.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods.selection; + +import org.mapstruct.MappingTarget; +import org.mapstruct.ap.test.updatemethods.DepartmentDto; +import org.mapstruct.ap.test.updatemethods.DepartmentEntity; + +/** + * + * @author Sjaak Derksen + */ +public class ExternalHandWrittenMapper { + + + public void toDepartmentEntity(DepartmentDto dto, @MappingTarget DepartmentEntity entity) { + if ( entity != null && dto != null ) { + entity.setName( dto.getName() ); + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalMapper.java new file mode 100644 index 000000000..cc66dc96f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalMapper.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods.selection; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ap.test.updatemethods.DepartmentDto; +import org.mapstruct.ap.test.updatemethods.DepartmentEntity; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper +public interface ExternalMapper { + + ExternalMapper INSTANCE = Mappers.getMapper( ExternalMapper.class ); + + void toDepartmentEntity(DepartmentDto dto, @MappingTarget DepartmentEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalSelectionTest.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalSelectionTest.java new file mode 100644 index 000000000..089189b88 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/ExternalSelectionTest.java @@ -0,0 +1,74 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods.selection; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.test.updatemethods.CompanyDto; +import org.mapstruct.ap.test.updatemethods.CompanyEntity; +import org.mapstruct.ap.test.updatemethods.DepartmentDto; +import org.mapstruct.ap.test.updatemethods.DepartmentEntity; +import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +/** + * + * @author Sjaak Derksen + */ +@IssueKey("160") +@RunWith(AnnotationProcessorTestRunner.class) +public class ExternalSelectionTest { + + @Test + @WithClasses({ + OrganizationMapper1.class, + ExternalMapper.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntityFactory.class, + DepartmentEntity.class + }) + public void shouldSelectGeneratedExternalMapper() { + + CompanyEntity entity = new CompanyEntity(); + CompanyDto dto = new CompanyDto(); + OrganizationMapper1.INSTANCE.toCompanyEntity( dto, entity ); + } + + @Test + @WithClasses({ + OrganizationMapper2.class, + ExternalHandWrittenMapper.class, + CompanyDto.class, + CompanyEntity.class, + DepartmentDto.class, + DepartmentEntityFactory.class, + DepartmentEntity.class + }) + public void shouldSelectGeneratedHandWrittenExternalMapper() { + + CompanyEntity entity = new CompanyEntity(); + CompanyDto dto = new CompanyDto(); + OrganizationMapper2.INSTANCE.toCompanyEntity( dto, entity ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper1.java new file mode 100644 index 000000000..dbb61d9b9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper1.java @@ -0,0 +1,39 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods.selection; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ap.test.updatemethods.CompanyDto; +import org.mapstruct.ap.test.updatemethods.CompanyEntity; +import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper(uses = { ExternalMapper.class, DepartmentEntityFactory.class } ) +public interface OrganizationMapper1 { + + OrganizationMapper1 INSTANCE = Mappers.getMapper( OrganizationMapper1.class ); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper2.java new file mode 100644 index 000000000..d6ca5a00a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/updatemethods/selection/OrganizationMapper2.java @@ -0,0 +1,39 @@ +/** + * Copyright 2012-2015 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mapstruct.ap.test.updatemethods.selection; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ap.test.updatemethods.CompanyDto; +import org.mapstruct.ap.test.updatemethods.CompanyEntity; +import org.mapstruct.ap.test.updatemethods.DepartmentEntityFactory; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper(uses = { ExternalHandWrittenMapper.class, DepartmentEntityFactory.class } ) +public interface OrganizationMapper2 { + + OrganizationMapper2 INSTANCE = Mappers.getMapper( OrganizationMapper2.class ); + + void toCompanyEntity(CompanyDto dto, @MappingTarget CompanyEntity entity); + +}