diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java index ba2417cb8..2256817b1 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java @@ -1,6 +1,6 @@ /* * Copyright 2011, Mysema Ltd - * + * * 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 @@ -64,94 +64,94 @@ import com.mysema.query.codegen.TypeMappings; /** * Base class for Querydsl annotation processors, contains the main processing logic. The subclasses * just provide the configuration. - * + * * @author tiwe * */ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { - - private static final Set delegateMethods = new HashSet(); - + + private static final Set DELEGATE_METHODS = new HashSet(); + public static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE; - + private final TypeExtractor typeExtractor = new TypeExtractor(true); - + private Configuration conf; - + private RoundEnvironment roundEnv; - + private ExtendedTypeFactory typeFactory; - + private TypeElementHandler elementHandler; - + private Context context; - + @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { + public boolean process(Set annotations, RoundEnvironment roundEnv) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName()); - + if (roundEnv.processingOver() || annotations.size() == 0) { return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } - + if (roundEnv.getRootElements() == null || roundEnv.getRootElements().isEmpty()) { processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "No sources to process"); return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } - + conf = createConfiguration(roundEnv); - context = new Context(); - Set> entityAnnotations = conf.getEntityAnnotations(); + context = new Context(); + Set> entityAnnotations = conf.getEntityAnnotations(); TypeMappings typeMappings = conf.getTypeMappings(); QueryTypeFactory queryTypeFactory = conf.getQueryTypeFactory(); this.typeFactory = new ExtendedTypeFactory(processingEnv, conf, entityAnnotations, typeMappings, queryTypeFactory); elementHandler = new TypeElementHandler(conf, typeFactory, typeMappings, queryTypeFactory); this.roundEnv = roundEnv; - + // process annotations - processAnnotations(); - + processAnnotations(); + validateMetaTypes(); - + // serialize created types - serializeMetaTypes(); - + serializeMetaTypes(); + return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } - - private void processAnnotations() { - processExclusions(); - - Set elements = collectElements(); - + + private void processAnnotations() { + processExclusions(); + + Set elements = collectElements(); + // create meta models for (Element element : elements) { - typeFactory.getEntityType(element.asType(), false); + typeFactory.getEntityType(element.asType(), false); } for (Element element : elements) { - typeFactory.getEntityType(element.asType(), true); + typeFactory.getEntityType(element.asType(), true); } - + // add properties boolean embeddableAnn = conf.getEmbeddableAnnotation() != null; boolean superAnn = conf.getSuperTypeAnnotation() != null; - for (Element element : elements) { - EntityType entityType = elementHandler.handleEntityType((TypeElement)element); - registerTypeElement(entityType.getFullName(), (TypeElement)element); + for (TypeElement element : elements) { + EntityType entityType = elementHandler.handleEntityType(element); + registerTypeElement(entityType.getFullName(), element); if (element.getAnnotation(conf.getEntityAnnotation()) != null) { context.entityTypes.put(entityType.getFullName(), entityType); } else if (embeddableAnn && element.getAnnotation(conf.getEmbeddableAnnotation()) != null ) { context.embeddableTypes.put(entityType.getFullName(), entityType); } else if (superAnn && element.getAnnotation(conf.getSuperTypeAnnotation()) != null) { context.supertypes.put(entityType.getFullName(), entityType); - } else if (!entityType.getDelegates().isEmpty()) { + } else if (!entityType.getDelegates().isEmpty()) { context.extensionTypes.put(entityType.getFullName(), entityType); } else { context.embeddableTypes.put(entityType.getFullName(), entityType); - } + } context.allTypes.put(entityType.getFullName(), entityType); } - + // track also methods from external entity types for (EntityType entityType : new ArrayList(typeFactory.getEntityTypes())) { String fullName = entityType.getFullName(); @@ -163,34 +163,34 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - + // add external parents for (Element element : elements) { EntityType entityType = typeFactory.getEntityType(element.asType(), false); addExternalParents(entityType); } - + // add properties from parents Set handled = new HashSet(); - for (EntityType entityType : context.allTypes.values()) { + for (EntityType entityType : context.allTypes.values()) { addSupertypeFields(entityType, handled); } - + processProjectionTypes(elements); - + // extend entity types typeFactory.extendTypes(); - - context.clean(); - + + context.clean(); + } private void addExternalParents(EntityType entityType) { Deque superTypes = new ArrayDeque(); if (entityType.getSuperType() != null) { - superTypes.push(entityType.getSuperType().getType()); + superTypes.push(entityType.getSuperType().getType()); } - + while (!superTypes.isEmpty()) { Type superType = superTypes.pop(); if (!context.allTypes.containsKey(superType.getFullName())) { @@ -203,49 +203,53 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { superTypes.push(superEntityType.getSuperType().getType()); } context.allTypes.put(superType.getFullName(), superEntityType); - } + } } - + } - protected Set collectElements() { - Set elements = new HashSet(); - + protected Set collectElements() { + Set elements = new HashSet(); + // from delegate methods elements.addAll(processDelegateMethods()); // from class annotations for (Class annotation : conf.getEntityAnnotations()) { - elements.addAll(getElements(annotation)); - } - + for (Element element : getElements(annotation)) { + if (element instanceof TypeElement) { + elements.add((TypeElement) element); + } + } + } + // from package annotations if (conf.getEntitiesAnnotation() != null) { for (Element element : getElements(conf.getEntitiesAnnotation())) { AnnotationMirror mirror = TypeUtils.getAnnotationMirrorOfType(element, conf.getEntitiesAnnotation()); elements.addAll(TypeUtils.getAnnotationValuesAsElements(mirror, "value")); } - } - + } + // from embedded annotations if (conf.getEmbeddedAnnotation() != null) { elements.addAll(getEmbeddedTypes()); } - + // from embedded if (conf.isUnknownAsEmbedded()) { elements.addAll(getTypeFromProperties(elements)); } - + // from annotation less supertypes elements.addAll(getAnnotationlessSupertypes(elements)); - + // register possible embedded types of non-tracked supertypes if (conf.getEmbeddedAnnotation() != null) { Class embedded = conf.getEmbeddedAnnotation(); - Set embeddedElements = new HashSet(); - for (Element element : elements) { - TypeMirror superTypeMirror = ((TypeElement)element).getSuperclass(); + Set embeddedElements = new HashSet(); + for (TypeElement element : elements) { + TypeMirror superTypeMirror = element.getSuperclass(); while (superTypeMirror != null) { TypeElement superTypeElement = (TypeElement) processingEnv.getTypeUtils().asElement(superTypeMirror); if (superTypeElement != null) { @@ -254,7 +258,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { if (child.getAnnotation(embedded) != null) { handleEmbeddedType(child, embeddedElements); } - } + } superTypeMirror = superTypeElement.getSuperclass(); if (superTypeMirror instanceof NoType) { superTypeMirror = null; @@ -264,29 +268,29 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - + // register found elements - for (Element element : embeddedElements) { + for (TypeElement element : embeddedElements) { if (!elements.contains(element)) { - elementHandler.handleEntityType((TypeElement)element); + elementHandler.handleEntityType(element); } } } - - + + return elements; } - - private Set getAnnotationlessSupertypes(Set elements) { - Set rv = new HashSet(); - for (Element element : elements) { - TypeMirror superTypeMirror = ((TypeElement)element).getSuperclass(); + + private Set getAnnotationlessSupertypes(Set elements) { + Set rv = new HashSet(); + for (TypeElement element : elements) { + TypeMirror superTypeMirror = element.getSuperclass(); while (superTypeMirror != null) { TypeElement superTypeElement = (TypeElement) processingEnv.getTypeUtils().asElement(superTypeMirror); - if (superTypeElement != null - && !superTypeElement.toString().startsWith("java.lang.") + if (superTypeElement != null + && !superTypeElement.toString().startsWith("java.lang.") && !TypeUtils.hasAnnotationOfType(superTypeElement, conf.getEntityAnnotations())) { - rv.add(superTypeElement); + rv.add(superTypeElement); superTypeMirror = superTypeElement.getSuperclass(); if (superTypeMirror instanceof NoType) { superTypeMirror = null; @@ -294,11 +298,11 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } else { superTypeMirror = null; } - } + } } return rv; - } - + } + private void registerTypeElement(String entityName, TypeElement element) { Set elements = context.typeElements.get(entityName); if (elements == null) { @@ -307,8 +311,8 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } elements.add(element); } - - private void processProjectionTypes(Set elements) { + + private void processProjectionTypes(Set elements) { Set visited = new HashSet(); for (Element element : getElements(QueryProjection.class)) { Element parent = element.getEnclosingElement(); @@ -320,19 +324,17 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - - private Set getEmbeddedTypes() { - Set elements = new HashSet(); + private Set getEmbeddedTypes() { + Set elements = new HashSet(); // only creation for (Element element : getElements(conf.getEmbeddedAnnotation())) { handleEmbeddedType(element, elements); } - - return elements; + return elements; } - private void handleEmbeddedType(Element element, Set elements) { + private void handleEmbeddedType(Element element, Set elements) { TypeMirror type = element.asType(); if (element.getKind() == ElementKind.METHOD) { type = ((ExecutableElement)element).getReturnType(); @@ -343,29 +345,29 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { || 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 && !TypeUtils.hasAnnotationOfType(typeElement, conf.getEntityAnnotations())) { if (!typeElement.getQualifiedName().toString().startsWith("java.")) { - elements.add(typeElement); - } + elements.add(typeElement); + } } - } + } - private Set getTypeFromProperties(Set parents) { + private Set getTypeFromProperties(Set parents) { Set elements = new HashSet(); for (Element element : parents) { if (element instanceof TypeElement) { - processFromProperties((TypeElement)element, elements); + processFromProperties((TypeElement)element, elements); } } - - Iterator iterator = elements.iterator(); + + Iterator iterator = elements.iterator(); while (iterator.hasNext()) { TypeElement element = iterator.next(); String name = element.getQualifiedName().toString(); @@ -381,14 +383,14 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - + return elements; } - + private void processFromProperties(TypeElement type, Set types) { List children = type.getEnclosedElements(); VisitorConfig config = conf.getConfig(type, children); - + // fields if (config.visitFieldProperties()) { for (VariableElement field : ElementFilter.fieldsIn(children)) { @@ -398,7 +400,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - + // getters if (config.visitMethodProperties()) { for (ExecutableElement method : ElementFilter.methodsIn(children)) { @@ -407,8 +409,8 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { TypeElement typeElement = typeExtractor.visit(method.getReturnType()); if (typeElement != null) { types.add(typeElement); - } - } + } + } } } } @@ -425,7 +427,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - + private void processExclusions() { for (Element element : getElements(QueryExclude.class)) { if (element instanceof PackageElement) { @@ -437,28 +439,28 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } } - - private Set processDelegateMethods() { - Set elements = new HashSet(); - elements.addAll(getElements(QueryDelegate.class)); - for (Element element : delegateMethods) { + + private Set processDelegateMethods() { + Set delegateMethods = new HashSet(); + delegateMethods.addAll(getElements(QueryDelegate.class)); + for (Element element : DELEGATE_METHODS) { TypeElement parent = (TypeElement)element.getEnclosingElement(); // replace with element from current session parent = processingEnv.getElementUtils().getTypeElement(parent.getQualifiedName().toString()); if (parent != null) { for (Element child : parent.getEnclosedElements()) { if (child.getKind() == element.getKind() && child.getSimpleName().equals(element.getSimpleName())) { - elements.add(child); + delegateMethods.add(child); } - } - } + } + } } - delegateMethods.clear(); - delegateMethods.addAll(elements); - - Set typeElements = new HashSet(); - - for (Element delegateMethod : elements) { + DELEGATE_METHODS.clear(); + DELEGATE_METHODS.addAll(delegateMethods); + + Set typeElements = new HashSet(); + + for (Element delegateMethod : delegateMethods) { ExecutableElement method = (ExecutableElement)delegateMethod; Element element = delegateMethod.getEnclosingElement(); String name = method.getSimpleName().toString(); @@ -474,11 +476,11 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { TypeMirror type = TypeUtils.getAnnotationValueAsTypeMirror(annotation, "value"); if (type != null) { entityType = typeFactory.getEntityType(type, true); - } + } } } - if (entityType != null) { + if (entityType != null) { registerTypeElement(entityType.getFullName(), (TypeElement)element); entityType.addDelegate(new Delegate(entityType, delegateType, name, parameters, returnType)); TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(entityType.getFullName()); @@ -490,18 +492,18 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } if (isAnnotated) { // handle also properties of entity type - typeElements.add(processingEnv.getElementUtils().getTypeElement(entityType.getFullName())); + typeElements.add(processingEnv.getElementUtils().getTypeElement(entityType.getFullName())); } else { // skip handling properties context.extensionTypes.put(entityType.getFullName(), entityType); - context.allTypes.put(entityType.getFullName(), entityType); - } + context.allTypes.put(entityType.getFullName(), entityType); + } } } - + return typeElements; } - + private void validateMetaTypes() { for (Collection entityTypes : Arrays.asList( context.supertypes.values(), @@ -524,14 +526,14 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { if (!init.startsWith("*") && property.getType() instanceof EntityType) { String initProperty = init.contains(".") ? init.substring(0, init.indexOf('.')) : init; if (!((EntityType)property.getType()).getPropertyNames().contains(initProperty)) { - processingEnv.getMessager().printMessage(Kind.ERROR, + processingEnv.getMessager().printMessage(Kind.ERROR, "Illegal inits of " + entityType.getFullName()+ "." + property.getName() + ": " + initProperty + " not found"); } } } } - + private void serializeMetaTypes() { if (!context.supertypes.isEmpty()) { processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Supertypes"); @@ -559,30 +561,30 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } - + private Set getElements(Class a) { return roundEnv.getElementsAnnotatedWith(a); } - + @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.latest(); } - + private void serialize(Serializer serializer, Collection models) { - for (EntityType model : models) { + for (EntityType model : models) { try { Type type = conf.getTypeMappings().getPathType(model, model, true); String packageName = type.getPackageName(); String className = !packageName.isEmpty() ? (packageName + "." + type.getSimpleName()) : type.getSimpleName(); - + // skip if type is excluded class or in excluded package if (conf.isExcludedPackage(model.getPackageName()) || conf.isExcludedClass(model.getFullName())) { continue; - } - + } + Set elements = context.typeElements.get(model.getFullName()); - + if (elements == null) { elements = new HashSet(); } @@ -596,7 +598,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } processingEnv.getMessager().printMessage(Kind.NOTE, "Generating " + className + " for " + elements); - JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(className, + JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(className, elements.toArray(new Element[elements.size()])); Writer writer = fileObject.openWriter(); try { @@ -607,7 +609,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { writer.close(); } } - + } catch (IOException e) { e.printStackTrace(); processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage()); @@ -615,7 +617,7 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { } } - + protected abstract Configuration createConfiguration(RoundEnvironment roundEnv); } diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java b/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java index 364a619c7..020eab908 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java +++ b/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java @@ -1,6 +1,6 @@ /* * Copyright 2011, Mysema Ltd - * + * * 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 @@ -23,12 +23,13 @@ import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; /** * Various utility classes for {@link Element} and {@link AnnotationMirror} handling - * + * * @author tiwe * */ @@ -42,11 +43,11 @@ public final class TypeUtils { } return false; } - + public static boolean hasAnnotationOfType(Element element, Class annotation) { return element.getAnnotation(annotation) != null; } - + public static AnnotationMirror getAnnotationMirrorOfType(Element element, Class annotation) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { if (mirror.getAnnotationType().toString().equals(annotation.getName())) { @@ -55,39 +56,39 @@ public final class TypeUtils { } return null; } - + public static boolean isAnnotationMirrorOfType(AnnotationMirror annotationMirror, Class clazz) { return isAnnotationMirrorOfType(annotationMirror, clazz.getName()); } - + public static boolean isAnnotationMirrorOfType(AnnotationMirror annotationMirror, String className) { String annotationClassName = annotationMirror.getAnnotationType().toString(); return annotationClassName.equals(className); } - - public static Set getAnnotationValuesAsElements(AnnotationMirror mirror, String method) { - Set elements = new HashSet(); + + public static Set getAnnotationValuesAsElements(AnnotationMirror mirror, String method) { + Set elements = new HashSet(); for (Map.Entry entry : mirror.getElementValues().entrySet()) { if (entry.getKey().getSimpleName().toString().equals(method)) { List values = ((List) entry.getValue().getValue()); for (AnnotationValue value : values) { DeclaredType type = (DeclaredType) value.getValue(); - elements.add(type.asElement()); + elements.add((TypeElement) type.asElement()); } } } return elements; } - + public static TypeMirror getAnnotationValueAsTypeMirror(AnnotationMirror mirror, String method) { for (Map.Entry entry : mirror.getElementValues().entrySet()) { if (entry.getKey().getSimpleName().toString().equals(method)) { - return (TypeMirror) entry.getValue().getValue(); + return (TypeMirror) entry.getValue().getValue(); } } return null; } - + private TypeUtils() {} - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java new file mode 100644 index 000000000..a7953bc12 --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java @@ -0,0 +1,8 @@ +package com.mysema.query.domain.p7; + +import javax.persistence.Entity; + +@Entity +public class MyEntity { + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p7/package-info.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p7/package-info.java new file mode 100644 index 000000000..521888679 --- /dev/null +++ b/querydsl-apt/src/test/java/com/mysema/query/domain/p7/package-info.java @@ -0,0 +1,4 @@ +@MappedSuperclass +package com.mysema.query.domain.p7; + +import javax.persistence.MappedSuperclass;