From 4e771244add8847ccd87b5febb78d4b0dd864e3b Mon Sep 17 00:00:00 2001 From: sjaakd Date: Sat, 10 Jan 2015 08:56:38 +0100 Subject: [PATCH] #385 Introduction of BeanMapping annotation and target type selection, reorder of selectors --- .../main/java/org/mapstruct/BeanMapping.java | 43 +++++++++++ .../source/selector/MethodSelectors.java | 5 +- .../source/selector/SelectionCriteria.java | 7 +- .../source/selector/TargetTypeSelector.java | 69 +++++++++++++++++ .../mapstruct/ap/prism/PrismGenerator.java | 2 + .../creation/MappingResolverImpl.java | 32 ++++---- .../ap/test/selection/inheritance/Apple.java | 31 ++++++++ .../test/selection/inheritance/AppleDto.java | 31 ++++++++ .../ap/test/selection/inheritance/Banana.java | 31 ++++++++ .../test/selection/inheritance/BananaDto.java | 31 ++++++++ .../inheritance/ConflictingFruitFactory.java | 34 +++++++++ .../inheritance/ErroneousFruitMapper.java | 38 ++++++++++ .../ap/test/selection/inheritance/Fruit.java | 42 +++++++++++ .../test/selection/inheritance/FruitDto.java | 42 +++++++++++ .../inheritance/InheritanceSelectionTest.java | 74 +++++++++++++++++++ .../TargetTypeSelectingFruitMapper.java | 40 ++++++++++ 16 files changed, 535 insertions(+), 17 deletions(-) create mode 100644 core-common/src/main/java/org/mapstruct/BeanMapping.java create mode 100644 processor/src/main/java/org/mapstruct/ap/model/source/selector/TargetTypeSelector.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Apple.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/AppleDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Banana.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/BananaDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ConflictingFruitFactory.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ErroneousFruitMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Fruit.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/FruitDto.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/InheritanceSelectionTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/TargetTypeSelectingFruitMapper.java diff --git a/core-common/src/main/java/org/mapstruct/BeanMapping.java b/core-common/src/main/java/org/mapstruct/BeanMapping.java new file mode 100644 index 000000000..981530f66 --- /dev/null +++ b/core-common/src/main/java/org/mapstruct/BeanMapping.java @@ -0,0 +1,43 @@ +/** + * Copyright 2012-2015 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; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Configures the mapping between two bean types + * + * @author Sjaak Derksen + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.SOURCE) +public @interface BeanMapping { + + + /** + * Specifies the result type of the method to select in case ambiguous mappings / factory methods. + * + * + * @return the resultType to select + */ + Class resultType() default void.class; +} diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/MethodSelectors.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/MethodSelectors.java index bdf313b69..c046f83c1 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/selector/MethodSelectors.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/MethodSelectors.java @@ -42,9 +42,10 @@ public class MethodSelectors implements MethodSelector { selectors = Arrays.asList( new TypeSelector( typeFactory ), - new InheritanceSelector(), + new QualifierSelector( typeUtils, elementUtils ), + new TargetTypeSelector( typeUtils, elementUtils ), new XmlElementDeclSelector( typeUtils ), - new QualifierSelector( typeUtils, elementUtils ) + new InheritanceSelector() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java index d51d5de1e..36330c4fb 100644 --- a/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/SelectionCriteria.java @@ -30,10 +30,12 @@ public class SelectionCriteria { private final List qualifiers; private final String targetPropertyName; + private final TypeMirror qualifyingResultType; - public SelectionCriteria(List qualifiers, String targetPropertyName) { + public SelectionCriteria(List qualifiers, String targetPropertyName, TypeMirror qualifyingResultType) { this.qualifiers = qualifiers; this.targetPropertyName = targetPropertyName; + this.qualifyingResultType = qualifyingResultType; } public List getQualifiers() { @@ -44,4 +46,7 @@ public class SelectionCriteria { return targetPropertyName; } + public TypeMirror getQualifyingResultType() { + return qualifyingResultType; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/model/source/selector/TargetTypeSelector.java b/processor/src/main/java/org/mapstruct/ap/model/source/selector/TargetTypeSelector.java new file mode 100644 index 000000000..dd6d056c6 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/model/source/selector/TargetTypeSelector.java @@ -0,0 +1,69 @@ +/** + * Copyright 2012-2015 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.model.source.selector; + +import java.util.ArrayList; +import java.util.List; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +import org.mapstruct.ap.model.common.Type; +import org.mapstruct.ap.model.source.Method; + +/** + * This selector selects a best match based on the result type. + *

