From 5834368b15f0f0955fd363ee45470b385889628d Mon Sep 17 00:00:00 2001 From: Filip Hrisafov Date: Sun, 15 Apr 2018 10:19:58 +0200 Subject: [PATCH] #1431 Factory method resolution should be done on the effective type This allows using factories for builder types as well --- .../creation/MappingResolverImpl.java | 4 +- .../builder/factory/BuilderFactoryMapper.java | 40 ++++++++++++ .../factory/BuilderFactoryMapperTest.java | 55 ++++++++++++++++ .../factory/BuilderImplicitFactoryMapper.java | 38 +++++++++++ .../ap/test/builder/factory/Person.java | 63 +++++++++++++++++++ .../ap/test/builder/factory/PersonDto.java | 35 +++++++++++ 6 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java index fbc3e1516..d6f505032 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java @@ -138,7 +138,7 @@ public class MappingResolverImpl implements MappingResolver { mappingMethod, sourceModel, java.util.Collections. emptyList(), - targetType, + targetType.getEffectiveType(), SelectionCriteria.forFactoryMethods( selectionParameters ) ); if (matchingFactoryMethods.isEmpty()) { @@ -149,7 +149,7 @@ public class MappingResolverImpl implements MappingResolver { messager.printMessage( mappingMethod.getExecutable(), Message.GENERAL_AMBIGIOUS_FACTORY_METHOD, - targetType, + targetType.getEffectiveType(), Strings.join( matchingFactoryMethods, ", " ) ); return null; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java new file mode 100644 index 000000000..e7ac6c2e9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java @@ -0,0 +1,40 @@ +/** + * Copyright 2012-2017 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.builder.factory; + +import org.mapstruct.Mapper; +import org.mapstruct.ObjectFactory; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public abstract class BuilderFactoryMapper { + + public static final BuilderFactoryMapper INSTANCE = Mappers.getMapper( BuilderFactoryMapper.class ); + + public abstract Person map(PersonDto source); + + @ObjectFactory + public Person.PersonBuilder personBuilder() { + return new Person.PersonBuilder( "Factory with @ObjectFactory" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java new file mode 100644 index 000000000..827d3f9f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java @@ -0,0 +1,55 @@ +/** + * Copyright 2012-2017 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.builder.factory; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses({ + BuilderFactoryMapper.class, + BuilderImplicitFactoryMapper.class, + Person.class, + PersonDto.class +}) +public class BuilderFactoryMapperTest { + + @Test + public void shouldUseBuilderFactory() { + Person person = BuilderFactoryMapper.INSTANCE.map( new PersonDto( "Filip" ) ); + + assertThat( person.getName() ).isEqualTo( "Filip" ); + assertThat( person.getSource() ).isEqualTo( "Factory with @ObjectFactory" ); + } + + @Test + public void shouldUseImplicitBuilderFactory() { + Person person = BuilderImplicitFactoryMapper.INSTANCE.map( new PersonDto( "Filip" ) ); + + assertThat( person.getName() ).isEqualTo( "Filip" ); + assertThat( person.getSource() ).isEqualTo( "Implicit Factory" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java new file mode 100644 index 000000000..cc1feeafa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java @@ -0,0 +1,38 @@ +/** + * Copyright 2012-2017 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.builder.factory; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public abstract class BuilderImplicitFactoryMapper { + + public static final BuilderImplicitFactoryMapper INSTANCE = Mappers.getMapper( BuilderImplicitFactoryMapper.class ); + + public abstract Person map(PersonDto source); + + public Person.PersonBuilder personBuilder() { + return new Person.PersonBuilder( "Implicit Factory" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java new file mode 100644 index 000000000..f94a16754 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java @@ -0,0 +1,63 @@ +/** + * Copyright 2012-2017 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.builder.factory; + +/** + * @author Filip Hrisafov + */ +public class Person { + + private final String name; + private final String source; + + protected Person(PersonBuilder builder) { + this.name = builder.name; + this.source = builder.source; + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public static PersonBuilder builder() { + throw new UnsupportedOperationException( "Factory should be used" ); + } + + public static class PersonBuilder { + private String name; + private final String source; + + public PersonBuilder(String source) { + this.source = source; + } + + public PersonBuilder name(String name) { + this.name = name; + return this; + } + + public Person create() { + return new Person( this ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java new file mode 100644 index 000000000..797b7bf56 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java @@ -0,0 +1,35 @@ +/** + * Copyright 2012-2017 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.builder.factory; + +/** + * @author Filip Hrisafov + */ +public class PersonDto { + + private String name; + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +}