Adding support for multiple bindings, adding converters

This commit is contained in:
Gunnar Morling 2012-05-28 23:15:13 +02:00
parent 02006a90b7
commit e07add7d43
14 changed files with 423 additions and 25 deletions

View File

@ -15,10 +15,15 @@
*/ */
package de.moapa.maple; package de.moapa.maple;
import de.moapa.maple.converter.Converter;
import de.moapa.maple.converter.NoOpConverter;
public @interface Mapping { public @interface Mapping {
String source(); String source();
String target(); String target();
Class<? extends Converter<?, ?>> converter() default NoOpConverter.class;
} }

View File

@ -0,0 +1,22 @@
/**
* Copyright 2012 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 de.moapa.maple;
public @interface Mappings {
Mapping[] value();
}

View File

@ -0,0 +1,23 @@
/**
* Copyright 2012 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 de.moapa.maple.converter;
public interface Converter<S, T> {
T from(S source);
S to(T target);
}

View File

@ -0,0 +1,29 @@
/**
* Copyright 2012 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 de.moapa.maple.converter;
public class NoOpConverter implements Converter<Object, Object> {
@Override
public Object from(Object source) {
return source;
}
@Override
public Object to(Object target) {
return target;
}
}

View File

@ -17,6 +17,7 @@ package de.moapa.maple.ap;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;
@ -26,8 +27,13 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementKindVisitor6; import javax.lang.model.util.ElementKindVisitor6;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleAnnotationValueVisitor6; import javax.lang.model.util.SimpleAnnotationValueVisitor6;
import javax.lang.model.util.TypeKindVisitor6;
import javax.lang.model.util.Types;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import de.moapa.maple.ap.model.Binding; import de.moapa.maple.ap.model.Binding;
@ -48,12 +54,24 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
private final static String MAPPING_ANNOTATION = "de.moapa.maple.Mapping"; private final static String MAPPING_ANNOTATION = "de.moapa.maple.Mapping";
private final static String MAPPINGS_ANNOTATION = "de.moapa.maple.Mappings";
private final static String CONVERTER_TYPE = "de.moapa.maple.converter.Converter";
private final ProcessingEnvironment processingEnvironment; private final ProcessingEnvironment processingEnvironment;
private final Configuration configuration; private final Configuration configuration;
private final Types typeUtils;
private final Elements elementUtils;
public MapperGenerationVisitor(ProcessingEnvironment processingEnvironment, Configuration configuration) { public MapperGenerationVisitor(ProcessingEnvironment processingEnvironment, Configuration configuration) {
this.processingEnvironment = processingEnvironment; this.processingEnvironment = processingEnvironment;
this.typeUtils = processingEnvironment.getTypeUtils();
this.elementUtils = processingEnvironment.getElementUtils();
this.configuration = configuration; this.configuration = configuration;
} }
@ -86,7 +104,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
private Mapper retrieveModel(TypeElement element) { private Mapper retrieveModel(TypeElement element) {
return new Mapper( return new Mapper(
processingEnvironment.getElementUtils().getPackageOf( element ).getQualifiedName().toString(), elementUtils.getPackageOf( element ).getQualifiedName().toString(),
element.getSimpleName() + IMPLEMENTATION_SUFFIX, element.getSimpleName() + IMPLEMENTATION_SUFFIX,
element.getSimpleName().toString(), element.getSimpleName().toString(),
retrieveMethods( element ) retrieveMethods( element )
@ -128,6 +146,33 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
if ( MAPPING_ANNOTATION.equals( annotationName ) ) { if ( MAPPING_ANNOTATION.equals( annotationName ) ) {
bindings.add( retrieveBinding( annotationMirror ) ); bindings.add( retrieveBinding( annotationMirror ) );
} }
else if ( MAPPINGS_ANNOTATION.equals( annotationName ) ) {
bindings.addAll( retrieveBindings( annotationMirror ) );
}
}
return bindings;
}
private List<Binding> retrieveBindings(AnnotationMirror annotationMirror) {
List<Binding> bindings = new ArrayList<Binding>();
for ( Entry<? extends ExecutableElement, ? extends AnnotationValue> oneAttribute : annotationMirror.getElementValues()
.entrySet() ) {
if ( oneAttribute.getKey().getSimpleName().contentEquals( "value" ) ) {
List<? extends AnnotationValue> values = oneAttribute.getValue()
.accept( new AnnotationValueListRetrievingVisitor(), null );
for ( AnnotationValue oneAnnotationValue : values ) {
AnnotationMirror oneAnnotation = oneAnnotationValue.accept(
new AnnotationRetrievingVisitor(),
null
);
bindings.add( retrieveBinding( oneAnnotation ) );
}
}
} }
return bindings; return bindings;
@ -137,19 +182,60 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
String sourcePropertyName = null; String sourcePropertyName = null;
String targetPropertyName = null; String targetPropertyName = null;
Type converterType = null;
Type sourceType = null;
Type targetType = null;
for ( Entry<? extends ExecutableElement, ? extends AnnotationValue> oneAttribute : annotationMirror.getElementValues() for ( Entry<? extends ExecutableElement, ? extends AnnotationValue> oneAttribute : annotationMirror.getElementValues()
.entrySet() ) { .entrySet() ) {
if ( oneAttribute.getKey().getSimpleName().contentEquals( "source" ) ) { if ( oneAttribute.getKey().getSimpleName().contentEquals( "source" ) ) {
sourcePropertyName = oneAttribute.getValue().accept( new ValueRetrievingVisitor(), null ); sourcePropertyName = oneAttribute.getValue().accept( new StringValueRetrievingVisitor(), null );
} }
else if ( oneAttribute.getKey().getSimpleName().contentEquals( "target" ) ) { else if ( oneAttribute.getKey().getSimpleName().contentEquals( "target" ) ) {
targetPropertyName = oneAttribute.getValue().accept( new ValueRetrievingVisitor(), null ); targetPropertyName = oneAttribute.getValue().accept( new StringValueRetrievingVisitor(), null );
}
else if ( oneAttribute.getKey().getSimpleName().contentEquals( "converter" ) ) {
TypeMirror converterTypeMirror = oneAttribute.getValue()
.accept(
new TypeRetrievingVisitor(), null
);
converterType = getType( typeUtils.asElement( converterTypeMirror ) );
List<? extends TypeMirror> converterTypeParameters = getTypeParameters(
converterTypeMirror,
CONVERTER_TYPE
);
sourceType = getType( typeUtils.asElement( converterTypeParameters.get( 0 ) ) );
targetType = getType( typeUtils.asElement( converterTypeParameters.get( 1 ) ) );
} }
} }
return new Binding( sourcePropertyName, targetPropertyName ); return new Binding( sourceType, sourcePropertyName, targetType, targetPropertyName, converterType );
}
private Type getType(Element sourceTypeElement) {
return new Type(
elementUtils.getPackageOf( sourceTypeElement ).toString(),
sourceTypeElement.getSimpleName().toString()
);
}
//TODO: consider complete type hierarchy
private List<? extends TypeMirror> getTypeParameters(TypeMirror type, String superTypeName) {
for ( TypeMirror oneSuperType : typeUtils.directSupertypes( type ) ) {
String oneSuperTypeName = typeUtils.asElement( oneSuperType )
.accept( new NameDeterminationVisitor(), null );
if ( oneSuperTypeName.equals( superTypeName ) ) {
return oneSuperType.accept( new TypeParameterDeterminationVisitor(), null );
}
}
return Collections.emptyList();
} }
private Parameter retrieveParameter(ExecutableElement method) { private Parameter retrieveParameter(ExecutableElement method) {
@ -161,31 +247,35 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
return null; return null;
} }
VariableElement parameter = parameters.get( 0 );
return new Parameter( return new Parameter(
parameters.get( 0 ).getSimpleName().toString(), parameter.getSimpleName().toString(),
new Type( new Type(
processingEnvironment.getElementUtils() elementUtils.getPackageOf( parameter ).getQualifiedName().toString(),
.getPackageOf( parameters.get( 0 ) ) typeUtils.asElement( parameter.asType() ).getSimpleName().toString()
.getQualifiedName()
.toString(),
processingEnvironment.getTypeUtils()
.asElement( parameters.get( 0 ).asType() )
.getSimpleName()
.toString()
) )
); );
} }
private Type retrieveReturnType(ExecutableElement method) { private Type retrieveReturnType(ExecutableElement method) {
Element returnTypeElement = processingEnvironment.getTypeUtils().asElement( method.getReturnType() ); Element returnTypeElement = typeUtils.asElement( method.getReturnType() );
return new Type( return new Type(
processingEnvironment.getElementUtils().getPackageOf( returnTypeElement ).getQualifiedName().toString(), elementUtils.getPackageOf( returnTypeElement ).getQualifiedName().toString(),
returnTypeElement.getSimpleName().toString() returnTypeElement.getSimpleName().toString()
); );
} }
private static class TypeParameterDeterminationVisitor extends TypeKindVisitor6<List<? extends TypeMirror>, Void> {
@Override
public List<? extends TypeMirror> visitDeclared(DeclaredType type, Void p) {
return type.getTypeArguments();
}
}
private static class NameDeterminationVisitor extends ElementKindVisitor6<String, Void> { private static class NameDeterminationVisitor extends ElementKindVisitor6<String, Void> {
@Override @Override
@ -194,12 +284,37 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
} }
} }
private static class ValueRetrievingVisitor extends SimpleAnnotationValueVisitor6<String, Void> { private static class StringValueRetrievingVisitor extends SimpleAnnotationValueVisitor6<String, Void> {
@Override @Override
public String visitString(String value, Void p) { public String visitString(String value, Void p) {
return value; return value;
} }
}
private static class TypeRetrievingVisitor
extends SimpleAnnotationValueVisitor6<TypeMirror, Void> {
@Override
public TypeMirror visitType(TypeMirror value, Void p) {
return value;
}
}
private static class AnnotationValueListRetrievingVisitor
extends SimpleAnnotationValueVisitor6<List<? extends AnnotationValue>, Void> {
@Override
public List<? extends AnnotationValue> visitArray(List<? extends AnnotationValue> value, Void p) {
return value;
}
}
private static class AnnotationRetrievingVisitor extends SimpleAnnotationValueVisitor6<AnnotationMirror, Void> {
@Override
public AnnotationMirror visitAnnotation(AnnotationMirror value, Void p) {
return value;
}
} }
} }

View File

@ -17,21 +17,42 @@ package de.moapa.maple.ap.model;
public class Binding { public class Binding {
private final Type sourceType;
private final String sourceProperty; private final String sourceProperty;
private final Type targetType;
private final String targetProperty; private final String targetProperty;
public Binding(String sourceProperty, String targetProperty) { private final Type converterType;
public Binding(Type sourceType, String sourceProperty, Type targetType, String targetProperty, Type converterType) {
this.sourceType = sourceType;
this.sourceProperty = sourceProperty; this.sourceProperty = sourceProperty;
this.targetType = targetType;
this.targetProperty = targetProperty; this.targetProperty = targetProperty;
this.converterType = converterType;
}
public Type getSourceType() {
return sourceType;
} }
public String getSourceProperty() { public String getSourceProperty() {
return sourceProperty; return sourceProperty;
} }
public Type getTargetType() {
return targetType;
}
public String getTargetProperty() { public String getTargetProperty() {
return targetProperty; return targetProperty;
} }
public Type getConverterType() {
return converterType;
}
} }

View File

@ -0,0 +1,42 @@
/**
* Copyright 2012 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 de.moapa.maple.ap.model;
public class Converter {
private final Type converterType;
private final Type sourceType;
private final Type targetType;
public Converter(Type converterType, Type sourceType, Type targetType) {
this.converterType = converterType;
this.sourceType = sourceType;
this.targetType = targetType;
}
public Type getConverterType() {
return converterType;
}
public Type getSourceType() {
return sourceType;
}
public Type getTargetType() {
return targetType;
}
}

View File

@ -15,6 +15,7 @@
*/ */
package de.moapa.maple.ap.model; package de.moapa.maple.ap.model;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Mapper { public class Mapper {
@ -27,11 +28,35 @@ public class Mapper {
private final List<MapperMethod> mapperMethods; private final List<MapperMethod> mapperMethods;
private final List<Converter> converters;
public Mapper(String packageName, String implementationType, String interfaceType, List<MapperMethod> mapperMethods) { public Mapper(String packageName, String implementationType, String interfaceType, List<MapperMethod> mapperMethods) {
this.packageName = packageName; this.packageName = packageName;
this.implementationType = implementationType; this.implementationType = implementationType;
this.interfaceType = interfaceType; this.interfaceType = interfaceType;
this.mapperMethods = mapperMethods; this.mapperMethods = mapperMethods;
this.converters = collectConverters( mapperMethods );
}
private List<Converter> collectConverters(List<MapperMethod> mapperMethods) {
List<Converter> converters = new ArrayList<Converter>();
for ( MapperMethod oneMapperMethod : mapperMethods ) {
for ( Binding oneBinding : oneMapperMethod.getBindings() ) {
if ( oneBinding.getConverterType() != null ) {
converters.add(
new Converter(
oneBinding.getConverterType(),
oneBinding.getSourceType(),
oneBinding.getTargetType()
)
);
}
}
}
return converters;
} }
public String getPackageName() { public String getPackageName() {
@ -49,4 +74,8 @@ public class Mapper {
public List<MapperMethod> getMapperMethods() { public List<MapperMethod> getMapperMethods() {
return mapperMethods; return mapperMethods;
} }
public List<Converter> getConverters() {
return converters;
}
} }

View File

@ -17,9 +17,14 @@
--> -->
package ${packageName}; package ${packageName};
import org.dozer.DozerConverter;
import org.dozer.DozerBeanMapper; import org.dozer.DozerBeanMapper;
import org.dozer.loader.api.BeanMappingBuilder; import org.dozer.loader.api.BeanMappingBuilder;
import de.moapa.maple.converter.Converter;
import static org.dozer.loader.api.FieldsMappingOptions.*;
public class ${implementationType} implements ${interfaceType} { public class ${implementationType} implements ${interfaceType} {
private final DozerBeanMapper mapper; private final DozerBeanMapper mapper;
@ -35,7 +40,7 @@ public class ${implementationType} implements ${interfaceType} {
protected void configure() { protected void configure() {
mapping( ${oneMethod.parameter.type.name}.class, ${oneMethod.returnType.name}.class ) mapping( ${oneMethod.parameter.type.name}.class, ${oneMethod.returnType.name}.class )
<#list oneMethod.bindings as oneBinding> <#list oneMethod.bindings as oneBinding>
.fields("${oneBinding.sourceProperty}", "${oneBinding.targetProperty}") .fields( "${oneBinding.sourceProperty}", "${oneBinding.targetProperty}"<#if oneBinding.converterType??>, customConverter( ${oneBinding.converterType.name}DozerAdapter.class )</#if> )
</#list> </#list>
; ;
} }
@ -51,4 +56,25 @@ public class ${implementationType} implements ${interfaceType} {
return mapper.map(${oneMethod.parameter.name}, ${oneMethod.returnType.name}.class); return mapper.map(${oneMethod.parameter.name}, ${oneMethod.returnType.name}.class);
} }
</#list> </#list>
<#list converters as oneConverter>
public static class ${oneConverter.converterType.name}DozerAdapter extends DozerConverter<${oneConverter.sourceType.name}, ${oneConverter.targetType.name}> {
private final Converter<${oneConverter.sourceType.name}, ${oneConverter.targetType.name}> converter = new ${oneConverter.converterType.name}();
public ${oneConverter.converterType.name}DozerAdapter() {
super(${oneConverter.sourceType.name}.class, ${oneConverter.targetType.name}.class);
}
@Override
public String convertTo(${oneConverter.sourceType.name} source, ${oneConverter.targetType.name} destination) {
return converter.from(source);
}
@Override
public ${oneConverter.sourceType.name} convertFrom(${oneConverter.targetType.name} source, ${oneConverter.sourceType.name} destination) {
return converter.to(source);
}
}
</#list>
} }

View File

@ -34,6 +34,7 @@ import de.moapa.maple.ap.MappingProcessor;
import de.moapa.maple.ap.test.model.Car; import de.moapa.maple.ap.test.model.Car;
import de.moapa.maple.ap.test.model.CarDto; import de.moapa.maple.ap.test.model.CarDto;
import de.moapa.maple.ap.test.model.CarMapper; import de.moapa.maple.ap.test.model.CarMapper;
import de.moapa.maple.ap.test.model.IntToStringConverter;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -83,7 +84,7 @@ public class CarMapperTest {
public void generateMapperImplementation() { public void generateMapperImplementation() {
diagnostics = new DiagnosticCollector<JavaFileObject>(); diagnostics = new DiagnosticCollector<JavaFileObject>();
File[] sourceFiles = getSourceFiles( Car.class, CarDto.class, CarMapper.class ); File[] sourceFiles = getSourceFiles( Car.class, CarDto.class, CarMapper.class, IntToStringConverter.class );
boolean compilationSuccessful = compile( diagnostics, sourceFiles ); boolean compilationSuccessful = compile( diagnostics, sourceFiles );
@ -101,7 +102,7 @@ public class CarMapperTest {
public void shouldMapAttributeByName() { public void shouldMapAttributeByName() {
//given //given
Car car = new Car( "Morris", 2 ); Car car = new Car( "Morris", 2, 1980 );
//when //when
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
@ -115,7 +116,7 @@ public class CarMapperTest {
public void shouldMapAttributeWithCustomMapping() { public void shouldMapAttributeWithCustomMapping() {
//given //given
Car car = new Car( "Morris", 2 ); Car car = new Car( "Morris", 2, 1980 );
//when //when
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
@ -129,7 +130,7 @@ public class CarMapperTest {
public void shouldConsiderCustomMappingForReverseMapping() { public void shouldConsiderCustomMappingForReverseMapping() {
//given //given
CarDto carDto = new CarDto( "Morris", 2 ); CarDto carDto = new CarDto( "Morris", 2, "1980" );
//when //when
Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); Car car = CarMapper.INSTANCE.carDtoToCar( carDto );
@ -139,6 +140,34 @@ public class CarMapperTest {
assertThat( car.getNumberOfSeats() ).isEqualTo( carDto.getSeatCount() ); assertThat( car.getNumberOfSeats() ).isEqualTo( carDto.getSeatCount() );
} }
@Test
public void shouldApplyConverter() {
//given
Car car = new Car( "Morris", 2, 1980 );
//when
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
//then
assertThat( carDto ).isNotNull();
assertThat( carDto.getManufacturingYear() ).isEqualTo( "1980" );
}
@Test
public void shouldApplyConverterForReverseMapping() {
//given
CarDto carDto = new CarDto( "Morris", 2, "1980" );
//when
Car car = CarMapper.INSTANCE.carDtoToCar( carDto );
//then
assertThat( car ).isNotNull();
assertThat( car.getYearOfManufacture() ).isEqualTo( 1980 );
}
private File[] getSourceFiles(Class<?>... clazz) { private File[] getSourceFiles(Class<?>... clazz) {
File[] sourceFiles = new File[clazz.length]; File[] sourceFiles = new File[clazz.length];

View File

@ -21,12 +21,15 @@ public class Car {
private int numberOfSeats; private int numberOfSeats;
private int yearOfManufacture;
public Car() { public Car() {
} }
public Car(String make, int numberOfSeats) { public Car(String make, int numberOfSeats, int yearOfManufacture) {
this.make = make; this.make = make;
this.numberOfSeats = numberOfSeats; this.numberOfSeats = numberOfSeats;
this.yearOfManufacture = yearOfManufacture;
} }
public String getMake() { public String getMake() {
@ -44,4 +47,12 @@ public class Car {
public void setNumberOfSeats(int numberOfSeats) { public void setNumberOfSeats(int numberOfSeats) {
this.numberOfSeats = numberOfSeats; this.numberOfSeats = numberOfSeats;
} }
public int getYearOfManufacture() {
return yearOfManufacture;
}
public void setYearOfManufacture(int yearOfManufacture) {
this.yearOfManufacture = yearOfManufacture;
}
} }

View File

@ -21,12 +21,15 @@ public class CarDto {
private int seatCount; private int seatCount;
private String manufacturingYear;
public CarDto() { public CarDto() {
} }
public CarDto(String make, int seatCount) { public CarDto(String make, int seatCount, String manufacturingYear) {
this.make = make; this.make = make;
this.seatCount = seatCount; this.seatCount = seatCount;
this.manufacturingYear = manufacturingYear;
} }
public String getMake() { public String getMake() {
@ -44,4 +47,12 @@ public class CarDto {
public void setSeatCount(int seatCount) { public void setSeatCount(int seatCount) {
this.seatCount = seatCount; this.seatCount = seatCount;
} }
public String getManufacturingYear() {
return manufacturingYear;
}
public void setManufacturingYear(String manufacturingYear) {
this.manufacturingYear = manufacturingYear;
}
} }

View File

@ -18,13 +18,17 @@ package de.moapa.maple.ap.test.model;
import de.moapa.maple.Mapper; import de.moapa.maple.Mapper;
import de.moapa.maple.Mappers; import de.moapa.maple.Mappers;
import de.moapa.maple.Mapping; import de.moapa.maple.Mapping;
import de.moapa.maple.Mappings;
@Mapper @Mapper
public interface CarMapper { public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); CarMapper INSTANCE = Mappers.getMapper( CarMapper.class );
@Mapping(source = "numberOfSeats", target = "seatCount") @Mappings({
@Mapping(source = "numberOfSeats", target = "seatCount"),
@Mapping(source = "yearOfManufacture", target = "manufacturingYear", converter = IntToStringConverter.class)
})
CarDto carToCarDto(Car car); CarDto carToCarDto(Car car);
Car carDtoToCar(CarDto carDto); Car carDtoToCar(CarDto carDto);

View File

@ -0,0 +1,31 @@
/**
* Copyright 2012 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 de.moapa.maple.ap.test.model;
import de.moapa.maple.converter.Converter;
public class IntToStringConverter implements Converter<Integer, String> {
@Override
public String from(Integer source) {
return source != null ? source.toString() : null;
}
@Override
public Integer to(String target) {
return target != null ? Integer.valueOf( target ) : null;
}
}