
com.venky.swf.db.model.reflection.TableReflector Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swf-db Show documentation
Show all versions of swf-db Show documentation
Succinct Web Framework - Db
The newest version!
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.venky.swf.db.model.reflection;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import com.venky.core.collections.SequenceSet;
import com.venky.core.util.ObjectUtil;
import com.venky.reflection.MethodSignatureCache;
import com.venky.reflection.Reflector;
import com.venky.reflection.Reflector.MethodMatcher;
import com.venky.swf.db.annotations.column.IS_VIRTUAL;
import com.venky.swf.db.annotations.model.DBPOOL;
import com.venky.swf.db.jdbc.ConnectionManager;
import com.venky.swf.db.model.Model;
import com.venky.swf.db.table.Table;
import com.venky.swf.routing.Config;
/**
*
* @author venky
*/
public class TableReflector {
private static final Map tableReflectorByTableName = new HashMap();
public static void dispose(){
tableReflectorByTableName.clear();
MReflector.dispose();
}
public static TableReflector instance(Class modelClass){
Class extends Model> realModelClass = getRealModelClass(modelClass);
if (realModelClass == null){
//The whole tree is Virtual.
realModelClass = modelClass;
}
String tableName = Table.tableName(realModelClass);
DBPOOL dbpool = realModelClass.getAnnotation(DBPOOL.class);
String pool = dbpool == null ? "" : dbpool.value();
if (ObjectUtil.isVoid(pool)){
pool = ConnectionManager.instance().getDefaultPool();
}
String tableKey = pool + "." + tableName;
TableReflector reflector = tableReflectorByTableName.get(tableKey);
if (reflector == null){
synchronized(tableReflectorByTableName){
reflector = tableReflectorByTableName.get(tableKey);
if (reflector == null){
reflector = new TableReflector(tableName,pool);
tableReflectorByTableName.put(tableKey, reflector);
}
}
}
reflector.registerModelClass(modelClass);
return reflector;
}
private SequenceSet> modelClassesInClasspathSequence = new SequenceSet>();
private Map>> modelClassesInClasspathSequenceByName = new HashMap>>();
public void registerModelClass(Class modelClass){
if (!modelClassesInClasspathSequence.contains(modelClass)){
modelClassesInClasspathSequence.add(modelClass);
SequenceSet> modelClassesForName = modelClassesInClasspathSequenceByName.get(modelClass.getSimpleName());
if (modelClassesForName == null){
modelClassesForName = new SequenceSet>();
modelClassesInClasspathSequenceByName.put(modelClass.getSimpleName(), modelClassesForName);
}
modelClassesForName.add(modelClass);
}
}
public SequenceSet> getModelClasses(){
return modelClassesInClasspathSequence;
}
/**
* @param modelClass
* @return modelClasses that have the same SimpleName as the the passed modelClass in the order in which they occur in classpath.
* If multiple classes with same simple name are present in a classpath entry (jar or a directory) the sequence between them is not guaranteed.
*/
public SequenceSet> getSiblingModelClasses(Class extends Model> modelClass){
if (modelClass == null){
return modelClassesInClasspathSequence;
}
return modelClassesInClasspathSequenceByName.get(modelClass.getSimpleName());
}
@SuppressWarnings("unchecked")
public static Class getRealModelClass(Class extends Model> modelClass){
MReflector extends Model> ref = MReflector.instance(modelClass);
Class extends Model> lastRealClass = null;
List> modelHierarchyClasses = ref.getClassHierarchy();
for (Class extends Model> claz:modelHierarchyClasses){
IS_VIRTUAL isVirtual = claz.getAnnotation(IS_VIRTUAL.class);
if (isVirtual != null){
if (isVirtual.value()){
lastRealClass = null;
}else if (lastRealClass == null){
lastRealClass = claz;
break;
}else {
break;
}
}else if (lastRealClass == null){
lastRealClass = claz;
}
}
if (lastRealClass == Model.class){
lastRealClass = null;
}
return (Class) lastRealClass;
}
private final String tableName;
private final String pool ;
private TableReflector(String tableName, String pool) {
this.tableName = tableName;
this.pool = pool;
}
public String getPool(){
return pool;
}
public String getTableName(){
return tableName;
}
public boolean reflects(Class extends Model> other){
return modelClassesInClasspathSequence.contains(other);
}
public boolean canReflect(Object o){
for (Class extends Model> model: modelClassesInClasspathSequence){
if (model.isInstance(o)){
return true;
}
}
return false;
}
public void loadMethods(Class extends Model> inModel , List into , MethodMatcher matcher ){
if (!into.isEmpty()){
return;
}
synchronized (into) {
if (into.isEmpty()){
HashSet signatures = new HashSet();
for (Class extends Model> modelClass:getSiblingModelClasses(inModel)){
List matchingMethods = MReflector.instance(modelClass).getMethods(matcher);
for (Method m: matchingMethods){
String signature = getSignature(m);
if (!signatures.contains(signature)){
into.add(m);
signatures.add(signature);
}
}
}
}
}
}
private transient MethodSignatureCache signatureCache = new MethodSignatureCache();
public String getSignature(Method method){
return signatureCache.get(method);
}
public boolean isAnnotationPresent(Class extends Model> inModel, Class extends Annotation> annotationClass){
return getAnnotation(inModel,annotationClass) != null;
}
public A getAnnotation(Class extends Model> inModel, Class annotationClass){
A a = null;
for (Class extends Model> sibling: getSiblingModelClasses(inModel)){
MReflector extends Model> ref = MReflector.instance(sibling);
a = ref.getAnnotation(annotationClass);
if (a != null){
break;
}
}
return a;
}
public boolean isAnnotationPresent(Class extends Model> inModel, Method method, Class extends Annotation> annotationClass ){
return getAnnotation(inModel, method, annotationClass) != null ;
}
public A getAnnotation(Class extends Model> inModel, Method method, Class annotationClass){
A a = null;
for (Class extends Model> sibling: getSiblingModelClasses(inModel)) {
MReflector extends Model> ref = MReflector.instance(sibling);
a = ref.getAnnotation(method,annotationClass);
if (a != null){
break;
}
}
return a;
}
public SequenceSet> getClassHierarchies(Class extends Model> modelClass){
if (modelClass == null || modelClassesInClasspathSequence.contains(modelClass)){
SequenceSet> hierarchy = new SequenceSet>();
for (Class extends Model> sibling : getSiblingModelClasses(modelClass)){
MReflector> ref = MReflector.instance(sibling);
hierarchy.addAll(ref.getClassHierarchy());
}
return hierarchy;
}else {
return null;
}
}
public SequenceSet> getClassForests(Class extends Model> modelClass){
if (modelClass == null || modelClassesInClasspathSequence.contains(modelClass)){
SequenceSet> forest = new SequenceSet>();
for (Class extends Model> sibling : getSiblingModelClasses(modelClass) ){
MReflector> ref = MReflector.instance(sibling);
forest.addAll(ref.getClassForest());
}
return forest;
}else {
return null;
}
}
public static class MReflector extends Reflector{
private static final Map, MReflector extends Model>> mreflectors = new HashMap, MReflector extends Model>>();
@SuppressWarnings("unchecked")
public static MReflector instance(Class modelClass){
MReflector ref = (MReflector)mreflectors.get(modelClass);
if (ref == null){
synchronized (mreflectors) {
ref = (MReflector)mreflectors.get(modelClass);
if (ref == null){
Config.instance().getLogger(TableReflector.class.getName()).fine("Trying to reflect "+ modelClass.getName());
ref = new MReflector(modelClass);
mreflectors.put(modelClass, ref);
}
}
}
return ref;
}
public static void dispose(){
mreflectors.clear();
}
private MReflector(Class reflectedClass) {
super(reflectedClass, Model.class);
}
public List getMethodsForSignature(Method method){
return super.getMethodsForSignature(getMethodSignature(method));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy