Skip to content

Commit

Permalink
Merge pull request #141 from Musikolo/feature#137-cdi-support
Browse files Browse the repository at this point in the history
New Feature  #137: Implement withIoC={CDI, CDI_SINGLETON} options
  • Loading branch information
slemesle authored Jan 23, 2017
2 parents 65b0f5c + 9fcb26e commit 95b8215
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void emitCustomMappersFields(JavaWriter writer, boolean assign) throws IOExcepti
writer.emitJavadoc("Custom Mapper setter for " + field);

EnumSet<Modifier> 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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ public void emitFactoryFields(JavaWriter writer, boolean assign) throws IOExcept
writer.emitJavadoc("Factory setter for " + field);

EnumSet<Modifier> 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");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/*
/*-
* Copyright 2013 Xebia and Séven Le Mesle
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -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<ExecutableElement> mapperMethods;
private final String origClasse;
Expand All @@ -45,77 +53,75 @@ public class MapperClassGenerator {
private final MapperWrapper mapper;
private final DeclaredType declaredType;
private List<MethodWrapper> methodWrappers;

public MapperClassGenerator(String classe, Collection<ExecutableElement> executableElements, ProcessingEnvironment processingEnvironment) {

public MapperClassGenerator(String classe, Collection<ExecutableElement> 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<MethodWrapper> validateTypes() {

List<MethodWrapper> res = new ArrayList<MethodWrapper>();

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<MapperMethodGenerator> methodGenerators = new ArrayList<MapperMethodGenerator>();



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 != "") {
Expand All @@ -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<Modifier> modifiers = EnumSet.of(PUBLIC);
if (mapper.isAbstractClass()) {
interfaceName = new String[]{};
interfaceName = new String[] {};
} else {
className = null;
}
Expand All @@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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);

}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
@@ -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);

}
Loading

0 comments on commit 95b8215

Please sign in to comment.