Search in sources :

Example 41 with Element

use of javax.lang.model.element.Element in project requery by requery.

the class AttributeMember method processAssociativeAnnotations.

private void processAssociativeAnnotations(ProcessingEnvironment processingEnvironment, ElementValidator validator) {
    Optional<Annotation> oneToOne = annotationOf(OneToOne.class);
    Optional<Annotation> oneToMany = annotationOf(OneToMany.class);
    Optional<Annotation> manyToOne = annotationOf(ManyToOne.class);
    Optional<Annotation> manyToMany = annotationOf(ManyToMany.class);
    oneToOne = oneToOne.isPresent() ? oneToOne : annotationOf(javax.persistence.OneToOne.class);
    oneToMany = oneToMany.isPresent() ? oneToMany : annotationOf(javax.persistence.OneToMany.class);
    manyToOne = manyToOne.isPresent() ? manyToOne : annotationOf(javax.persistence.ManyToOne.class);
    manyToMany = manyToMany.isPresent() ? manyToMany : annotationOf(javax.persistence.ManyToMany.class);
    if (Stream.of(oneToOne, oneToMany, manyToOne, manyToMany).filter(Optional::isPresent).count() > 1) {
        validator.error("Cannot have more than one associative annotation per field");
    }
    if (oneToOne.isPresent()) {
        cardinality = Cardinality.ONE_TO_ONE;
        ReflectiveAssociation reflect = new ReflectiveAssociation(oneToOne.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        if (!isForeignKey()) {
            isReadOnly = true;
            if (!isKey()) {
                isUnique = true;
            }
        }
    }
    if (oneToMany.isPresent()) {
        isIterable = true;
        cardinality = Cardinality.ONE_TO_MANY;
        isReadOnly = true;
        ReflectiveAssociation reflect = new ReflectiveAssociation(oneToMany.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        checkIterable(validator);
        processOrderBy();
    }
    if (manyToOne.isPresent()) {
        cardinality = Cardinality.MANY_TO_ONE;
        isForeignKey = true;
        ReflectiveAssociation reflect = new ReflectiveAssociation(manyToOne.get());
        cascadeActions = reflect.cascade();
        if (deleteAction == null) {
            deleteAction = ReferentialAction.CASCADE;
        }
        if (updateAction == null) {
            updateAction = ReferentialAction.CASCADE;
        }
    }
    if (manyToMany.isPresent()) {
        isIterable = true;
        cardinality = Cardinality.MANY_TO_MANY;
        ReflectiveAssociation reflect = new ReflectiveAssociation(manyToMany.get());
        mappedBy = reflect.mappedBy();
        cascadeActions = reflect.cascade();
        Optional<JunctionTable> junctionTable = annotationOf(JunctionTable.class);
        Optional<javax.persistence.JoinTable> joinTable = annotationOf(javax.persistence.JoinTable.class);
        if (junctionTable.isPresent()) {
            Elements elements = processingEnvironment.getElementUtils();
            associativeDescriptor = new JunctionTableAssociation(elements, this, junctionTable.get());
        } else if (joinTable.isPresent()) {
            associativeDescriptor = new JoinTableAssociation(joinTable.get());
        }
        isReadOnly = true;
        checkIterable(validator);
        processOrderBy();
    }
    if (isForeignKey()) {
        if (deleteAction == ReferentialAction.SET_NULL && !isNullable()) {
            validator.error("Cannot SET_NULL on optional attribute", ForeignKey.class);
        }
        // user mirror so generated type can be referenced
        Optional<? extends AnnotationMirror> mirror = Mirrors.findAnnotationMirror(element(), ForeignKey.class);
        if (mirror.isPresent()) {
            referencedType = mirror.flatMap(m -> Mirrors.findAnnotationValue(m, "references")).map(value -> value.getValue().toString()).orElse(null);
        } else if (!typeMirror().getKind().isPrimitive()) {
            referencedType = typeMirror().toString();
        }
    }
}
Also used : Arrays(java.util.Arrays) Nullable(io.requery.Nullable) Modifier(javax.lang.model.element.Modifier) Lazy(io.requery.Lazy) TypeElement(javax.lang.model.element.TypeElement) Elements(javax.lang.model.util.Elements) ForeignKey(io.requery.ForeignKey) EnumType(javax.persistence.EnumType) ConstraintMode(javax.persistence.ConstraintMode) OrderBy(io.requery.OrderBy) Locale(java.util.Locale) Map(java.util.Map) OneToOne(io.requery.OneToOne) PropertyNameStyle(io.requery.PropertyNameStyle) Enumerated(javax.persistence.Enumerated) OneToMany(io.requery.OneToMany) EnumSet(java.util.EnumSet) Index(io.requery.Index) CascadeType(javax.persistence.CascadeType) Naming(io.requery.Naming) Set(java.util.Set) ReadOnly(io.requery.ReadOnly) Element(javax.lang.model.element.Element) Types(javax.lang.model.util.Types) Version(io.requery.Version) TypeKind(javax.lang.model.type.TypeKind) ManyToOne(io.requery.ManyToOne) Basic(javax.persistence.Basic) SourceVersion(javax.lang.model.SourceVersion) GenerationType(javax.persistence.GenerationType) List(java.util.List) Cardinality(io.requery.meta.Cardinality) Stream(java.util.stream.Stream) GeneratedValue(javax.persistence.GeneratedValue) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) MapAttributeBuilder(io.requery.meta.MapAttributeBuilder) ListAttributeBuilder(io.requery.meta.ListAttributeBuilder) Key(io.requery.Key) Transient(io.requery.Transient) JunctionTable(io.requery.JunctionTable) VariableElement(javax.lang.model.element.VariableElement) SetAttributeBuilder(io.requery.meta.SetAttributeBuilder) Convert(io.requery.Convert) ReferentialAction(io.requery.ReferentialAction) Embedded(io.requery.Embedded) ElementFilter(javax.lang.model.util.ElementFilter) LinkedHashSet(java.util.LinkedHashSet) ElementKind(javax.lang.model.element.ElementKind) ExecutableElement(javax.lang.model.element.ExecutableElement) JoinColumn(javax.persistence.JoinColumn) EnumOrdinalConverter(io.requery.converter.EnumOrdinalConverter) ResultAttributeBuilder(io.requery.meta.ResultAttributeBuilder) Generated(io.requery.Generated) Order(io.requery.query.Order) AnnotationMirror(javax.lang.model.element.AnnotationMirror) CascadeAction(io.requery.CascadeAction) TypeMirror(javax.lang.model.type.TypeMirror) Column(io.requery.Column) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) FetchType(javax.persistence.FetchType) Collections(java.util.Collections) ManyToMany(io.requery.ManyToMany) AttributeBuilder(io.requery.meta.AttributeBuilder) Optional(java.util.Optional) Elements(javax.lang.model.util.Elements) Annotation(java.lang.annotation.Annotation) JunctionTable(io.requery.JunctionTable)

