126 lines
4.5 KiB
Java
126 lines
4.5 KiB
Java
package org.warp.cowdb;
|
|
|
|
import org.apache.commons.lang3.NotImplementedException;
|
|
import org.apache.commons.lang3.reflect.MethodUtils;
|
|
import org.warp.cowdb.database.EnhancedObjectFullInfo;
|
|
import org.warp.jcwdb.ann.DBClass;
|
|
import org.warp.jcwdb.ann.DBDataType;
|
|
import org.warp.jcwdb.ann.DBPropertyGetter;
|
|
import org.warp.jcwdb.ann.DBPropertySetter;
|
|
|
|
import java.io.IOException;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Map;
|
|
|
|
public abstract class EnhancedObject {
|
|
protected final int version;
|
|
protected IDatabaseTools databaseTools;
|
|
private Field[] fields;
|
|
private DBDataType[] fieldTypes;
|
|
private long[] fieldReferences;
|
|
private Method[] propertyGetters;
|
|
private Method[] propertySetters;
|
|
private DBDataType[] propertyTypes;
|
|
private long[] propertyReferences;
|
|
private boolean[] loadedProperties;
|
|
private Object[] loadedPropertyValues;
|
|
private Map<String, DBPropertySetter> setterMethods;
|
|
private Map<String, DBPropertyGetter> getterMethods;
|
|
|
|
public EnhancedObject() {
|
|
version = getClassVersion();
|
|
}
|
|
|
|
public EnhancedObject(IDatabaseTools databaseTools) throws IOException {
|
|
this.databaseTools = databaseTools;
|
|
version = getClassVersion();
|
|
databaseTools.initializeEnhancedObject(this);
|
|
}
|
|
|
|
public void setFields(Field[] fields, DBDataType[] fieldTypes, long[] fieldReferences) {
|
|
this.fields = fields;
|
|
this.fieldTypes = fieldTypes;
|
|
this.fieldReferences = fieldReferences;
|
|
}
|
|
|
|
public Method[] getPropertyGetters() {
|
|
return MethodUtils.getMethodsWithAnnotation(this.getClass(), DBPropertyGetter.class);
|
|
}
|
|
|
|
public Method[] getPropertySetters() {
|
|
return MethodUtils.getMethodsWithAnnotation(this.getClass(), DBPropertySetter.class);
|
|
}
|
|
|
|
public void setProperties(Method[] propertyGetters, Method[] propertySetters, DBDataType[] propertyTypes, long[] propertyReferences, Map<String, DBPropertySetter> setterMethods, Map<String, DBPropertyGetter> getterMethods) {
|
|
this.propertyGetters = propertyGetters;
|
|
this.propertySetters = propertySetters;
|
|
this.propertyTypes = propertyTypes;
|
|
this.propertyReferences = propertyReferences;
|
|
this.loadedProperties = new boolean[this.propertyReferences.length];
|
|
this.loadedPropertyValues = new Object[this.propertyReferences.length];
|
|
this.setterMethods = setterMethods;
|
|
this.getterMethods = getterMethods;
|
|
}
|
|
|
|
public EnhancedObjectFullInfo getAllInfo() {
|
|
return new EnhancedObjectFullInfo(version, fieldReferences, fieldTypes, fields, propertyReferences, propertyTypes, loadedPropertyValues);
|
|
}
|
|
|
|
|
|
public <T> T getProperty() {
|
|
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
|
StackWalker.StackFrame stackFrame = walker.walk(f -> f.skip(1).findFirst().orElse(null));
|
|
try {
|
|
int propertyId = stackFrame.getDeclaringClass().getDeclaredMethod(stackFrame.getMethodName()).getAnnotation(DBPropertyGetter.class).id();
|
|
return getProperty(propertyId);
|
|
} catch (IOException | NoSuchMethodException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private <T> T getProperty(int propertyId) throws IOException {
|
|
if (!loadedProperties[propertyId]) {
|
|
long propertyUID = propertyReferences[propertyId];
|
|
databaseTools.getObjectsIO().loadProperty(this, propertyId, propertyGetters[propertyId], propertyTypes[propertyId], propertyUID);
|
|
}
|
|
return (T) loadedPropertyValues[propertyId];
|
|
}
|
|
|
|
public <T> void setProperty(T value) {
|
|
StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
|
|
StackWalker.StackFrame stackFrame = walker.walk(f -> f.skip(1).findFirst().orElse(null));
|
|
DBPropertySetter propertyAnnotation = setterMethods.get(stackFrame.getMethodName());
|
|
setProperty(propertyAnnotation.id(), value);
|
|
}
|
|
|
|
public <T> void setProperty(int propertyId, T value) {
|
|
loadedPropertyValues[propertyId] = value;
|
|
loadedProperties[propertyId] = true;
|
|
}
|
|
|
|
private int getClassVersion() {
|
|
DBClass classAnnotation = this.getClass().getAnnotation(DBClass.class);
|
|
return classAnnotation == null ? 0 : classAnnotation.version();
|
|
}
|
|
|
|
/**
|
|
* Called when an unloaded class is older than the actual version
|
|
* @param oldObjectVersion
|
|
* @param enhancedObjectUpgrader
|
|
* @throws IOException
|
|
*/
|
|
public void onUpgrade(int oldObjectVersion, EnhancedObjectUpgrader enhancedObjectUpgrader) throws IOException {
|
|
throw new NotImplementedException("Method onUpgrade() is not implemented for class " + this.getClass().getSimpleName());
|
|
}
|
|
|
|
public IDatabaseTools getDatabaseTools() {
|
|
return databaseTools;
|
|
}
|
|
|
|
public void setDatabaseTools(IDatabaseTools databaseTools) {
|
|
this.databaseTools = databaseTools;
|
|
}
|
|
}
|