diff --git a/processor/src/main/java/org/mapstruct/ap/conversion/ConversionProvider.java b/processor/src/main/java/org/mapstruct/ap/conversion/ConversionProvider.java index 93df6b003..06a007c21 100644 --- a/processor/src/main/java/org/mapstruct/ap/conversion/ConversionProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/conversion/ConversionProvider.java @@ -18,7 +18,7 @@ */ package org.mapstruct.ap.conversion; -import org.mapstruct.ap.model.TypeConversion; +import org.mapstruct.ap.model.Assignment; import org.mapstruct.ap.model.common.ConversionContext; /** @@ -37,22 +37,18 @@ public interface ConversionProvider { /** * Creates the conversion from source to target of a property mapping. * - * @param sourceReference A reference to the source object, e.g. - * {@code beanName.getFoo()}. * @param conversionContext ConversionContext providing optional information required for creating the conversion. * * @return A conversion from source to target. */ - TypeConversion to(String sourceReference, ConversionContext conversionContext); + Assignment to(ConversionContext conversionContext); /** * Creates the conversion from target to source of a property mapping. * - * @param targetReference A reference to the targetReference object, e.g. - * {@code beanName.getFoo()}. * @param conversionContext ConversionContext providing optional information required for creating the conversion. * * @return A conversion from target to source. */ - TypeConversion from(String targetReference, ConversionContext conversionContext); + Assignment from(ConversionContext conversionContext); } diff --git a/processor/src/main/java/org/mapstruct/ap/conversion/DateToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/conversion/DateToStringConversion.java index e35589e58..e705aad7a 100644 --- a/processor/src/main/java/org/mapstruct/ap/conversion/DateToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/conversion/DateToStringConversion.java @@ -20,11 +20,10 @@ package org.mapstruct.ap.conversion; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Collections; import java.util.Date; - -import org.mapstruct.ap.model.TypeConversion; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.assignment.AssignmentFactory; import org.mapstruct.ap.model.common.ConversionContext; import org.mapstruct.ap.model.common.Type; @@ -38,23 +37,21 @@ import static org.mapstruct.ap.util.Collections.asSet; public class DateToStringConversion implements ConversionProvider { @Override - public TypeConversion to(String sourceReference, ConversionContext conversionContext) { - return new TypeConversion( + public Assignment to(ConversionContext conversionContext) { + return AssignmentFactory.createTypeConversion( asSet( conversionContext.getTypeFactory().getType( SimpleDateFormat.class ) ), - Collections.emptyList(), + Collections.emptySet(), getOpenExpression( conversionContext, "format" ), - sourceReference, - getCloseExpression() - ); + getCloseExpression() ); + } @Override - public TypeConversion from(String targetReference, ConversionContext conversionContext) { - return new TypeConversion( + public Assignment from(ConversionContext conversionContext) { + return AssignmentFactory.createTypeConversion( asSet( conversionContext.getTypeFactory().getType( SimpleDateFormat.class ) ), - Arrays.asList( conversionContext.getTypeFactory().getType( ParseException.class ) ), + asSet( conversionContext.getTypeFactory().getType( ParseException.class ) ), getOpenExpression( conversionContext, "parse" ), - targetReference, getCloseExpression() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/conversion/ReverseConversion.java b/processor/src/main/java/org/mapstruct/ap/conversion/ReverseConversion.java index 186375dca..28db49745 100644 --- a/processor/src/main/java/org/mapstruct/ap/conversion/ReverseConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/conversion/ReverseConversion.java @@ -18,7 +18,7 @@ */ package org.mapstruct.ap.conversion; -import org.mapstruct.ap.model.TypeConversion; +import org.mapstruct.ap.model.Assignment; import org.mapstruct.ap.model.common.ConversionContext; /** @@ -40,12 +40,12 @@ public class ReverseConversion implements ConversionProvider { } @Override - public TypeConversion to(String sourceReference, ConversionContext conversionContext) { - return conversionProvider.from( sourceReference, conversionContext ); + public Assignment to( ConversionContext conversionContext) { + return conversionProvider.from( conversionContext ); } @Override - public TypeConversion from(String targetReference, ConversionContext conversionContext) { - return conversionProvider.to( targetReference, conversionContext ); + public Assignment from(ConversionContext conversionContext) { + return conversionProvider.to( conversionContext ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/conversion/SimpleConversion.java b/processor/src/main/java/org/mapstruct/ap/conversion/SimpleConversion.java index 3c27b91f2..80fabb5e5 100644 --- a/processor/src/main/java/org/mapstruct/ap/conversion/SimpleConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/conversion/SimpleConversion.java @@ -20,9 +20,10 @@ package org.mapstruct.ap.conversion; import java.util.Collections; import java.util.Set; - -import org.mapstruct.ap.model.TypeConversion; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.assignment.AssignmentFactory; import org.mapstruct.ap.model.common.ConversionContext; +import org.mapstruct.ap.model.assignment.TypeConversion; import org.mapstruct.ap.model.common.Type; /** @@ -33,24 +34,22 @@ import org.mapstruct.ap.model.common.Type; public abstract class SimpleConversion implements ConversionProvider { @Override - public TypeConversion to(String sourceReference, ConversionContext conversionContext) { + public Assignment to(ConversionContext conversionContext) { ConversionExpression toExpressions = getToExpressions( conversionContext ); - return new TypeConversion( + return AssignmentFactory.createTypeConversion( getToConversionImportTypes( conversionContext ), - Collections.emptyList(), + Collections.emptySet(), toExpressions.getOpenExpression(), - sourceReference, toExpressions.getCloseExpression() ); } @Override - public TypeConversion from(String targetReference, ConversionContext conversionContext) { + public Assignment from(ConversionContext conversionContext) { ConversionExpression fromExpressions = getFromExpressions( conversionContext ); - return new TypeConversion( + return AssignmentFactory.createTypeConversion( getFromConversionImportTypes( conversionContext ), - Collections.emptyList(), + Collections.emptySet(), fromExpressions.getOpenExpression(), - targetReference, fromExpressions.getCloseExpression() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/model/Assignment.java b/processor/src/main/java/org/mapstruct/ap/model/Assignment.java new file mode 100644 index 000000000..6bd103ee1 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/Assignment.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2014 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; + +import java.util.Set; +import org.mapstruct.ap.model.common.Type; + +/** + * + * @author Sjaak Derksen + */ +public interface Assignment { + + Set getImportTypes(); + + Set getExceptionTypes(); + + void setAssignment( Assignment assignment ); + + String getSourceReference(); + + // TODO: tempfix.. + boolean isSimple(); +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java index 05b59d766..19755449a 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java @@ -38,11 +38,11 @@ import org.mapstruct.ap.model.source.SourceMethod; public class BeanMappingMethod extends MappingMethod { private final List propertyMappings; - private final MethodReference factoryMethod; + private final Factory factoryMethod; public BeanMappingMethod(SourceMethod method, List propertyMappings, - MethodReference factoryMethod) { + Factory factoryMethod) { super( method ); this.propertyMappings = propertyMappings; this.factoryMethod = factoryMethod; @@ -78,7 +78,7 @@ public class BeanMappingMethod extends MappingMethod { return types; } - public MethodReference getFactoryMethod() { + public Factory getFactoryMethod() { return this.factoryMethod; } diff --git a/processor/src/main/java/org/mapstruct/ap/model/Factory.java b/processor/src/main/java/org/mapstruct/ap/model/Factory.java new file mode 100644 index 000000000..394325057 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/Factory.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2014 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; + +import java.util.Set; +import org.mapstruct.ap.model.common.Type; + +/** + * + * @author Sjaak Derksen + */ +public interface Factory { + + Set getExceptionTypes(); + +} 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 0d40f8dd6..7ec4dc4f8 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/IterableMappingMethod.java @@ -33,11 +33,10 @@ import org.mapstruct.ap.util.Strings; */ public class IterableMappingMethod extends MappingMethod { - private final TargetAssignment elementAssignment; - private final MethodReference factoryMethod; + private final Assignment elementAssignment; + private final Factory factoryMethod; - public IterableMappingMethod(SourceMethod method, TargetAssignment parameterAssignment, - MethodReference factoryMethod) { + public IterableMappingMethod(SourceMethod method, Assignment parameterAssignment, Factory factoryMethod) { super( method ); this.elementAssignment = parameterAssignment; this.factoryMethod = factoryMethod; @@ -53,7 +52,7 @@ public class IterableMappingMethod extends MappingMethod { throw new IllegalStateException( "Method " + this + " has no source parameter." ); } - public TargetAssignment getElementAssignment() { + public Assignment getElementAssignment() { return elementAssignment; } @@ -75,7 +74,7 @@ public class IterableMappingMethod extends MappingMethod { ); } - public MethodReference getFactoryMethod() { + public Factory getFactoryMethod() { return this.factoryMethod; } } 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 a9d7abffc..de8e78772 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MapMappingMethod.java @@ -33,12 +33,12 @@ import org.mapstruct.ap.util.Strings; */ public class MapMappingMethod extends MappingMethod { - private final TargetAssignment keyAssignment; - private final TargetAssignment valueAssignment; - private final MethodReference factoryMethod; + private final Assignment keyAssignment; + private final Assignment valueAssignment; + private final Factory factoryMethod; - public MapMappingMethod(SourceMethod method, TargetAssignment keyAssignment, TargetAssignment valueAssignment, - MethodReference factoryMethod) { + public MapMappingMethod(SourceMethod method, Assignment keyAssignment, Assignment valueAssignment, + Factory factoryMethod) { super( method ); this.keyAssignment = keyAssignment; @@ -56,11 +56,11 @@ public class MapMappingMethod extends MappingMethod { throw new IllegalStateException( "Method " + this + " has no source parameter." ); } - public TargetAssignment getKeyAssignment() { + public Assignment getKeyAssignment() { return keyAssignment; } - public TargetAssignment getValueAssignment() { + public Assignment getValueAssignment() { return valueAssignment; } @@ -99,7 +99,7 @@ public class MapMappingMethod extends MappingMethod { ); } - public MethodReference getFactoryMethod() { + public Factory getFactoryMethod() { return this.factoryMethod; } 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 7ff33ed1f..b88abb203 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java @@ -23,7 +23,6 @@ import java.util.Set; import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.Type; -import org.mapstruct.ap.model.TargetAssignment.AssignmentType; /** * Represents the mapping between a source and target property, e.g. from * {@code String Source#foo} to {@code int Target#bar}. Name and type of source @@ -45,12 +44,12 @@ public class PropertyMapping extends ModelElement { private final boolean isTargetAccessorSetter; private final String targetReadAccessorName; - private final TargetAssignment propertyAssignment; + private final Assignment propertyAssignment; public PropertyMapping(String sourceBeanName, String sourceName, String sourceAccessorName, Type sourceType, String targetName, String targetAccessorName, Type targetType, - TargetAssignment propertyAssignment ) { + Assignment propertyAssignment ) { this.sourceBeanName = sourceBeanName; this.sourceName = sourceName; @@ -95,7 +94,7 @@ public class PropertyMapping extends ModelElement { return targetType; } - public TargetAssignment getPropertyAssignment() { + public Assignment getPropertyAssignment() { return propertyAssignment; } @@ -122,12 +121,12 @@ public class PropertyMapping extends ModelElement { Set importTypes = new HashSet(); if ( propertyAssignment != null ) { if ( isTargetAccessorSetter() - && propertyAssignment.getAssignmentType().equals( AssignmentType.ASSIGNMENT ) + && propertyAssignment.isSimple() && ( targetType.isCollectionType() || targetType.isMapType() ) ) { importTypes.addAll( targetType.getImportTypes() ); } - if ( !propertyAssignment.getAssignmentType().equals( AssignmentType.ASSIGNMENT ) ) { + if ( !propertyAssignment.isSimple() ) { importTypes.addAll( propertyAssignment.getImportTypes() ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/TargetAssignment.java b/processor/src/main/java/org/mapstruct/ap/model/TargetAssignment.java deleted file mode 100644 index 98f4bfece..000000000 --- a/processor/src/main/java/org/mapstruct/ap/model/TargetAssignment.java +++ /dev/null @@ -1,120 +0,0 @@ -/** - * Copyright 2012-2014 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; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import org.mapstruct.ap.model.common.ModelElement; -import org.mapstruct.ap.model.common.Type; - -/** - * This class carries the possible ways to do an assignment to a parameter on a mapping target - * - * The following options exist: - *
    - *
  1. MethodReference
  2. - *
  3. TypeConversion
  4. - *
  5. Simple Assignment (empty TargetAssignment)
  6. - *
- * - * @author Sjaak Derksen - */ -public class TargetAssignment extends ModelElement { - - - - public static enum AssignmentType { TYPE_CONVERSION, METHOD_REFERENCE, ASSIGNMENT }; - - private MethodReference methodReference; - private TypeConversion typeConversion; - private final AssignmentType assignmentType; - - - public TargetAssignment() { - assignmentType = AssignmentType.ASSIGNMENT; - } - - public TargetAssignment( MethodReference methodReference ) { - assignmentType = AssignmentType.METHOD_REFERENCE; - this.methodReference = methodReference; - } - - public TargetAssignment( TypeConversion typeConversion ) { - assignmentType = AssignmentType.TYPE_CONVERSION; - this.typeConversion = typeConversion; - } - - public MethodReference getMethodReference() { - return methodReference; - } - - public TypeConversion getTypeConversion() { - return typeConversion; - } - - public AssignmentType getAssignmentType() { - return assignmentType; - } - - public List getExceptionTypes() { - List exceptionTypes = new ArrayList(); - switch ( assignmentType ) { - case METHOD_REFERENCE: -// exceptionTypes.addAll( methodReference.getExceptionTypes() ); - break; - case TYPE_CONVERSION: - exceptionTypes.addAll( typeConversion.getExceptionTypes() ); - break; - default: - } - return exceptionTypes; - } - - @Override - public Set getImportTypes() { - Set importedTypes = new HashSet(); - switch ( assignmentType ) { - case METHOD_REFERENCE: - importedTypes.addAll( methodReference.getImportTypes() ); - break; - case TYPE_CONVERSION: - importedTypes.addAll( typeConversion.getImportTypes() ); - break; - default: - } - return importedTypes; - } - - @Override - public String toString() { - String result = ""; - switch ( assignmentType ) { - case METHOD_REFERENCE: - result = methodReference.toString(); - break; - case TYPE_CONVERSION: - result = typeConversion.toString(); - break; - default: - } - return result; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentDecorator.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentDecorator.java new file mode 100644 index 000000000..f695358e2 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentDecorator.java @@ -0,0 +1,66 @@ +/** + * Copyright 2012-2014 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.Set; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.common.ModelElement; +import org.mapstruct.ap.model.common.Type; + +/** + * + * @author Sjaak Derksen + */ +public abstract class AssignmentDecorator extends ModelElement implements Assignment { + + private final Assignment decoratedAssignment; + + public AssignmentDecorator( Assignment decoratedAssignment ) { + this.decoratedAssignment = decoratedAssignment; + } + + @Override + public Set getImportTypes() { + return decoratedAssignment.getImportTypes(); + } + + @Override + public Set getExceptionTypes() { + return decoratedAssignment.getExceptionTypes(); + } + + @Override + public void setAssignment( Assignment assignment ) { + decoratedAssignment.setAssignment( assignment ); + } + + public Assignment getAssignment() { + return decoratedAssignment; + } + + @Override + public String getSourceReference() { + return decoratedAssignment.getSourceReference(); + } + + @Override + public boolean isSimple() { + return decoratedAssignment.isSimple(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentFactory.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentFactory.java new file mode 100644 index 000000000..db7179a4d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/AssignmentFactory.java @@ -0,0 +1,70 @@ +/** + * Copyright 2012-2014 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.Collections; +import java.util.Set; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.Factory; +import org.mapstruct.ap.model.MapperReference; +import org.mapstruct.ap.model.common.ConversionContext; +import org.mapstruct.ap.model.common.Type; +import org.mapstruct.ap.model.source.SourceMethod; +import org.mapstruct.ap.model.source.builtin.BuiltInMethod; + +/** + * + * @author Sjaak Derksen + */ +public class AssignmentFactory { + + private AssignmentFactory() { + } + + public static Assignment createTypeConversion( Set importTypes, + Set exceptionTypes, + String openExpression, + String closeExpression ) { + return new TypeConversion( importTypes, exceptionTypes, openExpression, closeExpression ); + } + + public static Assignment createTypeConversion( String openExpression, String closeExpression ) { + return new TypeConversion( Collections.emptySet(), + Collections.emptySet(), + openExpression, + closeExpression ); + } + + public static Factory createFactory(SourceMethod method, MapperReference declaringMapper) { + return new MethodReference( method, declaringMapper, null ); + } + + public static Assignment createAssignment(SourceMethod method, MapperReference declaringMapper, Type targetType) { + return new MethodReference(method, declaringMapper, targetType); + } + + public static Assignment createAssignment( BuiltInMethod method, ConversionContext contextParam ) { + return new MethodReference( method, contextParam ); + } + + public static SimpleAssignment createAssignment( String sourceRef ) { + return new SimpleAssignment(sourceRef ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/LocalVarDecorator.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/LocalVarDecorator.java new file mode 100644 index 000000000..98f49985d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/LocalVarDecorator.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2014 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 org.mapstruct.ap.model.Assignment; + +/** + * + * @author Sjaak Derksen + */ +public class LocalVarDecorator extends AssignmentDecorator { + + public LocalVarDecorator( Assignment decoratedAssignment ) { + super( decoratedAssignment ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/MethodReference.java similarity index 77% rename from processor/src/main/java/org/mapstruct/ap/model/MethodReference.java rename to processor/src/main/java/org/mapstruct/ap/model/assignment/MethodReference.java index 57f5ea683..70907a311 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MethodReference.java +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/MethodReference.java @@ -16,10 +16,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.mapstruct.ap.model; +package org.mapstruct.ap.model.assignment; import java.util.Collections; +import java.util.HashSet; import java.util.Set; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.Factory; +import org.mapstruct.ap.model.MapperReference; +import org.mapstruct.ap.model.MappingMethod; import org.mapstruct.ap.model.common.ConversionContext; import org.mapstruct.ap.model.common.Parameter; @@ -32,19 +37,11 @@ import org.mapstruct.ap.model.source.builtin.BuiltInMethod; * * @author Gunnar Morling */ -public class MethodReference extends MappingMethod { +public class MethodReference extends MappingMethod implements Assignment, Factory { private final MapperReference declaringMapper; private final Set importTypes; - /** - * A reference to another mapping method or typeConversion in case this is a two-step mapping, e.g. from - * {@code JAXBElement} to {@code Foo} to for which a nested method call will be generated: - * {@code setFoo(barToFoo( jaxbElemToValue( bar) ) )} - */ - private MethodReference methodRefChild; - private TypeConversion typeConversion; - /** * In case this reference targets a built-in method, allows to pass specific context information to the invoked * method. Currently this is only used to pass in the configured date format string when invoking a built-in method @@ -52,6 +49,14 @@ public class MethodReference extends MappingMethod { */ private final String contextParam; + + /** + * A reference to another mapping method or typeConversion in case this is a two-step mapping, e.g. from + * {@code JAXBElement} to {@code Foo} to for which a nested method call will be generated: + * {@code setFoo(barToFoo( jaxbElemToValue( bar) ) )} + */ + private Assignment assignment; + /** * Creates a new reference to the given method. * @@ -88,6 +93,20 @@ public class MethodReference extends MappingMethod { return contextParam; } + public Assignment getAssignment() { + return assignment; + } + + @Override + public void setAssignment( Assignment assignment ) { + this.assignment = assignment; + } + + @Override + public String getSourceReference() { + return assignment.getSourceReference(); + } + /** * @return the type of the single source parameter that is not the {@code @TargetType} parameter */ @@ -100,32 +119,27 @@ public class MethodReference extends MappingMethod { return null; } - public void setMethodRefChild(MethodReference methodRefChild) { - this.methodRefChild = methodRefChild; - } - - public MethodReference getMethodRefChild() { - return methodRefChild; - } - - public void setTypeConversionChild( TypeConversion typeConversion ) { - this.typeConversion = typeConversion; - } - - public TypeConversion getTypeConversion() { - return typeConversion; - } - @Override public Set getImportTypes() { - Set imported = super.getImportTypes(); + Set imported = new HashSet(super.getImportTypes()); imported.addAll( importTypes ); - if ( methodRefChild != null ) { - imported.addAll( methodRefChild.getImportTypes() ); - } - else if ( typeConversion != null ) { - imported.addAll( typeConversion.getImportTypes() ); + if ( assignment != null ) { + imported.addAll( assignment.getImportTypes() ); } return imported; } + + @Override + public Set getExceptionTypes() { + Set exceptions = new HashSet(); + if ( assignment != null ) { + exceptions.addAll( assignment.getExceptionTypes() ); + } + return exceptions; + } + + @Override + public boolean isSimple() { + return false; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/NewCollectionOrMapDecorator.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/NewCollectionOrMapDecorator.java new file mode 100644 index 000000000..1365500f5 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/NewCollectionOrMapDecorator.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2014 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 org.mapstruct.ap.model.Assignment; + +/** + * + * @author Sjaak Derksen + */ +public class NewCollectionOrMapDecorator extends AssignmentDecorator { + + public NewCollectionOrMapDecorator( Assignment decoratedAssignment ) { + super( decoratedAssignment ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/NullCheckDecorator.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/NullCheckDecorator.java new file mode 100644 index 000000000..f78e60254 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/NullCheckDecorator.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2014 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 org.mapstruct.ap.model.Assignment; + +/** + * + * @author Sjaak Derksen + */ +public class NullCheckDecorator extends AssignmentDecorator { + + public NullCheckDecorator( Assignment decoratedAssignment ) { + super( decoratedAssignment ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/SetterDecorator.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/SetterDecorator.java new file mode 100644 index 000000000..73a900019 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/SetterDecorator.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2014 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 org.mapstruct.ap.model.Assignment; + +/** + * + * @author Sjaak Derksen + */ +public class SetterDecorator extends AssignmentDecorator { + + public SetterDecorator( Assignment decoratedAssignment ) { + super( decoratedAssignment ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/SimpleAssignment.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/SimpleAssignment.java new file mode 100644 index 000000000..da5ee4dba --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/SimpleAssignment.java @@ -0,0 +1,62 @@ +/** + * Copyright 2012-2014 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.Collections; +import java.util.Set; +import org.mapstruct.ap.model.Assignment; +import org.mapstruct.ap.model.common.ModelElement; +import org.mapstruct.ap.model.common.Type; + +/** + * + * @author Sjaak Derksen + */ +public class SimpleAssignment extends ModelElement implements Assignment { + + private final String sourceReference; + + public SimpleAssignment( String sourceReference ) { + this.sourceReference = sourceReference; + } + + @Override + public String getSourceReference() { + return sourceReference; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + @Override + public Set getExceptionTypes() { + return Collections.emptySet(); + } + + @Override + public void setAssignment( Assignment assignment ) { + throw new UnsupportedOperationException( "Not supported." ); + } + + public boolean isSimple() { + return true; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/TypeConversion.java similarity index 75% rename from processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java rename to processor/src/main/java/org/mapstruct/ap/model/assignment/TypeConversion.java index 9e2f9a1d7..1aefbbf0f 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/TypeConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/TypeConversion.java @@ -16,11 +16,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.mapstruct.ap.model; +package org.mapstruct.ap.model.assignment; import java.util.HashSet; -import java.util.List; import java.util.Set; +import org.mapstruct.ap.model.Assignment; import org.mapstruct.ap.model.common.ModelElement; import org.mapstruct.ap.model.common.Type; @@ -30,31 +30,30 @@ import org.mapstruct.ap.model.common.Type; * * @author Gunnar Morling */ -public class TypeConversion extends ModelElement { +public class TypeConversion extends ModelElement implements Assignment { private final Set importTypes; - private final List exceptionTypes; - private final String sourceReference; + private final Set exceptionTypes; private final String openExpression; private final String closeExpression; + /** * A reference to mapping method in case this is a two-step mapping, e.g. from * {@code JAXBElement} to {@code Foo} to for which a nested method call will be generated: * {@code setFoo(barToFoo( jaxbElemToValue( bar) ) )} */ - private MethodReference methodRefChild; + private Assignment assignment; - public TypeConversion( Set importTypes, - List exceptionTypes, + + TypeConversion( Set importTypes, + Set exceptionTypes, String openExpression, - String sourceReference, String closeExpression ) { this.importTypes = new HashSet( importTypes ); this.importTypes.addAll( exceptionTypes ); this.exceptionTypes = exceptionTypes; this.openExpression = openExpression; - this.sourceReference = sourceReference; this.closeExpression = closeExpression; } @@ -63,7 +62,8 @@ public class TypeConversion extends ModelElement { return importTypes; } - public List getExceptionTypes() { + @Override + public Set getExceptionTypes() { return exceptionTypes; } @@ -71,19 +71,26 @@ public class TypeConversion extends ModelElement { return openExpression; } - public String getSourceReference() { - return sourceReference; - } - public String getCloseExpression() { return closeExpression; } - public void setMethodRefChild( MethodReference methodRefChild ) { - this.methodRefChild = methodRefChild; + public Assignment getAssignment() { + return assignment; } - public MethodReference getMethodRefChild() { - return methodRefChild; + @Override + public String getSourceReference() { + return assignment.getSourceReference(); + } + + @Override + public void setAssignment( Assignment assignment ) { + this.assignment = assignment; + } + + @Override + public boolean isSimple() { + return false; } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/assignment/package-info.java b/processor/src/main/java/org/mapstruct/ap/model/assignment/package-info.java new file mode 100644 index 000000000..bd086eacc --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/assignment/package-info.java @@ -0,0 +1,24 @@ +/** + * Copyright 2012-2014 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. + */ +/** + *

+ * Meta-model of assignments + *

+ */ +package org.mapstruct.ap.model.assignment; diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java index cf7e49944..c48d0409f 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java @@ -19,7 +19,6 @@ package org.mapstruct.ap.processor; import org.mapstruct.ap.processor.creation.MappingResolver; -import org.mapstruct.ap.model.TargetAssignment; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashMap; @@ -37,19 +36,25 @@ import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic.Kind; +import org.mapstruct.ap.model.Assignment; import org.mapstruct.ap.model.BeanMappingMethod; import org.mapstruct.ap.model.Decorator; import org.mapstruct.ap.model.DefaultMapperReference; import org.mapstruct.ap.model.DelegatingMethod; import org.mapstruct.ap.model.EnumMappingMethod; +import org.mapstruct.ap.model.Factory; import org.mapstruct.ap.model.IterableMappingMethod; import org.mapstruct.ap.model.MapMappingMethod; import org.mapstruct.ap.model.Mapper; import org.mapstruct.ap.model.MapperReference; import org.mapstruct.ap.model.MappingMethod; -import org.mapstruct.ap.model.MethodReference; import org.mapstruct.ap.model.PropertyMapping; +import org.mapstruct.ap.model.assignment.AssignmentFactory; +import org.mapstruct.ap.model.assignment.NewCollectionOrMapDecorator; +import org.mapstruct.ap.model.assignment.LocalVarDecorator; +import org.mapstruct.ap.model.assignment.NullCheckDecorator; +import org.mapstruct.ap.model.assignment.SetterDecorator; import org.mapstruct.ap.model.common.Parameter; import org.mapstruct.ap.model.common.Type; import org.mapstruct.ap.model.common.TypeFactory; @@ -316,9 +321,9 @@ public class MapperCreationProcessor implements ModelElementProcessor mapperReferences, List methods, + private Factory getFactoryMethod(List mapperReferences, List methods, Type returnType) { - MethodReference result = null; + Factory result = null; for ( SourceMethod method : methods ) { if ( !method.requiresImplementation() && !method.isIterableMapping() && !method.isMapMapping() && method.getSourceParameters().size() == 0 ) { @@ -329,7 +334,7 @@ public class MapperCreationProcessor implements ModelElementProcessor mapperReferences, @@ -690,7 +712,7 @@ public class MapperCreationProcessor implements ModelElementProcessor - *
  • the source type is assignable to the target type
  • - *
  • a mapping method exists
  • - *
  • a built-in conversion exists
  • - *
  • the property is of a collection or map type and the constructor of the target type (either itself or its - * implementation type) accepts the source type.
  • - * - * - * @param property The property mapping to check. - * - * @return {@code true} if the specified property can be mapped, {@code false} otherwise. - */ - private boolean isPropertyMappable(PropertyMapping property) { - boolean collectionOrMapTargetTypeHasCompatibleConstructor = false; - - if ( property.getSourceType().isCollectionType() && property.getTargetType().isCollectionType() ) { - collectionOrMapTargetTypeHasCompatibleConstructor = collectionTypeHasCompatibleConstructor( - property.getSourceType(), - property.getTargetType().getImplementationType() != null ? - property.getTargetType().getImplementationType() : property.getTargetType() - ); - } - - if ( property.getSourceType().isMapType() && property.getTargetType().isMapType() ) { - collectionOrMapTargetTypeHasCompatibleConstructor = mapTypeHasCompatibleConstructor( - property.getSourceType(), - property.getTargetType().getImplementationType() != null ? - property.getTargetType().getImplementationType() : property.getTargetType() - ); - } - - if ( property.getPropertyAssignment() != null || - ( ( property.getTargetType().isCollectionType() || property.getTargetType().isMapType() ) && - collectionOrMapTargetTypeHasCompatibleConstructor ) ) { - return true; - } - - return false; - } - - /** - * Whether the given target type has a single-argument constructor which accepts the given source type. - * - * @param sourceType the source type - * @param targetType the target type - * - * @return {@code true} if the target type has a constructor accepting the given source type, {@code false} - * otherwise. - */ - private boolean collectionTypeHasCompatibleConstructor(Type sourceType, Type targetType) { - // note (issue #127): actually this should check for the presence of a matching constructor, with help of - // Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead we - // just check whether the target type is parameterized in a way that it implicitly should have a constructor - // which accepts the source type - - TypeMirror sourceElementType = sourceType.getTypeParameters().isEmpty() ? - typeFactory.getType( Object.class ).getTypeMirror() : - sourceType.getTypeParameters().get( 0 ).getTypeMirror(); - - TypeMirror targetElementType = targetType.getTypeParameters().isEmpty() ? - typeFactory.getType( Object.class ).getTypeMirror() : - targetType.getTypeParameters().get( 0 ).getTypeMirror(); - - return typeUtils.isAssignable( sourceElementType, targetElementType ); - } - - /** - * Whether the given target type has a single-argument constructor which accepts the given source type. - * - * @param sourceType the source type - * @param targetType the target type - * - * @return {@code true} if the target type has a constructor accepting the given source type, {@code false} - * otherwise. - */ - private boolean mapTypeHasCompatibleConstructor(Type sourceType, Type targetType) { - // note (issue #127): actually this should check for the presence of a matching constructor, with help of - // Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead we - // just check whether the target type is parameterized in a way that it implicitly should have a constructor - // which accepts the source type - - TypeMirror sourceKeyType = null; - TypeMirror targetKeyType = null; - TypeMirror sourceValueType = null; - TypeMirror targetValueType = null; - - if ( sourceType.getTypeParameters().isEmpty() ) { - sourceKeyType = typeFactory.getType( Object.class ).getTypeMirror(); - sourceValueType = typeFactory.getType( Object.class ).getTypeMirror(); - } - else { - sourceKeyType = sourceType.getTypeParameters().get( 0 ).getTypeMirror(); - sourceValueType = sourceType.getTypeParameters().get( 1 ).getTypeMirror(); - } - - if ( targetType.getTypeParameters().isEmpty() ) { - targetKeyType = typeFactory.getType( Object.class ).getTypeMirror(); - targetValueType = typeFactory.getType( Object.class ).getTypeMirror(); - } - else { - targetKeyType = targetType.getTypeParameters().get( 0 ).getTypeMirror(); - targetValueType = targetType.getTypeParameters().get( 1 ).getTypeMirror(); - } - - return typeUtils.isAssignable( sourceKeyType, targetKeyType ) && - typeUtils.isAssignable( sourceValueType, targetValueType ); - } } diff --git a/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolver.java b/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolver.java index 5b6d242dd..cd4e69dc6 100644 --- a/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolver.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolver.java @@ -18,22 +18,23 @@ */ package org.mapstruct.ap.processor.creation; -import org.mapstruct.ap.model.TargetAssignment; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.annotation.processing.Messager; +import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic.Kind; import org.mapstruct.ap.conversion.ConversionProvider; import org.mapstruct.ap.conversion.Conversions; +import org.mapstruct.ap.model.Assignment; import org.mapstruct.ap.model.MapperReference; -import org.mapstruct.ap.model.MethodReference; -import org.mapstruct.ap.model.TypeConversion; +import org.mapstruct.ap.model.assignment.SimpleAssignment; import org.mapstruct.ap.model.VirtualMappingMethod; +import org.mapstruct.ap.model.assignment.AssignmentFactory; import org.mapstruct.ap.model.common.ConversionContext; import org.mapstruct.ap.model.common.DefaultConversionContext; import org.mapstruct.ap.model.common.Type; @@ -71,6 +72,7 @@ public class MappingResolver { private final TypeFactory typeFactory; private final Conversions conversions; private final BuiltInMappingMethods builtInMethods; + private final Types typeUtils; private final MethodSelectors methodSelectors; /** @@ -87,6 +89,7 @@ public class MappingResolver { this.builtInMethods = new BuiltInMappingMethods( typeFactory ); this.virtualMethods = new HashSet(); this.methodSelectors = new MethodSelectors( typeUtils, typeFactory ); + this.typeUtils = typeUtils; } @@ -111,7 +114,7 @@ public class MappingResolver { *
  • null, no assignment found
  • * */ - public TargetAssignment getTargetAssignment( SourceMethod mappingMethod, + public Assignment getTargetAssignment( SourceMethod mappingMethod, String mappedElement, List mapperReferences, List methods, @@ -174,52 +177,55 @@ public class MappingResolver { this.virtualMethodCandidates = new HashSet(); } - private TargetAssignment getTargetAssignment( Type sourceType, Type targetType ) { + private Assignment getTargetAssignment( Type sourceType, Type targetType ) { // first simpele mapping method - MethodReference mappingMethodReference = resolveViaMethod( sourceType, targetType ); - if ( mappingMethodReference != null ) { + Assignment referencedMethod = resolveViaMethod( sourceType, targetType ); + if ( referencedMethod != null ) { + referencedMethod.setAssignment( AssignmentFactory.createAssignment( sourceReference ) ); context.virtualMethods.addAll( virtualMethodCandidates ); - return new TargetAssignment( mappingMethodReference ); + return referencedMethod; } // then direct assignable - if ( sourceType.isAssignableTo( targetType ) ) { - return new TargetAssignment(); + if ( sourceType.isAssignableTo( targetType ) || context.isPropertyMappable( sourceType, targetType ) ) { + SimpleAssignment simpleAssignment = AssignmentFactory.createAssignment( sourceReference ); + return simpleAssignment; } // then type conversion - TypeConversion conversion = resolveViaConversion( sourceType, targetType ); + Assignment conversion = resolveViaConversion( sourceType, targetType ); if ( conversion != null ) { - return new TargetAssignment( conversion ); + conversion.setAssignment( AssignmentFactory.createAssignment( sourceReference) ); + return conversion; } // 2 step method, first: method(method(souurce)) - mappingMethodReference = resolveViaMethodAndMethod( sourceType, targetType ); - if ( mappingMethodReference != null ) { + referencedMethod = resolveViaMethodAndMethod( sourceType, targetType ); + if ( referencedMethod != null ) { context.virtualMethods.addAll( virtualMethodCandidates ); - return new TargetAssignment( mappingMethodReference ); + return referencedMethod; } // 2 step method, then: method(conversion(souurce)) - mappingMethodReference = resolveViaConversionAndMethod( sourceType, targetType ); - if ( mappingMethodReference != null ) { + referencedMethod = resolveViaConversionAndMethod( sourceType, targetType ); + if ( referencedMethod != null ) { context.virtualMethods.addAll( virtualMethodCandidates ); - return new TargetAssignment( mappingMethodReference ); + return referencedMethod; } // 2 step method, finally: conversion(method(souurce)) conversion = resolveViaMethodAndConversion( sourceType, targetType ); if ( conversion != null ) { context.virtualMethods.addAll( virtualMethodCandidates ); - return new TargetAssignment( conversion ); + return conversion; } // if nothing works, alas, the result is null return null; } - private TypeConversion resolveViaConversion( Type sourceType, Type targetType ) { + private Assignment resolveViaConversion( Type sourceType, Type targetType ) { ConversionProvider conversionProvider = context.conversions.getConversion( sourceType, targetType ); @@ -227,10 +233,9 @@ public class MappingResolver { return null; } - return conversionProvider.to( - sourceReference, - new DefaultConversionContext( context.typeFactory, targetType, dateFormat ) - ); + ConversionContext ctx = new DefaultConversionContext( context.typeFactory, targetType, dateFormat ); + Assignment typeConversion = conversionProvider.to( ctx ); + return typeConversion; } /** @@ -238,7 +243,7 @@ public class MappingResolver { * exists. * */ - private MethodReference resolveViaMethod( Type sourceType, Type targetType ) { + private Assignment resolveViaMethod( Type sourceType, Type targetType ) { // first try to find a matching source method SourceMethod matchingSourceMethod = getBestMatch( methods, sourceType, targetType ); @@ -254,7 +259,9 @@ public class MappingResolver { if ( matchingBuiltInMethod != null ) { virtualMethodCandidates.add( new VirtualMappingMethod( matchingBuiltInMethod ) ); ConversionContext ctx = new DefaultConversionContext( context.typeFactory, targetType, dateFormat ); - return new MethodReference( matchingBuiltInMethod, ctx ); + Assignment methodReference = AssignmentFactory.createAssignment( matchingBuiltInMethod, ctx ); + methodReference.setAssignment( AssignmentFactory.createAssignment( sourceReference ) ); + return methodReference; } return null; @@ -270,12 +277,12 @@ public class MappingResolver { * * then this method tries to resolve this combination and make a mapping methodY( methodX ( parameter ) ) */ - private MethodReference resolveViaMethodAndMethod( Type sourceType, Type targetType ) { + private Assignment resolveViaMethodAndMethod( Type sourceType, Type targetType ) { List methodYCandidates = new ArrayList( methods ); methodYCandidates.addAll( context.builtInMethods.getBuiltInMethods() ); - MethodReference methodRefY = null; + Assignment methodRefY = null; // Iterate over all source methods. Check if the return type matches with the parameter that we need. // so assume we need a method from A to C we look for a methodX from A to B (all methods in the @@ -288,12 +295,13 @@ public class MappingResolver { methodRefY = resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType ); if ( methodRefY != null ) { - MethodReference methodRefX = resolveViaMethod( + Assignment methodRefX = resolveViaMethod( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType() ); if ( methodRefX != null ) { - methodRefY.setMethodRefChild( methodRefX ); + methodRefY.setAssignment( methodRefX ); + methodRefX.setAssignment( AssignmentFactory.createAssignment( sourceReference ) ); break; } else { @@ -315,12 +323,12 @@ public class MappingResolver { * * then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) ) */ - private MethodReference resolveViaConversionAndMethod( Type sourceType, Type targetType ) { + private Assignment resolveViaConversionAndMethod( Type sourceType, Type targetType ) { List methodYCandidates = new ArrayList( methods ); methodYCandidates.addAll( context.builtInMethods.getBuiltInMethods() ); - MethodReference methodRefY = null; + Assignment methodRefY = null; for ( Method methodYCandidate : methodYCandidates ) { if ( methodYCandidate.getSourceParameters().size() == 1 ) { @@ -329,12 +337,13 @@ public class MappingResolver { targetType ); if ( methodRefY != null ) { - TypeConversion conversionXRef = resolveViaConversion( + Assignment conversionXRef = resolveViaConversion( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType() ); if ( conversionXRef != null ) { - methodRefY.setTypeConversionChild( conversionXRef ); + methodRefY.setAssignment( conversionXRef ); + conversionXRef.setAssignment( new SimpleAssignment( sourceReference ) ); break; } else { @@ -356,27 +365,25 @@ public class MappingResolver { * * then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) ) */ - private TypeConversion resolveViaMethodAndConversion( Type sourceType, Type targetType ) { + private Assignment resolveViaMethodAndConversion( Type sourceType, Type targetType ) { List methodXCandidates = new ArrayList( methods ); methodXCandidates.addAll( context.builtInMethods.getBuiltInMethods() ); - TypeConversion conversionYRef = null; + Assignment conversionYRef = null; // search the other way arround for ( Method methodXCandidate : methodXCandidates ) { if ( methodXCandidate.getSourceParameters().size() == 1 ) { - MethodReference methodRefX = resolveViaMethod( + Assignment methodRefX = resolveViaMethod( sourceType, methodXCandidate.getReturnType() ); if ( methodRefX != null ) { - conversionYRef = resolveViaConversion( - methodXCandidate.getReturnType(), - targetType - ); + conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType ); if ( conversionYRef != null ) { - conversionYRef.setMethodRefChild( methodRefX ); + conversionYRef.setAssignment( methodRefX ); + methodRefX.setAssignment( new SimpleAssignment( sourceReference ) ); break; } else { @@ -423,12 +430,12 @@ public class MappingResolver { return null; } - private MethodReference getMappingMethodReference( SourceMethod method, + private Assignment getMappingMethodReference( SourceMethod method, List mapperReferences, Type targetType ) { MapperReference mapperReference = findMapperReference( mapperReferences, method ); - return new MethodReference( + return AssignmentFactory.createAssignment( method, mapperReference, SourceMethod.containsTargetTypeParameter( method.getParameters() ) ? targetType : null @@ -444,4 +451,113 @@ public class MappingResolver { return null; } } + + /** + * Whether the specified property can be mapped from source to target or not. A mapping if possible if one of + * the following conditions is true: + *
      + *
    • the source type is assignable to the target type
    • + *
    • a mapping method exists
    • + *
    • a built-in conversion exists
    • + *
    • the property is of a collection or map type and the constructor of the target type (either itself or its + * implementation type) accepts the source type.
    • + *
    + * + * @param property The property mapping to check. + * + * @return {@code true} if the specified property can be mapped, {@code false} otherwise. + */ + private boolean isPropertyMappable(Type sourceType, Type targetType) { + boolean collectionOrMapTargetTypeHasCompatibleConstructor = false; + + if ( sourceType.isCollectionType() && targetType.isCollectionType() ) { + collectionOrMapTargetTypeHasCompatibleConstructor = collectionTypeHasCompatibleConstructor( + sourceType, + targetType.getImplementationType() != null ? + targetType.getImplementationType() : targetType + ); + } + + if ( sourceType.isMapType() && targetType.isMapType() ) { + collectionOrMapTargetTypeHasCompatibleConstructor = mapTypeHasCompatibleConstructor( + sourceType, + targetType.getImplementationType() != null ? + targetType.getImplementationType() : targetType + ); + } + + if ( ( ( targetType.isCollectionType() || targetType.isMapType() ) && + collectionOrMapTargetTypeHasCompatibleConstructor ) ) { + return true; + } + + return false; + } + /** + * Whether the given target type has a single-argument constructor which accepts the given source type. + * + * @param sourceType the source type + * @param targetType the target type + * + * @return {@code true} if the target type has a constructor accepting the given source type, {@code false} + * otherwise. + */ + private boolean collectionTypeHasCompatibleConstructor(Type sourceType, Type targetType) { + // note (issue #127): actually this should check for the presence of a matching constructor, with help of + // Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead we + // just check whether the target type is parameterized in a way that it implicitly should have a constructor + // which accepts the source type + + TypeMirror sourceElementType = sourceType.getTypeParameters().isEmpty() ? + typeFactory.getType( Object.class ).getTypeMirror() : + sourceType.getTypeParameters().get( 0 ).getTypeMirror(); + + TypeMirror targetElementType = targetType.getTypeParameters().isEmpty() ? + typeFactory.getType( Object.class ).getTypeMirror() : + targetType.getTypeParameters().get( 0 ).getTypeMirror(); + + return typeUtils.isAssignable( sourceElementType, targetElementType ); + } + + /** + * Whether the given target type has a single-argument constructor which accepts the given source type. + * + * @param sourceType the source type + * @param targetType the target type + * + * @return {@code true} if the target type has a constructor accepting the given source type, {@code false} + * otherwise. + */ + private boolean mapTypeHasCompatibleConstructor(Type sourceType, Type targetType) { + // note (issue #127): actually this should check for the presence of a matching constructor, with help of + // Types#asMemberOf(); but this method seems to not work correctly in the Eclipse implementation, so instead we + // just check whether the target type is parameterized in a way that it implicitly should have a constructor + // which accepts the source type + + TypeMirror sourceKeyType = null; + TypeMirror targetKeyType = null; + TypeMirror sourceValueType = null; + TypeMirror targetValueType = null; + + if ( sourceType.getTypeParameters().isEmpty() ) { + sourceKeyType = typeFactory.getType( Object.class ).getTypeMirror(); + sourceValueType = typeFactory.getType( Object.class ).getTypeMirror(); + } + else { + sourceKeyType = sourceType.getTypeParameters().get( 0 ).getTypeMirror(); + sourceValueType = sourceType.getTypeParameters().get( 1 ).getTypeMirror(); + } + + if ( targetType.getTypeParameters().isEmpty() ) { + targetKeyType = typeFactory.getType( Object.class ).getTypeMirror(); + targetValueType = typeFactory.getType( Object.class ).getTypeMirror(); + } + else { + targetKeyType = targetType.getTypeParameters().get( 0 ).getTypeMirror(); + targetValueType = targetType.getTypeParameters().get( 1 ).getTypeMirror(); + } + + return typeUtils.isAssignable( sourceKeyType, targetKeyType ) && + typeUtils.isAssignable( sourceValueType, targetValueType ); + } } diff --git a/processor/src/main/resources/org.mapstruct.ap.model.IterableMappingMethod.ftl b/processor/src/main/resources/org.mapstruct.ap.model.IterableMappingMethod.ftl index 49e8aa46b..7ee651515 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.IterableMappingMethod.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.IterableMappingMethod.ftl @@ -32,7 +32,7 @@ for ( <@includeModel object=sourceParameter.type.typeParameters[0]/> ${loopVariableName} : ${sourceParameter.name} ) { - <@includeModel object=elementAssignment target="${resultName}.add" source="${loopVariableName}" targetType="${resultType.typeParameters[0].name}"/> + <@includeModel object=elementAssignment target="${resultName}.add" targetType="${resultType.typeParameters[0].name}"/> } <#if returnType.name != "void"> diff --git a/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl b/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl index 2c9664125..3c83646c8 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.MapMappingMethod.ftl @@ -36,13 +36,11 @@ <@includeModel object=keyAssignment target=keyVariableName targetType=typeName(resultType.typeParameters[0]) - source="entry.getKey()" isLocalVar=true/> <#-- value --> <@includeModel object=valueAssignment target=valueVariableName targetType=typeName(resultType.typeParameters[1]) - source="entry.getValue()" isLocalVar=true/> ${resultName}.put( ${keyVariableName}, ${valueVariableName} ); } diff --git a/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl b/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl index 5c2e30f8b..32faa815a 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.PropertyMapping.ftl @@ -20,13 +20,7 @@ --> <#if !( targetType.collectionType || targetType.mapType ) > <#-- non collections or maps --> - <#if ( !sourceType.primitive && propertyAssignment.assignmentType!="ASSIGNMENT" ) > - if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { - <@assignmentLine/> - } - <#else> - <@assignmentLine/> - + <@assignment aTargetType=targetType/> <#else> <#-- collections or maps --> <#if ( ext.existingInstanceMapping || !targetAccessorSetter ) > @@ -34,39 +28,19 @@ <#if ext.existingInstanceMapping> ${ext.targetBeanName}.${targetReadAccessorName}().clear(); <#t> - if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { <#if targetType.collectionType> - <@collectionOrMapAssignmentLine target="${ext.targetBeanName}.${targetReadAccessorName}().addAll"/> + <@assignment aTarget="${ext.targetBeanName}.${targetReadAccessorName}().addAll"/> <#else> - <@collectionOrMapAssignmentLine target="${ext.targetBeanName}.${targetReadAccessorName}().putAll"/> + <@assignment aTarget="${ext.targetBeanName}.${targetReadAccessorName}().putAll"/> - } } <#if targetAccessorSetter> - else if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { - <@collectionOrMapAssignmentLine/> - } + else <@assignment/> <#elseif targetAccessorSetter> - if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { - <@collectionOrMapAssignmentLine/> - } + <@assignment/> - <#macro collectionOrMapAssignmentLine - target="${ext.targetBeanName}.${targetAccessorName}" - source="${sourceBeanName}.${sourceAccessorName}"> - <#compress> - <#if propertyAssignment?? && propertyAssignment.assignmentType!="ASSIGNMENT"> - <@assignmentLine target source/> - <#else> - ${target}( new <#if targetType.implementationType??><@includeModel object=targetType.implementationType/><#else><@includeModel object=targetType/>( ${source}() ) ); - - - - -<#macro assignmentLine - target="${ext.targetBeanName}.${targetAccessorName}" - source="${sourceBeanName}.${sourceAccessorName}"> - <@includeModel object=propertyAssignment target=target source="${source}()" targetType=targetType raw=true/> + <#macro assignment aTarget="${ext.targetBeanName}.${targetAccessorName}" aTargetType=targetType> + <@includeModel object=propertyAssignment target=aTarget targetType=aTargetType raw=true/> diff --git a/processor/src/main/resources/org.mapstruct.ap.model.TargetAssignment.ftl b/processor/src/main/resources/org.mapstruct.ap.model.TargetAssignment.ftl deleted file mode 100644 index b189816d1..000000000 --- a/processor/src/main/resources/org.mapstruct.ap.model.TargetAssignment.ftl +++ /dev/null @@ -1,65 +0,0 @@ -<#-- - - Copyright 2012-2014 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 ( ext.isLocalVar?? && ext.isLocalVar==true )> - <#-- assignment is a local variable assignment --> - <#if (exceptionTypes?size == 0) > - ${ext.targetType} ${ext.target} = <@assignment/>; - <#else> - ${ext.targetType} ${ext.target}; - try { - ${ext.target} = <@assignment/>; - } - <#list exceptionTypes as exceptionType> - catch ( <@includeModel object=exceptionType/> e ) { - throw new RuntimeException( e ); - } - - -<#else> - <#-- assignment is a method call --> - <#if (exceptionTypes?size == 0) > - ${ext.target}( <@assignment/> ); - <#else> - try { - ${ext.target}( <@assignment/> ); - } - <#list exceptionTypes as exceptionType> - catch ( <@includeModel object=exceptionType/> e ) { - throw new RuntimeException( e ); - } - - - -<#macro assignment> - <#compress> - <#switch assignmentType> - <#case "TYPE_CONVERSION"> - <@includeModel object=typeConversion source="${ext.source}" targetType=ext.targetType/> - <#break> - <#case "METHOD_REFERENCE"> - <@includeModel object=methodReference source="${ext.source}" targetType=ext.targetType raw=ext.raw/> - <#break> - <#case "ASSIGNMENT"> - ${ext.source} - <#break> - - - diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.LocalVarDecorator.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.LocalVarDecorator.ftl new file mode 100644 index 000000000..92879e807 --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.LocalVarDecorator.ftl @@ -0,0 +1,33 @@ +<#-- + + Copyright 2012-2014 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) > + ${ext.targetType} ${ext.target} = <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/>; +<#else> + ${ext.targetType} ${ext.target}; + try { + ${ext.target} = <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/>; + } + <#list exceptionTypes as exceptionType> + catch ( <@includeModel object=exceptionType/> e ) { + throw new RuntimeException( e ); + } + + \ No newline at end of file diff --git a/processor/src/main/resources/org.mapstruct.ap.model.MethodReference.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.MethodReference.ftl similarity index 69% rename from processor/src/main/resources/org.mapstruct.ap.model.MethodReference.ftl rename to processor/src/main/resources/org.mapstruct.ap.model.assignment.MethodReference.ftl index 1c440062f..b8f281e2d 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.MethodReference.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.MethodReference.ftl @@ -27,20 +27,11 @@ <#-- a class is passed on for casting, see @TargetType --> ${ext.targetType}.class <#else> - <#if methodRefChild??> - <#-- the nested case: another method --> - <@includeModel object=methodRefChild source=ext.source targetType=singleSourceParameterType.name/> - <#elseif typeConversion??> - <#-- the nested case: a type conversion --> - <@includeModel object=typeConversion source=ext.source targetType=singleSourceParameterType.name/> - <#else> - <#-- the non nested case --> - ${ext.source} - + <@includeModel object=assignment targetType=singleSourceParameterType raw=ext.raw/> <#if param_has_next>, - <#-- context parameter, e.g. for buildin methods concerning date conversion --> + <#-- context parameter, e.g. for builtin methods concerning date conversion --> <#if contextParam??>, ${contextParam} diff --git a/processor/src/main/resources/org.mapstruct.ap.model.TypeConversion.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.NewCollectionOrMapDecorator.ftl similarity index 72% rename from processor/src/main/resources/org.mapstruct.ap.model.TypeConversion.ftl rename to processor/src/main/resources/org.mapstruct.ap.model.assignment.NewCollectionOrMapDecorator.ftl index 49032127a..30d3d75b4 100644 --- a/processor/src/main/resources/org.mapstruct.ap.model.TypeConversion.ftl +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.NewCollectionOrMapDecorator.ftl @@ -18,10 +18,4 @@ limitations under the License. --> -<#if methodRefChild??> - <#-- the nested case: mapping method --> - ${openExpression}<@includeModel object=methodRefChild source=ext.source targetType=ext.targetType/>${closeExpression} -<#else> - <#-- the non nested case: a type conversion --> - ${openExpression}${sourceReference}${closeExpression} - \ No newline at end of file +${ext.target}( new <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/>( ${sourceReference} ) ); diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.NullCheckDecorator.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.NullCheckDecorator.ftl new file mode 100644 index 000000000..983b304f8 --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.NullCheckDecorator.ftl @@ -0,0 +1,23 @@ +<#-- + + Copyright 2012-2014 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 ( ${sourceReference} != null ) { + <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/> +} diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.SetterDecorator.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.SetterDecorator.ftl new file mode 100644 index 000000000..3aa72d1f9 --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.SetterDecorator.ftl @@ -0,0 +1,32 @@ +<#-- + + Copyright 2012-2014 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) > + ${ext.target}( <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/> ); +<#else> + try { + ${ext.target}( <@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/> ); + } + <#list exceptionTypes as exceptionType> + catch ( <@includeModel object=exceptionType/> e ) { + throw new RuntimeException( e ); + } + + \ No newline at end of file diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.SimpleAssignment.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.SimpleAssignment.ftl new file mode 100644 index 000000000..9a0aacb6c --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.SimpleAssignment.ftl @@ -0,0 +1,21 @@ +<#-- + + Copyright 2012-2014 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. + +--> +${sourceReference} \ No newline at end of file diff --git a/processor/src/main/resources/org.mapstruct.ap.model.assignment.TypeConversion.ftl b/processor/src/main/resources/org.mapstruct.ap.model.assignment.TypeConversion.ftl new file mode 100644 index 000000000..6f540715b --- /dev/null +++ b/processor/src/main/resources/org.mapstruct.ap.model.assignment.TypeConversion.ftl @@ -0,0 +1,21 @@ +<#-- + + Copyright 2012-2014 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. + +--> +${openExpression}<@includeModel object=assignment target=ext.target targetType=ext.targetType raw=ext.raw/>${closeExpression} \ No newline at end of file