Example 42 with Element

use of javax.lang.model.element.Element in project realm-java by realm.

the class RealmProcessor method processAnnotations.

// Create all proxy classes
private boolean processAnnotations(RoundEnvironment roundEnv) {
    for (Element classElement : roundEnv.getElementsAnnotatedWith(RealmClass.class)) {
        // The class must either extend RealmObject or implement RealmModel
        if (!Utils.isImplementingMarkerInterface(classElement)) {
            Utils.error("A RealmClass annotated object must implement RealmModel or derive from RealmObject.", classElement);
            return false;
        }
        // Check the annotation was applied to a Class
        if (!classElement.getKind().equals(ElementKind.CLASS)) {
            Utils.error("The RealmClass annotation can only be applied to classes.", classElement);
            return false;
        }
        ClassMetaData metadata = new ClassMetaData(processingEnv, (TypeElement) classElement);
        if (!metadata.isModelClass()) {
            continue;
        }
        Utils.note("Processing class " + metadata.getSimpleClassName());
        if (!metadata.generate()) {
            return false;
        }
        classesToValidate.add(metadata);
        backlinksToValidate.addAll(metadata.getBacklinkFields());
        RealmProxyInterfaceGenerator interfaceGenerator = new RealmProxyInterfaceGenerator(processingEnv, metadata);
        try {
            interfaceGenerator.generate();
        } catch (IOException e) {
            Utils.error(e.getMessage(), classElement);
        }
        RealmProxyClassGenerator sourceCodeGenerator = new RealmProxyClassGenerator(processingEnv, metadata);
        try {
            sourceCodeGenerator.generate();
        } catch (IOException e) {
            Utils.error(e.getMessage(), classElement);
        } catch (UnsupportedOperationException e) {
            Utils.error(e.getMessage(), classElement);
        }
    }
    return true;
}
Also used : Element(javax.lang.model.element.Element) TypeElement(javax.lang.model.element.TypeElement) IOException(java.io.IOException)

Example 43 with Element

use of javax.lang.model.element.Element in project requery by requery.

