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();
}
}
}
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;
}
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;
}
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;
}
}
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();
}
Aggregations