mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-24 21:07:26 +08:00
worked on improving Querydsl APT
This commit is contained in:
parent
d2927174d3
commit
f13a653d52
@ -46,7 +46,6 @@ import com.mysema.query.codegen.EntityType;
|
||||
import com.mysema.query.codegen.QueryTypeFactory;
|
||||
import com.mysema.query.codegen.Supertype;
|
||||
import com.mysema.query.codegen.TypeMappings;
|
||||
import com.mysema.util.ClassPathUtils;
|
||||
|
||||
/**
|
||||
* ExtendedTypeFactory is a factory for APT inspection based Type creation
|
||||
@ -66,7 +65,7 @@ public final class ExtendedTypeFactory {
|
||||
|
||||
private final ProcessingEnvironment env;
|
||||
|
||||
private final TypeElement numberType, comparableType;
|
||||
private final TypeMirror numberType, comparableType, collectionType, setType, listType, mapType;
|
||||
|
||||
private final TypeMappings typeMappings;
|
||||
|
||||
@ -78,17 +77,7 @@ public final class ExtendedTypeFactory {
|
||||
|
||||
@Override
|
||||
public Type visitPrimitive(PrimitiveType primitiveType, Boolean p) {
|
||||
switch (primitiveType.getKind()) {
|
||||
case BOOLEAN: return Types.BOOLEAN;
|
||||
case BYTE: return Types.BYTE;
|
||||
case CHAR: return Types.CHARACTER;
|
||||
case DOUBLE: return Types.DOUBLE;
|
||||
case FLOAT: return Types.FLOAT;
|
||||
case INT: return Types.INTEGER;
|
||||
case LONG: return Types.LONG;
|
||||
case SHORT: return Types.SHORT;
|
||||
}
|
||||
return null;
|
||||
return visit(env.getTypeUtils().boxedClass(primitiveType).asType(), p);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -179,18 +168,7 @@ public final class ExtendedTypeFactory {
|
||||
|
||||
@Override
|
||||
public List<String> visitPrimitive(PrimitiveType t, Boolean p) {
|
||||
// TODO : optimize
|
||||
switch (t.getKind()) {
|
||||
case BOOLEAN: return Collections.singletonList("Boolean");
|
||||
case BYTE: return Collections.singletonList("Byte");
|
||||
case CHAR: return Collections.singletonList("Character");
|
||||
case DOUBLE: return Collections.singletonList("Double");
|
||||
case FLOAT: return Collections.singletonList("Float");
|
||||
case INT: return Collections.singletonList("Integer");
|
||||
case LONG: return Collections.singletonList("Long");
|
||||
case SHORT: return Collections.singletonList("Short");
|
||||
}
|
||||
return null;
|
||||
return visit(env.getTypeUtils().boxedClass(t).asType(), p);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -256,10 +234,9 @@ public final class ExtendedTypeFactory {
|
||||
public List<String> visitNoType(NoType t, Boolean p) {
|
||||
return Collections.singletonList("Object");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
public ExtendedTypeFactory(
|
||||
ProcessingEnvironment env,
|
||||
Configuration configuration,
|
||||
@ -269,14 +246,20 @@ public final class ExtendedTypeFactory {
|
||||
this.env = env;
|
||||
this.defaultType = Types.OBJECT;
|
||||
this.entityAnnotations = annotations;
|
||||
this.numberType = env.getElementUtils().getTypeElement(Number.class.getName());
|
||||
this.comparableType = env.getElementUtils().getTypeElement(Comparable.class.getName());
|
||||
this.numberType = getErasedType(Number.class);
|
||||
this.comparableType = getErasedType(Comparable.class);
|
||||
this.collectionType = getErasedType(Collection.class);
|
||||
this.listType = getErasedType(List.class);
|
||||
this.setType = getErasedType(Set.class);
|
||||
this.mapType = getErasedType(Map.class);
|
||||
this.typeMappings = typeMappings;
|
||||
this.queryTypeFactory = queryTypeFactory;
|
||||
}
|
||||
|
||||
private TypeMirror getErasedType(Class<?> clazz) {
|
||||
return env.getTypeUtils().erasure(env.getElementUtils().getTypeElement(clazz.getName()).asType());
|
||||
}
|
||||
|
||||
|
||||
private Type createType(TypeElement typeElement, TypeCategory category, List<? extends TypeMirror> typeArgs, boolean deep) {
|
||||
String name = typeElement.getQualifiedName().toString();
|
||||
String simpleName = typeElement.getSimpleName().toString();
|
||||
@ -324,10 +307,10 @@ public final class ExtendedTypeFactory {
|
||||
String name = typeElement.getQualifiedName().toString();
|
||||
TypeCategory typeCategory = TypeCategory.get(name);
|
||||
|
||||
if (typeCategory != TypeCategory.NUMERIC && isImplemented(typeElement, comparableType) && isSubType(typeElement, numberType)) {
|
||||
if (typeCategory != TypeCategory.NUMERIC && isAssignable(typeElement.asType(), comparableType) && isSubType(typeElement.asType(), numberType)) {
|
||||
typeCategory = TypeCategory.NUMERIC;
|
||||
|
||||
} else if (!typeCategory.isSubCategoryOf(TypeCategory.COMPARABLE) && isImplemented(typeElement, comparableType)) {
|
||||
} else if (!typeCategory.isSubCategoryOf(TypeCategory.COMPARABLE) && isAssignable(typeElement.asType(), comparableType)) {
|
||||
typeCategory = TypeCategory.COMPARABLE;
|
||||
|
||||
} if (typeCategory == TypeCategory.SIMPLE) {
|
||||
@ -401,18 +384,6 @@ public final class ExtendedTypeFactory {
|
||||
return new SimpleType(Types.MAP, keyType, valueType);
|
||||
}
|
||||
|
||||
private Type createCollectionType(String simpleName, Iterator<? extends TypeMirror> typeMirrors, boolean deep) {
|
||||
return createCollectionType(Types.COLLECTION, simpleName, typeMirrors, deep);
|
||||
}
|
||||
|
||||
private Type createListType(String simpleName, Iterator<? extends TypeMirror> typeMirrors, boolean deep) {
|
||||
return createCollectionType(Types.LIST, simpleName, typeMirrors, deep);
|
||||
}
|
||||
|
||||
private Type createSetType(String simpleName, Iterator<? extends TypeMirror> typeMirrors, boolean deep) {
|
||||
return createCollectionType(Types.SET, simpleName, typeMirrors, deep);
|
||||
}
|
||||
|
||||
private Type createCollectionType(Type baseType, String simpleName, Iterator<? extends TypeMirror> typeMirrors, boolean deep) {
|
||||
if (!typeMirrors.hasNext()){
|
||||
return new SimpleType(baseType, defaultType);
|
||||
@ -510,28 +481,24 @@ public final class ExtendedTypeFactory {
|
||||
return createType(typeElement, TypeCategory.ENTITY, declaredType.getTypeArguments(), deep);
|
||||
}
|
||||
}
|
||||
|
||||
String name = typeElement.getQualifiedName().toString();
|
||||
|
||||
String simpleName = typeElement.getSimpleName().toString();
|
||||
Iterator<? extends TypeMirror> i = declaredType.getTypeArguments().iterator();
|
||||
Class<?> cl = ClassPathUtils.safeClassForName(name);
|
||||
|
||||
if (cl == null) { // class not available
|
||||
return createType(typeElement, TypeCategory.get(name), declaredType.getTypeArguments(), deep);
|
||||
|
||||
} else if (Map.class.isAssignableFrom(cl)) {
|
||||
|
||||
if (isAssignable(declaredType, mapType)) {
|
||||
return createMapType(simpleName, i, deep);
|
||||
|
||||
} else if (List.class.isAssignableFrom(cl)) {
|
||||
return createListType(simpleName, i, deep);
|
||||
} else if (isAssignable(declaredType, listType)) {
|
||||
return createCollectionType(Types.LIST, simpleName, i, deep);
|
||||
|
||||
} else if (Set.class.isAssignableFrom(cl)) {
|
||||
return createSetType(simpleName, i, deep);
|
||||
} else if (isAssignable(declaredType, setType)) {
|
||||
return createCollectionType(Types.SET, simpleName, i, deep);
|
||||
|
||||
} else if (Collection.class.isAssignableFrom(cl)) {
|
||||
return createCollectionType(simpleName, i, deep);
|
||||
} else if (isAssignable(declaredType, collectionType)) {
|
||||
return createCollectionType(Types.COLLECTION, simpleName, i, deep);
|
||||
|
||||
} else {
|
||||
String name = typeElement.getQualifiedName().toString();
|
||||
return createType(typeElement, TypeCategory.get(name), declaredType.getTypeArguments(), deep);
|
||||
}
|
||||
}
|
||||
@ -578,38 +545,13 @@ public final class ExtendedTypeFactory {
|
||||
doubleIndexEntities = doubleIndex;
|
||||
return superTypes;
|
||||
}
|
||||
|
||||
|
||||
// TODO : simplify this
|
||||
private boolean isImplemented(TypeElement type, TypeElement iface) {
|
||||
for (TypeMirror t : type.getInterfaces()) {
|
||||
String name = t.toString();
|
||||
if (name.contains("<")) {
|
||||
name = name.substring(0, name.indexOf('<'));
|
||||
}
|
||||
// interface is directly implemented
|
||||
if (name.equals(iface.getQualifiedName().toString())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (type.getSuperclass() != null) {
|
||||
TypeElement superType = (TypeElement) env.getTypeUtils().asElement(type.getSuperclass());
|
||||
if (superType != null) {
|
||||
return isImplemented(superType, iface);
|
||||
}
|
||||
superType = env.getElementUtils().getTypeElement(type.getSuperclass().toString());
|
||||
if (superType != null) {
|
||||
return isImplemented(superType, iface);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
private boolean isAssignable(TypeMirror type, TypeMirror iface) {
|
||||
return env.getTypeUtils().isAssignable(type, iface);
|
||||
}
|
||||
|
||||
private boolean isSubType(TypeElement type1, TypeElement type2) {
|
||||
return env.getTypeUtils().isSubtype(type1.asType(), type2.asType());
|
||||
private boolean isSubType(TypeMirror type1, TypeMirror type2) {
|
||||
return env.getTypeUtils().isSubtype(type1, type2);
|
||||
}
|
||||
|
||||
private TypeMirror normalize(TypeMirror type) {
|
||||
|
||||
@ -9,7 +9,16 @@ import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.processing.Filer;
|
||||
@ -29,10 +38,10 @@ import javax.lang.model.type.NoType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.util.ElementFilter;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
|
||||
import com.mysema.codegen.JavaWriter;
|
||||
import com.mysema.codegen.model.Parameter;
|
||||
@ -41,7 +50,6 @@ import com.mysema.codegen.model.Type;
|
||||
import com.mysema.codegen.model.TypeCategory;
|
||||
import com.mysema.commons.lang.Assert;
|
||||
import com.mysema.query.annotations.QueryDelegate;
|
||||
import com.mysema.query.annotations.QueryEntities;
|
||||
import com.mysema.query.annotations.QueryExclude;
|
||||
import com.mysema.query.annotations.QueryProjection;
|
||||
import com.mysema.query.annotations.Variables;
|
||||
@ -53,7 +61,6 @@ import com.mysema.query.codegen.Serializer;
|
||||
import com.mysema.query.codegen.SerializerConfig;
|
||||
import com.mysema.query.codegen.Supertype;
|
||||
import com.mysema.query.codegen.TypeMappings;
|
||||
import com.mysema.util.BeanUtils;
|
||||
|
||||
/**
|
||||
* Processor handles the actual work in the Querydsl APT module
|
||||
@ -84,7 +91,7 @@ public class Processor {
|
||||
|
||||
private final Map<String, EntityType> projectionTypes = new HashMap<String, EntityType>();
|
||||
|
||||
private final ElementHandler elementHandler;
|
||||
private final TypeElementHandler elementHandler;
|
||||
|
||||
private final Map<String, EntityType> embeddables = new HashMap<String,EntityType>();
|
||||
|
||||
@ -98,6 +105,8 @@ public class Processor {
|
||||
|
||||
private final ExtendedTypeFactory typeFactory;
|
||||
|
||||
private final TypeExtractor typeExtractor = new TypeExtractor(true);
|
||||
|
||||
/**
|
||||
* Create a new Processor instance
|
||||
*
|
||||
@ -121,7 +130,7 @@ public class Processor {
|
||||
TypeMappings typeMappings = configuration.getTypeMappings();
|
||||
QueryTypeFactory queryTypeFactory = configuration.getQueryTypeFactory();
|
||||
this.typeFactory = new ExtendedTypeFactory(env, configuration, entityAnnotations, typeMappings, queryTypeFactory);
|
||||
this.elementHandler = new ElementHandler(configuration, typeFactory, typeMappings, queryTypeFactory);
|
||||
this.elementHandler = new TypeElementHandler(configuration, typeFactory, typeMappings, queryTypeFactory);
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@ -134,6 +143,7 @@ public class Processor {
|
||||
}
|
||||
|
||||
for (String key : entityTypes.keySet()) {
|
||||
actualSupertypes.remove(key);
|
||||
extensionTypes.remove(key);
|
||||
embeddables.remove(key);
|
||||
}
|
||||
@ -153,8 +163,10 @@ public class Processor {
|
||||
processFromProperties();
|
||||
}
|
||||
|
||||
boolean hasEmbeddableAnnotation = configuration.getEmbeddableAnnotation() != null;
|
||||
|
||||
if (configuration.getSuperTypeAnnotation() != null) {
|
||||
processSupertypes();
|
||||
process(configuration.getSuperTypeAnnotation(), hasEmbeddableAnnotation, actualSupertypes);
|
||||
}
|
||||
|
||||
if (configuration.getEmbeddedAnnotation() != null) {
|
||||
@ -162,76 +174,154 @@ public class Processor {
|
||||
}
|
||||
|
||||
if (configuration.getEmbeddableAnnotation() != null) {
|
||||
processEmbeddables();
|
||||
process(configuration.getEmbeddableAnnotation(), false, embeddables);
|
||||
}
|
||||
|
||||
if (configuration.getEntitiesAnnotation() != null) {
|
||||
processEntitiesFromPackage();
|
||||
}
|
||||
|
||||
processEntities();
|
||||
process(configuration.getEntityAnnotation(), hasEmbeddableAnnotation, entityTypes);
|
||||
|
||||
processProjectionTypes();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the elements with the given annotation type
|
||||
*
|
||||
* @param a
|
||||
* @return
|
||||
*/
|
||||
private Set<? extends Element> getElements(Class<? extends Annotation> a) {
|
||||
return roundEnv.getElementsAnnotatedWith(a);
|
||||
}
|
||||
|
||||
private void processExclusions() {
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(QueryExclude.class)) {
|
||||
for (Element element : getElements(QueryExclude.class)) {
|
||||
if (element instanceof PackageElement) {
|
||||
configuration.addExcludedPackage(((PackageElement)element).getQualifiedName().toString());
|
||||
} else {
|
||||
} else if (element instanceof TypeElement) {
|
||||
configuration.addExcludedClass(((TypeElement)element).getQualifiedName().toString());
|
||||
} else {
|
||||
throw new IllegalArgumentException(element.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void process(Class<? extends Annotation> annotation, boolean skipEmbeddables, Map<String, EntityType> types) {
|
||||
process(getElements(annotation), skipEmbeddables, types);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void process(Set<? extends Element> elements, boolean skipEmbeddables, Map<String, EntityType> types) {
|
||||
Deque<Type> superTypes = new ArrayDeque<Type>();
|
||||
List<TypeElement> allElements = new ArrayList<TypeElement>();
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
List<TypeMirror> superTypeMirrors = new ArrayList<TypeMirror>();
|
||||
|
||||
for (TypeElement element : (Set<TypeElement>)elements) {
|
||||
if (skipEmbeddables && element.getAnnotation(configuration.getEmbeddableAnnotation()) != null) {
|
||||
continue;
|
||||
}
|
||||
typeFactory.getEntityType(element.asType(), false);
|
||||
typeMirrors.add(element.asType());
|
||||
allElements.add(element);
|
||||
|
||||
addAnnotationlessSupertypes(superTypeMirrors, allElements, element);
|
||||
}
|
||||
|
||||
// super type handling
|
||||
for (TypeMirror typeMirror : superTypeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
for (TypeMirror typeMirror : typeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
// get annotated types
|
||||
for (TypeElement element : allElements) {
|
||||
EntityType model = elementHandler.handleEntityType(element);
|
||||
registerTypeElement(model.getFullName(), element);
|
||||
types.put(model.getFullName(), model);
|
||||
if (model.getSuperType() != null) {
|
||||
superTypes.push(model.getSuperType().getType());
|
||||
}
|
||||
}
|
||||
|
||||
mergeTypes(types, superTypes);
|
||||
}
|
||||
|
||||
private void processEmbedded() {
|
||||
Set<Element> elements = new HashSet<Element>();
|
||||
|
||||
// only creation
|
||||
for (Element element : getElements(configuration.getEmbeddedAnnotation())) {
|
||||
TypeMirror type = element.asType();
|
||||
if (element.getKind() == ElementKind.METHOD){
|
||||
type = ((ExecutableElement)element).getReturnType();
|
||||
}
|
||||
String typeName = type.toString();
|
||||
if (typeName.startsWith(Collection.class.getName())
|
||||
|| typeName.startsWith(List.class.getName())
|
||||
|| typeName.startsWith(Set.class.getName())) {
|
||||
type = ((DeclaredType)type).getTypeArguments().get(0);
|
||||
|
||||
} else if (typeName.startsWith(Map.class.getName())){
|
||||
type = ((DeclaredType)type).getTypeArguments().get(1);
|
||||
}
|
||||
|
||||
TypeElement typeElement = typeExtractor.visit(type);
|
||||
if (typeElement != null && typeElement.getAnnotation(configuration.getEntityAnnotation()) == null) {
|
||||
elements.add(typeElement);
|
||||
}
|
||||
}
|
||||
|
||||
process(elements, false, embeddables);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void processEntitiesFromPackage() {
|
||||
Class<? extends Annotation> annotation = configuration.getEntitiesAnnotation();
|
||||
Set<Element> elements = new HashSet<Element>();
|
||||
|
||||
// only creation
|
||||
for (Element element : getElements(annotation)) {
|
||||
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
|
||||
if (mirror.getAnnotationType().asElement().getSimpleName().toString().equals(annotation.getSimpleName())) {
|
||||
for (Map.Entry<? extends ExecutableElement,? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) {
|
||||
if (entry.getKey().getSimpleName().toString().equals("value")) {
|
||||
List<AnnotationValue> values = (List<AnnotationValue>) entry.getValue().getValue();
|
||||
for (AnnotationValue value : values) {
|
||||
DeclaredType type = (DeclaredType) value.getValue();
|
||||
elements.add(type.asElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process(elements, false, entityTypes);
|
||||
}
|
||||
|
||||
private void processFromProperties() {
|
||||
Set<Element> elements = new HashSet<Element>();
|
||||
for (Class<? extends Annotation> annotation : entityAnnotations) {
|
||||
elements.addAll(roundEnv.getElementsAnnotatedWith(annotation));
|
||||
elements.addAll(getElements(annotation));
|
||||
}
|
||||
|
||||
TypeExtractor typeExtractor = new TypeExtractor(true, true);
|
||||
Set<TypeElement> types = new HashSet<TypeElement>();
|
||||
|
||||
// classes
|
||||
for (Element element : elements) {
|
||||
if (element instanceof TypeElement) {
|
||||
TypeElement type = (TypeElement)element;
|
||||
List<? extends Element> children = type.getEnclosedElements();
|
||||
VisitorConfig config = configuration.getConfig(type, children);
|
||||
|
||||
// fields
|
||||
if (config.visitFieldProperties()) {
|
||||
for (VariableElement field : ElementFilter.fieldsIn(children)) {
|
||||
TypeElement typeElement = typeExtractor.handle(field.asType());
|
||||
if (typeElement != null) {
|
||||
types.add(typeElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getters
|
||||
if (config.visitMethodProperties()) {
|
||||
for (ExecutableElement method : ElementFilter.methodsIn(children)) {
|
||||
String name = method.getSimpleName().toString();
|
||||
if (name.startsWith("get") && method.getParameters().isEmpty()) {
|
||||
name = BeanUtils.uncapitalize(name.substring(3));
|
||||
} else if (name.startsWith("is") && method.getParameters().isEmpty()) {
|
||||
name = BeanUtils.uncapitalize(name.substring(2));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
TypeElement typeElement = typeExtractor.handle(method.getReturnType());
|
||||
if (typeElement != null) {
|
||||
types.add(typeElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
processFromProperties((TypeElement)element, types);
|
||||
}
|
||||
}
|
||||
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>(types.size());
|
||||
|
||||
for (TypeElement type : types) {
|
||||
// skip internal types
|
||||
@ -274,53 +364,35 @@ public class Processor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void serializeTypes() {
|
||||
if (!actualSupertypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Supertypes");
|
||||
serialize(configuration.getSupertypeSerializer(), actualSupertypes.values());
|
||||
}
|
||||
|
||||
if (!entityTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Entity types");
|
||||
serialize(configuration.getEntitySerializer(), entityTypes.values());
|
||||
}
|
||||
|
||||
if (!extensionTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Extension types");
|
||||
serialize(configuration.getEmbeddableSerializer(), extensionTypes.values());
|
||||
}
|
||||
|
||||
if (!embeddables.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Embeddable types");
|
||||
serialize(configuration.getEmbeddableSerializer(), embeddables.values());
|
||||
}
|
||||
|
||||
if (!projectionTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Projection types");
|
||||
serialize(configuration.getDTOSerializer(), projectionTypes.values());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void serializeVariableClasses() {
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(Variables.class)) {
|
||||
if (element instanceof PackageElement) {
|
||||
Variables vars = element.getAnnotation(Variables.class);
|
||||
PackageElement packageElement = (PackageElement)element;
|
||||
List<EntityType> models = new ArrayList<EntityType>();
|
||||
for (EntityType model : entityTypes.values()) {
|
||||
if (model.getPackageName().equals(packageElement.getQualifiedName().toString())) {
|
||||
models.add(model);
|
||||
}
|
||||
|
||||
private void processFromProperties(TypeElement type, Set<TypeElement> types) {
|
||||
List<? extends Element> children = type.getEnclosedElements();
|
||||
VisitorConfig config = configuration.getConfig(type, children);
|
||||
|
||||
// fields
|
||||
if (config.visitFieldProperties()) {
|
||||
for (VariableElement field : ElementFilter.fieldsIn(children)) {
|
||||
TypeElement typeElement = typeExtractor.visit(field.asType());
|
||||
if (typeElement != null) {
|
||||
types.add(typeElement);
|
||||
}
|
||||
serializeVariableList(packageElement.getQualifiedName().toString(), vars, models);
|
||||
}
|
||||
}
|
||||
|
||||
// getters
|
||||
if (config.visitMethodProperties()) {
|
||||
for (ExecutableElement method : ElementFilter.methodsIn(children)) {
|
||||
String name = method.getSimpleName().toString();
|
||||
if ((name.startsWith("get") || name.startsWith("is")) && method.getParameters().isEmpty()) {
|
||||
TypeElement typeElement = typeExtractor.visit(method.getReturnType());
|
||||
if (typeElement != null) {
|
||||
types.add(typeElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addSupertypeFields(EntityType model, Map<String, EntityType> superTypes, Set<EntityType> handled) {
|
||||
if (handled.add(model)) {
|
||||
for (Supertype supertype : model.getSuperTypes()) {
|
||||
@ -336,7 +408,7 @@ public class Processor {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Set<Element> getElementsAndCache(Class<? extends Annotation> annotationType) {
|
||||
Set<Element> elements = (Set<Element>)roundEnv.getElementsAnnotatedWith(annotationType);
|
||||
Set<Element> elements = (Set<Element>)getElements(annotationType);
|
||||
if (!elements.isEmpty()) {
|
||||
Set<Element> cached = elementCache.get(annotationType);
|
||||
if (cached == null) {
|
||||
@ -378,28 +450,7 @@ public class Processor {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileObject getSourceFile(String fullName) throws IOException {
|
||||
Elements elementUtils = env.getElementUtils();
|
||||
TypeElement sourceElement = elementUtils.getTypeElement(fullName);
|
||||
if (sourceElement == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (sourceElement.getNestingKind().isNested()) {
|
||||
sourceElement = (TypeElement) sourceElement.getEnclosingElement();
|
||||
}
|
||||
PackageElement packageElement = elementUtils.getPackageOf(sourceElement);
|
||||
try {
|
||||
return env.getFiler().getResource(StandardLocation.SOURCE_PATH,
|
||||
packageElement.getQualifiedName(),
|
||||
sourceElement.getSimpleName() + ".java");
|
||||
} catch(Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void mergeTypes(Map<String, EntityType> types, Deque<Type> superTypes) {
|
||||
// get external supertypes
|
||||
while (!superTypes.isEmpty()) {
|
||||
@ -426,63 +477,19 @@ public class Processor {
|
||||
}
|
||||
}
|
||||
|
||||
private void process(Class<? extends Annotation> annotation, Map<String,EntityType> types) {
|
||||
Deque<Type> superTypes = new ArrayDeque<Type>();
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
|
||||
// only creation
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
List<TypeMirror> superTypeMirrors = new ArrayList<TypeMirror>();
|
||||
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
|
||||
if (configuration.getEmbeddableAnnotation() == null
|
||||
|| element.getAnnotation(configuration.getEmbeddableAnnotation()) == null) {
|
||||
typeFactory.getEntityType(element.asType(), false);
|
||||
typeMirrors.add(element.asType());
|
||||
elements.add(element);
|
||||
|
||||
addAnnotationlessSupertypes(superTypeMirrors, elements, element);
|
||||
}
|
||||
}
|
||||
|
||||
for (TypeMirror typeMirror : superTypeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
// super type handling
|
||||
for (TypeMirror typeMirror : typeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
// get annotated types
|
||||
for (Element element : elements) {
|
||||
EntityType model = elementHandler.handleEntityType((TypeElement) element);
|
||||
registerTypeElement(model.getFullName(), (TypeElement)element);
|
||||
types.put(model.getFullName(), model);
|
||||
if (model.getSuperType() != null) {
|
||||
superTypes.push(model.getSuperType().getType());
|
||||
}
|
||||
}
|
||||
|
||||
mergeTypes(types, superTypes);
|
||||
}
|
||||
|
||||
private boolean hasKnownAnnotation(Element element) {
|
||||
if (configuration.getEmbeddableAnnotation() != null && element.getAnnotation(configuration.getEmbeddableAnnotation()) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (configuration.getSuperTypeAnnotation() != null && element.getAnnotation(configuration.getSuperTypeAnnotation()) != null) {
|
||||
} else if (configuration.getSuperTypeAnnotation() != null && element.getAnnotation(configuration.getSuperTypeAnnotation()) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.getAnnotation(configuration.getEntityAnnotation()) != null) {
|
||||
} else if (element.getAnnotation(configuration.getEntityAnnotation()) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processDelegateMethod(Element delegateMethod, boolean cached) {
|
||||
ExecutableElement method = (ExecutableElement)delegateMethod;
|
||||
Element element = delegateMethod.getEnclosingElement();
|
||||
@ -517,12 +524,12 @@ public class Processor {
|
||||
}
|
||||
|
||||
private void processDelegateMethods() {
|
||||
// 1 : get elements from cache
|
||||
// get elements from cache
|
||||
for (Element delegateMethod : getElementsFromCache(QueryDelegate.class)) {
|
||||
processDelegateMethod(delegateMethod, true);
|
||||
}
|
||||
|
||||
// 2 : get elements from roundEnv
|
||||
// get elements from roundEnv
|
||||
for (Element delegateMethod : getElementsAndCache(QueryDelegate.class)) {
|
||||
processDelegateMethod(delegateMethod, false);
|
||||
}
|
||||
@ -530,7 +537,7 @@ public class Processor {
|
||||
|
||||
private void processProjectionTypes() {
|
||||
Set<Element> visitedDTOTypes = new HashSet<Element>();
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(QueryProjection.class)) {
|
||||
for (Element element : getElements(QueryProjection.class)) {
|
||||
Element parent = element.getEnclosingElement();
|
||||
if (parent.getAnnotation(configuration.getEntityAnnotation()) == null
|
||||
&& parent.getAnnotation(configuration.getEmbeddableAnnotation()) == null
|
||||
@ -542,58 +549,20 @@ public class Processor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processEmbeddables() {
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
List<TypeMirror> superTypeMirrors = new ArrayList<TypeMirror>();
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
|
||||
// only creation
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(configuration.getEmbeddableAnnotation())) {
|
||||
// TODO: Why is this needed if there's no assignment? Just for cache?
|
||||
typeFactory.getEntityType(element.asType(), false);
|
||||
typeMirrors.add(element.asType());
|
||||
elements.add(element);
|
||||
|
||||
addAnnotationlessSupertypes(superTypeMirrors, elements, element);
|
||||
}
|
||||
|
||||
for (TypeMirror typeMirror : superTypeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
// supertype handling
|
||||
for (TypeMirror typeMirror : typeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
for (Element element : elements) {
|
||||
EntityType model = elementHandler.handleEntityType((TypeElement) element);
|
||||
registerTypeElement(model.getFullName(), (TypeElement)element);
|
||||
embeddables.put(model.getFullName(), model);
|
||||
}
|
||||
allSupertypes.putAll(embeddables);
|
||||
|
||||
// add super type fields
|
||||
Set<EntityType> handled = new HashSet<EntityType>();
|
||||
for (EntityType embeddable : embeddables.values()) {
|
||||
addSupertypeFields(embeddable, allSupertypes, handled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void addAnnotationlessSupertypes(List<TypeMirror> superTypeMirrors,
|
||||
List<Element> elements, Element element) {
|
||||
List<TypeElement> elements, TypeElement element) {
|
||||
// add annotationless supertype
|
||||
TypeMirror superTypeMirror = ((TypeElement)element).getSuperclass();
|
||||
TypeMirror superTypeMirror = element.getSuperclass();
|
||||
while (superTypeMirror != null){
|
||||
Element superTypeElement = env.getTypeUtils().asElement(superTypeMirror);
|
||||
TypeElement superTypeElement = (TypeElement) env.getTypeUtils().asElement(superTypeMirror);
|
||||
if (superTypeElement != null
|
||||
&& !superTypeElement.toString().startsWith("java.lang.")
|
||||
&& !hasKnownAnnotation(superTypeElement)) {
|
||||
typeFactory.getEntityType(superTypeMirror, false);
|
||||
superTypeMirrors.add(superTypeMirror);
|
||||
elements.add(superTypeElement);
|
||||
superTypeMirror = ((TypeElement)superTypeElement).getSuperclass();
|
||||
superTypeMirror = superTypeElement.getSuperclass();
|
||||
if (superTypeMirror instanceof NoType) {
|
||||
superTypeMirror = null;
|
||||
}
|
||||
@ -601,112 +570,7 @@ public class Processor {
|
||||
superTypeMirror = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processEmbedded() {
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
|
||||
// only creation
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(configuration.getEmbeddedAnnotation())) {
|
||||
TypeMirror type = element.asType();
|
||||
if (element.getKind() == ElementKind.METHOD){
|
||||
type = ((ExecutableElement)element).getReturnType();
|
||||
}
|
||||
String typeName = type.toString();
|
||||
if (typeName.startsWith(Collection.class.getName())
|
||||
|| typeName.startsWith(List.class.getName())
|
||||
|| typeName.startsWith(Set.class.getName())) {
|
||||
type = ((DeclaredType)type).getTypeArguments().get(0);
|
||||
|
||||
} else if (typeName.startsWith(Map.class.getName())){
|
||||
type = ((DeclaredType)type).getTypeArguments().get(1);
|
||||
}
|
||||
typeFactory.getEntityType(type, false);
|
||||
typeMirrors.add(type);
|
||||
}
|
||||
|
||||
// supertype handling
|
||||
for (TypeMirror typeMirror : typeMirrors) {
|
||||
typeFactory.getEntityType(typeMirror, true);
|
||||
}
|
||||
|
||||
// deep
|
||||
for (TypeMirror type : typeMirrors) {
|
||||
// remove generic signature of type for TypeElement lookup
|
||||
String typeName = type.toString();
|
||||
if (typeName.contains("<")) {
|
||||
typeName = typeName.substring(0, typeName.indexOf('<'));
|
||||
}
|
||||
TypeElement typeElement = env.getElementUtils().getTypeElement(typeName);
|
||||
if (typeElement == null) {
|
||||
continue;
|
||||
} else if (typeElement.getAnnotation(configuration.getEntityAnnotation()) != null){
|
||||
// skip Entity types here
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityType model = elementHandler.handleEntityType(typeElement);
|
||||
registerTypeElement(model.getFullName(), typeElement);
|
||||
embeddables.put(model.getFullName(), model);
|
||||
}
|
||||
allSupertypes.putAll(embeddables);
|
||||
|
||||
// add super type fields
|
||||
Set<EntityType> handled = new HashSet<EntityType>();
|
||||
for (EntityType embeddable : embeddables.values()) {
|
||||
addSupertypeFields(embeddable, allSupertypes, handled);
|
||||
}
|
||||
}
|
||||
|
||||
private void processEntities() {
|
||||
process(configuration.getEntityAnnotation(), entityTypes);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void processEntitiesFromPackage() {
|
||||
Class<? extends Annotation> annotation = configuration.getEntitiesAnnotation();
|
||||
List<TypeMirror> typeMirrors = new ArrayList<TypeMirror>();
|
||||
|
||||
// only creation
|
||||
for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
|
||||
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
|
||||
if (mirror.getAnnotationType().asElement().getSimpleName().toString().equals(QueryEntities.class.getSimpleName())) {
|
||||
for (Map.Entry<? extends ExecutableElement,? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) {
|
||||
if (entry.getKey().getSimpleName().toString().equals("value")) {
|
||||
List<AnnotationValue> values = (List<AnnotationValue>) entry.getValue().getValue();
|
||||
for (AnnotationValue value : values) {
|
||||
TypeMirror type = (TypeMirror) value.getValue();
|
||||
typeFactory.getEntityType(type, false);
|
||||
typeMirrors.add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String,EntityType> types = entityTypes;
|
||||
Deque<Type> superTypes = new ArrayDeque<Type>();
|
||||
|
||||
// get annotated types
|
||||
for (TypeMirror mirror : typeMirrors) {
|
||||
typeFactory.getEntityType(mirror, true);
|
||||
TypeElement element = (TypeElement) env.getTypeUtils().asElement(mirror);
|
||||
EntityType model = elementHandler.handleEntityType(element);
|
||||
registerTypeElement(model.getFullName(), element);
|
||||
types.put(model.getFullName(), model);
|
||||
if (model.getSuperType() != null) {
|
||||
superTypes.push(model.getSuperType().getType());
|
||||
}
|
||||
}
|
||||
|
||||
mergeTypes(types, superTypes);
|
||||
}
|
||||
|
||||
private void processSupertypes() {
|
||||
process(configuration.getSuperTypeAnnotation(), actualSupertypes);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerTypeElement(String entityName, TypeElement element) {
|
||||
Set<TypeElement> elements = typeElements.get(entityName);
|
||||
@ -716,6 +580,73 @@ public class Processor {
|
||||
}
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
// SERIALIZATION
|
||||
|
||||
private void serializeTypes() {
|
||||
if (!actualSupertypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Supertypes");
|
||||
serialize(configuration.getSupertypeSerializer(), actualSupertypes.values());
|
||||
}
|
||||
|
||||
if (!entityTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Entity types");
|
||||
serialize(configuration.getEntitySerializer(), entityTypes.values());
|
||||
}
|
||||
|
||||
if (!extensionTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Extension types");
|
||||
serialize(configuration.getEmbeddableSerializer(), extensionTypes.values());
|
||||
}
|
||||
|
||||
if (!embeddables.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Embeddable types");
|
||||
serialize(configuration.getEmbeddableSerializer(), embeddables.values());
|
||||
}
|
||||
|
||||
if (!projectionTypes.isEmpty()) {
|
||||
env.getMessager().printMessage(Kind.NOTE, "Serializing Projection types");
|
||||
serialize(configuration.getDTOSerializer(), projectionTypes.values());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void serializeVariableClasses() {
|
||||
for (Element element : getElements(Variables.class)) {
|
||||
if (element instanceof PackageElement) {
|
||||
Variables vars = element.getAnnotation(Variables.class);
|
||||
PackageElement packageElement = (PackageElement)element;
|
||||
List<EntityType> models = new ArrayList<EntityType>();
|
||||
for (EntityType model : entityTypes.values()) {
|
||||
if (model.getPackageName().equals(packageElement.getQualifiedName().toString())) {
|
||||
models.add(model);
|
||||
}
|
||||
}
|
||||
serializeVariableList(packageElement.getQualifiedName().toString(), vars, models);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FileObject getSourceFile(String fullName) throws IOException {
|
||||
Elements elementUtils = env.getElementUtils();
|
||||
TypeElement sourceElement = elementUtils.getTypeElement(fullName);
|
||||
if (sourceElement == null) {
|
||||
return null;
|
||||
} else {
|
||||
if (sourceElement.getNestingKind().isNested()) {
|
||||
sourceElement = (TypeElement) sourceElement.getEnclosingElement();
|
||||
}
|
||||
PackageElement packageElement = elementUtils.getPackageOf(sourceElement);
|
||||
try {
|
||||
return env.getFiler().getResource(StandardLocation.SOURCE_PATH,
|
||||
packageElement.getQualifiedName(),
|
||||
sourceElement.getSimpleName() + ".java");
|
||||
} catch(Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void serialize(Serializer serializer, Collection<EntityType> models) {
|
||||
Messager msg = env.getMessager();
|
||||
|
||||
@ -34,14 +34,13 @@ import com.mysema.query.codegen.TypeMappings;
|
||||
import com.mysema.util.BeanUtils;
|
||||
|
||||
/**
|
||||
* ElementHandler is a an APT visitor for entity types
|
||||
* TypeElementHandler is a an APT visitor for entity types
|
||||
*
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
@Immutable
|
||||
// TODO : rename
|
||||
public final class ElementHandler{
|
||||
public final class TypeElementHandler {
|
||||
|
||||
private final TypeMappings typeMappings;
|
||||
|
||||
@ -51,7 +50,7 @@ public final class ElementHandler{
|
||||
|
||||
private final ExtendedTypeFactory typeFactory;
|
||||
|
||||
public ElementHandler(Configuration configuration, ExtendedTypeFactory typeFactory,
|
||||
public TypeElementHandler(Configuration configuration, ExtendedTypeFactory typeFactory,
|
||||
TypeMappings typeMappings, QueryTypeFactory queryTypeFactory) {
|
||||
this.configuration = configuration;
|
||||
this.typeFactory = typeFactory;
|
||||
@ -1,49 +1,52 @@
|
||||
package com.mysema.query.apt;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.ArrayType;
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
import javax.lang.model.type.ErrorType;
|
||||
import javax.lang.model.type.ExecutableType;
|
||||
import javax.lang.model.type.NoType;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
import javax.lang.model.type.NullType;
|
||||
import javax.lang.model.type.PrimitiveType;
|
||||
import javax.lang.model.type.TypeVariable;
|
||||
import javax.lang.model.type.WildcardType;
|
||||
import javax.lang.model.util.AbstractTypeVisitor6;
|
||||
|
||||
public class TypeExtractor {
|
||||
/**
|
||||
* @author tiwe
|
||||
*
|
||||
*/
|
||||
public class TypeExtractor extends AbstractTypeVisitor6<TypeElement, Void> {
|
||||
|
||||
private final boolean skipPrimitive, skipEnum;
|
||||
private final boolean skipEnum;
|
||||
|
||||
public TypeExtractor(boolean skipPrimitive, boolean skipEnum) {
|
||||
this.skipPrimitive = skipPrimitive;
|
||||
public TypeExtractor(boolean skipEnum) {
|
||||
this.skipEnum = skipEnum;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TypeElement handle(TypeMirror typeMirror) {
|
||||
if (typeMirror instanceof DeclaredType) {
|
||||
return handleDeclaredType((DeclaredType)typeMirror);
|
||||
} else if (typeMirror instanceof TypeVariable) {
|
||||
return handleTypeVariable((TypeVariable)typeMirror);
|
||||
} else if (typeMirror instanceof WildcardType) {
|
||||
return handleWildcard((WildcardType)typeMirror);
|
||||
} else if (typeMirror instanceof ArrayType) {
|
||||
ArrayType t = (ArrayType)typeMirror;
|
||||
return handle(t.getComponentType());
|
||||
} else if (typeMirror instanceof NoType) {
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public TypeElement visitPrimitive(PrimitiveType t, Void p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleDeclaredType(DeclaredType typeMirror) {
|
||||
if (typeMirror.asElement() instanceof TypeElement) {
|
||||
TypeElement typeElement = (TypeElement)typeMirror.asElement();
|
||||
|
||||
@Override
|
||||
public TypeElement visitNull(NullType t, Void p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeElement visitArray(ArrayType t, Void p) {
|
||||
return visit(t.getComponentType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeElement visitDeclared(DeclaredType t, Void p) {
|
||||
if (t.asElement() instanceof TypeElement) {
|
||||
TypeElement typeElement = (TypeElement)t.asElement();
|
||||
switch (typeElement.getKind()) {
|
||||
case ENUM: return handleEnumType(typeMirror, typeElement);
|
||||
case CLASS: return handleClassType(typeMirror, typeElement);
|
||||
case INTERFACE: return handleInterfaceType(typeMirror, typeElement);
|
||||
case ENUM: return skipEnum ? null : typeElement;
|
||||
case CLASS: return typeElement;
|
||||
case INTERFACE: return visit(t.getTypeArguments().get(t.getTypeArguments().size()-1));
|
||||
default: throw new IllegalArgumentException("Illegal type " + typeElement);
|
||||
}
|
||||
} else {
|
||||
@ -51,41 +54,34 @@ public class TypeExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleWildcard(WildcardType typeMirror) {
|
||||
return handle(typeMirror.getExtendsBound());
|
||||
@Override
|
||||
public TypeElement visitError(ErrorType t, Void p) {
|
||||
return visitDeclared(t, p);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleTypeVariable(TypeVariable typeMirror) {
|
||||
if (typeMirror.getUpperBound() != null) {
|
||||
return handle(typeMirror.getUpperBound());
|
||||
@Override
|
||||
public TypeElement visitTypeVariable(TypeVariable t, Void p) {
|
||||
if (t.getUpperBound() != null) {
|
||||
return visit(t.getUpperBound());
|
||||
} else {
|
||||
return handle(typeMirror.getLowerBound());
|
||||
return visit(t.getLowerBound());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleInterfaceType(DeclaredType typeMirror, TypeElement typeElement) {
|
||||
return handle(typeMirror.getTypeArguments().get(typeMirror.getTypeArguments().size()-1));
|
||||
@Override
|
||||
public TypeElement visitWildcard(WildcardType t, Void p) {
|
||||
return visit(t.getExtendsBound());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleClassType(DeclaredType typeMirror, TypeElement typeElement) {
|
||||
if (skipPrimitive && typeMirror.getKind().isPrimitive()) {
|
||||
return null;
|
||||
} else {
|
||||
return typeElement;
|
||||
}
|
||||
@Override
|
||||
public TypeElement visitExecutable(ExecutableType t, Void p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private TypeElement handleEnumType(DeclaredType typeMirror, TypeElement typeElement) {
|
||||
if (skipEnum) {
|
||||
return null;
|
||||
} else {
|
||||
return typeElement;
|
||||
}
|
||||
@Override
|
||||
public TypeElement visitNoType(NoType t, Void p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -15,33 +15,33 @@ public enum VisitorConfig {
|
||||
/**
|
||||
* visit both fields and getters
|
||||
*/
|
||||
ALL(true,true),
|
||||
ALL(true, true, true),
|
||||
|
||||
/**
|
||||
* visit fields only
|
||||
*/
|
||||
FIELDS_ONLY(true,false),
|
||||
FIELDS_ONLY(true, false, true),
|
||||
|
||||
/**
|
||||
* visit methods only
|
||||
*/
|
||||
METHODS_ONLY(false,true),
|
||||
METHODS_ONLY(false, true, true),
|
||||
|
||||
/**
|
||||
* visit none
|
||||
*/
|
||||
NONE(false,false);
|
||||
NONE(false, false, false);
|
||||
|
||||
private final boolean visitFieldProperties, visitMethodProperties;
|
||||
private final boolean visitFieldProperties, visitMethodProperties, visitConstructors;
|
||||
|
||||
VisitorConfig(boolean fields, boolean methods) {
|
||||
VisitorConfig(boolean fields, boolean methods, boolean constructors) {
|
||||
this.visitFieldProperties = fields;
|
||||
this.visitMethodProperties = methods;
|
||||
this.visitConstructors = constructors;
|
||||
}
|
||||
|
||||
public boolean visitConstructors() {
|
||||
// TODO : parametrize!
|
||||
return true;
|
||||
return visitConstructors;
|
||||
}
|
||||
|
||||
public boolean visitFieldProperties() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user