the class EntityProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    // types to generate in this round
    Map<TypeElement, EntityElement> entities = new HashMap<>();
    SourceLanguage.map(processingEnv);
    Types types = processingEnv.getTypeUtils();
    Set<TypeElement> annotationElements = new LinkedHashSet<>();
    if (isEmptyKotlinAnnotationSet(annotations)) {
        annotationElements.addAll(SourceLanguage.getAnnotations());
    } else {
        annotationElements.addAll(annotations);
    }
    for (TypeElement annotation : annotationElements) {
        for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
            typeElementOf(element).ifPresent(typeElement -> {
                EntityElement entity = null;
                if (isEntity(typeElement)) {
                    entity = computeType(entities, typeElement);
                    String model = entity.modelName();
                    graphs.computeIfAbsent(model, key -> new EntityGraph(types, embeddedTypes)).add(entity);
                } else if (isSuperclass(typeElement)) {
                    entity = computeType(superTypes, typeElement);
                } else if (isEmbeddable(typeElement)) {
                    entity = computeType(embeddedTypes, typeElement);
                }
                if (entity != null) {
                    entity.addAnnotationElement(annotation, element);
                }
            });
        }
    }
    // process
    boolean hasErrors = false;
    Set<ElementValidator> validators = new LinkedHashSet<>();
    Elements elements = processingEnv.getElementUtils();
    for (EntityElement entity : entities.values()) {
        // add the annotated elements from the super type (if any)
        if (entity.element().getKind() == ElementKind.INTERFACE) {
            List<? extends TypeMirror> interfaces = entity.element().getInterfaces();
            for (TypeMirror mirror : interfaces) {
                TypeElement superElement = elements.getTypeElement(mirror.toString());
                if (superElement != null) {
                    mergeSuperType(entity, superElement);
                }
            }
        }
        TypeMirror typeMirror = entity.element().getSuperclass();
        while (typeMirror.getKind() != TypeKind.NONE) {
            TypeElement superElement = elements.getTypeElement(typeMirror.toString());
            if (superElement != null) {
                mergeSuperType(entity, superElement);
                typeMirror = superElement.getSuperclass();
            } else {
                break;
            }
        }
        // process the entity
        Set<ElementValidator> results = entity.process(processingEnv);
        validators.addAll(results);
    }
    for (EntityElement entity : embeddedTypes.values()) {
        Set<ElementValidator> results = entity.process(processingEnv);
        validators.addAll(results);
    }
    for (EntityGraph graph : graphs.values()) {
        EntityGraphValidator validator = new EntityGraphValidator(processingEnv, graph);
        Set<ElementValidator> results = validator.validate();
        validators.addAll(results);
    }
    if (ElementValidator.hasErrors(validators)) {
        hasErrors = true;
        StringBuilder sb = new StringBuilder("Model has error(s) code generation may fail: ");
        validators.forEach(validator -> sb.append(validator.toString()));
        processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, sb);
    }
    // generate
    Set<SourceGenerator> generators = new LinkedHashSet<>();
    if (!hasErrors || getOption(GENERATE_ALWAYS, true)) {
        for (EntityDescriptor entity : entities.values()) {
            EntityGraph graph = graphs.get(entity.modelName());
            if (graph != null) {
                generators.add(new EntityGenerator(processingEnv, graph, entity, null));
            }
        }
    }
    if (getOption(GENERATE_MODEL, true)) {
        Map<String, Collection<EntityDescriptor>> packagesMap = new LinkedHashMap<>();
        Set<EntityDescriptor> allEntities = graphs.values().stream().flatMap(graph -> graph.entities().stream()).collect(Collectors.toSet());
        for (EntityDescriptor entity : allEntities) {
            EntityGraph graph = graphs.get(entity.modelName());
            String packageName = findModelPackageName(graph);
            packagesMap.computeIfAbsent(packageName, key -> new LinkedHashSet<>());
            packagesMap.get(packageName).addAll(graph.entities());
        }
        for (EntityDescriptor entity : entities.values()) {
            EntityGraph graph = graphs.get(entity.modelName());
            String packageName = findModelPackageName(graph);
            if (entity.generatesAdditionalTypes()) {
                packagesMap.remove(packageName);
            }
        }
        generators.addAll(packagesMap.entrySet().stream().filter(entry -> !entry.getValue().isEmpty()).filter(entry -> !generatedModelPackages.contains(entry.getKey())).map(entry -> {
            generatedModelPackages.add(entry.getKey());
            return entry;
        }).map(entry -> new ModelGenerator(processingEnv, entry.getKey(), entry.getValue())).collect(Collectors.toList()));
    }
    for (SourceGenerator generator : generators) {
        try {
            generator.generate();
        } catch (IOException e) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
        }
    }
    return false;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) AbstractProcessor(javax.annotation.processing.AbstractProcessor) SupportedOptions(javax.annotation.processing.SupportedOptions) TypeElement(javax.lang.model.element.TypeElement) HashMap(java.util.HashMap) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Elements(javax.lang.model.util.Elements) GENERATE_MODEL(io.requery.processor.EntityProcessor.GENERATE_MODEL) LinkedHashMap(java.util.LinkedHashMap) Embedded(io.requery.Embedded) Diagnostic(javax.tools.Diagnostic) Map(java.util.Map) GENERATE_JPA(io.requery.processor.EntityProcessor.GENERATE_JPA) LinkedHashSet(java.util.LinkedHashSet) Entity(io.requery.Entity) ElementKind(javax.lang.model.element.ElementKind) Collection(java.util.Collection) Set(java.util.Set) Element(javax.lang.model.element.Element) IOException(java.io.IOException) GENERATE_ALWAYS(io.requery.processor.EntityProcessor.GENERATE_ALWAYS) Superclass(io.requery.Superclass) Types(javax.lang.model.util.Types) Collectors(java.util.stream.Collectors) TypeKind(javax.lang.model.type.TypeKind) SourceVersion(javax.lang.model.SourceVersion) TypeMirror(javax.lang.model.type.TypeMirror) List(java.util.List) RoundEnvironment(javax.annotation.processing.RoundEnvironment) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Optional(java.util.Optional) SupportedAnnotationTypes(javax.annotation.processing.SupportedAnnotationTypes) Types(javax.lang.model.util.Types) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) Elements(javax.lang.model.util.Elements) LinkedHashMap(java.util.LinkedHashMap) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) IOException(java.io.IOException) Collection(java.util.Collection)

