mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#1 Providing infrastructure for implicit conversions
This commit is contained in:
parent
df6ae29f2d
commit
192cfc8937
@ -41,6 +41,8 @@ import javax.lang.model.util.SimpleAnnotationValueVisitor6;
|
|||||||
import javax.lang.model.util.Types;
|
import javax.lang.model.util.Types;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.conversion.Conversion;
|
||||||
|
import org.mapstruct.ap.conversion.Conversions;
|
||||||
import org.mapstruct.ap.model.BeanMapping;
|
import org.mapstruct.ap.model.BeanMapping;
|
||||||
import org.mapstruct.ap.model.Mapper;
|
import org.mapstruct.ap.model.Mapper;
|
||||||
import org.mapstruct.ap.model.MappingMethod;
|
import org.mapstruct.ap.model.MappingMethod;
|
||||||
@ -52,7 +54,6 @@ import org.mapstruct.ap.model.source.Method;
|
|||||||
import org.mapstruct.ap.model.source.Parameter;
|
import org.mapstruct.ap.model.source.Parameter;
|
||||||
import org.mapstruct.ap.writer.ModelWriter;
|
import org.mapstruct.ap.writer.ModelWriter;
|
||||||
|
|
||||||
|
|
||||||
import static javax.lang.model.util.ElementFilter.methodsIn;
|
import static javax.lang.model.util.ElementFilter.methodsIn;
|
||||||
|
|
||||||
public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
||||||
@ -131,10 +132,14 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
Method propertyMappingMethod = getPropertyMappingMethod( methods, property );
|
Method propertyMappingMethod = getPropertyMappingMethod( methods, property );
|
||||||
Method reversePropertyMappingMethod = getReversePropertyMappingMethod( methods, property );
|
Method reversePropertyMappingMethod = getReversePropertyMappingMethod( methods, property );
|
||||||
|
|
||||||
|
Conversion conversion = Conversions.getConversion( property.getSourceType(), property.getTargetType() );
|
||||||
|
|
||||||
propertyMappings.add(
|
propertyMappings.add(
|
||||||
new PropertyMapping(
|
new PropertyMapping(
|
||||||
property.getSourceName(),
|
property.getSourceName(),
|
||||||
|
property.getSourceType(),
|
||||||
property.getTargetName(),
|
property.getTargetName(),
|
||||||
|
property.getTargetType(),
|
||||||
property.getConverterType(),
|
property.getConverterType(),
|
||||||
propertyMappingMethod != null ? new MappingMethod(
|
propertyMappingMethod != null ? new MappingMethod(
|
||||||
propertyMappingMethod.getName(),
|
propertyMappingMethod.getName(),
|
||||||
@ -143,6 +148,16 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
reversePropertyMappingMethod != null ? new MappingMethod(
|
reversePropertyMappingMethod != null ? new MappingMethod(
|
||||||
reversePropertyMappingMethod.getName(),
|
reversePropertyMappingMethod.getName(),
|
||||||
reversePropertyMappingMethod.getParameterName()
|
reversePropertyMappingMethod.getParameterName()
|
||||||
|
) : null,
|
||||||
|
conversion != null ? conversion.to(
|
||||||
|
mappingMethod.getParameterName() + "." + getAccessor(
|
||||||
|
property.getSourceName()
|
||||||
|
)
|
||||||
|
) : null,
|
||||||
|
conversion != null ? conversion.from(
|
||||||
|
reverseMappingMethod.getParameterName() + "." + getAccessor(
|
||||||
|
property.getTargetName()
|
||||||
|
)
|
||||||
) : null
|
) : null
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -168,6 +183,14 @@ public class MapperGenerationVisitor extends ElementKindVisitor6<Void, Void> {
|
|||||||
return mapper;
|
return mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getAccessor(String name) {
|
||||||
|
return "get" + capitalize( name ) + "()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String capitalize(String name) {
|
||||||
|
return name.substring( 0, 1 ).toUpperCase() + name.substring( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
private MappingMethod getElementMappingMethod(Iterable<Method> methods, Method method) {
|
private MappingMethod getElementMappingMethod(Iterable<Method> methods, Method method) {
|
||||||
Method elementMappingMethod = null;
|
Method elementMappingMethod = null;
|
||||||
for ( Method oneMethod : methods ) {
|
for ( Method oneMethod : methods ) {
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.conversion;
|
||||||
|
|
||||||
|
public interface Conversion {
|
||||||
|
|
||||||
|
String to(String sourcePropertyAccessor);
|
||||||
|
|
||||||
|
String from(String targetPropertyAccessor);
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.conversion;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.model.Type;
|
||||||
|
|
||||||
|
import static org.mapstruct.ap.conversion.ReverseConversion.reverse;
|
||||||
|
|
||||||
|
public class Conversions {
|
||||||
|
|
||||||
|
private static ConcurrentMap<Key, Conversion> conversions = new ConcurrentHashMap<Conversions.Key, Conversion>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
register( int.class, Long.class, new IntLongConversion() );
|
||||||
|
register( int.class, String.class, new IntStringConversion() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void register(Class<?> sourceType, Class<?> targetType, Conversion conversion) {
|
||||||
|
conversions.put( Key.forClasses( sourceType, targetType ), conversion );
|
||||||
|
conversions.put( Key.forClasses( targetType, sourceType ), reverse( conversion ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Conversion getConversion(Type sourceType, Type targetType) {
|
||||||
|
return conversions.get( new Key( sourceType, targetType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Key {
|
||||||
|
private final Type sourceType;
|
||||||
|
private final Type targetType;
|
||||||
|
|
||||||
|
private static Key forClasses(Class<?> sourceType, Class<?> targetType) {
|
||||||
|
return new Key( Type.forClass( sourceType ), Type.forClass( targetType ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key(Type sourceType, Type targetType) {
|
||||||
|
this.sourceType = sourceType;
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result
|
||||||
|
+ ( ( sourceType == null ) ? 0 : sourceType.hashCode() );
|
||||||
|
result = prime * result
|
||||||
|
+ ( ( targetType == null ) ? 0 : targetType.hashCode() );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if ( this == obj ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ( obj == null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( getClass() != obj.getClass() ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Key other = (Key) obj;
|
||||||
|
if ( sourceType == null ) {
|
||||||
|
if ( other.sourceType != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( !sourceType.equals( other.sourceType ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( targetType == null ) {
|
||||||
|
if ( other.targetType != null ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( !targetType.equals( other.targetType ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.conversion;
|
||||||
|
|
||||||
|
public class IntLongConversion implements Conversion {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String to(String sourcePropertyAccessor) {
|
||||||
|
return "Long.valueOf( " + sourcePropertyAccessor + " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String from(String targetPropertyAccessor) {
|
||||||
|
return targetPropertyAccessor + ".intValue()";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.conversion;
|
||||||
|
|
||||||
|
public class IntStringConversion implements Conversion {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String to(String sourcePropertyAccessor) {
|
||||||
|
return "String.valueOf( " + sourcePropertyAccessor + " )";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String from(String targetPropertyAccessor) {
|
||||||
|
return "Integer.parseInt( " + targetPropertyAccessor + " )";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.conversion;
|
||||||
|
|
||||||
|
public class ReverseConversion implements Conversion {
|
||||||
|
|
||||||
|
private Conversion conversion;
|
||||||
|
|
||||||
|
public static ReverseConversion reverse(Conversion conversion) {
|
||||||
|
return new ReverseConversion( conversion );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ReverseConversion(Conversion conversion) {
|
||||||
|
this.conversion = conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String to(String sourcePropertyAccessor) {
|
||||||
|
return conversion.from( sourcePropertyAccessor );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String from(String targetPropertyAccessor) {
|
||||||
|
return conversion.to( targetPropertyAccessor );
|
||||||
|
}
|
||||||
|
}
|
@ -18,27 +18,43 @@ package org.mapstruct.ap.model;
|
|||||||
public class PropertyMapping {
|
public class PropertyMapping {
|
||||||
|
|
||||||
private final String sourceName;
|
private final String sourceName;
|
||||||
|
private final Type sourceType;
|
||||||
private final String targetName;
|
private final String targetName;
|
||||||
|
private final Type targetType;
|
||||||
private final Type converterType;
|
private final Type converterType;
|
||||||
private final MappingMethod mappingMethod;
|
private final MappingMethod mappingMethod;
|
||||||
private final MappingMethod reverseMappingMethod;
|
private final MappingMethod reverseMappingMethod;
|
||||||
|
private final String toConversion;
|
||||||
|
private final String fromConversion;
|
||||||
|
|
||||||
public PropertyMapping(String sourceName, String targetName, Type converterType, MappingMethod mappingMethod, MappingMethod reverseMappingMethod) {
|
public PropertyMapping(String sourceName, Type sourceType, String targetName, Type targetType, Type converterType, MappingMethod mappingMethod, MappingMethod reverseMappingMethod, String toConversion, String fromConversion) {
|
||||||
this.sourceName = sourceName;
|
this.sourceName = sourceName;
|
||||||
|
this.sourceType = sourceType;
|
||||||
this.targetName = targetName;
|
this.targetName = targetName;
|
||||||
|
this.targetType = targetType;
|
||||||
this.converterType = converterType;
|
this.converterType = converterType;
|
||||||
this.mappingMethod = mappingMethod;
|
this.mappingMethod = mappingMethod;
|
||||||
this.reverseMappingMethod = reverseMappingMethod;
|
this.reverseMappingMethod = reverseMappingMethod;
|
||||||
|
this.toConversion = toConversion;
|
||||||
|
this.fromConversion = fromConversion;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSourceName() {
|
public String getSourceName() {
|
||||||
return sourceName;
|
return sourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getSourceType() {
|
||||||
|
return sourceType;
|
||||||
|
}
|
||||||
|
|
||||||
public String getTargetName() {
|
public String getTargetName() {
|
||||||
return targetName;
|
return targetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Type getTargetType() {
|
||||||
|
return targetType;
|
||||||
|
}
|
||||||
|
|
||||||
public Type getConverterType() {
|
public Type getConverterType() {
|
||||||
return converterType;
|
return converterType;
|
||||||
}
|
}
|
||||||
@ -50,4 +66,12 @@ public class PropertyMapping {
|
|||||||
public MappingMethod getReverseMappingMethod() {
|
public MappingMethod getReverseMappingMethod() {
|
||||||
return reverseMappingMethod;
|
return reverseMappingMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getToConversion() {
|
||||||
|
return toConversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFromConversion() {
|
||||||
|
return fromConversion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.model;
|
package org.mapstruct.ap.model;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the type of a bean property, parameter etc.
|
* Represents the type of a bean property, parameter etc.
|
||||||
*
|
*
|
||||||
@ -22,10 +26,26 @@ package org.mapstruct.ap.model;
|
|||||||
*/
|
*/
|
||||||
public class Type {
|
public class Type {
|
||||||
|
|
||||||
|
private final static Set<String> primitiveTypeNames = new HashSet<String>(
|
||||||
|
Arrays.asList( "boolean", "char", "byte", "short", "int", "long", "float", "double" )
|
||||||
|
);
|
||||||
|
|
||||||
private final String packageName;
|
private final String packageName;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final Type elementType;
|
private final Type elementType;
|
||||||
|
|
||||||
|
|
||||||
|
public static Type forClass(Class<?> clazz) {
|
||||||
|
Package pakkage = clazz.getPackage();
|
||||||
|
|
||||||
|
if ( pakkage != null ) {
|
||||||
|
return new Type( pakkage.getName(), clazz.getSimpleName() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Type( clazz.getSimpleName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Type(String name) {
|
public Type(String name) {
|
||||||
this.packageName = null;
|
this.packageName = null;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -56,6 +76,10 @@ public class Type {
|
|||||||
return elementType;
|
return elementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPrimitive() {
|
||||||
|
return packageName == null && primitiveTypeNames.contains( name );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if ( packageName == null ) {
|
if ( packageName == null ) {
|
||||||
|
@ -26,7 +26,6 @@ public class ${implementationName} implements ${interfaceName} {
|
|||||||
<#if beanMapping.iterableMapping == true>
|
<#if beanMapping.iterableMapping == true>
|
||||||
@Override
|
@Override
|
||||||
public ${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.mappingMethod.name}(${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.mappingMethod.parameterName}) {
|
public ${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.mappingMethod.name}(${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.mappingMethod.parameterName}) {
|
||||||
|
|
||||||
${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.targetType.name?uncap_first} = new ${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}>();
|
${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.targetType.name?uncap_first} = new ${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}>();
|
||||||
|
|
||||||
for ( ${beanMapping.sourceType.elementType.name} ${beanMapping.sourceType.elementType.name?uncap_first} : ${beanMapping.mappingMethod.parameterName} ) {
|
for ( ${beanMapping.sourceType.elementType.name} ${beanMapping.sourceType.elementType.name?uncap_first} : ${beanMapping.mappingMethod.parameterName} ) {
|
||||||
@ -38,11 +37,18 @@ public class ${implementationName} implements ${interfaceName} {
|
|||||||
<#else>
|
<#else>
|
||||||
@Override
|
@Override
|
||||||
public ${beanMapping.targetType.name} ${beanMapping.mappingMethod.name}(${beanMapping.sourceType.name} ${beanMapping.mappingMethod.parameterName}) {
|
public ${beanMapping.targetType.name} ${beanMapping.mappingMethod.name}(${beanMapping.sourceType.name} ${beanMapping.mappingMethod.parameterName}) {
|
||||||
|
|
||||||
${beanMapping.targetType.name} ${beanMapping.targetType.name?uncap_first} = new ${beanMapping.targetType.name}();
|
${beanMapping.targetType.name} ${beanMapping.targetType.name?uncap_first} = new ${beanMapping.targetType.name}();
|
||||||
|
|
||||||
<#list beanMapping.propertyMappings as propertyMapping>
|
<#list beanMapping.propertyMappings as propertyMapping>
|
||||||
<#if propertyMapping.converterType??>
|
<#if propertyMapping.toConversion??>
|
||||||
|
<#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>
|
||||||
|
${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${propertyMapping.toConversion} );
|
||||||
|
</#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}() ) );
|
${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( new ${propertyMapping.converterType.name}().from( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) );
|
||||||
<#elseif propertyMapping.mappingMethod??>
|
<#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}( ${propertyMapping.mappingMethod.name}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) );
|
||||||
@ -56,11 +62,9 @@ public class ${implementationName} implements ${interfaceName} {
|
|||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
<#if beanMapping.reverseMappingMethod??>
|
<#if beanMapping.reverseMappingMethod??>
|
||||||
|
|
||||||
<#if beanMapping.iterableMapping == true>
|
<#if beanMapping.iterableMapping == true>
|
||||||
@Override
|
@Override
|
||||||
public ${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.reverseMappingMethod.name}(${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.reverseMappingMethod.parameterName}) {
|
public ${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.reverseMappingMethod.name}(${beanMapping.targetType.name}<${beanMapping.targetType.elementType.name}> ${beanMapping.reverseMappingMethod.parameterName}) {
|
||||||
|
|
||||||
${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.sourceType.name?uncap_first} = new ${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}>();
|
${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}> ${beanMapping.sourceType.name?uncap_first} = new ${beanMapping.sourceType.name}<${beanMapping.sourceType.elementType.name}>();
|
||||||
|
|
||||||
for ( ${beanMapping.targetType.elementType.name} ${beanMapping.targetType.elementType.name?uncap_first} : ${beanMapping.reverseMappingMethod.parameterName} ) {
|
for ( ${beanMapping.targetType.elementType.name} ${beanMapping.targetType.elementType.name?uncap_first} : ${beanMapping.reverseMappingMethod.parameterName} ) {
|
||||||
@ -75,7 +79,15 @@ public class ${implementationName} implements ${interfaceName} {
|
|||||||
${beanMapping.sourceType.name} ${beanMapping.sourceType.name?uncap_first} = new ${beanMapping.sourceType.name}();
|
${beanMapping.sourceType.name} ${beanMapping.sourceType.name?uncap_first} = new ${beanMapping.sourceType.name}();
|
||||||
|
|
||||||
<#list beanMapping.propertyMappings as propertyMapping>
|
<#list beanMapping.propertyMappings as propertyMapping>
|
||||||
<#if propertyMapping.converterType??>
|
<#if propertyMapping.fromConversion??>
|
||||||
|
<#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>
|
||||||
|
${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${propertyMapping.fromConversion} );
|
||||||
|
</#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}() ) );
|
${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( new ${propertyMapping.converterType.name}().to( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) );
|
||||||
<#elseif propertyMapping.reverseMappingMethod??>
|
<#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}( ${propertyMapping.reverseMappingMethod.name}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) );
|
||||||
|
@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import javax.tools.DiagnosticCollector;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
|
||||||
|
import org.mapstruct.ap.test.conversion.Source;
|
||||||
|
import org.mapstruct.ap.test.conversion.SourceTargetMapper;
|
||||||
|
import org.mapstruct.ap.test.conversion.Target;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class ConversionTest extends MapperTestBase {
|
||||||
|
|
||||||
|
private DiagnosticCollector<JavaFileObject> diagnostics;
|
||||||
|
|
||||||
|
public ConversionTest() {
|
||||||
|
super( "mapstruct.jar" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void generateMapperImplementation() {
|
||||||
|
diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||||
|
File[] sourceFiles = getSourceFiles(
|
||||||
|
Source.class,
|
||||||
|
Target.class,
|
||||||
|
SourceTargetMapper.class
|
||||||
|
);
|
||||||
|
|
||||||
|
boolean compilationSuccessful = compile( diagnostics, sourceFiles );
|
||||||
|
|
||||||
|
assertThat( compilationSuccessful ).describedAs( "Compilation failed: " + diagnostics.getDiagnostics() )
|
||||||
|
.isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyConversions() {
|
||||||
|
Source source = new Source();
|
||||||
|
source.setFoo( 42 );
|
||||||
|
source.setBar( 23L );
|
||||||
|
source.setZip( 73 );
|
||||||
|
|
||||||
|
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getBar() ).isEqualTo( 23 );
|
||||||
|
assertThat( target.getZip() ).isEqualTo( "73" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldHandleNulls() {
|
||||||
|
Source source = new Source();
|
||||||
|
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 0 ) );
|
||||||
|
assertThat( target.getBar() ).isEqualTo( 0 );
|
||||||
|
assertThat( target.getZip() ).isEqualTo( "0" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyConversionsToMappedProperties() {
|
||||||
|
Source source = new Source();
|
||||||
|
source.setQax( 42 );
|
||||||
|
source.setBaz( 23L );
|
||||||
|
|
||||||
|
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
|
||||||
|
|
||||||
|
assertThat( target ).isNotNull();
|
||||||
|
assertThat( target.getBaz() ).isEqualTo( Long.valueOf( 42 ) );
|
||||||
|
assertThat( target.getQax() ).isEqualTo( 23 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyConversionsForReverseMapping() {
|
||||||
|
Target target = new Target();
|
||||||
|
target.setFoo( 42L );
|
||||||
|
target.setBar( 23 );
|
||||||
|
target.setZip( "73" );
|
||||||
|
|
||||||
|
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
|
||||||
|
|
||||||
|
assertThat( source ).isNotNull();
|
||||||
|
assertThat( source.getFoo() ).isEqualTo( 42 );
|
||||||
|
assertThat( source.getBar() ).isEqualTo( 23 );
|
||||||
|
assertThat( source.getZip() ).isEqualTo( 73 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldApplyConversionsToMappedPropertiesForReverseMapping() {
|
||||||
|
Target target = new Target();
|
||||||
|
target.setQax( 42 );
|
||||||
|
target.setBaz( 23L );
|
||||||
|
|
||||||
|
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
|
||||||
|
|
||||||
|
assertThat( source ).isNotNull();
|
||||||
|
assertThat( source.getBaz() ).isEqualTo( 42 );
|
||||||
|
assertThat( source.getQax() ).isEqualTo( 23 );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.test.conversion;
|
||||||
|
|
||||||
|
public class Source {
|
||||||
|
|
||||||
|
private int foo;
|
||||||
|
private Long bar;
|
||||||
|
private int qax;
|
||||||
|
private Long baz;
|
||||||
|
private int zip;
|
||||||
|
|
||||||
|
public int getFoo() {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoo(int foo) {
|
||||||
|
this.foo = foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBar() {
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBar(Long bar) {
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQax() {
|
||||||
|
return qax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQax(int qax) {
|
||||||
|
this.qax = qax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBaz() {
|
||||||
|
return baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaz(Long baz) {
|
||||||
|
this.baz = baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getZip() {
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZip(int zip) {
|
||||||
|
this.zip = zip;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.test.conversion;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mappers;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.Mappings;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface SourceTargetMapper {
|
||||||
|
|
||||||
|
public static SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class );
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "qax", target = "baz"),
|
||||||
|
@Mapping(source = "baz", target = "qax")
|
||||||
|
})
|
||||||
|
Target sourceToTarget(Source source);
|
||||||
|
|
||||||
|
Source targetToSource(Target target);
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/**
|
||||||
|
* 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.ap.test.conversion;
|
||||||
|
|
||||||
|
public class Target {
|
||||||
|
|
||||||
|
private Long foo;
|
||||||
|
private int bar;
|
||||||
|
private Long baz;
|
||||||
|
private int qax;
|
||||||
|
private String zip;
|
||||||
|
|
||||||
|
public Long getFoo() {
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoo(Long foo) {
|
||||||
|
this.foo = foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBar() {
|
||||||
|
return bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBar(int bar) {
|
||||||
|
this.bar = bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getBaz() {
|
||||||
|
return baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaz(Long baz) {
|
||||||
|
this.baz = baz;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getQax() {
|
||||||
|
return qax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQax(int qax) {
|
||||||
|
this.qax = qax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getZip() {
|
||||||
|
return zip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZip(String zip) {
|
||||||
|
this.zip = zip;
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ public class Car {
|
|||||||
private int yearOfManufacture;
|
private int yearOfManufacture;
|
||||||
private Person driver;
|
private Person driver;
|
||||||
private ArrayList<Person> passengers;
|
private ArrayList<Person> passengers;
|
||||||
|
private int price;
|
||||||
|
|
||||||
public Car() {
|
public Car() {
|
||||||
}
|
}
|
||||||
@ -75,4 +76,12 @@ public class Car {
|
|||||||
public void setPassengers(ArrayList<Person> passengers) {
|
public void setPassengers(ArrayList<Person> passengers) {
|
||||||
this.passengers = passengers;
|
this.passengers = passengers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(int price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ public class CarDto {
|
|||||||
private String manufacturingYear;
|
private String manufacturingYear;
|
||||||
private PersonDto driver;
|
private PersonDto driver;
|
||||||
private ArrayList<PersonDto> passengers;
|
private ArrayList<PersonDto> passengers;
|
||||||
|
private Long price;
|
||||||
|
|
||||||
public CarDto() {
|
public CarDto() {
|
||||||
}
|
}
|
||||||
@ -75,4 +76,12 @@ public class CarDto {
|
|||||||
public void setPassengers(ArrayList<PersonDto> passengers) {
|
public void setPassengers(ArrayList<PersonDto> passengers) {
|
||||||
this.passengers = passengers;
|
this.passengers = passengers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(Long price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import org.mapstruct.Mappers;
|
|||||||
import org.mapstruct.Mapping;
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.Mappings;
|
import org.mapstruct.Mappings;
|
||||||
|
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface CarMapper {
|
public interface CarMapper {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user