diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java new file mode 100644 index 000000000..3da26e03a --- /dev/null +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java @@ -0,0 +1,30 @@ +/** + * 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.itest.cdi; + +import org.mapstruct.Mapper; +import org.mapstruct.DecoratedWith; +import org.mapstruct.itest.cdi.other.DateMapper; + +@Mapper( componentModel = "cdi", uses = DateMapper.class ) +@DecoratedWith( SourceTargetMapperDecorator.class ) +public interface DecoratedSourceTargetMapper { + + Target sourceToTarget(Source source); +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java new file mode 100644 index 000000000..9d6cc2c11 --- /dev/null +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java @@ -0,0 +1,41 @@ +/** + * 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.itest.cdi; + +import javax.decorator.Decorator; +import javax.decorator.Delegate; +import javax.inject.Inject; + +@Decorator +public class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper { + + @Delegate + @Inject + private DecoratedSourceTargetMapper delegate; + + public SourceTargetMapperDecorator() { + } + + @Override + public Target sourceToTarget(Source source) { + Target t = delegate.sourceToTarget( source ); + t.setFoo( 43L ); + return t; + } +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java b/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java index e7f6049ea..5b8a130a7 100644 --- a/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java +++ b/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java @@ -25,7 +25,7 @@ import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.ShrinkWrap; -import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,12 +42,17 @@ public class CdiBasedMapperTest { @Inject private SourceTargetMapper mapper; + @Inject + private DecoratedSourceTargetMapper decoratedMapper; + @Deployment public static JavaArchive createDeployment() { return ShrinkWrap.create( JavaArchive.class ) .addPackage( SourceTargetMapper.class.getPackage() ) .addPackage( DateMapper.class.getPackage() ) - .addAsManifestResource( EmptyAsset.INSTANCE, "beans.xml" ); + .addAsManifestResource( + new StringAsset("org.mapstruct.itest.cdi.SourceTargetMapperDecorator"), + "beans.xml" ); } @Test @@ -60,4 +65,14 @@ public class CdiBasedMapperTest { assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) ); assertThat( target.getDate() ).isEqualTo( "1980" ); } -} + + @Test + public void shouldInjectDecorator() { + Source source = new Source(); + + Target target = decoratedMapper.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) ); + } +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java new file mode 100644 index 000000000..59e0bfdb2 --- /dev/null +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java @@ -0,0 +1,30 @@ +/** + * 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.itest.spring; + +import org.mapstruct.Mapper; +import org.mapstruct.DecoratedWith; +import org.mapstruct.itest.spring.other.DateMapper; + +@Mapper( componentModel = "spring", uses = DateMapper.class ) +@DecoratedWith( SourceTargetMapperDecorator.class ) +public interface DecoratedSourceTargetMapper { + + Target sourceToTarget(Source source); +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java new file mode 100644 index 000000000..32262713a --- /dev/null +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java @@ -0,0 +1,41 @@ +/** + * 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.itest.spring; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +@Component +public class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper { + + @Autowired + @Qualifier( "decoratedSourceTargetMapperImpl_" ) + private DecoratedSourceTargetMapper delegate; + + public SourceTargetMapperDecorator() { + } + + @Override + public Target sourceToTarget(Source source) { + Target t = delegate.sourceToTarget( source ); + t.setFoo( 43L ); + return t; + } +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java b/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java index ff13f7f0c..b2cd1b879 100644 --- a/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java +++ b/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mapstruct.itest.spring.SpringBasedMapperTest.SpringTestConfig; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; @@ -45,6 +46,9 @@ public class SpringBasedMapperTest { @Autowired private SourceTargetMapper mapper; + @Autowired + @Qualifier( "sourceTargetMapperDecorator" ) + private DecoratedSourceTargetMapper decoratedMapper; @Test public void shouldCreateSpringBasedMapper() { @@ -56,4 +60,15 @@ public class SpringBasedMapperTest { assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) ); assertThat( target.getDate() ).isEqualTo( "1980" ); } -} + + @Test + public void shouldInjectDecorator() { + Source source = new Source(); + + Target target = decoratedMapper.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 43 ) ); + } + +} \ No newline at end of file diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java index 947508c45..a8a57cc32 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java @@ -43,7 +43,7 @@ public class Mapper extends GeneratedType { private static final String DECORATED_IMPLEMENTATION_SUFFIX = "Impl_"; private final List referencedMappers; - private final Decorator decorator; + private Decorator decorator; @SuppressWarnings( "checkstyle:parameternumber" ) private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName, @@ -158,6 +158,10 @@ public class Mapper extends GeneratedType { return decorator; } + public void removeDecorator() { + this.decorator = null; + } + @Override protected String getTemplateName() { return getTemplateNameForClass( GeneratedType.class ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java index f502a30e1..d0e592e5d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java @@ -56,6 +56,10 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle return mapper; } + if ( shouldDecoratorBeRemoved() ) { + mapper.removeDecorator(); + } + mapper.addAnnotation( getTypeAnnotation() ); ListIterator iterator = mapper.getReferencedMappers().listIterator(); @@ -97,6 +101,11 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle */ protected abstract Annotation getMapperReferenceAnnotation(); + /** + * @return if generated decorator class should be removed + */ + protected abstract boolean shouldDecoratorBeRemoved(); + @Override public int getPriority() { return 1100; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java index 0486fcbe1..d7e11a07c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java @@ -44,4 +44,9 @@ public class CdiComponentProcessor extends AnnotationBasedComponentModelProcesso protected Annotation getMapperReferenceAnnotation() { return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ); } + + @Override + protected boolean shouldDecoratorBeRemoved() { + return true; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java index 2c11cbc8f..87f16d655 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java @@ -44,4 +44,9 @@ public class Jsr330ComponentProcessor extends AnnotationBasedComponentModelProce protected Annotation getMapperReferenceAnnotation() { return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ); } + + @Override + protected boolean shouldDecoratorBeRemoved() { + return false; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java index 5f98acd52..021e56c59 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java @@ -44,4 +44,9 @@ public class SpringComponentProcessor extends AnnotationBasedComponentModelProce protected Annotation getMapperReferenceAnnotation() { return new Annotation( getTypeFactory().getType( "org.springframework.beans.factory.annotation.Autowired" ) ); } + + @Override + protected boolean shouldDecoratorBeRemoved() { + return true; + } }