diff --git a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java index a6f7ada9c..b95874990 100644 --- a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java +++ b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java @@ -435,12 +435,23 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { } private List getMappedProperties(ExecutableElement method, Map mappings) { - Element returnTypeElement = typeUtils.asElement( method.getReturnType() ); - Element parameterElement = typeUtils.asElement( method.getParameters().get( 0 ).asType() ); + TypeElement returnTypeElement = (TypeElement) typeUtils.asElement( method.getReturnType() ); + TypeElement parameterElement = (TypeElement) typeUtils.asElement( method.getParameters().get( 0 ).asType() ); List properties = new ArrayList(); - List sourceGetters = Filters.getterMethodsIn( parameterElement.getEnclosedElements() ); - List targetSetters = Filters.setterMethodsIn( returnTypeElement.getEnclosedElements() ); + + List sourceGetters = Filters.getterMethodsIn( + elementUtils.getAllMembers( parameterElement ) + ); + List targetSetters = Filters.setterMethodsIn( + elementUtils.getAllMembers( returnTypeElement ) + ); + List sourceSetters = Filters.setterMethodsIn( + elementUtils.getAllMembers( parameterElement ) + ); + List targetGetters = Filters.getterMethodsIn( + elementUtils.getAllMembers( returnTypeElement ) + ); reportErrorIfMappedPropertiesDontExist( method, mappings, sourceGetters, targetSetters ); @@ -456,12 +467,12 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { new MappedProperty( sourcePropertyName, getterMethod.getSimpleName().toString(), - Executables.getCorrespondingSetterMethod( parameterElement, getterMethod ) + Executables.getCorrespondingPropertyAccessor( getterMethod, sourceSetters ) .getSimpleName() .toString(), retrieveReturnType( getterMethod ), mapping != null ? mapping.getTargetName() : targetPropertyName, - Executables.getCorrespondingGetterMethod( returnTypeElement, setterMethod ) + Executables.getCorrespondingPropertyAccessor( setterMethod, targetGetters ) .getSimpleName() .toString(), setterMethod.getSimpleName().toString(), diff --git a/processor/src/main/java/org/mapstruct/ap/util/Executables.java b/processor/src/main/java/org/mapstruct/ap/util/Executables.java index 0bce9fa80..8f1d288dc 100644 --- a/processor/src/main/java/org/mapstruct/ap/util/Executables.java +++ b/processor/src/main/java/org/mapstruct/ap/util/Executables.java @@ -19,7 +19,7 @@ package org.mapstruct.ap.util; import java.beans.Introspector; -import javax.lang.model.element.Element; +import java.util.List; import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeKind; @@ -86,24 +86,24 @@ public class Executables { throw new IllegalArgumentException( "Executable " + getterOrSetterMethod + " is not getter or setter method." ); } - public static ExecutableElement getCorrespondingSetterMethod(Element element, ExecutableElement getterMethod) { - String propertyName = getPropertyName( getterMethod ); + /** + * Returns that setter or getter from the given list of executables which + * corresponds to the given getter or setter method. + * + * @param getterOrSetter The getter or setter method of interest. + * @param elements A list of executables to retrieve the corresponding accessor + * from. + * + * @return The setter corresponding to the given getter or the getter + * corresponding to the given getter + */ + public static ExecutableElement getCorrespondingPropertyAccessor(ExecutableElement getterOrSetter, + List elements) { + String propertyName = getPropertyName( getterOrSetter ); - for ( ExecutableElement setterMethod : Filters.setterMethodsIn( element.getEnclosedElements() ) ) { - if ( getPropertyName( setterMethod ).equals( propertyName ) ) { - return setterMethod; - } - } - - return null; - } - - public static ExecutableElement getCorrespondingGetterMethod(Element element, ExecutableElement setterMethod) { - String propertyName = getPropertyName( setterMethod ); - - for ( ExecutableElement getterMethod : Filters.getterMethodsIn( element.getEnclosedElements() ) ) { - if ( getPropertyName( getterMethod ).equals( propertyName ) ) { - return getterMethod; + for ( ExecutableElement method : elements ) { + if ( getPropertyName( method ).equals( propertyName ) ) { + return method; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java new file mode 100644 index 000000000..799868247 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java @@ -0,0 +1,63 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.MapperTestBase; +import org.mapstruct.ap.testutil.WithClasses; +import org.testng.annotations.Test; + +import static org.fest.assertions.Assertions.assertThat; + +/** + * Test for propagation of attributes inherited from super types. + * + * @author Gunnar Morling + */ +@WithClasses({ SourceBase.class, SourceExt.class, TargetBase.class, TargetExt.class, SourceTargetMapper.class }) +public class InheritanceTest extends MapperTestBase { + + @Test + @IssueKey("17") + public void shouldMapAttributeFromSuperType() { + SourceExt source = new SourceExt(); + source.setFoo( 42 ); + source.setBar( 23L ); + + TargetExt target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) ); + assertThat( target.getBar() ).isEqualTo( 23 ); + } + + @Test + @IssueKey("17") + public void shouldReverseMapAttributeFromSuperType() { + TargetExt target = new TargetExt(); + target.setFoo( 42L ); + target.setBar( 23 ); + + SourceExt source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getFoo() ).isEqualTo( 42 ); + assertThat( source.getBar() ).isEqualTo( Long.valueOf( 23 ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java new file mode 100644 index 000000000..358cde086 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +public class SourceBase { + + private int foo; + + public int getFoo() { + return foo; + } + + public void setFoo(int foo) { + this.foo = foo; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java new file mode 100644 index 000000000..050681e97 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +public class SourceExt extends SourceBase { + + private Long bar; + + public Long getBar() { + return bar; + } + + public void setBar(Long bar) { + this.bar = bar; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java new file mode 100644 index 000000000..738f51d88 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +import org.mapstruct.Mapper; +import org.mapstruct.Mappers; + +@Mapper +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + TargetExt sourceToTarget(SourceExt source); + + SourceExt targetToSource(TargetExt target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java new file mode 100644 index 000000000..b9c63f635 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +public class TargetBase { + + private Long foo; + + public Long getFoo() { + return foo; + } + + public void setFoo(Long foo) { + this.foo = foo; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java new file mode 100644 index 000000000..be269f48e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java @@ -0,0 +1,32 @@ +/** + * Copyright 2012-2013 Gunnar Morling (http://www.gunnarmorling.de/) + * and/or other contributors as indicated by the @authors tag. See the + * copyright.txt file in the distribution for a full listing of all + * contributors. + * + * 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.inheritance; + +public class TargetExt extends TargetBase { + + private int bar; + + public int getBar() { + return bar; + } + + public void setBar(int bar) { + this.bar = bar; + } +}