From c41f47e03a42b9aca8a5b45f0be193322a82e155 Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Mon, 27 May 2013 21:05:37 +0200 Subject: [PATCH] Giving custom mapping methods precedence over built-in conversions --- .../main/resources/mapper-implementation.ftl | 10 ++--- .../conversion/precedence/ConversionTest.java | 40 +++++++++++++++++++ .../precedence/IntegerStringMapper.java | 26 ++++++++++++ .../ap/test/conversion/precedence/Source.java | 32 +++++++++++++++ .../precedence/SourceTargetMapper.java | 32 +++++++++++++++ .../ap/test/conversion/precedence/Target.java | 32 +++++++++++++++ 6 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java create mode 100644 processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java diff --git a/processor/src/main/resources/mapper-implementation.ftl b/processor/src/main/resources/mapper-implementation.ftl index 62d081ce3..065f8a3cc 100644 --- a/processor/src/main/resources/mapper-implementation.ftl +++ b/processor/src/main/resources/mapper-implementation.ftl @@ -138,8 +138,11 @@ public class ${implementationName} implements ${interfaceName} { <#-- Generates the mapping of one bean property --> <#macro simpleMap sourceBeanName sourceType sourceAccessorName targetBeanName targetType targetAccessorName conversion="" mappingMethod=""> - <#-- a) simple conversion --> - <#if conversion != ""> + <#-- a) invoke mapping method --> + <#if mappingMethod != ""> + ${targetBeanName}.${targetAccessorName}( <#if mappingMethod.declaringMapper??>${mappingMethod.declaringMapper.name?uncap_first}.${mappingMethod.name}( ${sourceBeanName}.${sourceAccessorName}() ) ); + <#-- b) simple conversion --> + <#elseif conversion != ""> <#if sourceType.primitive == false> if ( ${sourceBeanName}.${sourceAccessorName}() != null ) { ${targetBeanName}.${targetAccessorName}( ${conversion} ); @@ -147,9 +150,6 @@ public class ${implementationName} implements ${interfaceName} { <#else> ${targetBeanName}.${targetAccessorName}( ${conversion} ); - <#-- b) invoke mapping method --> - <#elseif mappingMethod != ""> - ${targetBeanName}.${targetAccessorName}( <#if mappingMethod.declaringMapper??>${mappingMethod.declaringMapper.name?uncap_first}.${mappingMethod.name}( ${sourceBeanName}.${sourceAccessorName}() ) ); <#-- c) simply set --> <#else> <#if targetType.collectionType == true> diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java new file mode 100644 index 000000000..bc87d04d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java @@ -0,0 +1,40 @@ +/** + * 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.conversion.precedence; + +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, IntegerStringMapper.class }) +public class ConversionTest extends MapperTestBase { + + @Test + public void shouldInvokeMappingMethodInsteadOfConversion() { + Source source = new Source(); + source.setFoo( 42 ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getFoo() ).isEqualTo( "000042" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java new file mode 100644 index 000000000..634671fa5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java @@ -0,0 +1,26 @@ +/** + * 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.conversion.precedence; + +public class IntegerStringMapper { + + public String asString(int source) { + return String.format( "%06d", source ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java new file mode 100644 index 000000000..f6f9535be --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.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.conversion.precedence; + +public class Source { + + 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/conversion/precedence/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java new file mode 100644 index 000000000..edd968b0a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/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.conversion.precedence; + +import org.mapstruct.Mapper; +import org.mapstruct.Mappers; + +@Mapper(uses = IntegerStringMapper.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/conversion/precedence/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java new file mode 100644 index 000000000..bab613918 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.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.conversion.precedence; + +public class Target { + + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } +}