mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
Adding support for multiple bindings, adding converters
This commit is contained in:
parent
02006a90b7
commit
e07add7d43
@ -15,10 +15,15 @@
|
||||
*/
|
||||
package de.moapa.maple;
|
||||
|
||||
import de.moapa.maple.converter.Converter;
|
||||
import de.moapa.maple.converter.NoOpConverter;
|
||||
|
||||
public @interface Mapping {
|
||||
|
||||
String source();
|
||||
|
||||
String target();
|
||||
|
||||
Class<? extends Converter<?, ?>> converter() default NoOpConverter.class;
|
||||
|
||||
}
|
||||
|
22
core/src/main/java/de/moapa/maple/Mappings.java
Normal file
22
core/src/main/java/de/moapa/maple/Mappings.java
Normal 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();
|
||||
}
|
23
core/src/main/java/de/moapa/maple/converter/Converter.java
Normal file
23
core/src/main/java/de/moapa/maple/converter/Converter.java
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ package de.moapa.maple.ap;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
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.TypeElement;
|
||||
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.Elements;
|
||||
import javax.lang.model.util.SimpleAnnotationValueVisitor6;
|
||||
import javax.lang.model.util.TypeKindVisitor6;
|
||||
import javax.lang.model.util.Types;
|
||||
import javax.tools.JavaFileObject;
|
||||
|
||||
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 MAPPINGS_ANNOTATION = "de.moapa.maple.Mappings";
|
||||
|
||||
private final static String CONVERTER_TYPE = "de.moapa.maple.converter.Converter";
|
||||
|
||||
private final ProcessingEnvironment processingEnvironment;
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
private final Types typeUtils;
|
||||
|
||||
private final Elements elementUtils;
|
||||
|
||||
public MapperGenerationVisitor(ProcessingEnvironment processingEnvironment, Configuration configuration) {
|
||||
|
||||
this.processingEnvironment = processingEnvironment;
|
||||
this.typeUtils = processingEnvironment.getTypeUtils();
|
||||
this.elementUtils = processingEnvironment.getElementUtils();
|
||||
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
@ -86,7 +104,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
private Mapper retrieveModel(TypeElement element) {
|
||||
|
||||
return new Mapper(
|
||||
processingEnvironment.getElementUtils().getPackageOf( element ).getQualifiedName().toString(),
|
||||
elementUtils.getPackageOf( element ).getQualifiedName().toString(),
|
||||
element.getSimpleName() + IMPLEMENTATION_SUFFIX,
|
||||
element.getSimpleName().toString(),
|
||||
retrieveMethods( element )
|
||||
@ -128,6 +146,33 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
if ( MAPPING_ANNOTATION.equals( annotationName ) ) {
|
||||
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;
|
||||
@ -137,19 +182,60 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
|
||||
String sourcePropertyName = null;
|
||||
String targetPropertyName = null;
|
||||
Type converterType = null;
|
||||
Type sourceType = null;
|
||||
Type targetType = null;
|
||||
|
||||
for ( Entry<? extends ExecutableElement, ? extends AnnotationValue> oneAttribute : annotationMirror.getElementValues()
|
||||
.entrySet() ) {
|
||||
|
||||
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" ) ) {
|
||||
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) {
|
||||
@ -161,31 +247,35 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
VariableElement parameter = parameters.get( 0 );
|
||||
|
||||
return new Parameter(
|
||||
parameters.get( 0 ).getSimpleName().toString(),
|
||||
parameter.getSimpleName().toString(),
|
||||
new Type(
|
||||
processingEnvironment.getElementUtils()
|
||||
.getPackageOf( parameters.get( 0 ) )
|
||||
.getQualifiedName()
|
||||
.toString(),
|
||||
processingEnvironment.getTypeUtils()
|
||||
.asElement( parameters.get( 0 ).asType() )
|
||||
.getSimpleName()
|
||||
.toString()
|
||||
elementUtils.getPackageOf( parameter ).getQualifiedName().toString(),
|
||||
typeUtils.asElement( parameter.asType() ).getSimpleName().toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private Type retrieveReturnType(ExecutableElement method) {
|
||||
|
||||
Element returnTypeElement = processingEnvironment.getTypeUtils().asElement( method.getReturnType() );
|
||||
Element returnTypeElement = typeUtils.asElement( method.getReturnType() );
|
||||
|
||||
return new Type(
|
||||
processingEnvironment.getElementUtils().getPackageOf( returnTypeElement ).getQualifiedName().toString(),
|
||||
elementUtils.getPackageOf( returnTypeElement ).getQualifiedName().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> {
|
||||
|
||||
@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
|
||||
public String visitString(String value, Void p) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,21 +17,42 @@ package de.moapa.maple.ap.model;
|
||||
|
||||
public class Binding {
|
||||
|
||||
private final Type sourceType;
|
||||
|
||||
private final String sourceProperty;
|
||||
|
||||
private final Type targetType;
|
||||
|
||||
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.targetType = targetType;
|
||||
this.targetProperty = targetProperty;
|
||||
this.converterType = converterType;
|
||||
}
|
||||
|
||||
public Type getSourceType() {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public String getSourceProperty() {
|
||||
return sourceProperty;
|
||||
}
|
||||
|
||||
public Type getTargetType() {
|
||||
return targetType;
|
||||
}
|
||||
|
||||
public String getTargetProperty() {
|
||||
return targetProperty;
|
||||
}
|
||||
|
||||
public Type getConverterType() {
|
||||
return converterType;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package de.moapa.maple.ap.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Mapper {
|
||||
@ -27,11 +28,35 @@ public class Mapper {
|
||||
|
||||
private final List<MapperMethod> mapperMethods;
|
||||
|
||||
private final List<Converter> converters;
|
||||
|
||||
public Mapper(String packageName, String implementationType, String interfaceType, List<MapperMethod> mapperMethods) {
|
||||
this.packageName = packageName;
|
||||
this.implementationType = implementationType;
|
||||
this.interfaceType = interfaceType;
|
||||
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() {
|
||||
@ -49,4 +74,8 @@ public class Mapper {
|
||||
public List<MapperMethod> getMapperMethods() {
|
||||
return mapperMethods;
|
||||
}
|
||||
|
||||
public List<Converter> getConverters() {
|
||||
return converters;
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,14 @@
|
||||
-->
|
||||
package ${packageName};
|
||||
|
||||
import org.dozer.DozerConverter;
|
||||
import org.dozer.DozerBeanMapper;
|
||||
import org.dozer.loader.api.BeanMappingBuilder;
|
||||
|
||||
import de.moapa.maple.converter.Converter;
|
||||
|
||||
import static org.dozer.loader.api.FieldsMappingOptions.*;
|
||||
|
||||
public class ${implementationType} implements ${interfaceType} {
|
||||
|
||||
private final DozerBeanMapper mapper;
|
||||
@ -35,7 +40,7 @@ public class ${implementationType} implements ${interfaceType} {
|
||||
protected void configure() {
|
||||
mapping( ${oneMethod.parameter.type.name}.class, ${oneMethod.returnType.name}.class )
|
||||
<#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>
|
||||
;
|
||||
}
|
||||
@ -51,4 +56,25 @@ public class ${implementationType} implements ${interfaceType} {
|
||||
return mapper.map(${oneMethod.parameter.name}, ${oneMethod.returnType.name}.class);
|
||||
}
|
||||
</#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>
|
||||
}
|
||||
|
@ -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.CarDto;
|
||||
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.BeforeMethod;
|
||||
import org.testng.annotations.Test;
|
||||
@ -83,7 +84,7 @@ public class CarMapperTest {
|
||||
public void generateMapperImplementation() {
|
||||
|
||||
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 );
|
||||
|
||||
@ -101,7 +102,7 @@ public class CarMapperTest {
|
||||
public void shouldMapAttributeByName() {
|
||||
|
||||
//given
|
||||
Car car = new Car( "Morris", 2 );
|
||||
Car car = new Car( "Morris", 2, 1980 );
|
||||
|
||||
//when
|
||||
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
|
||||
@ -115,7 +116,7 @@ public class CarMapperTest {
|
||||
public void shouldMapAttributeWithCustomMapping() {
|
||||
|
||||
//given
|
||||
Car car = new Car( "Morris", 2 );
|
||||
Car car = new Car( "Morris", 2, 1980 );
|
||||
|
||||
//when
|
||||
CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
|
||||
@ -129,7 +130,7 @@ public class CarMapperTest {
|
||||
public void shouldConsiderCustomMappingForReverseMapping() {
|
||||
|
||||
//given
|
||||
CarDto carDto = new CarDto( "Morris", 2 );
|
||||
CarDto carDto = new CarDto( "Morris", 2, "1980" );
|
||||
|
||||
//when
|
||||
Car car = CarMapper.INSTANCE.carDtoToCar( carDto );
|
||||
@ -139,6 +140,34 @@ public class CarMapperTest {
|
||||
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) {
|
||||
|
||||
File[] sourceFiles = new File[clazz.length];
|
||||
|
@ -21,12 +21,15 @@ public class Car {
|
||||
|
||||
private int numberOfSeats;
|
||||
|
||||
private int yearOfManufacture;
|
||||
|
||||
public Car() {
|
||||
}
|
||||
|
||||
public Car(String make, int numberOfSeats) {
|
||||
public Car(String make, int numberOfSeats, int yearOfManufacture) {
|
||||
this.make = make;
|
||||
this.numberOfSeats = numberOfSeats;
|
||||
this.yearOfManufacture = yearOfManufacture;
|
||||
}
|
||||
|
||||
public String getMake() {
|
||||
@ -44,4 +47,12 @@ public class Car {
|
||||
public void setNumberOfSeats(int numberOfSeats) {
|
||||
this.numberOfSeats = numberOfSeats;
|
||||
}
|
||||
|
||||
public int getYearOfManufacture() {
|
||||
return yearOfManufacture;
|
||||
}
|
||||
|
||||
public void setYearOfManufacture(int yearOfManufacture) {
|
||||
this.yearOfManufacture = yearOfManufacture;
|
||||
}
|
||||
}
|
||||
|
@ -21,12 +21,15 @@ public class CarDto {
|
||||
|
||||
private int seatCount;
|
||||
|
||||
private String manufacturingYear;
|
||||
|
||||
public CarDto() {
|
||||
}
|
||||
|
||||
public CarDto(String make, int seatCount) {
|
||||
public CarDto(String make, int seatCount, String manufacturingYear) {
|
||||
this.make = make;
|
||||
this.seatCount = seatCount;
|
||||
this.manufacturingYear = manufacturingYear;
|
||||
}
|
||||
|
||||
public String getMake() {
|
||||
@ -44,4 +47,12 @@ public class CarDto {
|
||||
public void setSeatCount(int seatCount) {
|
||||
this.seatCount = seatCount;
|
||||
}
|
||||
|
||||
public String getManufacturingYear() {
|
||||
return manufacturingYear;
|
||||
}
|
||||
|
||||
public void setManufacturingYear(String manufacturingYear) {
|
||||
this.manufacturingYear = manufacturingYear;
|
||||
}
|
||||
}
|
||||
|
@ -18,13 +18,17 @@ package de.moapa.maple.ap.test.model;
|
||||
import de.moapa.maple.Mapper;
|
||||
import de.moapa.maple.Mappers;
|
||||
import de.moapa.maple.Mapping;
|
||||
import de.moapa.maple.Mappings;
|
||||
|
||||
@Mapper
|
||||
public interface CarMapper {
|
||||
|
||||
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);
|
||||
|
||||
Car carDtoToCar(CarDto carDto);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user