Example 44 with Element

use of javax.lang.model.element.Element in project requery by requery.

the class EntityType method addAnnotationElement.

@Override
public void addAnnotationElement(TypeElement annotationElement, Element annotatedElement) {
    String qualifiedName = annotationElement.getQualifiedName().toString();
    Class<? extends Annotation> type;
    try {
        type = Class.forName(qualifiedName).asSubclass(Annotation.class);
    } catch (ClassNotFoundException e) {
        return;
    }
    switch(annotatedElement.getKind()) {
        case CLASS:
        case INTERFACE:
            annotations().put(type, annotatedElement.getAnnotation(type));
            break;
        case FIELD:
            if (annotatedElement.getModifiers().contains(Modifier.STATIC) || annotatedElement.getModifiers().contains(Modifier.FINAL)) {
                // check if this a requery annotation
                String packageName = Entity.class.getPackage().getName();
                if (annotationElement.getQualifiedName().toString().startsWith(packageName)) {
                    processingEnvironment.getMessager().printMessage(Diagnostic.Kind.ERROR, annotationElement.getQualifiedName() + " not applicable to static or final member", annotatedElement);
                }
            } else {
                VariableElement element = (VariableElement) annotatedElement;
                Optional<AttributeMember> attribute = computeAttribute(element);
                Annotation annotation = annotatedElement.getAnnotation(type);
                attribute.ifPresent(a -> a.annotations().put(type, annotation));
            }
            break;
        case METHOD:
            ExecutableElement element = (ExecutableElement) annotatedElement;
            Annotation annotation = annotatedElement.getAnnotation(type);
            if (ListenerAnnotations.all().anyMatch(a -> a.equals(type))) {
                ListenerMethod listener = listeners.computeIfAbsent(element, key -> new ListenerMethod(element));
                listener.annotations().put(type, annotation);
            } else if (isMethodProcessable(element)) {
                Optional<AttributeMember> attribute = computeAttribute(element);
                attribute.ifPresent(a -> a.annotations().put(type, annotation));
            }
            break;
    }
}
Also used : Transient(io.requery.Transient) Table(io.requery.Table) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Embedded(io.requery.Embedded) Diagnostic(javax.tools.Diagnostic) Map(java.util.Map) MirroredTypeException(javax.lang.model.type.MirroredTypeException) PropertyNameStyle(io.requery.PropertyNameStyle) NestingKind(javax.lang.model.element.NestingKind) ElementFilter(javax.lang.model.util.ElementFilter) LinkedHashSet(java.util.LinkedHashSet) Name(javax.lang.model.element.Name) View(io.requery.View) Entity(io.requery.Entity) ElementKind(javax.lang.model.element.ElementKind) ExecutableElement(javax.lang.model.element.ExecutableElement) Cacheable(javax.persistence.Cacheable) Set(java.util.Set) ReadOnly(io.requery.ReadOnly) Element(javax.lang.model.element.Element) Collectors(java.util.stream.Collectors) TypeKind(javax.lang.model.type.TypeKind) Objects(java.util.Objects) SourceVersion(javax.lang.model.SourceVersion) TypeMirror(javax.lang.model.type.TypeMirror) List(java.util.List) Stream(java.util.stream.Stream) Index(javax.persistence.Index) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Annotation(java.lang.annotation.Annotation) Factory(io.requery.Factory) Optional(java.util.Optional) Embeddable(javax.persistence.Embeddable) Entity(io.requery.Entity) Optional(java.util.Optional) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableElement(javax.lang.model.element.VariableElement) Annotation(java.lang.annotation.Annotation)

