
com.heliorm.mojo.annotated.AnnotatedPojoTable Maven / Gradle / Ivy
package com.heliorm.mojo.annotated;
import com.heliorm.Database;
import com.heliorm.Field;
import com.heliorm.Index;
import com.heliorm.Table;
import com.heliorm.annotation.Ignore;
import com.heliorm.annotation.Pojo;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* Implementation of Table that is build from POJO annotations.
*
* @author gideon
*/
public final class AnnotatedPojoTable implements Table {
private final Database database;
private final Class> pojoClass;
private final Set subs;
private List fieldModels;
private List indexes;
/**
* Create a new table with the given database, POJO class and set of
* sub-tables.
*
* @param database The database
* @param pojoClass The POJO class
* @param subTables The set of sub-tables
*/
public AnnotatedPojoTable(Database database, Class> pojoClass, Set subTables) {
this.database = database;
this.pojoClass = pojoClass;
this.subs = unrollSubTables(subTables);
}
@Override
public String getSqlTable() {
Optional pojo = getAnnotation(Pojo.class);
if (pojo.isPresent()) {
if (!pojo.get().tableName().isEmpty()) {
return pojo.get().tableName();
}
}
return getJavaName();
}
@Override
public List getFields() {
if (fieldModels == null) {
List fields = getAllFields(pojoClass);
fieldModels = new ArrayList<>();
for (java.lang.reflect.Field field : fields) {
if (isDataField(field)) {
fieldModels.add(new AnnotatedPojoField(this, field));
}
}
}
return fieldModels;
}
@Override
public Optional getPrimaryKey() {
return getFields().stream().filter(Field::isPrimaryKey).findAny();
}
@Override
public Database getDatabase() {
return database;
}
@Override
public Class getObjectClass() {
return pojoClass;
}
@Override
public Set getSubTables() {
return new HashSet<>(subs);
}
@Override
public boolean isAbstract() {
return Modifier.isAbstract(pojoClass.getModifiers());
}
@Override
public boolean isRecord() {
return pojoClass.isRecord();
}
@Override
public List getIndexes() {
if (indexes == null) {
indexes = new ArrayList<>();
List anns = getAnnotations(com.heliorm.annotation.Index.class);
for (com.heliorm.annotation.Index ann : anns) {
indexes.add(new AnnotatedPojoIndex(this, ann));
}
}
return indexes;
}
/**
* Decide if a reflected field is a data field we need to process. A field
* is considered a POJO field if it is not native, not transient, not static
* and not annotated with the @Ignore annotation.
*
* @param field The reflected field to evaluate
* @return True if it is considered a data field
*/
private boolean isDataField(java.lang.reflect.Field field) {
int modifiers = field.getModifiers();
if (Modifier.isNative(modifiers)) {
return false;
}
if (Modifier.isTransient(modifiers)) {
return false;
}
if (Modifier.isStatic(modifiers)) {
return false;
}
return !field.isAnnotationPresent(Ignore.class);
}
/**
* Return the Java name for the POJO class represented by this
*
* @return The Java name
*/
private String getJavaName() {
return pojoClass.getSimpleName();
}
/**
* Convenience method to find the optional annotation on the POJO class.
*
* @param The type of the annotation
* @param annotationClass The annotation class
* @return Optional annotation found
*/
private Optional getAnnotation(Class annotationClass) {
return Optional.ofNullable(pojoClass.getAnnotation(annotationClass));
}
private List getAnnotations(Class annotationClass) {
Class> target = pojoClass;
List annotations = new ArrayList<>();
while (!Object.class.equals(target)) {
T[] found = target.getAnnotationsByType(annotationClass);
annotations.addAll(Arrays.asList(found));
target = target.getSuperclass();
}
return annotations;
}
/**
* Return reflected fields for all fields declared on a class and it's super
* classes but stopping short of java.lang.Object (recursively)
*
* @param clazz The class to return the fields from
* @return The list of fields
*/
private List getAllFields(Class> clazz) {
List res = new LinkedList<>();
if (clazz.getSuperclass() != Object.class) {
res.addAll(getAllFields(clazz.getSuperclass()));
}
res.addAll(Arrays.asList(clazz.getDeclaredFields()));
return res;
}
private Set unrollSubTables(Set subs) {
Set res = new HashSet<>();
for (Table sub : subs) {
if (!sub.isAbstract()) {
res.add(sub);
}
res.addAll(unrollSubTables(sub.getSubTables()));
}
return res;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy