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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// not a global macro - need to find handler object
|
||||
// was called with this object - check it or its parents for matching prototype
|
||||
if (handlerName.equalsIgnoreCase(app.getPrototypeName(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;
|
||||
// was called with this object - check this-object for matching prototype
|
||||
Prototype proto = app.getPrototype(thisObject);
|
||||
|
||||
if (proto != null && proto.isInstanceOf(handlerName)) {
|
||||
return cacheHandler(handlerName, thisObject);
|
||||
}
|
||||
}
|
||||
|
||||
// next look in res.handlers
|
||||
Map macroHandlers = reval.getResponse().getMacroHandlers();
|
||||
Object obj = macroHandlers.get(handlerName);
|
||||
if (obj != null) {
|
||||
return cacheHandler(handlerName, 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) {
|
||||
String protoName = app.getPrototypeName(obj);
|
||||
Prototype proto = app.getPrototype(obj);
|
||||
|
||||
if (handlerName.equalsIgnoreCase(protoName)) {
|
||||
if (handlerCache != null)
|
||||
handlerCache.put(handlerName, obj);
|
||||
return obj;
|
||||
if (proto != null && proto.isInstanceOf(handlerName)) {
|
||||
return cacheHandler(handlerName, obj);
|
||||
}
|
||||
|
||||
obj = app.getParentElement(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return cacheHandler(handlerName, null);
|
||||
}
|
||||
|
||||
Map macroHandlers = reval.getResponse().getMacroHandlers();
|
||||
Object obj = macroHandlers.get(handlerName);
|
||||
if (handlerCache != null && obj != null) {
|
||||
handlerCache.put(handlerName, obj);
|
||||
private Object cacheHandler(String name, Object handler) {
|
||||
if (handlerCache != null) {
|
||||
handlerCache.put(name, handler);
|
||||
}
|
||||
return obj;
|
||||
return handler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue