diff --git a/core/src/main/java/org/mapstruct/Mapper.java b/core/src/main/java/org/mapstruct/Mapper.java
index 39d111aa6..8d438d261 100644
--- a/core/src/main/java/org/mapstruct/Mapper.java
+++ b/core/src/main/java/org/mapstruct/Mapper.java
@@ -47,4 +47,19 @@ public @interface Mapper {
* @return The reporting policy for unmapped target properties.
*/
ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN;
+
+ /**
+ * Specifies the component model to which the generated mapper should
+ * adhere. Supported values are
+ *
+ * - {@code default}: the mapper uses no component model, instances are
+ * typically retrieved via {@link Mappers#getMapper(Class)}
+ * -
+ * {@code cdi}: the generated mapper is an application-scoped CDI bean and
+ * can be retrieved via {@code @Inject}
+ *
+ *
+ * @return The component model for the generated mapper.
+ */
+ String componentModel() default "default";
}
diff --git a/integrationtest/pom.xml b/integrationtest/pom.xml
index 67875b954..3a320144f 100644
--- a/integrationtest/pom.xml
+++ b/integrationtest/pom.xml
@@ -39,6 +39,7 @@
mapstruct
provided
+
org.testng
testng
@@ -49,6 +50,26 @@
fest-assert
test
+
+
+ javax.enterprise
+ cdi-api
+
+
+ org.jboss.arquillian.testng
+ arquillian-testng-container
+ test
+
+
+ org.jboss.arquillian.container
+ arquillian-weld-se-embedded-1.1
+ test
+
+
+ org.jboss.weld
+ weld-core
+ test
+
diff --git a/integrationtest/src/main/java/org/mapstruct/itest/cdi/Source.java b/integrationtest/src/main/java/org/mapstruct/itest/cdi/Source.java
new file mode 100644
index 000000000..01e34c7ad
--- /dev/null
+++ b/integrationtest/src/main/java/org/mapstruct/itest/cdi/Source.java
@@ -0,0 +1,37 @@
+/**
+ * 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.itest.cdi;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+public class Source {
+
+ private int foo = 42;
+
+ private Date date = new GregorianCalendar( 1980, 0, 1 ).getTime();
+
+ public int getFoo() {
+ return foo;
+ }
+
+ public Date getDate() {
+ return date;
+ }
+}
diff --git a/integrationtest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java b/integrationtest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java
new file mode 100644
index 000000000..a9453f703
--- /dev/null
+++ b/integrationtest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java
@@ -0,0 +1,28 @@
+/**
+ * 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.itest.cdi;
+
+import org.mapstruct.Mapper;
+import org.mapstruct.itest.cdi.other.DateMapper;
+
+@Mapper(componentModel = "cdi", uses = DateMapper.class)
+public interface SourceTargetMapper {
+
+ Target sourceToTarget(Source source);
+}
diff --git a/integrationtest/src/main/java/org/mapstruct/itest/cdi/Target.java b/integrationtest/src/main/java/org/mapstruct/itest/cdi/Target.java
new file mode 100644
index 000000000..b40dfb5ea
--- /dev/null
+++ b/integrationtest/src/main/java/org/mapstruct/itest/cdi/Target.java
@@ -0,0 +1,42 @@
+/**
+ * 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.itest.cdi;
+
+public class Target {
+
+ private Long foo;
+
+ private String date;
+
+ public void setFoo(Long foo) {
+ this.foo = foo;
+ }
+
+ public Long getFoo() {
+ return foo;
+ }
+
+ public String getDate() {
+ return date;
+ }
+
+ public void setDate(String date) {
+ this.date = date;
+ }
+}
diff --git a/integrationtest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java b/integrationtest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java
new file mode 100644
index 000000000..b1d89d201
--- /dev/null
+++ b/integrationtest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java
@@ -0,0 +1,41 @@
+/**
+ * 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.itest.cdi.other;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import javax.enterprise.context.ApplicationScoped;
+
+@ApplicationScoped
+public class DateMapper {
+
+ public String asString(Date date) {
+ return date != null ? new SimpleDateFormat( "yyyy" ).format( date ) : null;
+ }
+
+ public Date asDate(String date) {
+ try {
+ return date != null ? new SimpleDateFormat( "yyyy" ).parse( date ) : null;
+ }
+ catch ( ParseException e ) {
+ throw new RuntimeException( e );
+ }
+ }
+}
diff --git a/integrationtest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java b/integrationtest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java
new file mode 100644
index 000000000..761b88620
--- /dev/null
+++ b/integrationtest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java
@@ -0,0 +1,61 @@
+/**
+ * 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.itest.cdi;
+
+import javax.inject.Inject;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.testng.Arquillian;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.mapstruct.itest.cdi.other.DateMapper;
+import org.testng.annotations.Test;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+/**
+ * Test for generation of CDI-based mapper implementations.
+ *
+ * @author Gunnar Morling
+ */
+public class CdiBasedMapperTest extends Arquillian {
+
+ @Inject
+ private SourceTargetMapper mapper;
+
+ @Deployment
+ public static JavaArchive createDeployment() {
+ return ShrinkWrap.create( JavaArchive.class )
+ .addPackage( SourceTargetMapper.class.getPackage() )
+ .addPackage( DateMapper.class.getPackage() )
+ .addAsManifestResource( EmptyAsset.INSTANCE, "beans.xml" );
+ }
+
+ @Test
+ public void shouldCreateCdiBasedMapper() {
+ Source source = new Source();
+
+ Target target = mapper.sourceToTarget( source );
+
+ assertThat( target ).isNotNull();
+ assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );
+ assertThat( target.getDate() ).isEqualTo( "1980" );
+ }
+}
diff --git a/parent/pom.xml b/parent/pom.xml
index 362fe8248..6583c9373 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -117,6 +117,32 @@
hickory
${com.jolira.hickory.version}
+
+
+
+ javax.enterprise
+ cdi-api
+ 1.1-PFD
+
+
+ org.jboss.arquillian
+ arquillian-bom
+ 1.0.4.Final
+ import
+ pom
+
+
+ org.jboss.arquillian.container
+ arquillian-weld-se-embedded-1.1
+ 1.0.0.CR3
+
+
+ org.jboss.weld
+ weld-core
+ 1.1.5.Final
+
+
+
${project.groupId}
mapstruct
@@ -127,6 +153,18 @@
mapstruct-processor
${project.version}
+
+
+
+ org.slf4j
+ slf4j-api
+ 1.6.1
+
+
+ ch.qos.cal10n
+ cal10n-api
+ 0.7.4
+
diff --git a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java
index e3f42776a..81886f1ea 100644
--- a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java
@@ -39,6 +39,7 @@ import org.mapstruct.Mappings;
import org.mapstruct.ap.model.Mapper;
import org.mapstruct.ap.model.Options;
import org.mapstruct.ap.model.ReportingPolicy;
+import org.mapstruct.ap.processor.CdiComponentProcessor;
import org.mapstruct.ap.processor.DefaultModelElementProcessorContext;
import org.mapstruct.ap.processor.MapperCreationProcessor;
import org.mapstruct.ap.processor.MapperRenderingProcessor;
@@ -146,6 +147,7 @@ public class MappingProcessor extends AbstractProcessor {
return Arrays.>asList(
new MethodRetrievalProcessor(),
new MapperCreationProcessor(),
+ new CdiComponentProcessor(),
new MapperRenderingProcessor()
);
}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/AbstractModelElement.java b/processor/src/main/java/org/mapstruct/ap/model/AbstractModelElement.java
index 596c603f5..9bfeff754 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/AbstractModelElement.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/AbstractModelElement.java
@@ -30,7 +30,7 @@ import org.mapstruct.ap.writer.FreeMarkerModelElementWriter;
*
* @author Gunnar Morling
*/
-public class AbstractModelElement implements ModelElement {
+public abstract class AbstractModelElement implements ModelElement {
@Override
public void write(Context context, Writer writer) throws Exception {
diff --git a/processor/src/main/java/org/mapstruct/ap/model/Annotation.java b/processor/src/main/java/org/mapstruct/ap/model/Annotation.java
new file mode 100644
index 000000000..3d1fad1b3
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/model/Annotation.java
@@ -0,0 +1,41 @@
+/**
+ * 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.model;
+
+import java.util.Set;
+
+import org.mapstruct.ap.util.Collections;
+
+public class Annotation extends AbstractModelElement {
+
+ private Type type;
+
+ public Annotation(Type type) {
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+
+ @Override
+ public Set getImportTypes() {
+ return Collections.asSet( type );
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
index 619ac6e82..1cd7134c9 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/BeanMappingMethod.java
@@ -43,12 +43,11 @@ public class BeanMappingMethod extends MappingMethod {
}
@Override
- public Set getReferencedTypes() {
- Set types = super.getReferencedTypes();
+ public Set getImportTypes() {
+ Set types = super.getImportTypes();
for ( PropertyMapping propertyMapping : propertyMappings ) {
- types.add( propertyMapping.getSourceType() );
- types.add( propertyMapping.getTargetType() );
+ types.addAll( propertyMapping.getImportTypes() );
}
return types;
diff --git a/processor/src/main/java/org/mapstruct/ap/model/CdiMapperReference.java b/processor/src/main/java/org/mapstruct/ap/model/CdiMapperReference.java
new file mode 100644
index 000000000..121cde86d
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/model/CdiMapperReference.java
@@ -0,0 +1,49 @@
+/**
+ * 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.model;
+
+import java.util.Set;
+
+import org.mapstruct.ap.util.Collections;
+
+/**
+ * Mapper reference which is retrieved via CDI-based dependency injection.
+ * method. Used if "cdi" is specified as component model via
+ * {@code Mapper#uses()}.
+ *
+ * @author Gunnar Morling
+ */
+public class CdiMapperReference extends AbstractModelElement implements MapperReference {
+
+ private Type type;
+
+ public CdiMapperReference(Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public Type getMapperType() {
+ return type;
+ }
+
+ @Override
+ public Set getImportTypes() {
+ return Collections.asSet( type, new Type( "javax.inject", "Inject" ) );
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/DefaultMapperReference.java b/processor/src/main/java/org/mapstruct/ap/model/DefaultMapperReference.java
new file mode 100644
index 000000000..42c053d21
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/model/DefaultMapperReference.java
@@ -0,0 +1,49 @@
+/**
+ * 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.model;
+
+import java.util.Set;
+
+import org.mapstruct.ap.util.Collections;
+
+/**
+ * Mapper reference which is retrieved via the {@code Mappers#getMapper()}
+ * method. Used by default if no other component model is specified via
+ * {@code Mapper#uses()}.
+ *
+ * @author Gunnar Morling
+ */
+public class DefaultMapperReference extends AbstractModelElement implements MapperReference {
+
+ private Type type;
+
+ public DefaultMapperReference(Type type) {
+ this.type = type;
+ }
+
+ @Override
+ public Type getMapperType() {
+ return type;
+ }
+
+ @Override
+ public Set getImportTypes() {
+ return Collections.asSet( type );
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java
index d330504b1..103884325 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/Mapper.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/Mapper.java
@@ -18,6 +18,7 @@
*/
package org.mapstruct.ap.model;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.SortedSet;
@@ -29,36 +30,46 @@ public class Mapper extends AbstractModelElement {
private final String packageName;
private final String interfaceName;
private final String implementationName;
+ private final List annotations;
private final List mappingMethods;
- private final List usedMapperTypes;
+ private final List referencedMappers;
private final Options options;
- private final SortedSet importedTypes;
private final boolean isErroneous;
- public Mapper(String packageName, String interfaceName,
- String implementationName, List mappingMethods, List usedMapperTypes,
- Options options, boolean isErroneous) {
+ public Mapper(String packageName, String interfaceName, String implementationName,
+ List mappingMethods, List referencedMappers, Options options,
+ boolean isErroneous) {
this.packageName = packageName;
this.interfaceName = interfaceName;
this.implementationName = implementationName;
+ this.annotations = new ArrayList();
this.mappingMethods = mappingMethods;
- this.usedMapperTypes = usedMapperTypes;
+ this.referencedMappers = referencedMappers;
this.options = options;
- this.importedTypes = determineImportedTypes();
this.isErroneous = isErroneous;
}
- private SortedSet determineImportedTypes() {
+ @Override
+ public SortedSet getImportTypes() {
SortedSet importedTypes = new TreeSet();
importedTypes.add( Type.forClass( Generated.class ) );
for ( MappingMethod mappingMethod : mappingMethods ) {
-
- for ( Type type : mappingMethod.getReferencedTypes() ) {
+ for ( Type type : mappingMethod.getImportTypes() ) {
addWithDependents( importedTypes, type );
}
}
+ for ( MapperReference mapperReference : referencedMappers ) {
+ for ( Type type : mapperReference.getImportTypes() ) {
+ addWithDependents( importedTypes, type );
+ }
+ }
+
+ for ( Annotation annotation : annotations ) {
+ addWithDependents( importedTypes, annotation.getType() );
+ }
+
return importedTypes;
}
@@ -91,7 +102,7 @@ public class Mapper extends AbstractModelElement {
sb.append( "\n " + beanMapping.toString().replaceAll( "\n", "\n " ) );
}
sb.append( "\n ]" );
- sb.append( "\n usedMapperTypes=" + usedMapperTypes );
+ sb.append( "\n referencedMappers=" + referencedMappers );
sb.append( "\n}," );
return sb.toString();
@@ -113,19 +124,23 @@ public class Mapper extends AbstractModelElement {
return mappingMethods;
}
- public List getUsedMapperTypes() {
- return usedMapperTypes;
+ public List getReferencedMappers() {
+ return referencedMappers;
}
public Options getOptions() {
return options;
}
- public SortedSet getImportedTypes() {
- return importedTypes;
- }
-
public boolean isErroneous() {
return isErroneous;
}
+
+ public void addAnnotation(Annotation annotation) {
+ annotations.add( annotation );
+ }
+
+ public List getAnnotations() {
+ return annotations;
+ }
}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/MapperReference.java b/processor/src/main/java/org/mapstruct/ap/model/MapperReference.java
new file mode 100644
index 000000000..383e66a3d
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/model/MapperReference.java
@@ -0,0 +1,30 @@
+/**
+ * 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.model;
+
+/**
+ * A reference to another mapper class, which itself may be generated or
+ * hand-written.
+ *
+ * @author Gunnar Morling
+ */
+public interface MapperReference extends ModelElement {
+
+ Type getMapperType();
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java b/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java
index 652cc3bd5..5a57d02d3 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/MappingMethod.java
@@ -56,7 +56,8 @@ public abstract class MappingMethod extends AbstractModelElement {
return targetType;
}
- public Set getReferencedTypes() {
+ @Override
+ public Set getImportTypes() {
Set types = new HashSet();
types.add( getSourceType() );
types.add( getTargetType() );
diff --git a/processor/src/main/java/org/mapstruct/ap/model/ModelElement.java b/processor/src/main/java/org/mapstruct/ap/model/ModelElement.java
index f89c1a653..fa12ff483 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/ModelElement.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/ModelElement.java
@@ -19,6 +19,7 @@
package org.mapstruct.ap.model;
import java.io.Writer;
+import java.util.Set;
/**
* A model element with the ability to write itself into a given {@link Writer}.
@@ -54,4 +55,13 @@ public interface ModelElement {
* implementations.
*/
void write(Context context, Writer writer) throws Exception;
+
+ /**
+ * Returns a set containing those {@link Type}s referenced by this model
+ * element for which an import statement needs to be declared.
+ *
+ * @return A set with type referenced by this model element. Must not be
+ * {@code null.}
+ */
+ Set getImportTypes();
}
diff --git a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java
index e33b653d2..7844e7855 100644
--- a/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java
+++ b/processor/src/main/java/org/mapstruct/ap/model/PropertyMapping.java
@@ -18,6 +18,10 @@
*/
package org.mapstruct.ap.model;
+import java.util.Set;
+
+import org.mapstruct.ap.util.Collections;
+
/**
* Represents the mapping between a source and target property, e.g. from
* {@code String Source#foo} to {@code int Target#bar}. Name and type of source
@@ -100,6 +104,11 @@ public class PropertyMapping extends AbstractModelElement {
return conversion;
}
+ @Override
+ public Set getImportTypes() {
+ return Collections.asSet( sourceType, targetType );
+ }
+
@Override
public String toString() {
return "PropertyMapping {" +
diff --git a/processor/src/main/java/org/mapstruct/ap/processor/CdiComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/CdiComponentProcessor.java
new file mode 100644
index 000000000..39577fdda
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/processor/CdiComponentProcessor.java
@@ -0,0 +1,59 @@
+/**
+ * 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.processor;
+
+import java.util.ListIterator;
+import javax.lang.model.element.TypeElement;
+
+import org.mapstruct.ap.MapperPrism;
+import org.mapstruct.ap.model.Annotation;
+import org.mapstruct.ap.model.CdiMapperReference;
+import org.mapstruct.ap.model.Mapper;
+import org.mapstruct.ap.model.MapperReference;
+import org.mapstruct.ap.model.Type;
+
+/**
+ * A {@link ModelElementProcessor} which converts the given {@link Mapper}
+ * object into an application-scoped CDI bean in case CDI is configured as the
+ * target component model for this mapper.
+ *
+ * @author Gunnar Morling
+ */
+public class CdiComponentProcessor implements ModelElementProcessor {
+
+ @Override
+ public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, Mapper mapper) {
+ String componentModel = MapperPrism.getInstanceOn( mapperTypeElement ).componentModel();
+
+ if ( !componentModel.equals( "cdi" ) ) {
+ return mapper;
+ }
+
+ mapper.addAnnotation( new Annotation( new Type( "javax.enterprise.context", "ApplicationScoped" ) ) );
+
+ ListIterator iterator = mapper.getReferencedMappers().listIterator();
+ while ( iterator.hasNext() ) {
+ MapperReference reference = iterator.next();
+ iterator.remove();
+ iterator.add( new CdiMapperReference( reference.getMapperType() ) );
+ }
+
+ return mapper;
+ }
+}
diff --git a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
index 185012996..82380ab7e 100644
--- a/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/processor/MapperCreationProcessor.java
@@ -41,8 +41,10 @@ import org.mapstruct.ap.MapperPrism;
import org.mapstruct.ap.conversion.Conversion;
import org.mapstruct.ap.conversion.Conversions;
import org.mapstruct.ap.model.BeanMappingMethod;
+import org.mapstruct.ap.model.DefaultMapperReference;
import org.mapstruct.ap.model.IterableMappingMethod;
import org.mapstruct.ap.model.Mapper;
+import org.mapstruct.ap.model.MapperReference;
import org.mapstruct.ap.model.MappingMethod;
import org.mapstruct.ap.model.MappingMethodReference;
import org.mapstruct.ap.model.Options;
@@ -91,17 +93,17 @@ public class MapperCreationProcessor implements ModelElementProcessor methods) {
- List usedMapperTypes = getUsedMapperTypes( element );
-
+ private Mapper getMapper(TypeElement element, List methods) {
ReportingPolicy unmappedTargetPolicy = getEffectiveUnmappedTargetPolicy( element );
+ List mappingMethods = getMappingMethods( methods, unmappedTargetPolicy );
+ List mapperReferences = getReferencedMappers( element );
return new Mapper(
elementUtils.getPackageOf( element ).getQualifiedName().toString(),
element.getSimpleName().toString(),
element.getSimpleName() + IMPLEMENTATION_SUFFIX,
- getMappingMethods( methods, unmappedTargetPolicy ),
- usedMapperTypes,
+ mappingMethods,
+ mapperReferences,
options,
isErroneous
);
@@ -132,13 +134,15 @@ public class MapperCreationProcessor implements ModelElementProcessor getUsedMapperTypes(TypeElement element) {
- List usedMapperTypes = new LinkedList();
+ private List getReferencedMappers(TypeElement element) {
+ List mapperReferences = new LinkedList();
MapperPrism mapperPrism = MapperPrism.getInstanceOn( element );
+
for ( TypeMirror usedMapper : mapperPrism.uses() ) {
- usedMapperTypes.add( typeUtil.retrieveType( usedMapper ) );
+ mapperReferences.add( new DefaultMapperReference( typeUtil.retrieveType( usedMapper ) ) );
}
- return usedMapperTypes;
+
+ return mapperReferences;
}
private List getMappingMethods(List methods, ReportingPolicy unmappedTargetPolicy) {
diff --git a/processor/src/main/java/org/mapstruct/ap/util/Collections.java b/processor/src/main/java/org/mapstruct/ap/util/Collections.java
new file mode 100644
index 000000000..4821660f4
--- /dev/null
+++ b/processor/src/main/java/org/mapstruct/ap/util/Collections.java
@@ -0,0 +1,43 @@
+/**
+ * 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.util;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Provides utility methods around collections.
+ *
+ * @author Gunnar Morling
+ */
+public class Collections {
+
+ private Collections() {
+ }
+
+ public static Set asSet(T... elements) {
+ Set set = new HashSet();
+
+ for ( T element : elements ) {
+ set.add( element );
+ }
+
+ return set;
+ }
+}
diff --git a/processor/src/main/resources/org.mapstruct.ap.model.Annotation.ftl b/processor/src/main/resources/org.mapstruct.ap.model.Annotation.ftl
new file mode 100644
index 000000000..a32b62b77
--- /dev/null
+++ b/processor/src/main/resources/org.mapstruct.ap.model.Annotation.ftl
@@ -0,0 +1,21 @@
+<#--
+
+ 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.
+
+-->
+@${type.name}
diff --git a/processor/src/main/resources/org.mapstruct.ap.model.CdiMapperReference.ftl b/processor/src/main/resources/org.mapstruct.ap.model.CdiMapperReference.ftl
new file mode 100644
index 000000000..72f7427b9
--- /dev/null
+++ b/processor/src/main/resources/org.mapstruct.ap.model.CdiMapperReference.ftl
@@ -0,0 +1,22 @@
+<#--
+
+ 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.
+
+-->
+ @Inject
+ private ${mapperType.name} ${mapperType.name?uncap_first};
\ No newline at end of file
diff --git a/processor/src/main/resources/org.mapstruct.ap.model.DefaultMapperReference.ftl b/processor/src/main/resources/org.mapstruct.ap.model.DefaultMapperReference.ftl
new file mode 100644
index 000000000..5c8a8bde7
--- /dev/null
+++ b/processor/src/main/resources/org.mapstruct.ap.model.DefaultMapperReference.ftl
@@ -0,0 +1,21 @@
+<#--
+
+ 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.
+
+-->
+ private final ${mapperType.name} ${mapperType.name?uncap_first} = new ${mapperType.name}();
\ No newline at end of file
diff --git a/processor/src/main/resources/org.mapstruct.ap.model.Mapper.ftl b/processor/src/main/resources/org.mapstruct.ap.model.Mapper.ftl
index b5f90d200..797d74cff 100644
--- a/processor/src/main/resources/org.mapstruct.ap.model.Mapper.ftl
+++ b/processor/src/main/resources/org.mapstruct.ap.model.Mapper.ftl
@@ -20,7 +20,7 @@
-->
package ${packageName};
-<#list importedTypes as importedType>
+<#list importTypes as importedType>
import ${importedType.fullyQualifiedName};
#list>
@@ -28,10 +28,13 @@ import ${importedType.fullyQualifiedName};
value = "org.mapstruct.ap.MappingProcessor"<#if options.suppressGeneratorTimestamp == false>,
date = "${.now?string("yyyy-MM-dd'T'HH:mm:ssZ")}"#if>
)
+<#list annotations as annotation>
+<@includeModel object=annotation/>
+#list>
public class ${implementationName} implements ${interfaceName} {
-<#list usedMapperTypes as mapperType>
- private final ${mapperType.name} ${mapperType.name?uncap_first} = new ${mapperType.name}();
+<#list referencedMappers as mapper>
+ <@includeModel object=mapper/>
#list>
<#list mappingMethods as mappingMethod>
diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java
index 394124289..e354fd215 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java
@@ -24,6 +24,7 @@ import org.mapstruct.Mapper;
import org.mapstruct.Mappers;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
+import org.mapstruct.ap.test.complex.other.DateMapper;
import org.mapstruct.ap.test.complex.source.Car;
import org.mapstruct.ap.test.complex.source.Person;
import org.mapstruct.ap.test.complex.target.CarDto;
diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java
index 56df15c3d..ee28e8a93 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java
@@ -23,6 +23,7 @@ import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.List;
+import org.mapstruct.ap.test.complex.other.DateMapper;
import org.mapstruct.ap.test.complex.source.Car;
import org.mapstruct.ap.test.complex.source.Category;
import org.mapstruct.ap.test.complex.source.Person;
diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/DateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java
similarity index 96%
rename from processor/src/test/java/org/mapstruct/ap/test/complex/DateMapper.java
rename to processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java
index a5594bce2..78370585d 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/complex/DateMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java
@@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.mapstruct.ap.test.complex;
+package org.mapstruct.ap.test.complex.other;
import java.text.ParseException;
import java.text.SimpleDateFormat;