diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java new file mode 100644 index 000000000..6a87431b9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java @@ -0,0 +1,88 @@ +/** + * Copyright 2012-2017 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; + +import org.mapstruct.ap.internal.model.assignment.Assignment; +import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.source.ForgedMethod; +import org.mapstruct.ap.internal.model.source.Method; + +/** + * @author Filip Hrisafov + */ +class AbstractBaseBuilder> { + + protected B myself; + protected MappingBuilderContext ctx; + protected Method method; + + AbstractBaseBuilder(Class selfType) { + myself = selfType.cast( this ); + } + + public B mappingContext(MappingBuilderContext mappingContext) { + this.ctx = mappingContext; + return myself; + } + + public B method(Method sourceMethod) { + this.method = sourceMethod; + return myself; + } + + /** + * Creates a forged assignment from the provided {@code sourceRHS} and {@code forgedMethod}. If a mapping method + * for the {@code forgedMethod} already exists, then this method used for the assignment. + * + * @param sourceRHS that needs to be used for the assignment + * @param forgedMethod the forged method for which we want to create an {@link Assignment} + * + * @return See above + */ + Assignment createForgedBeanAssignment(SourceRHS sourceRHS, ForgedMethod forgedMethod) { + BeanMappingMethod forgedMappingMethod = new BeanMappingMethod.Builder() + .forgedMethod( forgedMethod ) + .mappingContext( ctx ) + .build(); + + return createForgedAssignment( sourceRHS, forgedMethod, forgedMappingMethod ); + } + + Assignment createForgedAssignment(SourceRHS source, ForgedMethod methodRef, MappingMethod mappingMethod) { + if ( mappingMethod == null ) { + return null; + } + if ( !ctx.getMappingsToGenerate().contains( mappingMethod ) ) { + ctx.getMappingsToGenerate().add( mappingMethod ); + } + else { + String existingName = ctx.getExistingMappingMethod( mappingMethod ).getName(); + methodRef = new ForgedMethod( existingName, methodRef ); + } + + Assignment assignment = new MethodReference( + methodRef, + null, + ParameterBinding.fromParameters( methodRef.getParameters() ) + ); + assignment.setAssignment( source ); + + return assignment; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java index 683e1c8e6..25e8de0f4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java @@ -19,25 +19,72 @@ package org.mapstruct.ap.internal.model; +import org.mapstruct.ap.internal.model.assignment.Assignment; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.ForgedMethod; +import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; +import org.mapstruct.ap.internal.util.Strings; + /** * An abstract builder that can be reused for building {@link MappingMethod}(s). * * @author Filip Hrisafov */ public abstract class AbstractMappingMethodBuilder, - M extends MappingMethod> { - - protected B myself; - protected MappingBuilderContext ctx; + M extends MappingMethod> extends AbstractBaseBuilder { public AbstractMappingMethodBuilder(Class selfType) { - myself = selfType.cast( this ); - } - - public B mappingContext(MappingBuilderContext mappingContext) { - this.ctx = mappingContext; - return myself; + super( selfType ); } public abstract M build(); + + /** + * @return {@code true} if property names should be used for the creation of the {@link ForgedMethodHistory}. + */ + protected abstract boolean shouldUsePropertyNamesInHistory(); + + Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType) { + + String name = getName( sourceType, targetType ); + name = Strings.getSaveVariableName( name, ctx.getNamesOfMappingsToGenerate() ); + ForgedMethodHistory history = null; + if ( method instanceof ForgedMethod ) { + history = ( (ForgedMethod) method ).getHistory(); + } + ForgedMethod forgedMethod = new ForgedMethod( + name, + sourceType, + targetType, + method.getMapperConfiguration(), + method.getExecutable(), + method.getContextParameters(), + new ForgedMethodHistory( + history, + Strings.stubPropertyName( sourceRHS.getSourceType().getName() ), + Strings.stubPropertyName( targetType.getName() ), + sourceRHS.getSourceType(), + targetType, + shouldUsePropertyNamesInHistory(), + sourceRHS.getSourceErrorMessagePart() + ) + ); + + return createForgedBeanAssignment( sourceRHS, forgedMethod ); + } + + private String getName(Type sourceType, Type targetType) { + String fromName = getName( sourceType ); + String toName = getName( targetType ); + return Strings.decapitalize( fromName + "To" + toName ); + } + + private String getName(Type type) { + StringBuilder builder = new StringBuilder(); + for ( Type typeParam : type.getTypeParameters() ) { + builder.append( typeParam.getIdentification() ); + } + builder.append( type.getIdentification() ); + return builder.toString(); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index 1f2aae28e..149e26d21 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -217,11 +217,6 @@ public class BeanMappingMethod extends MappingMethod { List afterMappingMethods = LifecycleCallbackFactory.afterMappingMethods( method, selectionParameters, ctx, existingVariableNames ); - List allForgedMethods = new ArrayList(); - for ( PropertyMapping propertyMapping : propertyMappings ) { - allForgedMethods.addAll( propertyMapping.getForgedMethods() ); - } - return new BeanMappingMethod( method, propertyMappings, @@ -231,8 +226,7 @@ public class BeanMappingMethod extends MappingMethod { existingVariableNames, beforeMappingMethods, afterMappingMethods, - nestedTargetObjects, - allForgedMethods + nestedTargetObjects ); } @@ -637,9 +631,8 @@ public class BeanMappingMethod extends MappingMethod { Collection existingVariableNames, List beforeMappingReferences, List afterMappingReferences, - NestedTargetObjects nestedTargetObjects, - List allForgedMethods) { - super( method, existingVariableNames, beforeMappingReferences, afterMappingReferences, allForgedMethods ); + NestedTargetObjects nestedTargetObjects) { + super( method, existingVariableNames, beforeMappingReferences, afterMappingReferences ); this.propertyMappings = propertyMappings; // intialize constant mappings as all mappings, but take out the ones that can be contributed to a diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java index 6f58fb964..cc6dfa367 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java @@ -18,16 +18,13 @@ */ package org.mapstruct.ap.internal.model; -import java.util.Collections; import java.util.List; import java.util.Set; - import javax.lang.model.type.TypeKind; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.util.Strings; @@ -48,14 +45,11 @@ public abstract class ContainerMappingMethod extends MappingMethod { private final SelectionParameters selectionParameters; ContainerMappingMethod(Method method, Assignment parameterAssignment, MethodReference factoryMethod, - boolean mapNullToDefault, String loopVariableName, - List beforeMappingReferences, - List afterMappingReferences, - SelectionParameters selectionParameters, ForgedMethod forgedMethod) { - super( method, beforeMappingReferences, afterMappingReferences, - forgedMethod == null ? Collections.emptyList() : - java.util.Collections.singletonList( forgedMethod ) - ); + boolean mapNullToDefault, String loopVariableName, + List beforeMappingReferences, + List afterMappingReferences, + SelectionParameters selectionParameters) { + super( method, beforeMappingReferences, afterMappingReferences ); this.elementAssignment = parameterAssignment; this.factoryMethod = factoryMethod; this.overridden = method.overridesMethod(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java index 79bb7574a..81c791a3c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java @@ -23,10 +23,8 @@ import java.util.List; import java.util.Set; import org.mapstruct.ap.internal.model.assignment.Assignment; -import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; import org.mapstruct.ap.internal.model.source.FormattingParameters; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -46,11 +44,9 @@ import static org.mapstruct.ap.internal.util.Collections.first; public abstract class ContainerMappingMethodBuilder, M extends ContainerMappingMethod> extends AbstractMappingMethodBuilder { - private Method method; private SelectionParameters selectionParameters; private FormattingParameters formattingParameters; private NullValueMappingStrategyPrism nullValueMappingStrategy; - private ForgedMethod forgedMethod; private String errorMessagePart; private String callingContextTargetPropertyName; @@ -59,11 +55,6 @@ public abstract class ContainerMappingMethodBuilder beforeMappingMethods, List afterMappingMethods, - SelectionParameters selectionParameters, ForgedMethod forgedMethod); + SelectionParameters selectionParameters); protected abstract Type getElementType(Type parameterType); protected abstract Assignment getWrapper(Assignment assignment, Method method); - private Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType) { - ForgedMethodHistory forgedMethodHistory = null; - if ( method instanceof ForgedMethod ) { - forgedMethodHistory = ( (ForgedMethod) method ).getHistory(); - } - String name = getName( sourceType, targetType ); - forgedMethod = new ForgedMethod( - name, - sourceType, - targetType, - method.getMapperConfiguration(), - method.getExecutable(), - method.getContextParameters(), - new ForgedMethodHistory( forgedMethodHistory, - Strings.stubPropertyName( sourceRHS.getSourceType().getName() ), - Strings.stubPropertyName( targetType.getName() ), - sourceRHS.getSourceType(), - targetType, - false, - sourceRHS.getSourceErrorMessagePart() - ) - ); - - Assignment assignment = new MethodReference( - forgedMethod, - null, - ParameterBinding.fromParameters( forgedMethod.getParameters() ) - ); - - assignment.setAssignment( sourceRHS ); - - return assignment; - } - - private String getName(Type sourceType, Type targetType) { - String fromName = getName( sourceType ); - String toName = getName( targetType ); - return Strings.decapitalize( fromName + "To" + toName ); - } - - private String getName(Type type) { - StringBuilder builder = new StringBuilder(); - for ( Type typeParam : type.getTypeParameters() ) { - builder.append( typeParam.getIdentification() ); - } - builder.append( type.getIdentification() ); - return builder.toString(); + @Override + protected boolean shouldUsePropertyNamesInHistory() { + return false; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java index 85bac06a8..44f743c49 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java @@ -26,7 +26,6 @@ import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.assignment.LocalVarWrapper; import org.mapstruct.ap.internal.model.assignment.SetterWrapper; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -66,8 +65,7 @@ public class IterableMappingMethod extends ContainerMappingMethod { protected IterableMappingMethod instantiateMappingMethod(Method method, Assignment assignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingMethods, - List afterMappingMethods, SelectionParameters selectionParameters, - ForgedMethod forgedMethod) { + List afterMappingMethods, SelectionParameters selectionParameters) { return new IterableMappingMethod( method, assignment, @@ -76,8 +74,7 @@ public class IterableMappingMethod extends ContainerMappingMethod { loopVariableName, beforeMappingMethods, afterMappingMethods, - selectionParameters, - forgedMethod + selectionParameters ); } } @@ -86,7 +83,7 @@ public class IterableMappingMethod extends ContainerMappingMethod { boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, - SelectionParameters selectionParameters, ForgedMethod forgedMethod) { + SelectionParameters selectionParameters) { super( method, parameterAssignment, @@ -95,8 +92,7 @@ public class IterableMappingMethod extends ContainerMappingMethod { loopVariableName, beforeMappingReferences, afterMappingReferences, - selectionParameters, - forgedMethod + selectionParameters ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java index 5ca345677..f37729e74 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java @@ -20,7 +20,6 @@ package org.mapstruct.ap.internal.model; import static org.mapstruct.ap.internal.util.Collections.first; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -29,10 +28,8 @@ import java.util.Set; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.assignment.LocalVarWrapper; import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; import org.mapstruct.ap.internal.model.source.FormattingParameters; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -53,25 +50,16 @@ public class MapMappingMethod extends MappingMethod { private final boolean overridden; private final boolean mapNullToDefault; - public static class Builder { + public static class Builder extends AbstractMappingMethodBuilder { private FormattingParameters keyFormattingParameters; private FormattingParameters valueFormattingParameters; - private Method method; - private MappingBuilderContext ctx; private NullValueMappingStrategyPrism nullValueMappingStrategy; private SelectionParameters keySelectionParameters; private SelectionParameters valueSelectionParameters; - private List forgedMethods = new ArrayList(); - public Builder mappingContext(MappingBuilderContext mappingContext) { - this.ctx = mappingContext; - return this; - } - - public Builder method(Method sourceMethod) { - this.method = sourceMethod; - return this; + public Builder() { + super( Builder.class ); } public Builder keySelectionParameters(SelectionParameters keySelectionParameters) { @@ -181,70 +169,21 @@ public class MapMappingMethod extends MappingMethod { factoryMethod, mapNullToDefault, beforeMappingMethods, - afterMappingMethods, - forgedMethods + afterMappingMethods ); } - private Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType) { - - String name = getName( sourceType, targetType ); - ForgedMethodHistory history = null; - if ( method instanceof ForgedMethod ) { - history = ( (ForgedMethod) method ).getHistory(); - } - ForgedMethod forgedMethod = new ForgedMethod( - name, - sourceType, - targetType, - method.getMapperConfiguration(), - method.getExecutable(), - method.getContextParameters(), - new ForgedMethodHistory( history, - Strings.stubPropertyName( sourceRHS.getSourceType().getName() ), - Strings.stubPropertyName( targetType.getName() ), - sourceRHS.getSourceType(), - targetType, - true, - sourceRHS.getSourceErrorMessagePart() - ) - ); - - Assignment assignment = new MethodReference( - forgedMethod, - null, - ParameterBinding.fromParameters( forgedMethod.getParameters() ) ); - - assignment.setAssignment( sourceRHS ); - - forgedMethods.add( forgedMethod ); - - return assignment; + @Override + protected boolean shouldUsePropertyNamesInHistory() { + return true; } - - private String getName(Type sourceType, Type targetType) { - String fromName = getName( sourceType ); - String toName = getName( targetType ); - return Strings.decapitalize( fromName + "To" + toName ); - } - - private String getName(Type type) { - StringBuilder builder = new StringBuilder(); - for ( Type typeParam : type.getTypeParameters() ) { - builder.append( typeParam.getIdentification() ); - } - builder.append( type.getIdentification() ); - return builder.toString(); - } - } private MapMappingMethod(Method method, Assignment keyAssignment, Assignment valueAssignment, MethodReference factoryMethod, boolean mapNullToDefault, List beforeMappingReferences, - List afterMappingReferences, - List forgedMethods) { - super( method, beforeMappingReferences, afterMappingReferences, forgedMethods ); + List afterMappingReferences) { + super( method, beforeMappingReferences, afterMappingReferences ); this.keyAssignment = keyAssignment; this.valueAssignment = valueAssignment; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java index f83208437..e746f4bf4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java @@ -23,7 +23,6 @@ import static org.mapstruct.ap.internal.util.Strings.join; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -32,7 +31,6 @@ import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; /** @@ -54,7 +52,6 @@ public abstract class MappingMethod extends ModelElement { private final List beforeMappingReferencesWithMappingTarget; private final List beforeMappingReferencesWithoutMappingTarget; private final List afterMappingReferences; - private final List forgedMethods; /** * constructor to be overloaded when local variable names are required prior to calling this constructor. (e.g. for @@ -68,14 +65,12 @@ public abstract class MappingMethod extends ModelElement { protected MappingMethod(Method method, Collection existingVariableNames, List beforeMappingReferences, List afterMappingReferences) { - this( method, method.getParameters(), existingVariableNames, beforeMappingReferences, afterMappingReferences, - Collections.emptyList() ); + this( method, method.getParameters(), existingVariableNames, beforeMappingReferences, afterMappingReferences ); } protected MappingMethod(Method method, List parameters, Collection existingVariableNames, List beforeMappingReferences, - List afterMappingReferences, - List forgedMethods) { + List afterMappingReferences) { this.name = method.getName(); this.parameters = parameters; this.sourceParameters = Parameter.getSourceParameters( parameters ); @@ -88,12 +83,10 @@ public abstract class MappingMethod extends ModelElement { this.beforeMappingReferencesWithMappingTarget = filterMappingTarget( beforeMappingReferences, true ); this.beforeMappingReferencesWithoutMappingTarget = filterMappingTarget( beforeMappingReferences, false ); this.afterMappingReferences = afterMappingReferences; - this.forgedMethods = forgedMethods; } protected MappingMethod(Method method, List parameters) { - this( method, parameters, new ArrayList( method.getParameterNames() ), null, null, - Collections.emptyList() ); + this( method, parameters, new ArrayList( method.getParameterNames() ), null, null ); } protected MappingMethod(Method method) { @@ -106,21 +99,6 @@ public abstract class MappingMethod extends ModelElement { afterMappingReferences ); } - protected MappingMethod(Method method, List beforeMappingReferences, - List afterMappingReferences, - List forgedMethods) { - this( method, method.getParameters(), new ArrayList( method.getParameterNames() ), - beforeMappingReferences, afterMappingReferences, forgedMethods ); - } - - public MappingMethod(Method method, Collection existingVariableNames, - List beforeMappingReferences, - List afterMappingReferences, - List allForgedMethods) { - this( method, method.getParameters(), existingVariableNames, beforeMappingReferences, afterMappingReferences, - allForgedMethods ); - } - private String initResultName(Collection existingVarNames) { if ( targetParameter != null ) { return targetParameter.getName(); @@ -239,10 +217,6 @@ public abstract class MappingMethod extends ModelElement { return beforeMappingReferencesWithoutMappingTarget; } - public List getForgedMethods() { - return forgedMethods; - } - @Override public int hashCode() { int hash = 7; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java index 4bac7add3..a0fa78d2b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java @@ -36,7 +36,6 @@ import org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAnd import org.mapstruct.ap.internal.model.assignment.UpdateWrapper; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; @@ -76,7 +75,6 @@ public class PropertyMapping extends ModelElement { private final Assignment assignment; private final List dependsOn; private final Assignment defaultValueAssignment; - private List forgedMethods = new ArrayList(); private enum TargetWriteAccessorType { FIELD, @@ -101,10 +99,7 @@ public class PropertyMapping extends ModelElement { } @SuppressWarnings("unchecked") - private static class MappingBuilderBase> { - - protected MappingBuilderContext ctx; - protected Method method; + private static class MappingBuilderBase> extends AbstractBaseBuilder { protected Accessor targetWriteAccessor; protected TargetWriteAccessorType targetWriteAccessorType; @@ -117,14 +112,12 @@ public class PropertyMapping extends ModelElement { protected List dependsOn; protected Set existingVariableNames; - public T mappingContext(MappingBuilderContext mappingContext) { - this.ctx = mappingContext; - return (T) this; + MappingBuilderBase(Class selfType) { + super( selfType ); } public T sourceMethod(Method sourceMethod) { - this.method = sourceMethod; - return (T) this; + return super.method( sourceMethod ); } public T targetProperty(PropertyEntry targetProp) { @@ -205,7 +198,10 @@ public class PropertyMapping extends ModelElement { private SourceRHS rightHandSide; private FormattingParameters formattingParameters; private SelectionParameters selectionParameters; - private List forgedMethods = new ArrayList(); + + PropertyMappingBuilder() { + super( PropertyMappingBuilder.class ); + } public PropertyMappingBuilder sourceReference(SourceReference sourceReference) { this.sourceReference = sourceReference; @@ -303,8 +299,7 @@ public class PropertyMapping extends ModelElement { localTargetVarName, assignment, dependsOn, - getDefaultValueAssignment( assignment ), - forgedMethods + getDefaultValueAssignment( assignment ) ); } @@ -563,31 +558,7 @@ public class PropertyMapping extends ModelElement { .callingContextTargetPropertyName( targetPropertyName ) .build(); - return getForgedAssignment( source, methodRef, iterableMappingMethod ); - } - - private Assignment getForgedAssignment(SourceRHS source, ForgedMethod methodRef, - MappingMethod mappingMethod) { - Assignment assignment = null; - if ( mappingMethod != null ) { - if ( !ctx.getMappingsToGenerate().contains( mappingMethod ) ) { - ctx.getMappingsToGenerate().add( mappingMethod ); - } - else { - String existingName = ctx.getExistingMappingMethod( mappingMethod ).getName(); - methodRef = new ForgedMethod( existingName, methodRef ); - } - - assignment = new MethodReference( - methodRef, - null, - ParameterBinding.fromParameters( methodRef.getParameters() ) - ); - assignment.setAssignment( source ); - forgedMethods.addAll( mappingMethod.getForgedMethods() ); - } - - return assignment; + return createForgedAssignment( source, methodRef, iterableMappingMethod ); } private ForgedMethod prepareForgedMethod(Type sourceType, Type targetType, SourceRHS source, @@ -619,7 +590,7 @@ public class PropertyMapping extends ModelElement { .method( methodRef ) .build(); - return getForgedAssignment( source, methodRef, mapMappingMethod ); + return createForgedAssignment( source, methodRef, mapMappingMethod ); } private Assignment forgeMapping(SourceRHS sourceRHS) { @@ -632,6 +603,7 @@ public class PropertyMapping extends ModelElement { } String name = getName( sourceType, targetType ); + name = Strings.getSaveVariableName( name, ctx.getNamesOfMappingsToGenerate() ); List parameters = new ArrayList( method.getContextParameters() ); Type returnType; if ( method.isUpdateMethod() ) { @@ -651,16 +623,8 @@ public class PropertyMapping extends ModelElement { getForgedMethodHistory( sourceRHS ) ); - Assignment assignment = new MethodReference( - forgedMethod, - null, - ParameterBinding.fromParameters( forgedMethod.getParameters() ) ); - assignment.setAssignment( sourceRHS ); - - this.forgedMethods.add( forgedMethod ); - - return assignment; + return createForgedBeanAssignment( sourceRHS, forgedMethod ); } private ForgedMethodHistory getForgedMethodHistory(SourceRHS sourceRHS) { @@ -715,6 +679,10 @@ public class PropertyMapping extends ModelElement { private FormattingParameters formattingParameters; private SelectionParameters selectionParameters; + ConstantMappingBuilder() { + super( ConstantMappingBuilder.class ); + } + public ConstantMappingBuilder constantExpression(String constantExpression) { this.constantExpression = constantExpression; return this; @@ -834,6 +802,10 @@ public class PropertyMapping extends ModelElement { private String javaExpression; + JavaExpressionMappingBuilder() { + super( JavaExpressionMappingBuilder.class ); + } + public JavaExpressionMappingBuilder javaExpression(String javaExpression) { this.javaExpression = javaExpression; return this; @@ -876,15 +848,14 @@ public class PropertyMapping extends ModelElement { Type targetType, String localTargetVarName, Assignment propertyAssignment, List dependsOn, Assignment defaultValueAssignment ) { this( name, null, targetWriteAccessorName, targetReadAccessorProvider, - targetType, localTargetVarName, propertyAssignment, dependsOn, defaultValueAssignment, - Collections.emptyList() ); + targetType, localTargetVarName, propertyAssignment, dependsOn, defaultValueAssignment + ); } private PropertyMapping(String name, String sourceBeanName, String targetWriteAccessorName, ValueProvider targetReadAccessorProvider, Type targetType, String localTargetVarName, Assignment assignment, - List dependsOn, Assignment defaultValueAssignment, - List forgedMethods) { + List dependsOn, Assignment defaultValueAssignment) { this.name = name; this.sourceBeanName = sourceBeanName; this.targetWriteAccessorName = targetWriteAccessorName; @@ -895,7 +866,6 @@ public class PropertyMapping extends ModelElement { this.assignment = assignment; this.dependsOn = dependsOn != null ? dependsOn : Collections.emptyList(); this.defaultValueAssignment = defaultValueAssignment; - this.forgedMethods = forgedMethods; } /** @@ -950,10 +920,6 @@ public class PropertyMapping extends ModelElement { return dependsOn; } - public List getForgedMethods() { - return forgedMethods; - } - @Override public String toString() { return "PropertyMapping {" diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java index ed8b7ceb1..318831bba 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java @@ -28,7 +28,6 @@ import java.util.stream.StreamSupport; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -64,8 +63,7 @@ public class StreamMappingMethod extends ContainerMappingMethod { protected StreamMappingMethod instantiateMappingMethod(Method method, Assignment assignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingMethods, - List afterMappingMethods, SelectionParameters selectionParameters, - ForgedMethod forgedMethod) { + List afterMappingMethods, SelectionParameters selectionParameters) { Set helperImports = new HashSet(); if ( method.getResultType().isIterableType() ) { @@ -87,8 +85,7 @@ public class StreamMappingMethod extends ContainerMappingMethod { beforeMappingMethods, afterMappingMethods, selectionParameters, - helperImports, - forgedMethod + helperImports ); } } @@ -97,8 +94,7 @@ public class StreamMappingMethod extends ContainerMappingMethod { boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, - SelectionParameters selectionParameters, Set helperImports, - ForgedMethod forgedMethod) { + SelectionParameters selectionParameters, Set helperImports) { super( method, parameterAssignment, @@ -107,8 +103,7 @@ public class StreamMappingMethod extends ContainerMappingMethod { loopVariableName, beforeMappingReferences, afterMappingReferences, - selectionParameters, - forgedMethod + selectionParameters ); this.helperImports = helperImports; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java index f0c72477e..00d5a7f93 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java @@ -19,12 +19,9 @@ package org.mapstruct.ap.internal.processor; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.lang.model.element.ExecutableElement; @@ -52,7 +49,6 @@ import org.mapstruct.ap.internal.model.StreamMappingMethod; import org.mapstruct.ap.internal.model.ValueMappingMethod; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.FormattingParameters; import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.Method; @@ -153,7 +149,7 @@ public class MapperCreationProcessor implements ModelElementProcessor methods) { List mapperReferences = mappingContext.getMapperReferences(); - List mappingMethods = getAllMappingMethods( mapperConfig, methods ); + List mappingMethods = getMappingMethods( mapperConfig, methods ); mappingMethods.addAll( mappingContext.getUsedVirtualMappings() ); mappingMethods.addAll( mappingContext.getMappingsToGenerate() ); @@ -262,55 +258,6 @@ public class MapperCreationProcessor implements ModelElementProcessor getAllMappingMethods(MapperConfiguration mapperConfig, List methods) { - List mappingMethods = getMappingMethods( mapperConfig, methods ); - - Collection excludedForgedMethods = new HashSet( ); - Collection forgedMethods = collectAllForgedMethods( mappingMethods, excludedForgedMethods ); - - while ( !forgedMethods.isEmpty() ) { - List mappingMethodsFromForged = createBeanMapping( forgedMethods ); - forgedMethods = collectAllForgedMethods( mappingMethodsFromForged, excludedForgedMethods ); - mappingMethods.addAll( mappingMethodsFromForged ); - } - - return mappingMethods; - } - - private List createBeanMapping(Collection forgedMethods) { - List mappingMethods = new ArrayList(); - - for ( ForgedMethod method : forgedMethods ) { - - BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder(); - BeanMappingMethod beanMappingMethod = builder - .mappingContext( mappingContext ) - .forgedMethod( method ) - .build(); - - - if ( beanMappingMethod != null ) { - mappingMethods.add( beanMappingMethod ); - } - } - - return mappingMethods; - } - - private Collection collectAllForgedMethods(Collection mappingMethods, - Collection excludedForgedMethods) { - Set forgedMethods = new HashSet(); - for ( MappingMethod mappingMethod : mappingMethods ) { - for ( ForgedMethod forgedMethod : mappingMethod.getForgedMethods() ) { - if ( !excludedForgedMethods.contains( forgedMethod )) { - forgedMethods.add( forgedMethod ); - excludedForgedMethods.add( forgedMethod ); - } - } - } - return forgedMethods; - } - private List getMappingMethods(MapperConfiguration mapperConfig, List methods) { List mappingMethods = new ArrayList(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java index 7e650e640..629f74efc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java @@ -122,6 +122,11 @@ public class CollectionMappingTest { line = 30, messageRegExp = "Can't map Map key \".* nonMappableMap\\{:key\\}\" to \".* nonMappableMap\\{:key\\}\". " + "Consider to declare/implement a mapping method: .*."), + @Diagnostic(type = ErroneousCollectionNonMappableMapMapper.class, + kind = Kind.ERROR, + line = 30, + messageRegExp = "Can't map Map value \".* nonMappableMap\\{:value\\}\" to \".* " + + "nonMappableMap\\{:value\\}\". Consider to declare/implement a mapping method: .*."), } ) public void shouldGenerateNonMappleMethodForMapMapping() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java index 4c780bc71..c01bc5406 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java @@ -29,6 +29,11 @@ import static org.assertj.core.api.Assertions.assertThat; User.class, UserDto.class, Car.class, CarDto.class, House.class, HouseDto.class, Wheel.class, WheelDto.class, Roof.class, RoofDto.class, + org.mapstruct.ap.test.nestedbeans.other.CarDto.class, + org.mapstruct.ap.test.nestedbeans.other.UserDto.class, + org.mapstruct.ap.test.nestedbeans.other.HouseDto.class, + org.mapstruct.ap.test.nestedbeans.other.RoofDto.class, + org.mapstruct.ap.test.nestedbeans.other.WheelDto.class, UserDtoMapperClassic.class, UserDtoMapperSmart.class, UserDtoUpdateMapperSmart.class diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java index 23bf6544d..6b50b65f3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java @@ -22,6 +22,7 @@ public class User { private String name; private Car car; + private Car secondCar; private House house; public User() { @@ -49,6 +50,14 @@ public class User { this.car = car; } + public Car getSecondCar() { + return secondCar; + } + + public void setSecondCar(Car secondCar) { + this.secondCar = secondCar; + } + public House getHouse() { return house; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java index 3ff64bd9f..a36b08ca0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java @@ -22,6 +22,7 @@ public class UserDto { private String name; private CarDto car; + private CarDto secondCar; private HouseDto house; public UserDto() { @@ -49,6 +50,14 @@ public class UserDto { this.car = car; } + public CarDto getSecondCar() { + return secondCar; + } + + public void setSecondCar(CarDto secondCar) { + this.secondCar = secondCar; + } + public HouseDto getHouse() { return house; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java index 86598904b..90e5322cc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java @@ -28,4 +28,5 @@ public interface UserDtoMapperSmart { UserDto userToUserDto(User user); + org.mapstruct.ap.test.nestedbeans.other.UserDto userToUserDto2( User user ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java new file mode 100644 index 000000000..40678c5f9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java @@ -0,0 +1,100 @@ +/** + * Copyright 2012-2017 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.nestedbeans.other; + +import java.util.List; + +public class CarDto { + + private String name; + private int year; + private List wheels; + + public CarDto() { + } + + public CarDto(String name, int year, List wheels) { + this.name = name; + this.year = year; + this.wheels = wheels; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public List getWheels() { + return wheels; + } + + public void setWheels(List wheels) { + this.wheels = wheels; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + CarDto carDto = (CarDto) o; + + if ( year != carDto.year ) { + return false; + } + if ( name != null ? !name.equals( carDto.name ) : carDto.name != null ) { + return false; + } + return wheels != null ? wheels.equals( carDto.wheels ) : carDto.wheels == null; + + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + year; + result = 31 * result + ( wheels != null ? wheels.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "CarDto{" + + "name='" + name + '\'' + + ", year=" + year + + ", wheels=" + wheels + + '}'; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java new file mode 100644 index 000000000..fd927131a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java @@ -0,0 +1,98 @@ +/** + * Copyright 2012-2017 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.nestedbeans.other; + +public class HouseDto { + + private String name; + private int year; + private RoofDto roof; + + public HouseDto() { + } + + public HouseDto(String name, int year, RoofDto roof) { + this.name = name; + this.year = year; + this.roof = roof; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public RoofDto getRoof() { + return roof; + } + + public void setRoof(RoofDto roof) { + this.roof = roof; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + HouseDto houseDto = (HouseDto) o; + + if ( year != houseDto.year ) { + return false; + } + if ( name != null ? !name.equals( houseDto.name ) : houseDto.name != null ) { + return false; + } + return roof != null ? roof.equals( houseDto.roof ) : houseDto.roof == null; + + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + year; + result = 31 * result + ( roof != null ? roof.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "HouseDto{" + + "name='" + name + '\'' + + ", year=" + year + + ", roof=" + roof + + '}'; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java new file mode 100644 index 000000000..1101df7c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java @@ -0,0 +1,66 @@ +/** + * Copyright 2012-2017 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.nestedbeans.other; + +public class RoofDto { + private String color; + + public RoofDto() { + } + + public RoofDto(String color) { + this.color = color; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + RoofDto roofDto = (RoofDto) o; + + return color != null ? color.equals( roofDto.color ) : roofDto.color == null; + + } + + @Override + public int hashCode() { + return color != null ? color.hashCode() : 0; + } + + @Override + public String toString() { + return "RoofDto{" + + "color='" + color + '\'' + + '}'; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java new file mode 100644 index 000000000..3ede3acba --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java @@ -0,0 +1,98 @@ +/** + * Copyright 2012-2017 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.nestedbeans.other; + +public class UserDto { + + private String name; + private CarDto car; + private HouseDto house; + + public UserDto() { + } + + public UserDto(String name, CarDto car, HouseDto house) { + this.name = name; + this.car = car; + this.house = house; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public CarDto getCar() { + return car; + } + + public void setCar(CarDto car) { + this.car = car; + } + + public HouseDto getHouse() { + return house; + } + + public void setHouse(HouseDto house) { + this.house = house; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + UserDto userDto = (UserDto) o; + + if ( name != null ? !name.equals( userDto.name ) : userDto.name != null ) { + return false; + } + if ( car != null ? !car.equals( userDto.car ) : userDto.car != null ) { + return false; + } + return house != null ? house.equals( userDto.house ) : userDto.house == null; + + } + + @Override + public int hashCode() { + int result = name != null ? name.hashCode() : 0; + result = 31 * result + ( car != null ? car.hashCode() : 0 ); + result = 31 * result + ( house != null ? house.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "UserDto{" + + "name='" + name + '\'' + + ", car=" + car + + ", house=" + house + + '}'; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java new file mode 100644 index 000000000..feb4de4ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java @@ -0,0 +1,80 @@ +/** + * Copyright 2012-2017 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.nestedbeans.other; + +public class WheelDto { + private boolean front; + private boolean right; + + public WheelDto() { + } + + public WheelDto(boolean front, boolean right) { + this.front = front; + this.right = right; + } + + public boolean isFront() { + return front; + } + + public void setFront(boolean front) { + this.front = front; + } + + public boolean isRight() { + return right; + } + + public void setRight(boolean right) { + this.right = right; + } + + @Override + public boolean equals(Object o) { + + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + WheelDto wheel = (WheelDto) o; + + if ( front != wheel.front ) { + return false; + } + return right == wheel.right; + + } + + @Override + public int hashCode() { + int result = ( front ? 1 : 0 ); + result = 31 * result + ( right ? 1 : 0 ); + return result; + } + + @Override + public String toString() { + return "Wheel{" + ( front ? "front" : "rear" ) + ";" + ( right ? "right" : "left" ) + '}'; + } + +}