From 6e545347d09591ebbc889ebfb8c17ee6c7d076ff Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Tue, 31 Jan 2017 22:03:31 +0100 Subject: [PATCH] #1045 Supporting mappers with generated source/target types by deferring their generation to a later round --- .../itest/tests/TargetTypeGenerationTest.java | 34 ++++++++ .../generator/pom.xml | 39 +++++++++ .../DtoGenerationProcessor.java | 80 +++++++++++++++++++ .../javax.annotation.processing.Processor | 17 ++++ .../targetTypeGenerationTest/pom.xml | 40 ++++++++++ .../targetTypeGenerationTest/usage/pom.xml | 47 +++++++++++ .../targettypegeneration/usage/Order.java | 35 ++++++++ .../usage/OrderMapper.java | 33 ++++++++ .../usage/GeneratedTargetTypeTest.java | 41 ++++++++++ .../ap/internal/model/common/TypeFactory.java | 9 +-- 10 files changed, 370 insertions(+), 5 deletions(-) create mode 100644 integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java create mode 100644 integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java new file mode 100644 index 000000000..04b9155c5 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java @@ -0,0 +1,34 @@ +/** + * 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.itest.tests; + +import org.junit.runner.RunWith; +import org.mapstruct.itest.testutil.runner.ProcessorSuite; +import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; +import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; + +/** + * Tests usage of MapStruct with another processor that generates the target type of a mapping method. + * + * @author Gunnar Morling + */ +@RunWith( ProcessorSuiteRunner.class ) +@ProcessorSuite(baseDir = "targetTypeGenerationTest", processorTypes = ProcessorType.ORACLE_JAVA_8) +public class TargetTypeGenerationTest { +} diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml new file mode 100644 index 000000000..589af8215 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml @@ -0,0 +1,39 @@ + + 4.0.0 + + + org.mapstruct.itest + itest-targettypegeneration-aggregator + 1.0.0 + ../pom.xml + + + itest-targettypegeneration-generator + jar + + + + junit + junit + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + -proc:none + + + + + + diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java new file mode 100644 index 000000000..e4d27a885 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java @@ -0,0 +1,80 @@ +/** + * 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.itest.targettypegeneration; + +import java.io.IOException; +import java.io.Writer; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.Name; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaFileObject; + +/** + * Generates a DTO. + * + * @author Gunnar Morling + * + */ +@SupportedAnnotationTypes("*") +public class DtoGenerationProcessor extends AbstractProcessor { + + private boolean hasRun = false; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if ( !hasRun ) { + try { + JavaFileObject dto = processingEnv.getFiler().createSourceFile( "org.mapstruct.itest.targettypegeneration.usage.OrderDto" ); + Writer writer = dto.openWriter(); + + writer.append( "package org.mapstruct.itest.targettypegeneration.usage;" ); + writer.append( "\n" ); + writer.append( "public class OrderDto {" ); + writer.append( "\n" ); + writer.append( " private String item;" ); + writer.append( "\n" ); + writer.append( " public String getItem() {" ); + writer.append( " return item;" ); + writer.append( " }" ); + writer.append( "\n" ); + writer.append( " public void setItem(String item) {" ); + writer.append( " this.item = item;" ); + writer.append( " }" ); + writer.append( "}" ); + + writer.flush(); + writer.close(); + } + catch (IOException e) { + throw new RuntimeException( e ); + } + + hasRun = true; + } + + return false; + } +} diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 000000000..1bd077500 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1,17 @@ +# 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. +org.mapstruct.itest.targettypegeneration.DtoGenerationProcessor diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml new file mode 100644 index 000000000..5f7726204 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml @@ -0,0 +1,40 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + org.mapstruct.itest + itest-targettypegeneration-aggregator + pom + + + generator + usage + + diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml new file mode 100644 index 000000000..520576dad --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + + org.mapstruct.itest + itest-targettypegeneration-aggregator + 1.0.0 + ../pom.xml + + + itest-targettypegeneration-usage + jar + + + + junit + junit + 4.12 + test + + + org.mapstruct.itest + itest-targettypegeneration-generator + 1.0.0 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + -XprintProcessorInfo + -XprintRounds + + + + + + diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java new file mode 100644 index 000000000..c6a496112 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.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.itest.targettypegeneration.usage; + +/** + * @author Gunnar Morling + */ +public class Order { + + private String item; + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } +} diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java new file mode 100644 index 000000000..cb842c60f --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java @@ -0,0 +1,33 @@ +/** + * 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.itest.targettypegeneration.usage; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Gunnar Morling + */ +@Mapper +public abstract class OrderMapper { + + public static final OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); + + public abstract OrderDto orderToDto(Order order); +} diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java new file mode 100644 index 000000000..724754958 --- /dev/null +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java @@ -0,0 +1,41 @@ +/** + * 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.itest.targettypegeneration.usage; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * Integration test for using MapStruct with another annotation processor that generates the target type of a mapping + * method. + * + * @author Gunnar Morling + */ +public class GeneratedTargetTypeTest { + + @Test + public void considersPropertiesOnGeneratedSourceAndTargetTypes() { + Order order = new Order(); + order.setItem( "my item" ); + + OrderDto dto = OrderMapper.INSTANCE.orderToDto( order ); + assertEquals( order.getItem(), dto.getItem() ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java index b99242b23..7001b6bfa 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java @@ -147,11 +147,6 @@ public class TypeFactory { } public Type getType(TypeMirror mirror) { - - if ( mirror.getKind() == TypeKind.ERROR ) { - throw new AnnotationProcessingException( "Encountered erroneous type " + mirror ); - } - if ( !canBeProcessed( mirror ) ) { throw new TypeHierarchyErroneousException( mirror ); } @@ -580,6 +575,10 @@ public class TypeFactory { * processed the type. */ private boolean canBeProcessed(TypeMirror type) { + if ( type.getKind() == TypeKind.ERROR ) { + return false; + } + if ( type.getKind() != TypeKind.DECLARED ) { return true; }