diff --git a/processor/src/main/java/fr/xebia/extras/selma/codegen/CustomMapperWrapper.java b/processor/src/main/java/fr/xebia/extras/selma/codegen/CustomMapperWrapper.java index 129b189..49e095d 100644 --- a/processor/src/main/java/fr/xebia/extras/selma/codegen/CustomMapperWrapper.java +++ b/processor/src/main/java/fr/xebia/extras/selma/codegen/CustomMapperWrapper.java @@ -108,7 +108,7 @@ void emitCustomMappersFields(JavaWriter writer, boolean assign) throws IOExcepti writer.emitJavadoc("Custom Mapper setter for " + field); EnumSet modifiers = EnumSet.of(PUBLIC, FINAL); - if (ioC == IoC.CDI) { + if (ioC == IoC.CDI || ioC == IoC.CDI_SINGLETON || ioC == IoC.CDI_APPLICATION_SCOPED) { modifiers = EnumSet.of(PUBLIC); } writer.beginMethod("void", "setCustomMapper" + customMapperField.getSimpleName(),modifiers, customMapperField.asType().toString(), "mapper"); diff --git a/processor/src/main/java/fr/xebia/extras/selma/codegen/FactoryWrapper.java b/processor/src/main/java/fr/xebia/extras/selma/codegen/FactoryWrapper.java index 35f2ccf..caa0ad7 100644 --- a/processor/src/main/java/fr/xebia/extras/selma/codegen/FactoryWrapper.java +++ b/processor/src/main/java/fr/xebia/extras/selma/codegen/FactoryWrapper.java @@ -197,7 +197,7 @@ public void emitFactoryFields(JavaWriter writer, boolean assign) throws IOExcept writer.emitJavadoc("Factory setter for " + field); EnumSet modifiers = EnumSet.of(PUBLIC, FINAL); - if (ioC == IoC.CDI) { + if (ioC == IoC.CDI || ioC == IoC.CDI_SINGLETON || ioC == IoC.CDI_APPLICATION_SCOPED) { modifiers = EnumSet.of(PUBLIC); } writer.beginMethod("void", "setFactory" + factoryField.getSimpleName(), modifiers, factoryField.asType().toString(), "_factory"); diff --git a/processor/src/main/java/fr/xebia/extras/selma/codegen/MapperClassGenerator.java b/processor/src/main/java/fr/xebia/extras/selma/codegen/MapperClassGenerator.java index d3bc3f8..109d351 100644 --- a/processor/src/main/java/fr/xebia/extras/selma/codegen/MapperClassGenerator.java +++ b/processor/src/main/java/fr/xebia/extras/selma/codegen/MapperClassGenerator.java @@ -1,4 +1,4 @@ -/* +/*- * Copyright 2013 Xebia and Séven Le Mesle * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,26 +16,34 @@ */ package fr.xebia.extras.selma.codegen; -import com.squareup.javawriter.JavaWriter; -import fr.xebia.extras.selma.SelmaConstants; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PUBLIC; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.*; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.tools.JavaFileObject; -import java.io.IOException; -import java.util.*; -import static javax.lang.model.element.Modifier.FINAL; -import static javax.lang.model.element.Modifier.PUBLIC; - -/** - * Handles the generation of the Mapper class - */ -public class MapperClassGenerator { +import com.squareup.javawriter.JavaWriter; +import fr.xebia.extras.selma.SelmaConstants; +/** Handles the generation of the Mapper class */ +public class MapperClassGenerator { + public static final String GENERATED_BY_SELMA = "GENERATED BY S3LM4"; private final Collection mapperMethods; private final String origClasse; @@ -45,77 +53,75 @@ public class MapperClassGenerator { private final MapperWrapper mapper; private final DeclaredType declaredType; private List methodWrappers; - - public MapperClassGenerator(String classe, Collection executableElements, ProcessingEnvironment processingEnvironment) { + + public MapperClassGenerator(String classe, Collection executableElements, + ProcessingEnvironment processingEnvironment) { this.origClasse = classe; this.mapperMethods = executableElements; this.processingEnv = processingEnvironment; context = new MapperGeneratorContext(processingEnv); - + element = context.getTypeElement(classe); declaredType = (DeclaredType) element.asType(); - + mapper = new MapperWrapper(context, element); context.setWrapper(mapper); - + methodWrappers = validateTypes(); - } - - + private List validateTypes() { - + List res = new ArrayList(); - + for (ExecutableElement mapperMethod : mapperMethods) { - + MethodWrapper methodWrapper = new MethodWrapper(mapperMethod, declaredType, context); res.add(methodWrapper); - + mapper.buildEnumForMethod(methodWrapper); - + InOutType inOutType = methodWrapper.inOutType(); if (inOutType.differs()) { MappingBuilder builder = MappingBuilder.getBuilderFor(context, inOutType); - + if ((inOutType.in().getKind() != TypeKind.DECLARED || inOutType.out().getKind() != TypeKind.DECLARED) && builder == null) { - context.error(mapperMethod, "In type : %s and Out type : %s differs and this kind of conversion is not supported here", inOutType.in(), inOutType.out()); + context.error(mapperMethod, "In type : %s and Out type : %s differs and this kind of conversion is not supported here", + inOutType.in(), inOutType.out()); } else { context.mappingMethod(methodWrapper.inOutType(), methodWrapper.getSimpleName()); } } - } + return res; } - + public void build() throws IOException { - + boolean firstMethod = true; JavaWriter writer = null; JavaFileObject sourceFile = null; - + final TypeElement type = processingEnv.getElementUtils().getTypeElement(origClasse); final String packageName = getPackage(type).getQualifiedName().toString(); final String strippedTypeName = strippedTypeName(type.getQualifiedName().toString(), packageName); - - final String adapterName = new StringBuilder(packageName) - .append('.') - .append(strippedTypeName.replace('.', '_')) + + final String adapterName = new StringBuilder(packageName).append('.').append(strippedTypeName.replace('.', '_')) .append(SelmaConstants.MAPPER_CLASS_SUFFIX).toString(); + final List methodGenerators = new ArrayList(); - - + for (MethodWrapper mapperMethod : methodWrappers) { - + if (firstMethod) { sourceFile = processingEnv.getFiler().createSourceFile(adapterName, type); writer = new JavaWriter(sourceFile.openWriter()); - + writer.emitSingleLineComment(GENERATED_BY_SELMA); writer.emitPackage(packageName); writer.emitEmptyLine(); - + switch (mapper.ioC) { case SPRING: if (mapper.ioCServiceName != "") { @@ -124,44 +130,55 @@ public void build() throws IOException { writer.emitAnnotation("org.springframework.stereotype.Service"); } break; + case CDI: + writer.emitAnnotation("javax.inject.Named"); + break; + + case CDI_SINGLETON: + writer.emitAnnotation("javax.inject.Named"); + writer.emitAnnotation("javax.inject.Singleton"); + break; + + case CDI_APPLICATION_SCOPED: writer.emitAnnotation("javax.enterprise.context.ApplicationScoped"); break; + default: break; } - + openClassBlock(writer, adapterName, strippedTypeName); writer.emitEmptyLine(); firstMethod = false; } - // Prepare mapping method + // Prepare mapping method methodGenerators.add(new MapperMethodGenerator(writer, mapperMethod, mapper)); } - - // Build mapping methods + + // Build mapping methods for (MapperMethodGenerator mapperMethodGenerator : methodGenerators) { mapperMethodGenerator.build(methodGenerators); - + mapper.collectMaps(mapperMethodGenerator.maps()); - + writer.emitEmptyLine(); } - + buildConstructor(writer, adapterName); - + writer.endType(); writer.close(); - + mapper.reportUnused(); } - + private void openClassBlock(JavaWriter writer, String adapterName, String strippedTypeName) throws IOException { - String[] interfaceName = new String[]{strippedTypeName}; + String[] interfaceName = new String[] { strippedTypeName }; String className = strippedTypeName; Set modifiers = EnumSet.of(PUBLIC); if (mapper.isAbstractClass()) { - interfaceName = new String[]{}; + interfaceName = new String[] {}; } else { className = null; } @@ -170,38 +187,36 @@ private void openClassBlock(JavaWriter writer, String adapterName, String stripp } writer.beginType(adapterName, "class", modifiers, className, interfaceName); } - + private void buildConstructor(JavaWriter writer, String adapterName) throws IOException { mapper.emitSourceFields(writer); mapper.emitCustomMappersFields(writer, false); mapper.emitFactoryFields(writer, false); - + // First build default constructor writer.emitEmptyLine(); writer.emitJavadoc("Single constructor"); writer.beginMethod(null, adapterName, EnumSet.of(PUBLIC), mapper.sourceConstructorArgs()); - + // assign source in parameters to instance fields mapper.emitSourceAssigns(writer); - + // Add customMapper instantiation mapper.emitCustomMappersFields(writer, true); mapper.emitFactoryFields(writer, true); - + writer.endMethod(); writer.emitEmptyLine(); } - - + public PackageElement getPackage(Element type) { while (type.getKind() != ElementKind.PACKAGE) { type = type.getEnclosingElement(); } return (PackageElement) type; } - + public String strippedTypeName(String type, String packageName) { return type.substring(packageName.isEmpty() ? 0 : packageName.length() + 1); } - } diff --git a/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMaps.java b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMaps.java new file mode 100644 index 0000000..6d87d4f --- /dev/null +++ b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMaps.java @@ -0,0 +1,31 @@ +/*- + * Copyright 2013 Xebia and Séven Le Mesle + * + * 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 fr.xebia.extras.selma.it.custom.mapper; + +import fr.xebia.extras.selma.IoC; +import fr.xebia.extras.selma.Mapper; +import fr.xebia.extras.selma.beans.Book; +import fr.xebia.extras.selma.beans.BookDTO; + +@Mapper(withIoC = IoC.CDI) +public interface CustomCdiMapperInMaps { + + public Book asBook(BookDTO source); + + public BookDTO asBookDto(Book source); + +} diff --git a/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMapsIT.java b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMapsIT.java new file mode 100644 index 0000000..b248ff6 --- /dev/null +++ b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiMapperInMapsIT.java @@ -0,0 +1,37 @@ +/*- + * Copyright 2013 Xebia and Séven Le Mesle + * + * 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 fr.xebia.extras.selma.it.custom.mapper; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import fr.xebia.extras.selma.Selma; +import fr.xebia.extras.selma.it.utils.Compile; +import fr.xebia.extras.selma.it.utils.IntegrationTestBase; + +@Compile(withClasses = CustomCdiMapperInMaps.class) +public class CustomCdiMapperInMapsIT extends IntegrationTestBase { + + @Test + public void given_cdi_mapper_should_be_annotated_with_Inject() { + + final CustomCdiMapperInMaps mapper = Selma.getMapper(CustomCdiMapperInMaps.class); + assertThat(mapper.getClass().getAnnotation(javax.inject.Named.class), notNullValue()); + } +} diff --git a/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMaps.java b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMaps.java new file mode 100644 index 0000000..6d94d3f --- /dev/null +++ b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMaps.java @@ -0,0 +1,31 @@ +/*- + * Copyright 2013 Xebia and Séven Le Mesle + * + * 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 fr.xebia.extras.selma.it.custom.mapper; + +import fr.xebia.extras.selma.IoC; +import fr.xebia.extras.selma.Mapper; +import fr.xebia.extras.selma.beans.Book; +import fr.xebia.extras.selma.beans.BookDTO; + +@Mapper(withIoC = IoC.CDI_SINGLETON) +public interface CustomCdiSingletonMapperInMaps { + + public Book asBook(BookDTO source); + + public BookDTO asBookDto(Book source); + +} diff --git a/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMapsIT.java b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMapsIT.java new file mode 100644 index 0000000..2f03886 --- /dev/null +++ b/processor/src/test/java/fr/xebia/extras/selma/it/custom/mapper/CustomCdiSingletonMapperInMapsIT.java @@ -0,0 +1,38 @@ +/*- + * Copyright 2013 Xebia and Séven Le Mesle + * + * 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 fr.xebia.extras.selma.it.custom.mapper; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +import fr.xebia.extras.selma.Selma; +import fr.xebia.extras.selma.it.utils.Compile; +import fr.xebia.extras.selma.it.utils.IntegrationTestBase; + +@Compile(withClasses = CustomCdiSingletonMapperInMaps.class) +public class CustomCdiSingletonMapperInMapsIT extends IntegrationTestBase { + + @Test + public void given_cdi_mapper_should_be_annotated_with_Inject_and_Singleton() { + + final CustomCdiSingletonMapperInMaps mapper = Selma.getMapper(CustomCdiSingletonMapperInMaps.class); + assertThat(mapper.getClass().getAnnotation(javax.inject.Named.class), notNullValue()); + assertThat(mapper.getClass().getAnnotation(javax.inject.Singleton.class), notNullValue()); + } +} diff --git a/processor/src/test/java/fr/xebia/extras/selma/it/inject/AddressMapperCDI.java b/processor/src/test/java/fr/xebia/extras/selma/it/inject/AddressMapperCDI.java index 6a79f13..8f96088 100644 --- a/processor/src/test/java/fr/xebia/extras/selma/it/inject/AddressMapperCDI.java +++ b/processor/src/test/java/fr/xebia/extras/selma/it/inject/AddressMapperCDI.java @@ -24,7 +24,7 @@ /** * Created by slemesle on 25/03/15. */ -@Mapper(withIgnoreFields = "extras", withCustom = CustomImmutableMapperClass.class, withFactories = BeanFactoryClass.class, withIoC = IoC.CDI, withFinalMappers = false) +@Mapper(withIgnoreFields = "extras", withCustom = CustomImmutableMapperClass.class, withFactories = BeanFactoryClass.class, withIoC = IoC.CDI_APPLICATION_SCOPED, withFinalMappers = false) public interface AddressMapperCDI { AddressOut asAddressOut(AddressIn in); diff --git a/selma/src/main/java/fr/xebia/extras/selma/IoC.java b/selma/src/main/java/fr/xebia/extras/selma/IoC.java index 334d67e..021ac23 100644 --- a/selma/src/main/java/fr/xebia/extras/selma/IoC.java +++ b/selma/src/main/java/fr/xebia/extras/selma/IoC.java @@ -1,4 +1,4 @@ -/* +/*- * Copyright 2013 Séven Le Mesle * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,5 +20,14 @@ * Created by slemesle on 27/03/15. */ public enum IoC { - NO, SPRING, CDI + /** Adds no annotation for IoC */ + NO, + /** Adds @Service annotation to the generated mapper */ + SPRING, + /** Adds @Inject annotation to the generated mapper */ + CDI, + /** Adds @Inject and @Singleton annotations to the generated mapper */ + CDI_SINGLETON, + /** Adds @ApplicationScoped annotation to the generated mapper */ + CDI_APPLICATION_SCOPED }