Example 45 with Element

use of javax.lang.model.element.Element in project requery by requery.

the class EntityType method builderType.

@Override
public Optional<TypeMirror> builderType() {
    Optional<Entity> entityAnnotation = annotationOf(Entity.class);
    if (entityAnnotation.isPresent()) {
        Entity entity = entityAnnotation.get();
        Elements elements = processingEnvironment.getElementUtils();
        TypeMirror mirror = null;
        try {
            // easiest way to get the class TypeMirror
            Class<?> builderClass = entity.builder();
            if (builderClass != void.class) {
                mirror = elements.getTypeElement(builderClass.getName()).asType();
            }
        } catch (MirroredTypeException typeException) {
            mirror = typeException.getTypeMirror();
        }
        if (mirror != null && mirror.getKind() != TypeKind.VOID) {
            return Optional.of(mirror);
        }
    }
    if (builderFactoryMethod().isPresent()) {
        return Optional.of(builderFactoryMethod().get().getReturnType());
    }
    return ElementFilter.typesIn(element().getEnclosedElements()).stream().filter(element -> element.getSimpleName().toString().contains("Builder")).map(Element::asType).filter(Objects::nonNull).filter(type -> type.getKind() != TypeKind.VOID).findFirst();
}
Also used : MirroredTypeException(javax.lang.model.type.MirroredTypeException) Transient(io.requery.Transient) Table(io.requery.Table) Modifier(javax.lang.model.element.Modifier) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) Elements(javax.lang.model.util.Elements) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Embedded(io.requery.Embedded) Diagnostic(javax.tools.Diagnostic) Map(java.util.Map) MirroredTypeException(javax.lang.model.type.MirroredTypeException) PropertyNameStyle(io.requery.PropertyNameStyle) NestingKind(javax.lang.model.element.NestingKind) ElementFilter(javax.lang.model.util.ElementFilter) LinkedHashSet(java.util.LinkedHashSet) Name(javax.lang.model.element.Name) View(io.requery.View) Entity(io.requery.Entity) ElementKind(javax.lang.model.element.ElementKind) ExecutableElement(javax.lang.model.element.ExecutableElement) Cacheable(javax.persistence.Cacheable) Set(java.util.Set) ReadOnly(io.requery.ReadOnly) Element(javax.lang.model.element.Element) Collectors(java.util.stream.Collectors) TypeKind(javax.lang.model.type.TypeKind) Objects(java.util.Objects) SourceVersion(javax.lang.model.SourceVersion) TypeMirror(javax.lang.model.type.TypeMirror) List(java.util.List) Stream(java.util.stream.Stream) Index(javax.persistence.Index) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Annotation(java.lang.annotation.Annotation) Factory(io.requery.Factory) Optional(java.util.Optional) Embeddable(javax.persistence.Embeddable) Entity(io.requery.Entity) TypeMirror(javax.lang.model.type.TypeMirror) Objects(java.util.Objects) Elements(javax.lang.model.util.Elements)

Aggregations

Element (javax.lang.model.element.Element)286 TypeElement (javax.lang.model.element.TypeElement)227 ExecutableElement (javax.lang.model.element.ExecutableElement)148 VariableElement (javax.lang.model.element.VariableElement)96 TypeMirror (javax.lang.model.type.TypeMirror)68 PackageElement (javax.lang.model.element.PackageElement)48 ArrayList (java.util.ArrayList)39 DeclaredType (javax.lang.model.type.DeclaredType)30 IOException (java.io.IOException)29 Map (java.util.Map)26 HashSet (java.util.HashSet)23 LinkedHashSet (java.util.LinkedHashSet)22 List (java.util.List)22 Set (java.util.Set)22 Test (org.junit.Test)21 ElementKind (javax.lang.model.element.ElementKind)20 AnnotationMirror (javax.lang.model.element.AnnotationMirror)19 Elements (javax.lang.model.util.Elements)18 HashMap (java.util.HashMap)16 LinkedHashMap (java.util.LinkedHashMap)15