From 090cfe3db235953c4a4ecd36bb72ce82b26a9b28 Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Tue, 27 Dec 2016 17:09:38 +0100 Subject: [PATCH] #1012 extract common class between IterableMappingMethod and StreamMappingMethod --- .../internal/model/IterableMappingMethod.java | 168 +-------------- .../internal/model/StreamMappingMethod.java | 160 +------------- .../model/WithElementMappingMethod.java | 195 ++++++++++++++++++ 3 files changed, 217 insertions(+), 306 deletions(-) create mode 100644 processor/src/main/java/org/mapstruct/ap/internal/model/WithElementMappingMethod.java 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 b4e357f33..c8e1cf577 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 @@ -20,17 +20,13 @@ package org.mapstruct.ap.internal.model; import static org.mapstruct.ap.internal.util.Collections.first; -import java.util.Collections; import java.util.HashSet; 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.assignment.LocalVarWrapper; import org.mapstruct.ap.internal.model.assignment.SetterWrapper; -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; @@ -47,14 +43,7 @@ import org.mapstruct.ap.internal.util.Strings; * * @author Gunnar Morling */ -public class IterableMappingMethod extends MappingMethod { - - private final Assignment elementAssignment; - private final MethodReference factoryMethod; - private final boolean overridden; - private final boolean mapNullToDefault; - private final String loopVariableName; - private final SelectionParameters selectionParameters; +public class IterableMappingMethod extends WithElementMappingMethod { public static class Builder { @@ -231,81 +220,17 @@ public class IterableMappingMethod extends MappingMethod { List beforeMappingReferences, List afterMappingReferences, SelectionParameters selectionParameters, ForgedMethod forgedMethod) { - super( method, beforeMappingReferences, afterMappingReferences, - forgedMethod == null ? Collections.emptyList() : - java.util.Collections.singletonList( forgedMethod ) + super( + method, + parameterAssignment, + factoryMethod, + mapNullToDefault, + loopVariableName, + beforeMappingReferences, + afterMappingReferences, + selectionParameters, + forgedMethod ); - this.elementAssignment = parameterAssignment; - this.factoryMethod = factoryMethod; - this.overridden = method.overridesMethod(); - this.mapNullToDefault = mapNullToDefault; - this.loopVariableName = loopVariableName; - this.selectionParameters = selectionParameters; - } - - public Parameter getSourceParameter() { - for ( Parameter parameter : getParameters() ) { - if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { - return parameter; - } - } - - throw new IllegalStateException( "Method " + this + " has no source parameter." ); - } - - public Assignment getElementAssignment() { - return elementAssignment; - } - - @Override - public Set getImportTypes() { - Set types = super.getImportTypes(); - if ( elementAssignment != null ) { - types.addAll( elementAssignment.getImportTypes() ); - } - if ( ( factoryMethod == null ) && ( !isExistingInstanceMapping() ) ) { - if ( getReturnType().getImplementationType() != null ) { - types.addAll( getReturnType().getImplementationType().getImportTypes() ); - } - } - return types; - } - - public boolean isMapNullToDefault() { - return mapNullToDefault; - } - - public boolean isOverridden() { - return overridden; - } - - public String getLoopVariableName() { - return loopVariableName; - } - - public String getDefaultValue() { - TypeKind kind = getResultElementType().getTypeMirror().getKind(); - switch ( kind ) { - case BOOLEAN: - return "false"; - case BYTE: - case SHORT: - case INT: - case CHAR: /*"'\u0000'" would have been better, but depends on platformencoding */ - return "0"; - case LONG: - return "0L"; - case FLOAT: - return "0.0f"; - case DOUBLE: - return "0.0d"; - default: - return "null"; - } - } - - public MethodReference getFactoryMethod() { - return this.factoryMethod; } public Type getSourceElementType() { @@ -327,75 +252,4 @@ public class IterableMappingMethod extends MappingMethod { return first( getResultType().determineTypeArguments( Iterable.class ) ); } } - - public String getIndex1Name() { - return Strings.getSaveVariableName( "i", loopVariableName, getSourceParameter().getName(), getResultName() ); - } - - public String getIndex2Name() { - return Strings.getSaveVariableName( "j", loopVariableName, getSourceParameter().getName(), getResultName() ); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ( ( getResultType() == null ) ? 0 : getResultType().hashCode() ); - return result; - } - - @Override - public boolean equals(Object obj) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - IterableMappingMethod other = (IterableMappingMethod) obj; - - if ( !getResultType().equals( other.getResultType() ) ) { - return false; - } - - if ( getSourceParameters().size() != other.getSourceParameters().size() ) { - return false; - } - - for ( int i = 0; i < getSourceParameters().size(); i++ ) { - if ( !getSourceParameters().get( i ).getType().equals( other.getSourceParameters().get( i ).getType() ) ) { - return false; - } - List thisTypeParameters = getSourceParameters().get( i ).getType().getTypeParameters(); - List otherTypeParameters = other.getSourceParameters().get( i ).getType().getTypeParameters(); - - if ( !thisTypeParameters.equals( otherTypeParameters ) ) { - return false; - } - } - - if ( this.selectionParameters != null ) { - if ( !this.selectionParameters.equals( other.selectionParameters ) ) { - return false; - } - } - else if ( other.selectionParameters != null ) { - return false; - } - - if ( this.factoryMethod != null ) { - if ( !this.factoryMethod.equals( other.factoryMethod ) ) { - return false; - } - } - else if ( other.factoryMethod != null ) { - return false; - } - - return isMapNullToDefault() == other.isMapNullToDefault(); - } - } 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 929a03317..69adc95ea 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 @@ -18,19 +18,15 @@ */ package org.mapstruct.ap.internal.model; -import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import javax.lang.model.type.TypeKind; import org.mapstruct.ap.internal.model.assignment.Assignment; import org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper; -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; @@ -49,14 +45,8 @@ import static org.mapstruct.ap.internal.util.Collections.first; * * @author Filip Hrisafov */ -public class StreamMappingMethod extends MappingMethod { +public class StreamMappingMethod extends WithElementMappingMethod { - private final Assignment elementAssignment; - private final MethodReference factoryMethod; - private final boolean overridden; - private final boolean mapNullToDefault; - private final String loopVariableName; - private final SelectionParameters selectionParameters; private final Set helperImports; public static class Builder { @@ -237,86 +227,29 @@ public class StreamMappingMethod extends MappingMethod { List afterMappingReferences, SelectionParameters selectionParameters, Set helperImports, ForgedMethod forgedMethod) { - super( method, beforeMappingReferences, afterMappingReferences, - forgedMethod == null ? new ArrayList() : Collections.singletonList( forgedMethod ) + super( + method, + parameterAssignment, + factoryMethod, + mapNullToDefault, + loopVariableName, + beforeMappingReferences, + afterMappingReferences, + selectionParameters, + forgedMethod ); - this.elementAssignment = parameterAssignment; - this.factoryMethod = factoryMethod; - this.overridden = method.overridesMethod(); - this.mapNullToDefault = mapNullToDefault; - this.loopVariableName = loopVariableName; - this.selectionParameters = selectionParameters; this.helperImports = helperImports; } - public Parameter getSourceParameter() { - for ( Parameter parameter : getParameters() ) { - if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { - return parameter; - } - } - - throw new IllegalStateException( "Method " + this + " has no source parameter." ); - } - - public Assignment getElementAssignment() { - return elementAssignment; - } - @Override public Set getImportTypes() { Set types = super.getImportTypes(); - if ( elementAssignment != null ) { - types.addAll( elementAssignment.getImportTypes() ); - } - if ( ( factoryMethod == null ) && ( !isExistingInstanceMapping() ) ) { - if ( getReturnType().getImplementationType() != null ) { - types.addAll( getReturnType().getImplementationType().getImportTypes() ); - } - } types.addAll( helperImports ); return types; } - public boolean isMapNullToDefault() { - return mapNullToDefault; - } - - public boolean isOverridden() { - return overridden; - } - - public String getLoopVariableName() { - return loopVariableName; - } - - public String getDefaultValue() { - TypeKind kind = getResultElementType().getTypeMirror().getKind(); - switch ( kind ) { - case BOOLEAN: - return "false"; - case BYTE: - case SHORT: - case INT: - case CHAR: /*"'\u0000'" would have been better, but depends on platformencoding */ - return "0"; - case LONG: - return "0L"; - case FLOAT: - return "0.0f"; - case DOUBLE: - return "0.0d"; - default: - return "null"; - } - } - - public MethodReference getFactoryMethod() { - return this.factoryMethod; - } - public Type getSourceElementType() { return getElementType( getSourceParameter().getType() ); } @@ -325,77 +258,6 @@ public class StreamMappingMethod extends MappingMethod { return getElementType( getResultType() ); } - public String getIndex1Name() { - return Strings.getSaveVariableName( "i", loopVariableName, getSourceParameter().getName(), getResultName() ); - } - - public String getIndex2Name() { - return Strings.getSaveVariableName( "j", loopVariableName, getSourceParameter().getName(), getResultName() ); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ( ( getResultType() == null ) ? 0 : getResultType().hashCode() ); - return result; - } - - @Override - public boolean equals(Object obj) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - StreamMappingMethod other = (StreamMappingMethod) obj; - - if ( !getResultType().equals( other.getResultType() ) ) { - return false; - } - - if ( getSourceParameters().size() != other.getSourceParameters().size() ) { - return false; - } - - for ( int i = 0; i < getSourceParameters().size(); i++ ) { - if ( !getSourceParameters().get( i ).getType().equals( other.getSourceParameters().get( i ).getType() ) ) { - return false; - } - - List thisTypeParameters = getSourceParameters().get( i ).getType().getTypeParameters(); - List otherTypeParameters = other.getSourceParameters().get( i ).getType().getTypeParameters(); - - if ( !thisTypeParameters.equals( otherTypeParameters ) ) { - return false; - } - } - - if ( this.selectionParameters != null ) { - if ( !this.selectionParameters.equals( other.selectionParameters ) ) { - return false; - } - } - else if ( other.selectionParameters != null ) { - return false; - } - - if ( this.factoryMethod != null ) { - if ( !this.factoryMethod.equals( other.factoryMethod ) ) { - return false; - } - } - else if ( other.factoryMethod != null ) { - return false; - } - - return isMapNullToDefault() == other.isMapNullToDefault(); - } - private static Type getElementType(Type parameterType) { if ( parameterType.isArrayType() ) { return parameterType.getComponentType(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/WithElementMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/WithElementMappingMethod.java new file mode 100644 index 000000000..86440c638 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/WithElementMappingMethod.java @@ -0,0 +1,195 @@ +/** + * 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 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; + +/** + * A {@link MappingMethod} implemented by a {@link Mapper} class which does mapping of typed based methods. + * For example Iterable or Stream. + * The typed elements are mapped either by a {@link TypeConversion} or another mapping method. + * + * @author Filip Hrisafov + */ +abstract class WithElementMappingMethod extends MappingMethod { + private final Assignment elementAssignment; + private final MethodReference factoryMethod; + private final boolean overridden; + private final boolean mapNullToDefault; + private final String loopVariableName; + private final SelectionParameters selectionParameters; + + WithElementMappingMethod(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 ) + ); + this.elementAssignment = parameterAssignment; + this.factoryMethod = factoryMethod; + this.overridden = method.overridesMethod(); + this.mapNullToDefault = mapNullToDefault; + this.loopVariableName = loopVariableName; + this.selectionParameters = selectionParameters; + } + + public Parameter getSourceParameter() { + for ( Parameter parameter : getParameters() ) { + if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { + return parameter; + } + } + + throw new IllegalStateException( "Method " + this + " has no source parameter." ); + } + + public Assignment getElementAssignment() { + return elementAssignment; + } + + @Override + public Set getImportTypes() { + Set types = super.getImportTypes(); + if ( elementAssignment != null ) { + types.addAll( elementAssignment.getImportTypes() ); + } + if ( ( factoryMethod == null ) && ( !isExistingInstanceMapping() ) ) { + if ( getReturnType().getImplementationType() != null ) { + types.addAll( getReturnType().getImplementationType().getImportTypes() ); + } + } + return types; + } + + public boolean isMapNullToDefault() { + return mapNullToDefault; + } + + public boolean isOverridden() { + return overridden; + } + + public String getLoopVariableName() { + return loopVariableName; + } + + public String getDefaultValue() { + TypeKind kind = getResultElementType().getTypeMirror().getKind(); + switch ( kind ) { + case BOOLEAN: + return "false"; + case BYTE: + case SHORT: + case INT: + case CHAR: /*"'\u0000'" would have been better, but depends on platformencoding */ + return "0"; + case LONG: + return "0L"; + case FLOAT: + return "0.0f"; + case DOUBLE: + return "0.0d"; + default: + return "null"; + } + } + + public MethodReference getFactoryMethod() { + return this.factoryMethod; + } + + public abstract Type getResultElementType(); + + public String getIndex1Name() { + return Strings.getSaveVariableName( "i", loopVariableName, getSourceParameter().getName(), getResultName() ); + } + + public String getIndex2Name() { + return Strings.getSaveVariableName( "j", loopVariableName, getSourceParameter().getName(), getResultName() ); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( getResultType() == null ) ? 0 : getResultType().hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + WithElementMappingMethod other = (WithElementMappingMethod) obj; + + if ( !getResultType().equals( other.getResultType() ) ) { + return false; + } + + if ( getSourceParameters().size() != other.getSourceParameters().size() ) { + return false; + } + + for ( int i = 0; i < getSourceParameters().size(); i++ ) { + if ( !getSourceParameters().get( i ).getType().equals( other.getSourceParameters().get( i ).getType() ) ) { + return false; + } + List thisTypeParameters = getSourceParameters().get( i ).getType().getTypeParameters(); + List otherTypeParameters = other.getSourceParameters().get( i ).getType().getTypeParameters(); + + if ( !thisTypeParameters.equals( otherTypeParameters ) ) { + return false; + } + } + + if ( this.selectionParameters != null ) { + if ( !this.selectionParameters.equals( other.selectionParameters ) ) { + return false; + } + } + else if ( other.selectionParameters != null ) { + return false; + } + + return isMapNullToDefault() == other.isMapNullToDefault(); + } + +}