New logic for skin handler lookup to fix the fix for bug 617. New algorithm works like this:
- resolve against the this-object prototype name, including extended prototypes - resolve against the res.handlers collection - resolve against the parent path of the this-object, including extended prototypes. The following thread provides more context: http://groups.google.com/group/helma/browse_frm/thread/b15805fd6f661d64
This commit is contained in:
parent
afcb459c0d
commit
b48fb4e277
1 changed files with 35 additions and 28 deletions
|
@ -1102,44 +1102,51 @@ public final class Skin {
|
||||||
return handlerCache.get(handlerName);
|
return handlerCache.get(handlerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if handler object wasn't found in cache retrieve it
|
// if handler object wasn't found in cache first check this-object
|
||||||
if (thisObject != null) {
|
if (thisObject != null) {
|
||||||
// not a global macro - need to find handler object
|
// not a global macro - need to find handler object
|
||||||
// was called with this object - check it or its parents for matching prototype
|
// was called with this object - check this-object for matching prototype
|
||||||
if (handlerName.equalsIgnoreCase(app.getPrototypeName(thisObject))) {
|
Prototype proto = app.getPrototype(thisObject);
|
||||||
// we already have the right handler object
|
|
||||||
// put the found handler object into the cache so we don't have to look again
|
|
||||||
if (handlerCache != null)
|
|
||||||
handlerCache.put(handlerName, thisObject);
|
|
||||||
return thisObject;
|
|
||||||
} else {
|
|
||||||
// the handler object is not what we want
|
|
||||||
Object obj = thisObject;
|
|
||||||
|
|
||||||
// walk down parent chain to find handler object,
|
if (proto != null && proto.isInstanceOf(handlerName)) {
|
||||||
// limiting to 50 passes to avoid infinite loops
|
return cacheHandler(handlerName, thisObject);
|
||||||
int maxloop = 50;
|
|
||||||
while (obj != null && maxloop-- > 0) {
|
|
||||||
String protoName = app.getPrototypeName(obj);
|
|
||||||
|
|
||||||
if (handlerName.equalsIgnoreCase(protoName)) {
|
|
||||||
if (handlerCache != null)
|
|
||||||
handlerCache.put(handlerName, obj);
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = app.getParentElement(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// next look in res.handlers
|
||||||
Map macroHandlers = reval.getResponse().getMacroHandlers();
|
Map macroHandlers = reval.getResponse().getMacroHandlers();
|
||||||
Object obj = macroHandlers.get(handlerName);
|
Object obj = macroHandlers.get(handlerName);
|
||||||
if (handlerCache != null && obj != null) {
|
if (obj != null) {
|
||||||
handlerCache.put(handlerName, obj);
|
return cacheHandler(handlerName, obj);
|
||||||
}
|
}
|
||||||
return obj;
|
|
||||||
|
// finally walk down the this-object's parent chain
|
||||||
|
if (thisObject != null) {
|
||||||
|
obj = app.getParentElement(thisObject);
|
||||||
|
// walk down parent chain to find handler object,
|
||||||
|
// limiting to 50 passes to avoid infinite loops
|
||||||
|
int maxloop = 50;
|
||||||
|
while (obj != null && maxloop-- > 0) {
|
||||||
|
Prototype proto = app.getPrototype(obj);
|
||||||
|
|
||||||
|
if (proto != null && proto.isInstanceOf(handlerName)) {
|
||||||
|
return cacheHandler(handlerName, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj = app.getParentElement(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cacheHandler(handlerName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Object cacheHandler(String name, Object handler) {
|
||||||
|
if (handlerCache != null) {
|
||||||
|
handlerCache.put(name, handler);
|
||||||
|
}
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue