From 50d916c370f6915d5577d2dc89004049deabe5ee Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Sun, 12 May 2013 23:03:07 +0200 Subject: [PATCH] #6 Raising error in case of mappings from iterable to non-iterable types and vice versa --- parent/pom.xml | 5 ++ processor/pom.xml | 5 ++ .../mapstruct/ap/MapperGenerationVisitor.java | 21 ++++++++ .../ErronuousCollectionMappingTest.java | 42 +++++++++++++++ .../collection/erronuous/ErronuousMapper.java | 28 ++++++++++ .../IterableToNonIterableMappingTest.java | 52 +++++++++++++++++++ .../iterabletononiterable/Source.java | 31 +++++++++++ .../SourceTargetMapper.java | 29 +++++++++++ .../StringListMapper.java | 32 ++++++++++++ .../iterabletononiterable/Target.java | 29 +++++++++++ .../mapstruct/ap/testutil/MapperTestBase.java | 4 +- .../model/CompilationOutcomeDescriptor.java | 6 ++- 12 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousCollectionMappingTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java diff --git a/parent/pom.xml b/parent/pom.xml index 3df2cd45c..2076e2169 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -82,6 +82,11 @@ fest-assert 1.4 + + com.google.guava + guava + 14.0.1 + com.jolira hickory diff --git a/processor/pom.xml b/processor/pom.xml index 28cda2df0..8cf7d2bfd 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -61,6 +61,11 @@ fest-assert test + + com.google.guava + guava + test + diff --git a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java index 7d84395c5..59106ebf4 100644 --- a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java +++ b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java @@ -34,6 +34,7 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementKindVisitor6; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; +import javax.tools.Diagnostic.Kind; import javax.tools.JavaFileObject; import org.mapstruct.ap.conversion.Conversion; @@ -308,6 +309,26 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 { properties ) ); + + if ( declaringMapper == null ) { + if ( parameter.getType().isIterableType() && !returnType.isIterableType() ) { + processingEnvironment.getMessager() + .printMessage( + Kind.ERROR, + "Can't generate mapping method from iterable type to non-iterable ype.", + method + ); + } + + if ( !parameter.getType().isIterableType() && returnType.isIterableType() ) { + processingEnvironment.getMessager() + .printMessage( + Kind.ERROR, + "Can't generate mapping method from non-iterable type to iterable ype.", + method + ); + } + } } MapperPrism mapperPrism = MapperPrism.getInstanceOn( element ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousCollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousCollectionMappingTest.java new file mode 100644 index 000000000..6e78daa71 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousCollectionMappingTest.java @@ -0,0 +1,42 @@ +/** + * 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 org.mapstruct.ap.test.collection.erronuous; + +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.MapperTestBase; +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.testng.annotations.Test; + +@WithClasses({ ErronuousMapper.class }) +public class ErronuousCollectionMappingTest extends MapperTestBase { + + @Test + @IssueKey("6") + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErronuousMapper.class, kind = Kind.ERROR, line = 25), + @Diagnostic(type = ErronuousMapper.class, kind = Kind.ERROR, line = 27) + } + ) + public void shouldFailToGenerateMappingFromListToString() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousMapper.java new file mode 100644 index 000000000..9eaf9a22e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erronuous/ErronuousMapper.java @@ -0,0 +1,28 @@ +/** + * 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 org.mapstruct.ap.test.collection.erronuous; + +import java.util.Set; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErronuousMapper { + + Integer stringSetToInteger(Set strings); + + Set integerToStringSet(Integer integer); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java new file mode 100644 index 000000000..6afe868eb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java @@ -0,0 +1,52 @@ +/** + * 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 org.mapstruct.ap.test.collection.iterabletononiterable; + +import java.util.Arrays; + +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; + +@WithClasses({ Source.class, Target.class, SourceTargetMapper.class, StringListMapper.class }) +public class IterableToNonIterableMappingTest extends MapperTestBase { + + @Test + @IssueKey("6") + public void shouldMapStringListToStringUsingCustomMapper() { + Source source = new Source(); + source.setNames( Arrays.asList( "Alice", "Bob", "Jim" ) ); + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNames() ).isEqualTo( "Alice-Bob-Jim" ); + } + + @Test + @IssueKey("6") + public void shouldReverseMapStringListToStringUsingCustomMapper() { + Target target = new Target(); + target.setNames( "Alice-Bob-Jim" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getNames() ).isEqualTo( Arrays.asList( "Alice", "Bob", "Jim" ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java new file mode 100644 index 000000000..91268f967 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java @@ -0,0 +1,31 @@ +/** + * 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 org.mapstruct.ap.test.collection.iterabletononiterable; + +import java.util.List; + +public class Source { + + private List names; + + public List getNames() { + return names; + } + + public void setNames(List names) { + this.names = names; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java new file mode 100644 index 000000000..84890e492 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java @@ -0,0 +1,29 @@ +/** + * 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 org.mapstruct.ap.test.collection.iterabletononiterable; + +import org.mapstruct.Mapper; +import org.mapstruct.Mappers; + +@Mapper(uses = StringListMapper.class) +public interface SourceTargetMapper { + + public static SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + Target sourceToTarget(Source source); + + Source targetToSource(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java new file mode 100644 index 000000000..c362efc1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java @@ -0,0 +1,32 @@ +/** + * 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 org.mapstruct.ap.test.collection.iterabletononiterable; + +import java.util.Arrays; +import java.util.List; + +import com.google.common.base.Joiner; + +public class StringListMapper { + + public String stringListToString(List strings) { + return strings == null ? null : Joiner.on( "-" ).join( strings ); + } + + public List stringToStringList(String string) { + return string == null ? null : Arrays.asList( string.split( "-" ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java new file mode 100644 index 000000000..00cd2ebd3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java @@ -0,0 +1,29 @@ +/** + * 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 org.mapstruct.ap.test.collection.iterabletononiterable; + +public class Target { + + private String names; + + public String getNames() { + return names; + } + + public void setNames(String names) { + this.names = names; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java b/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java index c15e9726a..a72c024da 100644 --- a/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java +++ b/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java @@ -59,7 +59,7 @@ public abstract class MapperTestBase { private DiagnosticCollector diagnostics; public MapperTestBase() { - this.libraries = Arrays.asList( "mapstruct.jar" ); + this.libraries = Arrays.asList( "mapstruct.jar", "guava.jar" ); } @BeforeClass @@ -107,7 +107,7 @@ public abstract class MapperTestBase { if ( expectedResult.getCompilationResult() == CompilationResult.SUCCEEDED ) { assertThat( actualResult.getCompilationResult() ) - .describedAs( "Compilation failed. Diagnostics: " + actualResult.getDiagnostics() ) + .describedAs( "Compilation failed. Diagnostics: " + diagnostics.getDiagnostics() ) .isEqualTo( CompilationResult.SUCCEEDED ); } else { diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java index 0938a943d..fc70f097f 100644 --- a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java +++ b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.tools.Diagnostic.Kind; import javax.tools.JavaFileObject; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; @@ -63,7 +64,10 @@ public class CompilationOutcomeDescriptor { Set diagnosticDescriptors = new HashSet(); for ( javax.tools.Diagnostic diagnostic : diagnostics ) { - diagnosticDescriptors.add( DiagnosticDescriptor.forDiagnostic( sourceDir, diagnostic ) ); + //ignore notes created by the compiler + if ( diagnostic.getKind() != Kind.NOTE ) { + diagnosticDescriptors.add( DiagnosticDescriptor.forDiagnostic( sourceDir, diagnostic ) ); + } } return new CompilationOutcomeDescriptor( compilationResult, diagnosticDescriptors );