WrappedClassData.java
package hu.ddsi.java.database;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import eu.javaexperience.functional.BoolFunctions;
import eu.javaexperience.interfaces.ObjectWithProperty;
import eu.javaexperience.interfaces.ObjectWithPropertyStorage;
import eu.javaexperience.interfaces.simple.getBy.GetBy1;
import eu.javaexperience.reflect.FieldSelectTools;
import eu.javaexperience.reflect.Mirror;
import eu.javaexperience.semantic.references.MayNull;
public class WrappedClassData implements ObjectWithProperty
{
protected Class type;
public boolean shallow = false;
protected GetBy1<Boolean, Field> fieldSelector;
public WrappedClassData(Class<?> type)
{
this.type = type;
fieldSelector = BoolFunctions.always();
}
public WrappedClassData(Class c, GetBy1<Boolean, Field> fieldSelector)
{
type = c;
this.fieldSelector = fieldSelector;
}
@Override
public Object get(String key)
{
return PROPS.get(this, key);
}
@Override
public String[] keys()
{
return PROPS.keys();
}
public static @MayNull WrappedClassData wrap(Class c, GetBy1<Boolean, Field> fieldSelector)
{
if(null == c)
{
return null;
}
return new WrappedClassData(c, fieldSelector);
}
public static @MayNull WrappedClassData[] wrap(Class[] c, GetBy1<Boolean, Field> fieldSelector)
{
if(null == c)
{
return null;
}
WrappedClassData[] ret = new WrappedClassData[c.length];
for(int i=0;i<ret.length;++i)
{
ret[i] = wrap(c[i], fieldSelector);
}
return ret;
}
protected Object extractSuperClass()
{
if(shallow)
{
Class cls = type.getSuperclass();
if(null == cls)
{
return null;
}
return cls.getName();
}
else
{
return wrap(type.getSuperclass(), fieldSelector);
}
}
protected Object extractInterface()
{
if(shallow)
{
Class[] cls = type.getInterfaces();
if(null == cls)
{
return null;
}
String[] ret = new String[cls.length];
int i = 0;
for(Class c:cls)
{
ret[i++] = c.getName();
}
return ret;
}
else
{
return wrap(type.getInterfaces(), fieldSelector);
}
}
protected static ObjectWithPropertyStorage<WrappedClassData> PROPS = new ObjectWithPropertyStorage<>();
static
{
PROPS.addExaminer("name", (e)->e.type.getSimpleName());
PROPS.addExaminer("fullName", (e)->e.type.getName());
PROPS.addExaminer("superClass", (e)->e.extractSuperClass());
PROPS.addExaminer("superInterfaces", (e)->e.extractInterface());
PROPS.addExaminer("isArray", (e)->e.type.isArray());
PROPS.addExaminer("isEnum", (e)->e.type.isEnum());
PROPS.addExaminer("arrayComponent", (e)->wrap(e.type.getComponentType(), e.fieldSelector));
PROPS.addExaminer("enums", (e)->e.type.getEnumConstants());
PROPS.addExaminer("isInterface", (e)->e.type.isInterface());
PROPS.addExaminer("isAbstract", (e)->Modifier.isAbstract(e.type.getModifiers()));
PROPS.addExaminer("modifiers", (e)->e.type.getModifiers());
PROPS.addExaminer("fields", (e)->WrappedFieldData.wrapAll(e.type.getFields(), e.fieldSelector));
//TODO annontations
}
public static void discoverAndWrapShallow
(
Map<Class, WrappedClassData> map,
Class c,
boolean discoverFields
)
{
if(null == c)
{
return;
}
if(!map.containsKey(c))
{
WrappedClassData wc = new WrappedClassData(c);
wc.shallow = true;
discoverAndWrapShallow(map, c.getSuperclass(), discoverFields);
for(Class i:c.getInterfaces())
{
discoverAndWrapShallow(map, i, discoverFields);
}
if(discoverFields)
{
for(Field f:Mirror.getClassData(c).select(FieldSelectTools.SELECT_ALL_INSTANCE_FIELD))
{
discoverAndWrapShallow(map, f.getType(), discoverFields);
}
}
}
}
}