diff --git a/core/src/main/java/org/mapstruct/Mapper.java b/core/src/main/java/org/mapstruct/Mapper.java index d70cf5e5e..ac5298fcf 100644 --- a/core/src/main/java/org/mapstruct/Mapper.java +++ b/core/src/main/java/org/mapstruct/Mapper.java @@ -29,4 +29,5 @@ import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Mapper { + Class[] uses() default { }; } diff --git a/core/src/main/java/org/mapstruct/Mapping.java b/core/src/main/java/org/mapstruct/Mapping.java index 9732753c5..07026f9a3 100644 --- a/core/src/main/java/org/mapstruct/Mapping.java +++ b/core/src/main/java/org/mapstruct/Mapping.java @@ -15,15 +15,9 @@ */ package org.mapstruct; -import org.mapstruct.converter.Converter; -import org.mapstruct.converter.NoOpConverter; - public @interface Mapping { String source(); String target(); - - Class> converter() default NoOpConverter.class; - } diff --git a/core/src/main/java/org/mapstruct/converter/Converter.java b/core/src/main/java/org/mapstruct/converter/Converter.java deleted file mode 100644 index 5567b7111..000000000 --- a/core/src/main/java/org/mapstruct/converter/Converter.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) - * - * 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.converter; - -public interface Converter { - - T from(S source); - - S to(T target); -} diff --git a/core/src/main/java/org/mapstruct/converter/NoOpConverter.java b/core/src/main/java/org/mapstruct/converter/NoOpConverter.java deleted file mode 100644 index a65cc3a98..000000000 --- a/core/src/main/java/org/mapstruct/converter/NoOpConverter.java +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) - * - * 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.converter; - -public class NoOpConverter implements Converter { - - @Override - public Object from(Object source) { - return source; - } - - @Override - public Object to(Object target) { - return target; - } -} diff --git a/core/src/test/java/org/mapstruct/MappersTest.java b/core/src/test/java/org/mapstruct/MappersTest.java index dfc7b0460..7dde0d8ee 100644 --- a/core/src/test/java/org/mapstruct/MappersTest.java +++ b/core/src/test/java/org/mapstruct/MappersTest.java @@ -16,7 +16,6 @@ package org.mapstruct; -import org.mapstruct.Mappers; import org.mapstruct.test.model.Foo; import org.testng.annotations.Test; diff --git a/pom.xml b/pom.xml index e3df3b655..f1f2b0ca5 100644 --- a/pom.xml +++ b/pom.xml @@ -37,5 +37,5 @@ core processor integrationtest - + diff --git a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java index ce7572dc5..9f26bd7e1 100644 --- a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java +++ b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java @@ -29,7 +29,9 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementKindVisitor6; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; @@ -91,18 +93,34 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } private Mapper retrieveModel(TypeElement element) { - List methods = retrieveMethods( element ); - Set processedMethods = new HashSet(); - List mappings = new ArrayList(); + List methods = retrieveMethods( null, element ); + List mappings = getMappings( methods ); + List usedMapperTypes = getUsedMapperTypes( element ); + Mapper mapper = new Mapper( + elementUtils.getPackageOf( element ).getQualifiedName().toString(), + element.getSimpleName().toString(), + element.getSimpleName() + IMPLEMENTATION_SUFFIX, + mappings, + usedMapperTypes + ); + + return mapper; + } + + private List getMappings(List methods) { Conversions conversions = new Conversions( elementUtils, typeUtils, typeUtil ); + List mappings = new ArrayList(); + Set processedMethods = new HashSet(); + for ( Method method : methods ) { if ( processedMethods.contains( method ) ) { continue; } MappingMethod mappingMethod = new MappingMethod( + method.getDeclaringMapper(), method.getName(), method.getParameterName(), getElementMappingMethod( methods, method ) @@ -114,6 +132,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { processedMethods.add( rawReverseMappingMethod ); reverseMappingMethod = new MappingMethod( + rawReverseMappingMethod.getDeclaringMapper(), rawReverseMappingMethod.getName(), rawReverseMappingMethod.getParameterName(), getElementMappingMethod( methods, rawReverseMappingMethod ) @@ -134,12 +153,13 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { property.getSourceType(), property.getTargetName(), property.getTargetType(), - property.getConverterType(), propertyMappingMethod != null ? new MappingMethod( + propertyMappingMethod.getDeclaringMapper(), propertyMappingMethod.getName(), propertyMappingMethod.getParameterName() ) : null, reversePropertyMappingMethod != null ? new MappingMethod( + reversePropertyMappingMethod.getDeclaringMapper(), reversePropertyMappingMethod.getName(), reversePropertyMappingMethod.getParameterName() ) : null, @@ -168,15 +188,16 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { mappings.add( mapping ); } + return mappings; + } - Mapper mapper = new Mapper( - elementUtils.getPackageOf( element ).getQualifiedName().toString(), - element.getSimpleName().toString(), - element.getSimpleName() + IMPLEMENTATION_SUFFIX, - mappings - ); - - return mapper; + private List getUsedMapperTypes(TypeElement element) { + List usedMapperTypes = new LinkedList(); + MapperPrism mapperPrism = MapperPrism.getInstanceOn( element ); + for ( TypeMirror usedMapper : mapperPrism.uses() ) { + usedMapperTypes.add( typeUtil.retrieveType( usedMapper ) ); + } + return usedMapperTypes; } private String getAccessor(String name) { @@ -196,6 +217,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } } return elementMappingMethod == null ? null : new MappingMethod( + elementMappingMethod.getDeclaringMapper(), elementMappingMethod.getName(), elementMappingMethod.getParameterName() ); @@ -231,7 +253,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { return null; } - private List retrieveMethods(TypeElement element) { + private List retrieveMethods(Type declaringMapper, Element element) { List methods = new ArrayList(); for ( ExecutableElement method : methodsIn( element.getEnclosedElements() ) ) { @@ -241,6 +263,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { methods.add( new Method( + declaringMapper, method.getSimpleName().toString(), parameter.getName(), parameter.getType(), @@ -250,6 +273,21 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { ); } + List usedMapperTypes = new LinkedList(); + MapperPrism mapperPrism = MapperPrism.getInstanceOn( element ); + + if ( mapperPrism != null ) { + for ( TypeMirror usedMapper : mapperPrism.uses() ) { + methods.addAll( + retrieveMethods( + typeUtil.retrieveType( usedMapper ), + ( (DeclaredType) usedMapper ).asElement() + ) + ); + } + } + + return methods; } @@ -291,8 +329,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { sourcePropertyName, retrieveReturnType( getterMethod ), mapping != null ? mapping.getTargetName() : targetPropertyName, - retrieveParameter( setterMethod ).getType(), - mapping != null ? mapping.getConverterType() : null + retrieveParameter( setterMethod ).getType() ) ); } @@ -320,12 +357,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } private Mapping getMapping(MappingPrism mapping) { - Type converterType = typeUtil.retrieveType( mapping.converter() ); - return new Mapping( - mapping.source(), - mapping.target(), - converterType.getName().equals( "NoOpConverter" ) ? null : converterType - ); + return new Mapping( mapping.source(), mapping.target() ); } private Parameter retrieveParameter(ExecutableElement method) { diff --git a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java index 981d34224..ff3fb01e2 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java @@ -20,19 +20,18 @@ import java.util.List; public class Mapper { private final String packageName; - private final String interfaceName; - private final String implementationName; - private final List beanMappings; + private final List usedMapperTypes; public Mapper(String packageName, String interfaceName, - String implementationName, List beanMappings) { + String implementationName, List beanMappings, List usedMapperTypes) { this.packageName = packageName; this.interfaceName = interfaceName; this.implementationName = implementationName; this.beanMappings = beanMappings; + this.usedMapperTypes = usedMapperTypes; } public String getPackageName() { @@ -50,4 +49,8 @@ public class Mapper { public List getBeanMappings() { return beanMappings; } + + public List getUsedMapperTypes() { + return usedMapperTypes; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java index 05fc92286..ebe8e1193 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java @@ -17,22 +17,29 @@ package org.mapstruct.ap.model; public class MappingMethod { + private final Type declaringMapper; private final String name; private final String parameterName; private final MappingMethod elementMappingMethod; - public MappingMethod(String name, String parameterName) { + public MappingMethod(Type declaringMapper, String name, String parameterName) { + this.declaringMapper = declaringMapper; this.name = name; this.parameterName = parameterName; this.elementMappingMethod = null; } - public MappingMethod(String name, String parameterName, MappingMethod elementMappingMethod) { + public MappingMethod(Type declaringMapper, String name, String parameterName, MappingMethod elementMappingMethod) { + this.declaringMapper = declaringMapper; this.name = name; this.parameterName = parameterName; this.elementMappingMethod = elementMappingMethod; } + public Type getDeclaringMapper() { + return declaringMapper; + } + public String getName() { return name; } @@ -44,4 +51,8 @@ public class MappingMethod { public MappingMethod getElementMappingMethod() { return elementMappingMethod; } + + public boolean isGenerationRequired() { + return declaringMapper == null; + } } 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 b5c14efb6..f6ef49cd6 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java @@ -21,18 +21,16 @@ public class PropertyMapping { private final Type sourceType; private final String targetName; private final Type targetType; - private final Type converterType; private final MappingMethod mappingMethod; private final MappingMethod reverseMappingMethod; private final String toConversion; private final String fromConversion; - public PropertyMapping(String sourceName, Type sourceType, String targetName, Type targetType, Type converterType, MappingMethod mappingMethod, MappingMethod reverseMappingMethod, String toConversion, String fromConversion) { + public PropertyMapping(String sourceName, Type sourceType, String targetName, Type targetType, MappingMethod mappingMethod, MappingMethod reverseMappingMethod, String toConversion, String fromConversion) { this.sourceName = sourceName; this.sourceType = sourceType; this.targetName = targetName; this.targetType = targetType; - this.converterType = converterType; this.mappingMethod = mappingMethod; this.reverseMappingMethod = reverseMappingMethod; this.toConversion = toConversion; @@ -55,10 +53,6 @@ public class PropertyMapping { return targetType; } - public Type getConverterType() { - return converterType; - } - public MappingMethod getMappingMethod() { return mappingMethod; } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/MappedProperty.java b/processor/src/main/java/org/mapstruct/ap/model/source/MappedProperty.java index f6df69d5d..09115a7be 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/MappedProperty.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/MappedProperty.java @@ -23,15 +23,12 @@ public class MappedProperty { private final Type sourceType; private final String targetName; private final Type targetType; - private final Type converterType; - public MappedProperty(String sourceName, Type sourceType, String targetName, - Type targetType, Type converterType) { + public MappedProperty(String sourceName, Type sourceType, String targetName, Type targetType) { this.sourceName = sourceName; this.sourceType = sourceType; this.targetName = targetName; this.targetType = targetType; - this.converterType = converterType; } public String getSourceName() { @@ -50,12 +47,8 @@ public class MappedProperty { return targetType; } - public Type getConverterType() { - return converterType; - } - @Override public String toString() { - return sourceType + " " + sourceName + " <=> " + targetType + " " + targetName + " (" + ( converterType != null ? converterType : "no converter" ) + ")"; + return sourceType + " " + sourceName + " <=> " + targetType + " " + targetName; } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java b/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java index a395fe8a1..9b3f782aa 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/Mapping.java @@ -15,18 +15,14 @@ */ package org.mapstruct.ap.model.source; -import org.mapstruct.ap.model.Type; - public class Mapping { private final String sourceName; private final String targetName; - private final Type converterType; - public Mapping(String sourceName, String targetName, Type converterType) { + public Mapping(String sourceName, String targetName) { this.sourceName = sourceName; this.targetName = targetName; - this.converterType = converterType; } public String getSourceName() { @@ -36,8 +32,4 @@ public class Mapping { public String getTargetName() { return targetName; } - - public Type getConverterType() { - return converterType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/Method.java b/processor/src/main/java/org/mapstruct/ap/model/source/Method.java index fd99cea53..34e7169be 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/Method.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/Method.java @@ -22,6 +22,7 @@ import org.mapstruct.ap.model.Type; public class Method { + private final Type declaringMapper; private final String name; private final String parameterName; private final Type sourceType; @@ -29,6 +30,11 @@ public class Method { private final List mappedProperties; public Method(String name, String parameterName, Type sourceType, Type targetType, List mappedProperties) { + this( null, name, parameterName, sourceType, targetType, mappedProperties ); + } + + public Method(Type declaringMapper, String name, String parameterName, Type sourceType, Type targetType, List mappedProperties) { + this.declaringMapper = declaringMapper; this.name = name; this.parameterName = parameterName; this.sourceType = sourceType; @@ -36,6 +42,10 @@ public class Method { this.mappedProperties = mappedProperties; } + public Type getDeclaringMapper() { + return declaringMapper; + } + public String getName() { return name; } @@ -58,12 +68,12 @@ public class Method { public boolean reverses(Method method) { return - equals( sourceType, method.getTargetType() ) && - equals( targetType, method.getSourceType() ); + equals( sourceType, method.getTargetType() ) && + equals( targetType, method.getSourceType() ); } - + private boolean equals(Object o1, Object o2) { - return (o1 == null && o2 == null) || (o1 != null) && o1.equals( o2 ); + return ( o1 == null && o2 == null ) || ( o1 != null ) && o1.equals( o2 ); } @Override diff --git a/processor/src/main/resources/mapper-implementation.ftl b/processor/src/main/resources/mapper-implementation.ftl index 957b0c5d5..c75d83b22 100644 --- a/processor/src/main/resources/mapper-implementation.ftl +++ b/processor/src/main/resources/mapper-implementation.ftl @@ -20,6 +20,7 @@ package ${packageName}; import java.util.ArrayList; import java.util.List; import javax.annotation.Generated; +import java.util.Date; @Generated( value = "org.mapstruct.ap.MappingProcessor", @@ -27,7 +28,12 @@ import javax.annotation.Generated; ) public class ${implementationName} implements ${interfaceName} { + <#list usedMapperTypes as mapperType> + private final ${mapperType.name} ${mapperType.name?uncap_first} = new ${mapperType.name}(); + + <#list beanMappings as beanMapping> + <#if beanMapping.mappingMethod.generationRequired == true> <#if beanMapping.iterableMapping == true> @Override public ${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.mappingMethod.name}(${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.mappingMethod.parameterName}) { @@ -53,18 +59,20 @@ public class ${implementationName} implements ${interfaceName} { ${beanMapping.targetType.name} ${beanMapping.targetType.name?uncap_first} = new ${beanMapping.targetType.name}(); <#list beanMapping.propertyMappings as propertyMapping> + <#-- primitive conversion --> <#if propertyMapping.toConversion??> - <#if propertyMapping.targetType.primitive == true> + <#if propertyMapping.targetType.primitive == true> if( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() != null ) { ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${propertyMapping.toConversion} ); } - <#else> + <#else> ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${propertyMapping.toConversion} ); - + <#elseif propertyMapping.converterType??> ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( new ${propertyMapping.converterType.name}().from( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) ); + <#-- invoke mapping method --> <#elseif propertyMapping.mappingMethod??> - ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${propertyMapping.mappingMethod.name}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) ); + ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( <#if propertyMapping.mappingMethod.declaringMapper??>${propertyMapping.mappingMethod.declaringMapper.name?uncap_first}.${propertyMapping.mappingMethod.name}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) ); <#else> ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ); @@ -73,8 +81,10 @@ public class ${implementationName} implements ${interfaceName} { return ${beanMapping.targetType.name?uncap_first}; } + <#if beanMapping.reverseMappingMethod??> + <#if beanMapping.reverseMappingMethod.generationRequired == true> <#if beanMapping.iterableMapping == true> @Override public ${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.reverseMappingMethod.name}(${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.reverseMappingMethod.parameterName}) { @@ -101,17 +111,18 @@ public class ${implementationName} implements ${interfaceName} { <#list beanMapping.propertyMappings as propertyMapping> <#if propertyMapping.fromConversion??> - <#if propertyMapping.sourceType.primitive == true> + <#if propertyMapping.sourceType.primitive == true> if( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() != null ) { ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${propertyMapping.fromConversion} ); } - <#else> + <#else> ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${propertyMapping.fromConversion} ); - + <#elseif propertyMapping.converterType??> ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( new ${propertyMapping.converterType.name}().to( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) ); + <#-- invoke mapping method --> <#elseif propertyMapping.reverseMappingMethod??> - ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${propertyMapping.reverseMappingMethod.name}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) ); + ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( <#if propertyMapping.reverseMappingMethod.declaringMapper??>${propertyMapping.reverseMappingMethod.declaringMapper.name?uncap_first}.${propertyMapping.reverseMappingMethod.name}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) ); <#else> ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ); @@ -121,6 +132,7 @@ public class ${implementationName} implements ${interfaceName} { } + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/CarMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/CarMapperTest.java index e4d648185..6893b90bf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/CarMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/CarMapperTest.java @@ -18,6 +18,7 @@ package org.mapstruct.ap.test; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.GregorianCalendar; import java.util.List; import javax.tools.DiagnosticCollector; import javax.tools.JavaFileObject; @@ -26,7 +27,7 @@ import org.mapstruct.ap.test.model.Car; import org.mapstruct.ap.test.model.CarDto; import org.mapstruct.ap.test.model.CarMapper; import org.mapstruct.ap.test.model.Category; -import org.mapstruct.ap.test.model.IntToStringConverter; +import org.mapstruct.ap.test.model.DateMapper; import org.mapstruct.ap.test.model.Person; import org.mapstruct.ap.test.model.PersonDto; import org.testng.annotations.BeforeMethod; @@ -51,8 +52,8 @@ public class CarMapperTest extends MapperTestBase { Person.class, PersonDto.class, CarMapper.class, - IntToStringConverter.class, - Category.class + Category.class, + DateMapper.class ); boolean compilationSuccessful = compile( diagnostics, sourceFiles ); @@ -69,7 +70,13 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldMapAttributeByName() { //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); + Car car = new Car( + "Morris", + 2, + new GregorianCalendar( 1980, 0, 1 ).getTime(), + new Person( "Bob" ), + new ArrayList() + ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -82,7 +89,13 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldMapReferenceAttribute() { //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); + Car car = new Car( + "Morris", + 2, + new GregorianCalendar( 1980, 0, 1 ).getTime(), + new Person( "Bob" ), + new ArrayList() + ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -110,7 +123,13 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldMapAttributeWithCustomMapping() { //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); + Car car = new Car( + "Morris", + 2, + new GregorianCalendar( 1980, 0, 1 ).getTime(), + new Person( "Bob" ), + new ArrayList() + ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -136,7 +155,13 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldApplyConverter() { //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); + Car car = new Car( + "Morris", + 2, + new GregorianCalendar( 1980, 0, 1 ).getTime(), + new Person( "Bob" ), + new ArrayList() + ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -156,14 +181,26 @@ public class CarMapperTest extends MapperTestBase { //then assertThat( car ).isNotNull(); - assertThat( car.getYearOfManufacture() ).isEqualTo( 1980 ); + assertThat( car.getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1980, 0, 1 ).getTime() ); } @Test public void shouldMapIterable() { //given - Car car1 = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); - Car car2 = new Car( "Railton", 4, 1934, new Person( "Bill" ), new ArrayList() ); + Car car1 = new Car( + "Morris", + 2, + new GregorianCalendar( 1980, 0, 1 ).getTime(), + new Person( "Bob" ), + new ArrayList() + ); + Car car2 = new Car( + "Railton", + 4, + new GregorianCalendar( 1934, 0, 1 ).getTime(), + new Person( "Bill" ), + new ArrayList() + ); //when List dtos = CarMapper.INSTANCE.carsToCarDtos( new ArrayList( Arrays.asList( car1, car2 ) ) ); @@ -198,12 +235,12 @@ public class CarMapperTest extends MapperTestBase { assertThat( cars.get( 0 ).getMake() ).isEqualTo( "Morris" ); assertThat( cars.get( 0 ).getNumberOfSeats() ).isEqualTo( 2 ); - assertThat( cars.get( 0 ).getYearOfManufacture() ).isEqualTo( 1980 ); + assertThat( cars.get( 0 ).getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1980, 0, 1 ).getTime() ); assertThat( cars.get( 0 ).getDriver().getName() ).isEqualTo( "Bob" ); assertThat( cars.get( 1 ).getMake() ).isEqualTo( "Railton" ); assertThat( cars.get( 1 ).getNumberOfSeats() ).isEqualTo( 4 ); - assertThat( cars.get( 1 ).getYearOfManufacture() ).isEqualTo( 1934 ); + assertThat( cars.get( 1 ).getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1934, 0, 1 ).getTime() ); assertThat( cars.get( 1 ).getDriver().getName() ).isEqualTo( "Bill" ); } @@ -213,7 +250,7 @@ public class CarMapperTest extends MapperTestBase { Car car = new Car( "Morris", 2, - 1980, + new GregorianCalendar( 1980, 0, 1 ).getTime(), new Person( "Bob" ), new ArrayList( Arrays.asList( new Person( "Alice" ), new Person( "Bill" ) ) ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/model/Car.java b/processor/src/test/java/org/mapstruct/ap/test/model/Car.java index d2abb9345..2377671a2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/model/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/model/Car.java @@ -16,12 +16,13 @@ package org.mapstruct.ap.test.model; import java.util.ArrayList; +import java.util.Date; public class Car { private String make; private int numberOfSeats; - private int yearOfManufacture; + private Date manufacturingDate; private Person driver; private ArrayList passengers; private int price; @@ -30,10 +31,10 @@ public class Car { public Car() { } - public Car(String make, int numberOfSeats, int yearOfManufacture, Person driver, ArrayList passengers) { + public Car(String make, int numberOfSeats, Date manufacturingDate, Person driver, ArrayList passengers) { this.make = make; this.numberOfSeats = numberOfSeats; - this.yearOfManufacture = yearOfManufacture; + this.manufacturingDate = manufacturingDate; this.driver = driver; this.passengers = passengers; } @@ -54,12 +55,12 @@ public class Car { this.numberOfSeats = numberOfSeats; } - public int getYearOfManufacture() { - return yearOfManufacture; + public Date getManufacturingDate() { + return manufacturingDate; } - public void setYearOfManufacture(int yearOfManufacture) { - this.yearOfManufacture = yearOfManufacture; + public void setManufacturingDate(Date manufacturingDate) { + this.manufacturingDate = manufacturingDate; } public Person getDriver() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/model/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/model/CarMapper.java index de8943048..b2834f785 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/model/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/model/CarMapper.java @@ -22,14 +22,14 @@ import org.mapstruct.Mappers; import org.mapstruct.Mapping; import org.mapstruct.Mappings; -@Mapper +@Mapper(uses = DateMapper.class) public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); @Mappings({ @Mapping(source = "numberOfSeats", target = "seatCount"), - @Mapping(source = "yearOfManufacture", target = "manufacturingYear", converter = IntToStringConverter.class) + @Mapping(source = "manufacturingDate", target = "manufacturingYear") }) CarDto carToCarDto(Car car); diff --git a/processor/src/test/java/org/mapstruct/ap/test/model/IntToStringConverter.java b/processor/src/test/java/org/mapstruct/ap/test/model/DateMapper.java similarity index 61% rename from processor/src/test/java/org/mapstruct/ap/test/model/IntToStringConverter.java rename to processor/src/test/java/org/mapstruct/ap/test/model/DateMapper.java index 7be57a329..2b5aa8b5c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/model/IntToStringConverter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/model/DateMapper.java @@ -15,17 +15,22 @@ */ package org.mapstruct.ap.test.model; -import org.mapstruct.converter.Converter; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; -public class IntToStringConverter implements Converter { +public class DateMapper { - @Override - public String from(Integer source) { - return source != null ? source.toString() : null; + public String asString(Date date) { + return date != null ? new SimpleDateFormat( "yyyy" ).format( date ) : null; } - @Override - public Integer to(String target) { - return target != null ? Integer.valueOf( target ) : null; + public Date asDate(String date) { + try { + return date != null ? new SimpleDateFormat( "yyyy" ).parse( date ) : null; + } + catch ( ParseException e ) { + throw new RuntimeException( e ); + } } }