+ * Suppose: Sedan -> Car -> Vehicle, MotorCycle -> Vehicle + * By means of this selector one can pinpoint the exact desired return type (Sedan, Car, MotorCycle, Vehicle) + * + * @author Sjaak Derksen + */ +public class TargetTypeSelector implements MethodSelector { + + private final Types typeUtils; + + public TargetTypeSelector( Types typeUtils, Elements elementUtils ) { + this.typeUtils = typeUtils; + } + + @Override + public List getMatchingMethods(Method mappingMethod, List methods, + Type sourceType, Type targetType, + SelectionCriteria criteria) { + + TypeMirror qualifyingTypeMirror = criteria.getQualifyingResultType(); + if ( qualifyingTypeMirror != null ) { + + List candidatesWithQualifyingTargetType = new ArrayList(); + for ( T method : methods ) { + TypeMirror resultTypeMirror = method.getResultType().getTypeElement().asType(); + if ( typeUtils.isSameType( qualifyingTypeMirror, resultTypeMirror ) ) { + candidatesWithQualifyingTargetType.add( method ); + } + } + + return candidatesWithQualifyingTargetType; + } + else { + return methods; + } + } +} + diff --git a/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java b/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java index ec5e27332..fca54dccb 100644 --- a/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java +++ b/processor/src/main/java/org/mapstruct/ap/prism/PrismGenerator.java @@ -22,6 +22,7 @@ import javax.xml.bind.annotation.XmlElementDecl; import net.java.dev.hickory.prism.GeneratePrism; import net.java.dev.hickory.prism.GeneratePrisms; +import org.mapstruct.BeanMapping; import org.mapstruct.DecoratedWith; import org.mapstruct.InheritConfiguration; import org.mapstruct.InheritInverseConfiguration; @@ -46,6 +47,7 @@ import org.mapstruct.TargetType; @GeneratePrism(value = Mapping.class, publicAccess = true), @GeneratePrism(value = Mappings.class, publicAccess = true), @GeneratePrism(value = IterableMapping.class, publicAccess = true), + @GeneratePrism(value = BeanMapping.class, publicAccess = true), @GeneratePrism(value = MapMapping.class, publicAccess = true), @GeneratePrism(value = TargetType.class, publicAccess = true), @GeneratePrism(value = MappingTarget.class, publicAccess = true), diff --git a/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolverImpl.java b/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolverImpl.java index 5cd6abc5f..ca08ba2fc 100755 --- a/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolverImpl.java +++ b/processor/src/main/java/org/mapstruct/ap/processor/creation/MappingResolverImpl.java @@ -47,6 +47,7 @@ import org.mapstruct.ap.model.source.builtin.BuiltInMappingMethods; import org.mapstruct.ap.model.source.builtin.BuiltInMethod; import org.mapstruct.ap.model.source.selector.MethodSelectors; import org.mapstruct.ap.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.prism.BeanMappingPrism; import org.mapstruct.ap.util.Strings; /** @@ -124,14 +125,15 @@ public class MappingResolverImpl implements MappingResolver { List qualifiers, String sourceReference) { + SelectionCriteria criteria = new SelectionCriteria(qualifiers, targetPropertyName, null ); + ResolvingAttempt attempt = new ResolvingAttempt( sourceModel, mappingMethod, mappedElement, - targetPropertyName, dateFormat, - qualifiers, - sourceReference + sourceReference, + criteria ); return attempt.getTargetAssignment( sourceType, targetType ); @@ -145,14 +147,20 @@ public class MappingResolverImpl implements MappingResolver { @Override public MethodReference getFactoryMethod( Method mappingMethod, Type targetType ) { + TypeMirror qualifyingResultTypeMirror = null; + BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( mappingMethod.getExecutable() ); + if ( beanMappingPrism != null ) { + qualifyingResultTypeMirror = beanMappingPrism.resultType(); + } + SelectionCriteria criteria = new SelectionCriteria(null, null, qualifyingResultTypeMirror ); + ResolvingAttempt attempt = new ResolvingAttempt( sourceModel, mappingMethod, null, null, null, - null, - null + criteria ); SourceMethod matchingSourceMethod = attempt.getBestMatch( sourceModel, null, targetType ); @@ -169,9 +177,8 @@ public class MappingResolverImpl implements MappingResolver { private final Method mappingMethod; private final String mappedElement; private final List methods; - private final String targetPropertyName; private final String dateFormat; - private final List qualifiers; + private final SelectionCriteria selectionCriteria; private final String sourceReference; // resolving via 2 steps creates the possibillity of wrong matches, first builtin method matches, @@ -182,18 +189,16 @@ public class MappingResolverImpl implements MappingResolver { private ResolvingAttempt(List sourceModel, Method mappingMethod, String mappedElement, - String targetPropertyName, String dateFormat, - List qualifiers, - String sourceReference) { + String sourceReference, + SelectionCriteria criteria) { this.mappingMethod = mappingMethod; this.mappedElement = mappedElement; this.methods = filterPossibleCandidateMethods( sourceModel ); - this.targetPropertyName = targetPropertyName; this.dateFormat = dateFormat; - this.qualifiers = qualifiers; this.sourceReference = sourceReference; this.virtualMethodCandidates = new HashSet(); + this.selectionCriteria = criteria; } private List filterPossibleCandidateMethods(List candidateMethods) { @@ -440,13 +445,12 @@ public class MappingResolverImpl implements MappingResolver { private T getBestMatch(List methods, Type sourceType, Type returnType) { - SelectionCriteria criteria = new SelectionCriteria( qualifiers, targetPropertyName ); List candidates = methodSelectors.getMatchingMethods( mappingMethod, methods, sourceType, returnType, - criteria + selectionCriteria ); // raise an error if more than one mapping method is suitable to map the given source type diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Apple.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Apple.java new file mode 100644 index 000000000..dac4a30e6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Apple.java @@ -0,0 +1,31 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class Apple extends Fruit { + + public Apple(String type) { + super( type ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/AppleDto.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/AppleDto.java new file mode 100644 index 000000000..3d97397b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/AppleDto.java @@ -0,0 +1,31 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class AppleDto extends FruitDto { + + public AppleDto(String type) { + super( type ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Banana.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Banana.java new file mode 100644 index 000000000..1c15f5efa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Banana.java @@ -0,0 +1,31 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class Banana extends Fruit { + + public Banana(String type) { + super( type ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/BananaDto.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/BananaDto.java new file mode 100644 index 000000000..dff5ea65d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/BananaDto.java @@ -0,0 +1,31 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class BananaDto extends FruitDto { + + public BananaDto(String type) { + super( type ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ConflictingFruitFactory.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ConflictingFruitFactory.java new file mode 100644 index 000000000..9161bc36a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ConflictingFruitFactory.java @@ -0,0 +1,34 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class ConflictingFruitFactory { + + public Apple createApple() { + return new Apple( "apple" ); + } + + public Banana createBanana() { + return new Banana( "banana" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ErroneousFruitMapper.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ErroneousFruitMapper.java new file mode 100644 index 000000000..ebd741fba --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/ErroneousFruitMapper.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper(uses = ConflictingFruitFactory.class) + +public interface ErroneousFruitMapper { + + ErroneousFruitMapper INSTANCE = Mappers.getMapper( ErroneousFruitMapper.class ); + + @Mapping(target = "type", ignore = true) + Fruit map(FruitDto source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Fruit.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Fruit.java new file mode 100644 index 000000000..e64988900 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/Fruit.java @@ -0,0 +1,42 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class Fruit { + + private String type; + + public Fruit(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/FruitDto.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/FruitDto.java new file mode 100644 index 000000000..408b126e5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/FruitDto.java @@ -0,0 +1,42 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +/** + * + * @author Sjaak Derksen + */ +public class FruitDto { + + private String type; + + public FruitDto(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/InheritanceSelectionTest.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/InheritanceSelectionTest.java new file mode 100644 index 000000000..8dd9b6c35 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/InheritanceSelectionTest.java @@ -0,0 +1,74 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +import javax.tools.Diagnostic.Kind; +import static org.fest.assertions.Assertions.assertThat; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +/** + * + * @author Sjaak Derksen + */ +@IssueKey("385") +@WithClasses({ + Fruit.class, + FruitDto.class, + Apple.class, + AppleDto.class +}) +@RunWith(AnnotationProcessorTestRunner.class) +public class InheritanceSelectionTest { + + + @Test + @WithClasses( { ConflictingFruitFactory.class, ErroneousFruitMapper.class, Banana.class } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousFruitMapper.class, + kind = Kind.ERROR, + line = 36, + messageRegExp = "Ambiguous mapping methods found for factorizing .*Fruit: " + + ".*Apple .*ConflictingFruitFactory\\.createApple\\(\\), " + + ".*Banana .*ConflictingFruitFactory\\.createBanana\\(\\)\\.") + } + ) + public void testForkedInheritanceHierarchyShouldResultInAmbigousMappingMethod() { + } + + @Test + @WithClasses( { ConflictingFruitFactory.class, TargetTypeSelectingFruitMapper.class, Banana.class } ) + public void testForkedInheritanceHierarchyButDefinedTargetType() { + + FruitDto fruitDto = new FruitDto( null ); + Fruit fruit = TargetTypeSelectingFruitMapper.INSTANCE.map( fruitDto ); + assertThat( fruit ).isNotNull(); + assertThat( fruit.getType() ).isEqualTo( "apple" ); + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/TargetTypeSelectingFruitMapper.java b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/TargetTypeSelectingFruitMapper.java new file mode 100644 index 000000000..e4148e112 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/selection/inheritance/TargetTypeSelectingFruitMapper.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2015 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.selection.inheritance; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper(uses = ConflictingFruitFactory.class) + +public interface TargetTypeSelectingFruitMapper { + + TargetTypeSelectingFruitMapper INSTANCE = Mappers.getMapper( TargetTypeSelectingFruitMapper.class ); + + @BeanMapping(resultType = Apple.class) + @Mapping(target = "type", ignore = true) + Fruit map(FruitDto source); + +}