diff --git a/core/etc/license.txt b/core/etc/license.txt index a9168191b..b2014c4b4 100644 --- a/core/etc/license.txt +++ b/core/etc/license.txt @@ -1,4 +1,4 @@ - Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + 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. diff --git a/core/src/main/java/de/moapa/maple/Mapper.java b/core/src/main/java/de/moapa/maple/Mapper.java index 0da816f81..b193388b6 100644 --- a/core/src/main/java/de/moapa/maple/Mapper.java +++ b/core/src/main/java/de/moapa/maple/Mapper.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -29,12 +29,4 @@ import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Mapper { - - /** - * Specifies the type of the mapper implementation to be generated. - * Currently supported values are {@code native} and {@code dozer}. - * - * @return The type of the mapper implementation to be generated. - */ - String value() default ""; } diff --git a/core/src/main/java/de/moapa/maple/Mappers.java b/core/src/main/java/de/moapa/maple/Mappers.java index 0193d7012..ce04b1b4b 100644 --- a/core/src/main/java/de/moapa/maple/Mappers.java +++ b/core/src/main/java/de/moapa/maple/Mappers.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/main/java/de/moapa/maple/Mapping.java b/core/src/main/java/de/moapa/maple/Mapping.java index dd4fcf160..496469339 100644 --- a/core/src/main/java/de/moapa/maple/Mapping.java +++ b/core/src/main/java/de/moapa/maple/Mapping.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/main/java/de/moapa/maple/Mappings.java b/core/src/main/java/de/moapa/maple/Mappings.java index 3dcc96fe9..a33d88f6c 100644 --- a/core/src/main/java/de/moapa/maple/Mappings.java +++ b/core/src/main/java/de/moapa/maple/Mappings.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/main/java/de/moapa/maple/converter/Converter.java b/core/src/main/java/de/moapa/maple/converter/Converter.java index 764e3fec9..7828f7135 100644 --- a/core/src/main/java/de/moapa/maple/converter/Converter.java +++ b/core/src/main/java/de/moapa/maple/converter/Converter.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/main/java/de/moapa/maple/converter/NoOpConverter.java b/core/src/main/java/de/moapa/maple/converter/NoOpConverter.java index 9872b6b8c..33032f574 100644 --- a/core/src/main/java/de/moapa/maple/converter/NoOpConverter.java +++ b/core/src/main/java/de/moapa/maple/converter/NoOpConverter.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/test/java/de/moapa/maple/MappersTest.java b/core/src/test/java/de/moapa/maple/MappersTest.java index 13b08e98f..a4c90d829 100644 --- a/core/src/test/java/de/moapa/maple/MappersTest.java +++ b/core/src/test/java/de/moapa/maple/MappersTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/test/java/de/moapa/maple/test/model/Foo.java b/core/src/test/java/de/moapa/maple/test/model/Foo.java index b052afdaf..ed024a31f 100644 --- a/core/src/test/java/de/moapa/maple/test/model/Foo.java +++ b/core/src/test/java/de/moapa/maple/test/model/Foo.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/core/src/test/java/de/moapa/maple/test/model/FooImpl.java b/core/src/test/java/de/moapa/maple/test/model/FooImpl.java index 44c7881f4..ef4ce24a3 100644 --- a/core/src/test/java/de/moapa/maple/test/model/FooImpl.java +++ b/core/src/test/java/de/moapa/maple/test/model/FooImpl.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/etc/license.txt b/etc/license.txt index a9168191b..b2014c4b4 100644 --- a/etc/license.txt +++ b/etc/license.txt @@ -1,4 +1,4 @@ - Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + 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. diff --git a/parent/etc/license.txt b/parent/etc/license.txt index a9168191b..b2014c4b4 100644 --- a/parent/etc/license.txt +++ b/parent/etc/license.txt @@ -1,4 +1,4 @@ - Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + 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. diff --git a/parent/pom.xml b/parent/pom.xml index c53a9eb0c..0bbcedf99 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -17,88 +17,77 @@ --> - 4.0.0 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - de.moapa.maple - maple-parent - 1.0-SNAPSHOT - pom + de.moapa.maple + maple-parent + 1.0-SNAPSHOT + pom - Maple Parent - https://github.com/gunnarmorling/maple + Maple Parent + https://github.com/gunnarmorling/maple - - UTF-8 - + + UTF-8 + - - - - org.freemarker - freemarker - 2.3.14 - - - net.sf.dozer - dozer - 5.3.2 - + + - org.slf4j - slf4j-jdk14 - 1.5.10 + org.freemarker + freemarker + 2.3.14 + + + org.testng + testng + 6.3.1 + + + org.easytesting + fest-assert + 1.4 - - org.testng - testng - 6.3.1 - - - org.easytesting - fest-assert - 1.4 - + + ${project.groupId} + maple + ${project.version} + + + - - ${project.groupId} - maple - ${project.version} - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.4 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + com.mycila.maven-license-plugin maven-license-plugin 1.9.0 - - - - + + + + com.mycila.maven-license-plugin @@ -115,7 +104,7 @@ - - + + diff --git a/processor/etc/license.txt b/processor/etc/license.txt index a9168191b..b2014c4b4 100644 --- a/processor/etc/license.txt +++ b/processor/etc/license.txt @@ -1,4 +1,4 @@ - Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + 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. diff --git a/processor/pom.xml b/processor/pom.xml index 350126425..1f8feb2cf 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -36,17 +36,6 @@ org.freemarker freemarker - - - net.sf.dozer - dozer - test - - - org.slf4j - slf4j-jdk14 - test - org.testng testng diff --git a/processor/src/main/java/de/moapa/maple/ap/MapperGenerationVisitor.java b/processor/src/main/java/de/moapa/maple/ap/MapperGenerationVisitor.java index 10241428b..10607c0d1 100644 --- a/processor/src/main/java/de/moapa/maple/ap/MapperGenerationVisitor.java +++ b/processor/src/main/java/de/moapa/maple/ap/MapperGenerationVisitor.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,11 +15,12 @@ */ package de.moapa.maple.ap; +import java.beans.Introspector; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -37,19 +38,19 @@ 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; +import de.moapa.maple.ap.model.BeanMapping; import de.moapa.maple.ap.model.Mapper; -import de.moapa.maple.ap.model.MapperMethod; -import de.moapa.maple.ap.model.Parameter; -import de.moapa.maple.ap.model.Property; +import de.moapa.maple.ap.model.MappingMethod; +import de.moapa.maple.ap.model.PropertyMapping; import de.moapa.maple.ap.model.Type; -import de.moapa.maple.ap.writer.DozerModelWriter; +import de.moapa.maple.ap.model.source.MappedProperty; +import de.moapa.maple.ap.model.source.Mapping; +import de.moapa.maple.ap.model.source.Method; +import de.moapa.maple.ap.model.source.Parameter; import de.moapa.maple.ap.writer.ModelWriter; -import de.moapa.maple.ap.writer.NativeModelWriter; import static javax.lang.model.util.ElementFilter.methodsIn; @@ -57,21 +58,14 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { private final static String IMPLEMENTATION_SUFFIX = "Impl"; - private final static String MAPPER_ANNOTATION = "de.moapa.maple.Mapper"; 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 static String DEFAULT_MAPPER_TYPE = "dozer"; private final ProcessingEnvironment processingEnvironment; - private final Types typeUtils; - private final Elements elementUtils; public MapperGenerationVisitor(ProcessingEnvironment processingEnvironment) { - this.processingEnvironment = processingEnvironment; this.typeUtils = processingEnvironment.getTypeUtils(); this.elementUtils = processingEnvironment.getElementUtils(); @@ -79,7 +73,6 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { @Override public Void visitTypeAsInterface(TypeElement element, Void p) { - Mapper model = retrieveModel( element ); String sourceFileName = element.getQualifiedName() + IMPLEMENTATION_SUFFIX; @@ -89,7 +82,6 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } private void writeModelToSourceFile(String fileName, Mapper model) { - JavaFileObject sourceFile; try { sourceFile = processingEnvironment.getFiler().createSourceFile( fileName ); @@ -98,44 +90,142 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { throw new RuntimeException( e ); } - ModelWriter modelWriter = model.getMapperType() - .equals( "native" ) ? new NativeModelWriter() : new DozerModelWriter(); + ModelWriter modelWriter = new ModelWriter( "mapper-implementation.ftl" ); modelWriter.writeModel( sourceFile, model ); } private Mapper retrieveModel(TypeElement element) { - return new Mapper( - retrieveMapperType( element ), + List methods = retrieveMethods( element ); + Set processedMethods = new HashSet(); + List mappings = new ArrayList(); + + for ( Method method : methods ) { + if ( processedMethods.contains( method ) ) { + continue; + } + + MappingMethod mappingMethod = new MappingMethod( + method.getName(), + method.getParameterName(), + getElementMappingMethod( methods, method ) + ); + + MappingMethod reverseMappingMethod = null; + Method rawReverseMappingMethod = getReverseMappingMethod( methods, method ); + if ( rawReverseMappingMethod != null ) { + processedMethods.add( rawReverseMappingMethod ); +// MappingMethod reverseElementMappingMethod = rawReverseElementMappingMethod == null ? null : new MappingMethod(rawReverseElementMappingMethod.getName(), rawReverseElementMappingMethod.getParameterName() ); + + reverseMappingMethod = new MappingMethod( + rawReverseMappingMethod.getName(), + rawReverseMappingMethod.getParameterName(), + getElementMappingMethod( methods, rawReverseMappingMethod ) + ); + } + + + List propertyMappings = new ArrayList(); + + for ( MappedProperty property : method.getMappedProperties() ) { + Method propertyMappingMethod = getPropertyMappingMethod( methods, property ); + Method reversePropertyMappingMethod = getReversePropertyMappingMethod( methods, property ); + + propertyMappings.add( + new PropertyMapping( + property.getSourceName(), + property.getTargetName(), + property.getConverterType(), + propertyMappingMethod != null ? new MappingMethod( + propertyMappingMethod.getName(), + propertyMappingMethod.getParameterName() + ) : null, + reversePropertyMappingMethod != null ? new MappingMethod( + reversePropertyMappingMethod.getName(), + reversePropertyMappingMethod.getParameterName() + ) : null + ) + ); + } + BeanMapping mapping = new BeanMapping( + method.getSourceType(), + method.getTargetType(), + propertyMappings, + mappingMethod, + reverseMappingMethod + ); + + mappings.add( mapping ); + } + + Mapper mapper = new Mapper( elementUtils.getPackageOf( element ).getQualifiedName().toString(), - element.getSimpleName() + IMPLEMENTATION_SUFFIX, element.getSimpleName().toString(), - retrieveMethods( element ) + element.getSimpleName() + IMPLEMENTATION_SUFFIX, + mappings + ); + + return mapper; + } + + private MappingMethod getElementMappingMethod(Iterable methods, Method method) { + Method elementMappingMethod = null; + for ( Method oneMethod : methods ) { + if ( oneMethod.getSourceType().equals( method.getSourceType().getElementType() ) ) { + elementMappingMethod = oneMethod; + break; + } + } + return elementMappingMethod == null ? null : new MappingMethod( + elementMappingMethod.getName(), + elementMappingMethod.getParameterName() ); } - private String retrieveMapperType(TypeElement element) { - - AnnotationMirror mapperAnnotation = getAnnotation( element, MAPPER_ANNOTATION ); - String mapperType = getStringValue( mapperAnnotation, "value" ); - - return mapperType != null && !mapperType.isEmpty() ? mapperType : DEFAULT_MAPPER_TYPE; + private Method getPropertyMappingMethod(Iterable rawMethods, MappedProperty property) { + for ( Method oneMethod : rawMethods ) { + if ( oneMethod.getSourceType().equals( property.getSourceType() ) && oneMethod.getTargetType() + .equals( property.getTargetType() ) ) { + return oneMethod; + } + } + return null; } - private List retrieveMethods(TypeElement element) { + private Method getReversePropertyMappingMethod(Iterable methods, MappedProperty property) { + for ( Method method : methods ) { + if ( method.getSourceType().equals( property.getTargetType() ) && method.getTargetType() + .equals( property.getSourceType() ) ) { + return method; + } + } + return null; + } - List methods = new ArrayList(); + private Method getReverseMappingMethod(List rawMethods, + Method method) { + for ( Method oneMethod : rawMethods ) { + if ( oneMethod.reverses( method ) ) { + return oneMethod; + } + } + return null; + } - for ( ExecutableElement oneMethod : methodsIn( element.getEnclosedElements() ) ) { + private List retrieveMethods(TypeElement element) { + List methods = new ArrayList(); + + for ( ExecutableElement method : methodsIn( element.getEnclosedElements() ) ) { + Parameter parameter = retrieveParameter( method ); + Type returnType = retrieveReturnType( method ); + List properties = retrieveMappedProperties( method ); - Type returnType = retrieveReturnType( oneMethod ); - Parameter parameter = retrieveParameter( oneMethod ); - Map bindings = retrieveBindings( oneMethod ); methods.add( - new MapperMethod( - oneMethod.getSimpleName().toString(), + new Method( + method.getSimpleName().toString(), + parameter.getName(), + parameter.getType(), returnType, - parameter, - bindings + properties ) ); } @@ -143,11 +233,9 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { return methods; } - private Map retrieveBindings(ExecutableElement method) { + private List retrieveMappedProperties(ExecutableElement method) { - Map bindings = new LinkedHashMap(); - - retrieveDefaultBindings( method, bindings ); + Map mappings = new HashMap(); for ( AnnotationMirror annotationMirror : method.getAnnotationMirrors() ) { @@ -156,67 +244,59 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { .accept( new NameDeterminationVisitor(), null ); if ( MAPPING_ANNOTATION.equals( annotationName ) ) { - retrieveBinding( annotationMirror, bindings ); + Mapping mapping = getMapping( annotationMirror ); + mappings.put( mapping.getSourceName(), mapping ); } else if ( MAPPINGS_ANNOTATION.equals( annotationName ) ) { - retrieveBindings( annotationMirror, bindings ); + mappings.putAll( getMappings( annotationMirror ) ); } } - return bindings; + return getMappedProperties( method, mappings ); } - private void retrieveDefaultBindings(ExecutableElement method, Map bindings) { - + private List getMappedProperties(ExecutableElement method, Map mappings) { Element returnTypeElement = typeUtils.asElement( method.getReturnType() ); - - Set writableTargetProperties = new LinkedHashSet(); - - //collect writable properties of the target type - for ( ExecutableElement oneMethod : methodsIn( returnTypeElement.getEnclosedElements() ) ) { - if ( oneMethod.getSimpleName().toString().startsWith( "set" ) && - oneMethod.getParameters().size() == 1 ) { - - writableTargetProperties.add( - new Property( - retrieveParameter( oneMethod ).getType(), - oneMethod.getSimpleName().toString().substring( 3 ) - ) - ); - } - } - - //collect readable properties of the source type Element parameterElement = typeUtils.asElement( method.getParameters().get( 0 ).asType() ); - Set readableSourceProperties = new LinkedHashSet(); + List properties = new ArrayList(); - for ( ExecutableElement oneMethod : methodsIn( parameterElement.getEnclosedElements() ) ) { - //TODO: consider is/has - if ( oneMethod.getSimpleName().toString().startsWith( "get" ) && - oneMethod.getParameters().isEmpty() && - oneMethod.getReturnType().getKind() != TypeKind.VOID ) { + for ( ExecutableElement getterMethod : getterMethodsIn( parameterElement.getEnclosedElements() ) ) { - readableSourceProperties.add( - new Property( - retrieveReturnType( oneMethod ), - oneMethod.getSimpleName().toString().substring( 3 ) - ) + String sourcePropertyName = Introspector.decapitalize( + getterMethod.getSimpleName() + .toString() + .substring( 3 ) + ); + Mapping mapping = mappings.get( sourcePropertyName ); + + for ( ExecutableElement setterMethod : setterMethodsIn( returnTypeElement.getEnclosedElements() ) ) { + + String targetPropertyName = Introspector.decapitalize( + setterMethod.getSimpleName() + .toString() + .substring( 3 ) ); + + if ( targetPropertyName.equals( mapping != null ? mapping.getTargetName() : sourcePropertyName ) ) { + properties.add( + new MappedProperty( + sourcePropertyName, + retrieveReturnType( getterMethod ), + mapping != null ? mapping.getTargetName() : targetPropertyName, + retrieveParameter( setterMethod ).getType(), + mapping != null ? mapping.getConverterType() : null + ) + ); + } } } - writableTargetProperties.retainAll( readableSourceProperties ); - - for ( Property oneWritableProperty : writableTargetProperties ) { - bindings.put( - oneWritableProperty.getName(), - new Binding( oneWritableProperty.getName(), oneWritableProperty.getName() ) - ); - } + return properties; } - private void retrieveBindings(AnnotationMirror annotationMirror, Map bindings) { + private Map getMappings(AnnotationMirror annotationMirror) { + Map mappings = new HashMap(); List values = getAnnotationValueListValue( annotationMirror, "value" ); @@ -225,62 +305,41 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { new AnnotationRetrievingVisitor(), null ); - retrieveBinding( oneAnnotation, bindings ); + Mapping mapping = getMapping( oneAnnotation ); + mappings.put( mapping.getSourceName(), mapping ); } + + return mappings; } - private void retrieveBinding(AnnotationMirror annotationMirror, Map bindings) { - + private Mapping getMapping(AnnotationMirror annotationMirror) { String sourcePropertyName = getStringValue( annotationMirror, "source" ); String targetPropertyName = getStringValue( annotationMirror, "target" ); TypeMirror converterTypeMirror = getTypeMirrorValue( annotationMirror, "converter" ); Type converterType = null; - Type sourceType = null; - Type targetType = null; if ( converterTypeMirror != null ) { - converterType = getType( typeUtils.asElement( converterTypeMirror ) ); - - List converterTypeParameters = getTypeParameters( - converterTypeMirror, - CONVERTER_TYPE - ); - - sourceType = getType( typeUtils.asElement( converterTypeParameters.get( 0 ) ) ); - targetType = getType( typeUtils.asElement( converterTypeParameters.get( 1 ) ) ); + converterType = getType( (DeclaredType) converterTypeMirror ); } - bindings.put( - sourcePropertyName, - new Binding( sourceType, sourcePropertyName, targetType, targetPropertyName, converterType ) - ); + return new Mapping( sourcePropertyName, targetPropertyName, converterType ); } - private Type getType(Element sourceTypeElement) { + private Type getType(DeclaredType type) { + Type elementType = null; + if ( !type.getTypeArguments().isEmpty() ) { + elementType = retrieveType( type.getTypeArguments().iterator().next() ); + } + return new Type( - elementUtils.getPackageOf( sourceTypeElement ).toString(), - sourceTypeElement.getSimpleName().toString() + elementUtils.getPackageOf( type.asElement() ).toString(), + type.asElement().getSimpleName().toString(), + elementType ); } - //TODO: consider complete type hierarchy - private List 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) { - List parameters = method.getParameters(); if ( parameters.size() != 1 ) { @@ -302,30 +361,14 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } private Type retrieveType(TypeMirror mirror) { - if ( mirror.getKind() == TypeKind.DECLARED ) { - return getType( ( (DeclaredType) mirror ).asElement() ); + return getType( ( (DeclaredType) mirror ) ); } else { return new Type( null, mirror.toString() ); } } - private AnnotationMirror getAnnotation(TypeElement element, String annotationName) { - - for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { - - if ( annotationName.equals( - annotationMirror.getAnnotationType().asElement().accept( new NameDeterminationVisitor(), null ) - ) ) { - - return annotationMirror; - } - } - - return null; - } - private String getStringValue(AnnotationMirror annotationMirror, String attributeName) { for ( Entry oneAttribute : annotationMirror.getElementValues() @@ -365,14 +408,39 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { return null; } - private static class TypeParameterDeterminationVisitor extends TypeKindVisitor6, Void> { + private List getterMethodsIn(Iterable elements) { + List getterMethods = new LinkedList(); - @Override - public List visitDeclared(DeclaredType type, Void p) { - return type.getTypeArguments(); + for ( ExecutableElement method : methodsIn( elements ) ) { + //TODO: consider is/has + String name = method.getSimpleName().toString(); + + if ( name.startsWith( "get" ) && name.length() > 3 && method.getParameters() + .isEmpty() && method.getReturnType().getKind() != TypeKind.VOID ) { + getterMethods.add( method ); + } } + + return getterMethods; } + private List setterMethodsIn(Iterable elements) { + List setterMethods = new LinkedList(); + + for ( ExecutableElement method : methodsIn( elements ) ) { + //TODO: consider is/has + String name = method.getSimpleName().toString(); + + if ( name.startsWith( "set" ) && name.length() > 3 && method.getParameters() + .size() == 1 && method.getReturnType().getKind() == TypeKind.VOID ) { + setterMethods.add( method ); + } + } + + return setterMethods; + } + + private static class NameDeterminationVisitor extends ElementKindVisitor6 { @Override diff --git a/processor/src/main/java/de/moapa/maple/ap/MappingProcessor.java b/processor/src/main/java/de/moapa/maple/ap/MappingProcessor.java index 9888ac362..cbd5816f5 100644 --- a/processor/src/main/java/de/moapa/maple/ap/MappingProcessor.java +++ b/processor/src/main/java/de/moapa/maple/ap/MappingProcessor.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/processor/src/main/java/de/moapa/maple/ap/model/BeanMapping.java b/processor/src/main/java/de/moapa/maple/ap/model/BeanMapping.java new file mode 100644 index 000000000..6c7804a47 --- /dev/null +++ b/processor/src/main/java/de/moapa/maple/ap/model/BeanMapping.java @@ -0,0 +1,74 @@ +/** + * 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 de.moapa.maple.ap.model; + +import java.util.List; + +public class BeanMapping { + + private final Type sourceType; + private final Type targetType; + private final List propertyMappings; + private final MappingMethod mappingMethod; + private final MappingMethod reverseMappingMethod; + private final boolean isIterableMapping; + + public BeanMapping(Type sourceType, Type targetType, List propertyMappings, MappingMethod mappingMethod, + MappingMethod reverseMappingMethod) { + this.sourceType = sourceType; + this.targetType = targetType; + this.propertyMappings = propertyMappings; + this.mappingMethod = mappingMethod; + this.reverseMappingMethod = reverseMappingMethod; + this.isIterableMapping = mappingMethod.getElementMappingMethod() != null; + } + + public Type getSourceType() { + return sourceType; + } + + public Type getTargetType() { + return targetType; + } + + public List getPropertyMappings() { + return propertyMappings; + } + + public MappingMethod getMappingMethod() { + return mappingMethod; + } + + public MappingMethod getReverseMappingMethod() { + return reverseMappingMethod; + } + + public boolean getIterableMapping() { + return isIterableMapping; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.append( sourceType ); + stringBuilder.append( " <=> " ); + stringBuilder.append( targetType ); + + + return stringBuilder.toString(); + } +} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Mapper.java b/processor/src/main/java/de/moapa/maple/ap/model/Mapper.java index 4e084a69a..172c4fb0e 100644 --- a/processor/src/main/java/de/moapa/maple/ap/model/Mapper.java +++ b/processor/src/main/java/de/moapa/maple/ap/model/Mapper.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,69 +15,39 @@ */ package de.moapa.maple.ap.model; -import java.util.ArrayList; import java.util.List; public class Mapper { - private final String mapperType; private final String packageName; - private final String implementationType; - private final String interfaceType; - private final List mapperMethods; - private final List converters; - public Mapper(String mapperType, String packageName, String implementationType, String interfaceType, List mapperMethods) { - this.mapperType = mapperType; + private final String interfaceName; + + private final String implementationName; + + private final List beanMappings; + + public Mapper(String packageName, String interfaceName, + String implementationName, List beanMappings) { this.packageName = packageName; - this.implementationType = implementationType; - this.interfaceType = interfaceType; - this.mapperMethods = mapperMethods; - this.converters = collectConverters( mapperMethods ); - } - - private List collectConverters(List mapperMethods) { - - List converters = new ArrayList(); - - for ( MapperMethod oneMapperMethod : mapperMethods ) { - for ( Binding oneBinding : oneMapperMethod.getBindings().values() ) { - if ( oneBinding.getConverterType() != null ) { - converters.add( - new Converter( - oneBinding.getConverterType(), - oneBinding.getSourceType(), - oneBinding.getTargetType() - ) - ); - } - } - } - - return converters; - } - - public String getMapperType() { - return mapperType; + this.interfaceName = interfaceName; + this.implementationName = implementationName; + this.beanMappings = beanMappings; } public String getPackageName() { return packageName; } - public String getImplementationType() { - return implementationType; + public String getInterfaceName() { + return interfaceName; } - public String getInterfaceType() { - return interfaceType; + public String getImplementationName() { + return implementationName; } - public List getMapperMethods() { - return mapperMethods; - } - - public List getConverters() { - return converters; + public List getBeanMappings() { + return beanMappings; } } diff --git a/processor/src/main/java/de/moapa/maple/ap/model/MapperMethod.java b/processor/src/main/java/de/moapa/maple/ap/model/MapperMethod.java deleted file mode 100644 index cfce25484..000000000 --- a/processor/src/main/java/de/moapa/maple/ap/model/MapperMethod.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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; - -import java.util.Map; - -public class MapperMethod { - - private final String name; - private final Type returnType; - private final Parameter parameter; - - /** - * Bindings for the properties of this method's converted object. Keyed by - * property name of the source type. - */ - private final Map bindings; - - public MapperMethod(String name, Type returnType, Parameter parameter, Map bindings) { - this.name = name; - this.returnType = returnType; - this.parameter = parameter; - this.bindings = bindings; - } - - public String getName() { - return name; - } - - public Type getReturnType() { - return returnType; - } - - public Parameter getParameter() { - return parameter; - } - - public Map getBindings() { - return bindings; - } - - public boolean getNonDefaultBindingExisting() { - for ( Binding oneBinding : bindings.values() ) { - if ( !oneBinding.isDefault() ) { - return true; - } - } - - return false; - } -} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/MappingMethod.java b/processor/src/main/java/de/moapa/maple/ap/model/MappingMethod.java new file mode 100644 index 000000000..925d9b8aa --- /dev/null +++ b/processor/src/main/java/de/moapa/maple/ap/model/MappingMethod.java @@ -0,0 +1,47 @@ +/** + * 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 de.moapa.maple.ap.model; + +public class MappingMethod { + + private final String name; + private final String parameterName; + private final MappingMethod elementMappingMethod; + + public MappingMethod(String name, String parameterName) { + this.name = name; + this.parameterName = parameterName; + this.elementMappingMethod = null; + } + + public MappingMethod(String name, String parameterName, MappingMethod elementMappingMethod) { + this.name = name; + this.parameterName = parameterName; + this.elementMappingMethod = elementMappingMethod; + } + + public String getName() { + return name; + } + + public String getParameterName() { + return parameterName; + } + + public MappingMethod getElementMappingMethod() { + return elementMappingMethod; + } +} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Property.java b/processor/src/main/java/de/moapa/maple/ap/model/Property.java deleted file mode 100644 index ea630db2c..000000000 --- a/processor/src/main/java/de/moapa/maple/ap/model/Property.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * 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; - -/** - * Represents a property of a Java bean. - * - * @author Gunnar Morling - */ -public class Property { - - private final Type type; - private final String name; - - public Property(Type type, String name) { - this.type = type; - this.name = name; - } - - public Type getType() { - return type; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return "Property [type=" + type + ", name=" + name + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ( ( name == null ) ? 0 : name.hashCode() ); - result = prime * result + ( ( type == null ) ? 0 : type.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; - } - Property other = (Property) obj; - if ( name == null ) { - if ( other.name != null ) { - return false; - } - } - else if ( !name.equals( other.name ) ) { - return false; - } - if ( type == null ) { - if ( other.type != null ) { - return false; - } - } - else if ( !type.equals( other.type ) ) { - return false; - } - return true; - } -} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/PropertyMapping.java b/processor/src/main/java/de/moapa/maple/ap/model/PropertyMapping.java new file mode 100644 index 000000000..ad8d33fce --- /dev/null +++ b/processor/src/main/java/de/moapa/maple/ap/model/PropertyMapping.java @@ -0,0 +1,53 @@ +/** + * 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 de.moapa.maple.ap.model; + +public class PropertyMapping { + + private final String sourceName; + private final String targetName; + private final Type converterType; + private final MappingMethod mappingMethod; + private final MappingMethod reverseMappingMethod; + + public PropertyMapping(String sourceName, String targetName, Type converterType, MappingMethod mappingMethod, MappingMethod reverseMappingMethod) { + this.sourceName = sourceName; + this.targetName = targetName; + this.converterType = converterType; + this.mappingMethod = mappingMethod; + this.reverseMappingMethod = reverseMappingMethod; + } + + public String getSourceName() { + return sourceName; + } + + public String getTargetName() { + return targetName; + } + + public Type getConverterType() { + return converterType; + } + + public MappingMethod getMappingMethod() { + return mappingMethod; + } + + public MappingMethod getReverseMappingMethod() { + return reverseMappingMethod; + } +} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Type.java b/processor/src/main/java/de/moapa/maple/ap/model/Type.java index 743d3e17b..74012bb00 100644 --- a/processor/src/main/java/de/moapa/maple/ap/model/Type.java +++ b/processor/src/main/java/de/moapa/maple/ap/model/Type.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -23,12 +23,25 @@ package de.moapa.maple.ap.model; public class Type { private final String packageName; - private final String name; + private final Type elementType; + + public Type(String name) { + this.packageName = null; + this.name = name; + this.elementType = null; + } public Type(String packageName, String name) { this.packageName = packageName; this.name = name; + this.elementType = null; + } + + public Type(String packageName, String name, Type elementType) { + this.packageName = packageName; + this.name = name; + this.elementType = elementType; } public String getPackageName() { @@ -39,15 +52,29 @@ public class Type { return name; } + public Type getElementType() { + return elementType; + } + @Override public String toString() { - return "Type [packageName=" + packageName + ", name=" + name + "]"; + if ( packageName == null ) { + return name; + } + else if ( elementType == null ) { + return packageName + "." + name; + } + else { + return packageName + "." + name + "<" + elementType + ">"; + } } @Override public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + + ( ( elementType == null ) ? 0 : elementType.hashCode() ); result = prime * result + ( ( name == null ) ? 0 : name.hashCode() ); result = prime * result + ( ( packageName == null ) ? 0 : packageName.hashCode() ); @@ -66,6 +93,14 @@ public class Type { return false; } Type other = (Type) obj; + if ( elementType == null ) { + if ( other.elementType != null ) { + return false; + } + } + else if ( !elementType.equals( other.elementType ) ) { + return false; + } if ( name == null ) { if ( other.name != null ) { return false; diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Binding.java b/processor/src/main/java/de/moapa/maple/ap/model/source/MappedProperty.java similarity index 54% rename from processor/src/main/java/de/moapa/maple/ap/model/Binding.java rename to processor/src/main/java/de/moapa/maple/ap/model/source/MappedProperty.java index bf4f2d79c..0d5342393 100644 --- a/processor/src/main/java/de/moapa/maple/ap/model/Binding.java +++ b/processor/src/main/java/de/moapa/maple/ap/model/source/MappedProperty.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -13,50 +13,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.moapa.maple.ap.model; +package de.moapa.maple.ap.model.source; -public class Binding { +import de.moapa.maple.ap.model.Type; +public class MappedProperty { + + private final String sourceName; private final Type sourceType; - private final String sourceProperty; + private final String targetName; private final Type targetType; - private final String targetProperty; private final Type converterType; - public Binding(String sourceProperty, String targetProperty) { - this( null, sourceProperty, null, targetProperty, null ); + public MappedProperty(String sourceName, Type sourceType, String targetName, + Type targetType, Type converterType) { + this.sourceName = sourceName; + this.sourceType = sourceType; + this.targetName = targetName; + this.targetType = targetType; + this.converterType = 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 String getSourceName() { + return sourceName; } public Type getSourceType() { return sourceType; } - public String getSourceProperty() { - return sourceProperty; + public String getTargetName() { + return targetName; } public Type getTargetType() { return targetType; } - public String getTargetProperty() { - return targetProperty; - } - public Type getConverterType() { return converterType; } - public boolean isDefault() { - return !sourceProperty.equals( targetProperty ) || ( sourceType != null && !sourceType.equals( targetType ) ) ? false : true; + @Override + public String toString() { + return sourceType + " " + sourceName + " <=> " + targetType + " " + targetName + " (" + ( converterType != null ? converterType : "no converter" ) + ")"; } } diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Converter.java b/processor/src/main/java/de/moapa/maple/ap/model/source/Mapping.java similarity index 59% rename from processor/src/main/java/de/moapa/maple/ap/model/Converter.java rename to processor/src/main/java/de/moapa/maple/ap/model/source/Mapping.java index 8cbd78b31..cf87cc338 100644 --- a/processor/src/main/java/de/moapa/maple/ap/model/Converter.java +++ b/processor/src/main/java/de/moapa/maple/ap/model/source/Mapping.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -13,30 +13,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.moapa.maple.ap.model; +package de.moapa.maple.ap.model.source; -public class Converter { +import de.moapa.maple.ap.model.Type; +public class Mapping { + + private final String sourceName; + private final String targetName; private final Type converterType; - private final Type sourceType; - private final Type targetType; - - public Converter(Type converterType, Type sourceType, Type targetType) { + public Mapping(String sourceName, String targetName, Type converterType) { + this.sourceName = sourceName; + this.targetName = targetName; this.converterType = converterType; - this.sourceType = sourceType; - this.targetType = targetType; + } + + public String getSourceName() { + return sourceName; + } + + public String getTargetName() { + return targetName; } public Type getConverterType() { return converterType; } - - public Type getSourceType() { - return sourceType; - } - - public Type getTargetType() { - return targetType; - } } diff --git a/processor/src/main/java/de/moapa/maple/ap/model/source/Method.java b/processor/src/main/java/de/moapa/maple/ap/model/source/Method.java new file mode 100644 index 000000000..7d3653ab3 --- /dev/null +++ b/processor/src/main/java/de/moapa/maple/ap/model/source/Method.java @@ -0,0 +1,72 @@ +/** + * 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 de.moapa.maple.ap.model.source; + +import java.util.List; + +import de.moapa.maple.ap.model.Type; + +public class Method { + + private final String name; + private final String parameterName; + private final Type sourceType; + private final Type targetType; + private final List mappedProperties; + + public Method(String name, String parameterName, Type sourceType, Type targetType, List mappedProperties) { + this.name = name; + this.parameterName = parameterName; + this.sourceType = sourceType; + this.targetType = targetType; + this.mappedProperties = mappedProperties; + } + + public String getName() { + return name; + } + + public String getParameterName() { + return parameterName; + } + + public Type getSourceType() { + return sourceType; + } + + public Type getTargetType() { + return targetType; + } + + public List getMappedProperties() { + return mappedProperties; + } + + public boolean reverses(Method method) { + return + equals( sourceType, method.getTargetType() ) && + equals( targetType, method.getSourceType() ); + } + + private boolean equals(Object o1, Object o2) { + return (o1 == null && o2 == null) || (o1 != null) && o1.equals( o2 ); + } + + @Override + public String toString() { + return targetType + " " + name + "(" + sourceType + " " + parameterName + ")"; + } +} diff --git a/processor/src/main/java/de/moapa/maple/ap/model/Parameter.java b/processor/src/main/java/de/moapa/maple/ap/model/source/Parameter.java similarity index 85% rename from processor/src/main/java/de/moapa/maple/ap/model/Parameter.java rename to processor/src/main/java/de/moapa/maple/ap/model/source/Parameter.java index c82c8eb0d..0447263cb 100644 --- a/processor/src/main/java/de/moapa/maple/ap/model/Parameter.java +++ b/processor/src/main/java/de/moapa/maple/ap/model/source/Parameter.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -13,7 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package de.moapa.maple.ap.model; +package de.moapa.maple.ap.model.source; + +import de.moapa.maple.ap.model.Type; public class Parameter { diff --git a/processor/src/main/java/de/moapa/maple/ap/writer/DozerModelWriter.java b/processor/src/main/java/de/moapa/maple/ap/writer/DozerModelWriter.java deleted file mode 100644 index 6098721ca..000000000 --- a/processor/src/main/java/de/moapa/maple/ap/writer/DozerModelWriter.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.writer; - -import java.io.BufferedWriter; -import javax.tools.JavaFileObject; - -import de.moapa.maple.ap.model.Mapper; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; - -public class DozerModelWriter implements ModelWriter { - - private final static String TEMPLATE_NAME = "dozer-mapper-implementation.ftl"; - - private static final Configuration configuration; - - static { - - configuration = new Configuration(); - configuration.setClassForTemplateLoading( DozerModelWriter.class, "/" ); - configuration.setObjectWrapper( new DefaultObjectWrapper() ); - - } - - @Override - public void writeModel(JavaFileObject sourceFile, Mapper model) { - - try { - BufferedWriter writer = new BufferedWriter( sourceFile.openWriter() ); - - Template template = configuration.getTemplate( TEMPLATE_NAME ); - template.process( model, writer ); - writer.flush(); - writer.close(); - } - catch ( RuntimeException e ) { - throw e; - } - catch ( Exception e ) { - throw new RuntimeException( e ); - } - } -} diff --git a/processor/src/main/java/de/moapa/maple/ap/writer/ModelWriter.java b/processor/src/main/java/de/moapa/maple/ap/writer/ModelWriter.java index 0a64c1a49..b89e61e17 100644 --- a/processor/src/main/java/de/moapa/maple/ap/writer/ModelWriter.java +++ b/processor/src/main/java/de/moapa/maple/ap/writer/ModelWriter.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,11 +15,44 @@ */ package de.moapa.maple.ap.writer; +import java.io.BufferedWriter; import javax.tools.JavaFileObject; -import de.moapa.maple.ap.model.Mapper; +import freemarker.template.Configuration; +import freemarker.template.DefaultObjectWrapper; +import freemarker.template.Template; -public interface ModelWriter { +public class ModelWriter { - void writeModel(JavaFileObject sourceFile, Mapper model); + private static final Configuration configuration; + + private final String templateName; + + static { + configuration = new Configuration(); + configuration.setClassForTemplateLoading( ModelWriter.class, "/" ); + configuration.setObjectWrapper( new DefaultObjectWrapper() ); + } + + public ModelWriter(String templateName) { + this.templateName = templateName; + } + + public void writeModel(JavaFileObject sourceFile, Object model) { + + try { + BufferedWriter writer = new BufferedWriter( sourceFile.openWriter() ); + + Template template = configuration.getTemplate( templateName ); + template.process( model, writer ); + writer.flush(); + writer.close(); + } + catch ( RuntimeException e ) { + throw e; + } + catch ( Exception e ) { + throw new RuntimeException( e ); + } + } } diff --git a/processor/src/main/java/de/moapa/maple/ap/writer/NativeModelWriter.java b/processor/src/main/java/de/moapa/maple/ap/writer/NativeModelWriter.java deleted file mode 100644 index bda756496..000000000 --- a/processor/src/main/java/de/moapa/maple/ap/writer/NativeModelWriter.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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.writer; - -import java.io.BufferedWriter; -import javax.tools.JavaFileObject; - -import de.moapa.maple.ap.model.Mapper; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; - -public class NativeModelWriter implements ModelWriter { - - private final static String TEMPLATE_NAME = "native-mapper-implementation.ftl"; - - private static final Configuration configuration; - - static { - - configuration = new Configuration(); - configuration.setClassForTemplateLoading( NativeModelWriter.class, "/" ); - configuration.setObjectWrapper( new DefaultObjectWrapper() ); - - } - - @Override - public void writeModel(JavaFileObject sourceFile, Mapper model) { - - try { - BufferedWriter writer = new BufferedWriter( sourceFile.openWriter() ); - - Template template = configuration.getTemplate( TEMPLATE_NAME ); - template.process( model, writer ); - writer.flush(); - writer.close(); - } - catch ( RuntimeException e ) { - throw e; - } - catch ( Exception e ) { - throw new RuntimeException( e ); - } - } -} diff --git a/processor/src/main/resources/dozer-mapper-implementation.ftl b/processor/src/main/resources/dozer-mapper-implementation.ftl deleted file mode 100644 index ed34facfd..000000000 --- a/processor/src/main/resources/dozer-mapper-implementation.ftl +++ /dev/null @@ -1,80 +0,0 @@ -<#-- - - 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 ${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; - - public ${implementationType}() { - mapper = new DozerBeanMapper(); - - BeanMappingBuilder builder = null; - - <#list mapperMethods as oneMethod> - <#if oneMethod.nonDefaultBindingExisting> - builder = new BeanMappingBuilder() { - protected void configure() { - mapping( ${oneMethod.parameter.type.name}.class, ${oneMethod.returnType.name}.class ) - <#list oneMethod.bindings?values as oneBinding> - .fields( "${oneBinding.sourceProperty}", "${oneBinding.targetProperty}"<#if oneBinding.converterType??>, customConverter( ${oneBinding.converterType.name}DozerAdapter.class ) ) - - ; - } - }; - mapper.addMapping( builder ); - - - - } - - <#list mapperMethods as oneMethod> - public ${oneMethod.returnType.name} ${oneMethod.name}(${oneMethod.parameter.type.name} ${oneMethod.parameter.name}) { - return mapper.map(${oneMethod.parameter.name}, ${oneMethod.returnType.name}.class); - } - - - <#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); - } - } - -} diff --git a/processor/src/main/resources/mapper-implementation.ftl b/processor/src/main/resources/mapper-implementation.ftl new file mode 100644 index 000000000..b531dd76b --- /dev/null +++ b/processor/src/main/resources/mapper-implementation.ftl @@ -0,0 +1,93 @@ +<#-- + + 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 ${packageName}; + +import java.util.ArrayList; +import java.util.List; + +public class ${implementationName} implements ${interfaceName} { + + <#list beanMappings as beanMapping> + <#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}) { + + ${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} ) { + ${beanMapping.targetType.name?uncap_first}.add( ${beanMapping.mappingMethod.elementMappingMethod.name}( ${beanMapping.sourceType.elementType.name?uncap_first} ) ); + } + + return ${beanMapping.targetType.name?uncap_first}; + } + <#else> + @Override + 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}(); + + <#list beanMapping.propertyMappings as propertyMapping> + <#if 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}() ) ); + <#elseif propertyMapping.mappingMethod??> + ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${propertyMapping.mappingMethod.name}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ) ); + <#else> + ${beanMapping.targetType.name?uncap_first}.set${propertyMapping.targetName?cap_first}( ${beanMapping.mappingMethod.parameterName}.get${propertyMapping.sourceName?cap_first}() ); + + + + return ${beanMapping.targetType.name?uncap_first}; + } + + + <#if beanMapping.reverseMappingMethod??> + + <#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}) { + + ${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} ) { + ${beanMapping.sourceType.name?uncap_first}.add( ${beanMapping.reverseMappingMethod.elementMappingMethod.name}( ${beanMapping.targetType.elementType.name?uncap_first} ) ); + } + + return ${beanMapping.sourceType.name?uncap_first}; + } + <#else> + @Override + public ${beanMapping.sourceType.name} ${beanMapping.reverseMappingMethod.name}(${beanMapping.targetType.name} ${beanMapping.reverseMappingMethod.parameterName}) { + ${beanMapping.sourceType.name} ${beanMapping.sourceType.name?uncap_first} = new ${beanMapping.sourceType.name}(); + + <#list beanMapping.propertyMappings as propertyMapping> + <#if 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}() ) ); + <#elseif propertyMapping.reverseMappingMethod??> + ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${propertyMapping.reverseMappingMethod.name}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ) ); + <#else> + ${beanMapping.sourceType.name?uncap_first}.set${propertyMapping.sourceName?cap_first}( ${beanMapping.reverseMappingMethod.parameterName}.get${propertyMapping.targetName?cap_first}() ); + + + + return ${beanMapping.sourceType.name?uncap_first}; + } + + + + +} diff --git a/processor/src/main/resources/native-mapper-implementation.ftl b/processor/src/main/resources/native-mapper-implementation.ftl deleted file mode 100644 index cd0cae8aa..000000000 --- a/processor/src/main/resources/native-mapper-implementation.ftl +++ /dev/null @@ -1,38 +0,0 @@ -<#-- - - 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 ${packageName}; - -public class ${implementationType} implements ${interfaceType} { - <#list mapperMethods as oneMethod> - - public ${oneMethod.returnType.name} ${oneMethod.name}(${oneMethod.parameter.type.name} ${oneMethod.parameter.name}) { - - ${oneMethod.returnType.name} convertedObject = new ${oneMethod.returnType.name}(); - - <#list oneMethod.bindings?values as oneBinding> - <#if oneBinding.converterType??> - convertedObject.set${oneBinding.targetProperty?cap_first}( new ${oneBinding.converterType.name}().from( ${oneMethod.parameter.name}.get${oneBinding.sourceProperty?cap_first}() ) ); - <#else> - convertedObject.set${oneBinding.targetProperty?cap_first}( ${oneMethod.parameter.name}.get${oneBinding.sourceProperty?cap_first}() ); - - - - return convertedObject; - } - -} diff --git a/processor/src/test/java/de/moapa/maple/ap/test/CarMapperTest.java b/processor/src/test/java/de/moapa/maple/ap/test/CarMapperTest.java index 77a21d206..b423f5ddf 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/CarMapperTest.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/CarMapperTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -16,13 +16,16 @@ package de.moapa.maple.ap.test; import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import javax.tools.DiagnosticCollector; import javax.tools.JavaFileObject; 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 de.moapa.maple.ap.test.model.CarMapper; import de.moapa.maple.ap.test.model.Person; import de.moapa.maple.ap.test.model.PersonDto; import org.testng.annotations.BeforeMethod; @@ -35,12 +38,11 @@ public class CarMapperTest extends MapperTestBase { private DiagnosticCollector diagnostics; public CarMapperTest() { - super( "maple.jar", "dozer.jar", "slf4j-api.jar", "slf4j-jdk14.jar" ); + super( "maple.jar" ); } @BeforeMethod public void generateMapperImplementation() { - diagnostics = new DiagnosticCollector(); File[] sourceFiles = getSourceFiles( Car.class, @@ -59,15 +61,13 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldProvideMapperInstance() throws Exception { - assertThat( CarMapper.INSTANCE ).isNotNull(); } @Test public void shouldMapAttributeByName() { - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); + Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -79,9 +79,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldMapReferenceAttribute() { - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); + Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -94,9 +93,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldReverseMapReferenceAttribute() { - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); @@ -109,9 +107,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldMapAttributeWithCustomMapping() { - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); + Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -123,9 +120,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldConsiderCustomMappingForReverseMapping() { - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); @@ -137,9 +133,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldApplyConverter() { - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); + Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); //when CarDto carDto = CarMapper.INSTANCE.carToCarDto( car ); @@ -151,9 +146,8 @@ public class CarMapperTest extends MapperTestBase { @Test public void shouldApplyConverterForReverseMapping() { - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); @@ -162,4 +156,96 @@ public class CarMapperTest extends MapperTestBase { assertThat( car ).isNotNull(); assertThat( car.getYearOfManufacture() ).isEqualTo( 1980 ); } + + @Test + public void shouldMapIterable() { + //given + Car car1 = new Car( "Morris", 2, 1980, new Person( "Bob" ), new ArrayList() ); + Car car2 = new Car( "Railton", 4, 1934, new Person( "Bill" ), new ArrayList() ); + + //when + List dtos = CarMapper.INSTANCE.carsToCarDtos( new ArrayList( Arrays.asList( car1, car2 ) ) ); + + //then + assertThat( dtos ).isNotNull(); + assertThat( dtos ).hasSize( 2 ); + + assertThat( dtos.get( 0 ).getMake() ).isEqualTo( "Morris" ); + assertThat( dtos.get( 0 ).getSeatCount() ).isEqualTo( 2 ); + assertThat( dtos.get( 0 ).getManufacturingYear() ).isEqualTo( "1980" ); + assertThat( dtos.get( 0 ).getDriver().getName() ).isEqualTo( "Bob" ); + + assertThat( dtos.get( 1 ).getMake() ).isEqualTo( "Railton" ); + assertThat( dtos.get( 1 ).getSeatCount() ).isEqualTo( 4 ); + assertThat( dtos.get( 1 ).getManufacturingYear() ).isEqualTo( "1934" ); + assertThat( dtos.get( 1 ).getDriver().getName() ).isEqualTo( "Bill" ); + } + + @Test + public void shouldReverseMapIterable() { + //given + CarDto car1 = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); + CarDto car2 = new CarDto( "Railton", 4, "1934", new PersonDto( "Bill" ), new ArrayList() ); + + //when + List cars = CarMapper.INSTANCE.carDtosToCars( new ArrayList( Arrays.asList( car1, car2 ) ) ); + + //then + assertThat( cars ).isNotNull(); + assertThat( cars ).hasSize( 2 ); + + 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 ).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 ).getDriver().getName() ).isEqualTo( "Bill" ); + } + + @Test + public void shouldMapIterableAttribute() { + //given + Car car = new Car( + "Morris", + 2, + 1980, + new Person( "Bob" ), + new ArrayList( Arrays.asList( new Person( "Alice" ), new Person( "Bill" ) ) ) + ); + + //when + CarDto dto = CarMapper.INSTANCE.carToCarDto( car ); + + //then + assertThat( dto ).isNotNull(); + + assertThat( dto.getPassengers() ).hasSize( 2 ); + assertThat( dto.getPassengers().get( 0 ).getName() ).isEqualTo( "Alice" ); + assertThat( dto.getPassengers().get( 1 ).getName() ).isEqualTo( "Bill" ); + } + + @Test + public void shouldReverseMapIterableAttribute() { + //given + CarDto carDto = new CarDto( + "Morris", + 2, + "1980", + new PersonDto( "Bob" ), + new ArrayList( Arrays.asList( new PersonDto( "Alice" ), new PersonDto( "Bill" ) ) ) + ); + + //when + Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); + + //then + assertThat( car ).isNotNull(); + + assertThat( car.getPassengers() ).hasSize( 2 ); + assertThat( car.getPassengers().get( 0 ).getName() ).isEqualTo( "Alice" ); + assertThat( car.getPassengers().get( 1 ).getName() ).isEqualTo( "Bill" ); + } } diff --git a/processor/src/test/java/de/moapa/maple/ap/test/MapperTestBase.java b/processor/src/test/java/de/moapa/maple/ap/test/MapperTestBase.java index 7cccf89ea..4706ffdea 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/MapperTestBase.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/MapperTestBase.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/processor/src/test/java/de/moapa/maple/ap/test/NativeCarMapperTest.java b/processor/src/test/java/de/moapa/maple/ap/test/NativeCarMapperTest.java deleted file mode 100644 index 2d531309e..000000000 --- a/processor/src/test/java/de/moapa/maple/ap/test/NativeCarMapperTest.java +++ /dev/null @@ -1,165 +0,0 @@ -/** - * 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; - -import java.io.File; -import javax.tools.DiagnosticCollector; -import javax.tools.JavaFileObject; - -import de.moapa.maple.ap.test.model.Car; -import de.moapa.maple.ap.test.model.CarDto; -import de.moapa.maple.ap.test.model.IntToStringConverter; -import de.moapa.maple.ap.test.model.NativeCarMapper; -import de.moapa.maple.ap.test.model.Person; -import de.moapa.maple.ap.test.model.PersonDto; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import static org.fest.assertions.Assertions.assertThat; - -public class NativeCarMapperTest extends MapperTestBase { - - private DiagnosticCollector diagnostics; - - public NativeCarMapperTest() { - super( "maple.jar" ); - } - - @BeforeMethod - public void generateMapperImplementation() { - - diagnostics = new DiagnosticCollector(); - File[] sourceFiles = getSourceFiles( - Car.class, - CarDto.class, - Person.class, - PersonDto.class, - NativeCarMapper.class, - IntToStringConverter.class - ); - - boolean compilationSuccessful = compile( diagnostics, sourceFiles ); - - assertThat( compilationSuccessful ).describedAs( "Compilation failed: " + diagnostics.getDiagnostics() ) - .isTrue(); - } - - @Test - public void shouldProvideMapperInstance() throws Exception { - - assertThat( NativeCarMapper.INSTANCE ).isNotNull(); - } - - @Test - public void shouldMapAttributeByName() { - - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); - - //when - CarDto carDto = NativeCarMapper.INSTANCE.carToCarDto( car ); - - //then - assertThat( carDto ).isNotNull(); - assertThat( carDto.getMake() ).isEqualTo( car.getMake() ); - } - - @Test(enabled = false) - public void shouldMapReferenceAttribute() { - - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); - - //when - CarDto carDto = NativeCarMapper.INSTANCE.carToCarDto( car ); - - //then - assertThat( carDto ).isNotNull(); - assertThat( carDto.getDriver() ).isNotNull(); - assertThat( carDto.getDriver().getName() ).isEqualTo( "Bob" ); - } - - @Test(enabled = false) - public void shouldReverseMapReferenceAttribute() { - - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); - - //when - Car car = NativeCarMapper.INSTANCE.carDtoToCar( carDto ); - - //then - assertThat( car ).isNotNull(); - assertThat( car.getDriver() ).isNotNull(); - assertThat( car.getDriver().getName() ).isEqualTo( "Bob" ); - } - - @Test - public void shouldMapAttributeWithCustomMapping() { - - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); - - //when - CarDto carDto = NativeCarMapper.INSTANCE.carToCarDto( car ); - - //then - assertThat( carDto ).isNotNull(); - assertThat( carDto.getSeatCount() ).isEqualTo( car.getNumberOfSeats() ); - } - - @Test(enabled = false) - public void shouldConsiderCustomMappingForReverseMapping() { - - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); - - //when - Car car = NativeCarMapper.INSTANCE.carDtoToCar( carDto ); - - //then - assertThat( car ).isNotNull(); - assertThat( car.getNumberOfSeats() ).isEqualTo( carDto.getSeatCount() ); - } - - @Test - public void shouldApplyConverter() { - - //given - Car car = new Car( "Morris", 2, 1980, new Person( "Bob" ) ); - - //when - CarDto carDto = NativeCarMapper.INSTANCE.carToCarDto( car ); - - //then - assertThat( carDto ).isNotNull(); - assertThat( carDto.getManufacturingYear() ).isEqualTo( "1980" ); - } - - @Test(enabled = false) - public void shouldApplyConverterForReverseMapping() { - - //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ) ); - - //when - Car car = NativeCarMapper.INSTANCE.carDtoToCar( carDto ); - - //then - assertThat( car ).isNotNull(); - assertThat( car.getYearOfManufacture() ).isEqualTo( 1980 ); - } -} diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/Car.java b/processor/src/test/java/de/moapa/maple/ap/test/model/Car.java index b2d76d93a..f3ac9ec94 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/Car.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/Car.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,21 +15,25 @@ */ package de.moapa.maple.ap.test.model; +import java.util.ArrayList; + public class Car { private String make; private int numberOfSeats; private int yearOfManufacture; private Person driver; + private ArrayList passengers; public Car() { } - public Car(String make, int numberOfSeats, int yearOfManufacture, Person driver) { + public Car(String make, int numberOfSeats, int yearOfManufacture, Person driver, ArrayList passengers) { this.make = make; this.numberOfSeats = numberOfSeats; this.yearOfManufacture = yearOfManufacture; this.driver = driver; + this.passengers = passengers; } public String getMake() { @@ -63,4 +67,12 @@ public class Car { public void setDriver(Person driver) { this.driver = driver; } + + public ArrayList getPassengers() { + return passengers; + } + + public void setPassengers(ArrayList passengers) { + this.passengers = passengers; + } } diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/CarDto.java b/processor/src/test/java/de/moapa/maple/ap/test/model/CarDto.java index 62ff0cfa0..56348df5e 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/CarDto.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/CarDto.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,21 +15,25 @@ */ package de.moapa.maple.ap.test.model; +import java.util.ArrayList; + public class CarDto { private String make; private int seatCount; private String manufacturingYear; private PersonDto driver; + private ArrayList passengers; public CarDto() { } - public CarDto(String make, int seatCount, String manufacturingYear, PersonDto driver) { + public CarDto(String make, int seatCount, String manufacturingYear, PersonDto driver, ArrayList passengers) { this.make = make; this.seatCount = seatCount; this.manufacturingYear = manufacturingYear; this.driver = driver; + this.passengers = passengers; } public String getMake() { @@ -63,4 +67,12 @@ public class CarDto { public void setDriver(PersonDto driver) { this.driver = driver; } + + public ArrayList getPassengers() { + return passengers; + } + + public void setPassengers(ArrayList passengers) { + this.passengers = passengers; + } } diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/CarMapper.java b/processor/src/test/java/de/moapa/maple/ap/test/model/CarMapper.java index cccda75e3..981319408 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/CarMapper.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/CarMapper.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. @@ -15,6 +15,8 @@ */ package de.moapa.maple.ap.test.model; +import java.util.ArrayList; + import de.moapa.maple.Mapper; import de.moapa.maple.Mappers; import de.moapa.maple.Mapping; @@ -32,4 +34,16 @@ public interface CarMapper { CarDto carToCarDto(Car car); Car carDtoToCar(CarDto carDto); + + ArrayList carsToCarDtos(ArrayList cars); + + ArrayList carDtosToCars(ArrayList carDtos); + + PersonDto personToPersonDto(Person person); + + Person personDtoToPerson(PersonDto personDto); + + ArrayList personsToPersonDtos(ArrayList persons); + + ArrayList personDtosToPersons(ArrayList personDtos); } diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/IntToStringConverter.java b/processor/src/test/java/de/moapa/maple/ap/test/model/IntToStringConverter.java index 7d38893ed..6b8fab450 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/IntToStringConverter.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/IntToStringConverter.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/NativeCarMapper.java b/processor/src/test/java/de/moapa/maple/ap/test/model/NativeCarMapper.java deleted file mode 100644 index 5a9a4195d..000000000 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/NativeCarMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * 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.Mapper; -import de.moapa.maple.Mappers; -import de.moapa.maple.Mapping; -import de.moapa.maple.Mappings; - -@Mapper("native") -public interface NativeCarMapper { - - NativeCarMapper INSTANCE = Mappers.getMapper( NativeCarMapper.class ); - - @Mappings({ - @Mapping(source = "numberOfSeats", target = "seatCount"), - @Mapping(source = "yearOfManufacture", target = "manufacturingYear", converter = IntToStringConverter.class) - }) - CarDto carToCarDto(Car car); - - Car carDtoToCar(CarDto carDto); -} diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/Person.java b/processor/src/test/java/de/moapa/maple/ap/test/model/Person.java index 02715a86b..fcf304f28 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/Person.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/Person.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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. diff --git a/processor/src/test/java/de/moapa/maple/ap/test/model/PersonDto.java b/processor/src/test/java/de/moapa/maple/ap/test/model/PersonDto.java index 35f765f0f..773056d66 100644 --- a/processor/src/test/java/de/moapa/maple/ap/test/model/PersonDto.java +++ b/processor/src/test/java/de/moapa/maple/ap/test/model/PersonDto.java @@ -1,5 +1,5 @@ /** - * Copyright 2012 Gunnar Morling (http://www.gunnarmorling.de/) + * 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.