* Rewrite getPrototypeName() to check interfaces on all superclasses,

because classes do not report interfaces inherited from a superclass.
This commit is contained in:
hns 2008-01-29 09:35:37 +00:00
parent e6fad59612
commit 1ccb272c82

View file

@ -1327,24 +1327,29 @@ public final class Application implements Runnable {
return ((IPathElement) obj).getPrototype(); return ((IPathElement) obj).getPrototype();
} }
// How class name to prototype name lookup works:
// If an object is not found by its direct class name, a cache entry is added
// for the class name. For negative result, the string "(unmapped)" is used
// as cache value.
//
// Caching is done directly in classProperties, as ResourceProperties have
// the nice effect of being purged when the underlying resource is updated,
// so cache invalidation happens implicitely.
Class clazz = obj.getClass(); Class clazz = obj.getClass();
String className = clazz.getName(); String className = clazz.getName();
String protoName = classMapping.getProperty(className); String protoName = classMapping.getProperty(className);
// fast path: direct hit, either positive or negative
if (protoName != null) { if (protoName != null) {
return protoName == CLASS_NOT_MAPPED ? null : protoName; return protoName == CLASS_NOT_MAPPED ? null : protoName;
} }
// walk down superclass path // walk down superclass path. We already checked the actual class,
while ((clazz = clazz.getSuperclass()) != null) { // and we know that java.lang.Object does not implement any interfaces,
protoName = classMapping.getProperty(clazz.getName()); // and the code is streamlined a bit to take advantage of this.
if (protoName != null) { while (clazz != Object.class) {
// cache the class name for the object so we run faster next time // check interfaces
classMapping.setProperty(className, protoName); Class[] classes = clazz.getInterfaces();
return protoName;
}
}
// check interfaces, too
Class[] classes = obj.getClass().getInterfaces();
for (int i = 0; i < classes.length; i++) { for (int i = 0; i < classes.length; i++) {
protoName = classMapping.getProperty(classes[i].getName()); protoName = classMapping.getProperty(classes[i].getName());
if (protoName != null) { if (protoName != null) {
@ -1353,6 +1358,14 @@ public final class Application implements Runnable {
return protoName; return protoName;
} }
} }
clazz = clazz.getSuperclass();
protoName = classMapping.getProperty(clazz.getName());
if (protoName != null) {
// cache the class name for the object so we run faster next time
classMapping.setProperty(className, protoName);
return protoName == CLASS_NOT_MAPPED ? null : protoName;
}
}
// not mapped - cache negative result // not mapped - cache negative result
classMapping.setProperty(className, CLASS_NOT_MAPPED); classMapping.setProperty(className, CLASS_NOT_MAPPED);
return null; return null;