mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#12 Allowing delegation to other mapper classes
This commit is contained in:
parent
8f4b45c4f2
commit
458718e346
@ -29,4 +29,5 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Mapper {
|
||||
Class<?>[] uses() default { };
|
||||
}
|
||||
|
@ -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<? extends Converter<?, ?>> converter() default NoOpConverter.class;
|
||||
|
||||
}
|
||||
|
@ -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<S, T> {
|
||||
|
||||
T from(S source);
|
||||
|
||||
S to(T target);
|
||||
}
|
@ -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<Object, Object> {
|
||||
|
||||
@Override
|
||||
public Object from(Object source) {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object to(Object target) {
|
||||
return target;
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
package org.mapstruct;
|
||||
|
||||
|
||||
import org.mapstruct.Mappers;
|
||||
import org.mapstruct.test.model.Foo;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -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<Void, Void> {
|
||||
}
|
||||
|
||||
private Mapper retrieveModel(TypeElement element) {
|
||||
List<Method> methods = retrieveMethods( element );
|
||||
Set<Method> processedMethods = new HashSet<Method>();
|
||||
List<BeanMapping> mappings = new ArrayList<BeanMapping>();
|
||||
List<Method> methods = retrieveMethods( null, element );
|
||||
List<BeanMapping> mappings = getMappings( methods );
|
||||
List<Type> 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<BeanMapping> getMappings(List<Method> methods) {
|
||||
Conversions conversions = new Conversions( elementUtils, typeUtils, typeUtil );
|
||||
|
||||
List<BeanMapping> mappings = new ArrayList<BeanMapping>();
|
||||
Set<Method> processedMethods = new HashSet<Method>();
|
||||
|
||||
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<Void, Void> {
|
||||
processedMethods.add( rawReverseMappingMethod );
|
||||
|
||||
reverseMappingMethod = new MappingMethod(
|
||||
rawReverseMappingMethod.getDeclaringMapper(),
|
||||
rawReverseMappingMethod.getName(),
|
||||
rawReverseMappingMethod.getParameterName(),
|
||||
getElementMappingMethod( methods, rawReverseMappingMethod )
|
||||
@ -134,12 +153,13 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
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<Void, Void> {
|
||||
|
||||
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<Type> getUsedMapperTypes(TypeElement element) {
|
||||
List<Type> usedMapperTypes = new LinkedList<Type>();
|
||||
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<Void, Void> {
|
||||
}
|
||||
}
|
||||
return elementMappingMethod == null ? null : new MappingMethod(
|
||||
elementMappingMethod.getDeclaringMapper(),
|
||||
elementMappingMethod.getName(),
|
||||
elementMappingMethod.getParameterName()
|
||||
);
|
||||
@ -231,7 +253,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Method> retrieveMethods(TypeElement element) {
|
||||
private List<Method> retrieveMethods(Type declaringMapper, Element element) {
|
||||
List<Method> methods = new ArrayList<Method>();
|
||||
|
||||
for ( ExecutableElement method : methodsIn( element.getEnclosedElements() ) ) {
|
||||
@ -241,6 +263,7 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
|
||||
methods.add(
|
||||
new Method(
|
||||
declaringMapper,
|
||||
method.getSimpleName().toString(),
|
||||
parameter.getName(),
|
||||
parameter.getType(),
|
||||
@ -250,6 +273,21 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||
);
|
||||
}
|
||||
|
||||
List<Type> usedMapperTypes = new LinkedList<Type>();
|
||||
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<Void, Void> {
|
||||
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<Void, Void> {
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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<BeanMapping> beanMappings;
|
||||
private final List<Type> usedMapperTypes;
|
||||
|
||||
public Mapper(String packageName, String interfaceName,
|
||||
String implementationName, List<BeanMapping> beanMappings) {
|
||||
String implementationName, List<BeanMapping> beanMappings, List<Type> 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<BeanMapping> getBeanMappings() {
|
||||
return beanMappings;
|
||||
}
|
||||
|
||||
public List<Type> getUsedMapperTypes() {
|
||||
return usedMapperTypes;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<MappedProperty> mappedProperties;
|
||||
|
||||
public Method(String name, String parameterName, Type sourceType, Type targetType, List<MappedProperty> mappedProperties) {
|
||||
this( null, name, parameterName, sourceType, targetType, mappedProperties );
|
||||
}
|
||||
|
||||
public Method(Type declaringMapper, String name, String parameterName, Type sourceType, Type targetType, List<MappedProperty> 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;
|
||||
}
|
||||
@ -63,7 +73,7 @@ public class Method {
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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>
|
||||
|
||||
<#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,6 +59,7 @@ 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( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() != null ) {
|
||||
@ -63,8 +70,9 @@ public class ${implementationName} implements ${interfaceName} {
|
||||
</#if>
|
||||
<#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}.</#if>${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}() );
|
||||
</#if>
|
||||
@ -73,8 +81,10 @@ public class ${implementationName} implements ${interfaceName} {
|
||||
return ${beanMapping.targetType.name?uncap_first};
|
||||
}
|
||||
</#if>
|
||||
</#if>
|
||||
|
||||
<#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}) {
|
||||
@ -110,8 +120,9 @@ public class ${implementationName} implements ${interfaceName} {
|
||||
</#if>
|
||||
<#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}.</#if>${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}() );
|
||||
</#if>
|
||||
@ -121,6 +132,7 @@ public class ${implementationName} implements ${interfaceName} {
|
||||
}
|
||||
</#if>
|
||||
</#if>
|
||||
</#if>
|
||||
|
||||
</#list>
|
||||
}
|
||||
|
@ -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<Person>() );
|
||||
Car car = new Car(
|
||||
"Morris",
|
||||
2,
|
||||
new GregorianCalendar( 1980, 0, 1 ).getTime(),
|
||||
new Person( "Bob" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
|
||||
//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<Person>() );
|
||||
Car car = new Car(
|
||||
"Morris",
|
||||
2,
|
||||
new GregorianCalendar( 1980, 0, 1 ).getTime(),
|
||||
new Person( "Bob" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
|
||||
//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<Person>() );
|
||||
Car car = new Car(
|
||||
"Morris",
|
||||
2,
|
||||
new GregorianCalendar( 1980, 0, 1 ).getTime(),
|
||||
new Person( "Bob" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
|
||||
//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<Person>() );
|
||||
Car car = new Car(
|
||||
"Morris",
|
||||
2,
|
||||
new GregorianCalendar( 1980, 0, 1 ).getTime(),
|
||||
new Person( "Bob" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
|
||||
//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<Person>() );
|
||||
Car car2 = new Car( "Railton", 4, 1934, new Person( "Bill" ), new ArrayList<Person>() );
|
||||
Car car1 = new Car(
|
||||
"Morris",
|
||||
2,
|
||||
new GregorianCalendar( 1980, 0, 1 ).getTime(),
|
||||
new Person( "Bob" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
Car car2 = new Car(
|
||||
"Railton",
|
||||
4,
|
||||
new GregorianCalendar( 1934, 0, 1 ).getTime(),
|
||||
new Person( "Bill" ),
|
||||
new ArrayList<Person>()
|
||||
);
|
||||
|
||||
//when
|
||||
List<CarDto> dtos = CarMapper.INSTANCE.carsToCarDtos( new ArrayList<Car>( 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<Person>( Arrays.asList( new Person( "Alice" ), new Person( "Bill" ) ) )
|
||||
);
|
||||
|
@ -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<Person> passengers;
|
||||
private int price;
|
||||
@ -30,10 +31,10 @@ public class Car {
|
||||
public Car() {
|
||||
}
|
||||
|
||||
public Car(String make, int numberOfSeats, int yearOfManufacture, Person driver, ArrayList<Person> passengers) {
|
||||
public Car(String make, int numberOfSeats, Date manufacturingDate, Person driver, ArrayList<Person> 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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<Integer, String> {
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user