Changeset 9828

Show
Ignore:
Timestamp:
06/15/09 15:25:36 (1 year ago)
Author:
hannes
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • helma/helma/trunk/src/helma/framework/core/Skin.java

    r9576 r9828  
    11031103            } 
    11041104 
    1105             // if handler object wasn't found in cache retrieve i
     1105            // if handler object wasn't found in cache first check this-objec
    11061106            if (thisObject != null) { 
    11071107                // not a global macro - need to find handler object 
    1108                 // was called with this object - check it or its parents for matching prototype 
    1109                 if (handlerName.equalsIgnoreCase(app.getPrototypeName(thisObject))) { 
    1110                     // we already have the right handler object 
    1111                     // put the found handler object into the cache so we don't have to look again 
    1112                     if (handlerCache != null) 
    1113                         handlerCache.put(handlerName, thisObject); 
    1114                     return thisObject; 
    1115                 } else { 
    1116                     // the handler object is not what we want 
    1117                     Object obj = thisObject; 
    1118  
    1119                     // walk down parent chain to find handler object, 
    1120                     // limiting to 50 passes to avoid infinite loops 
    1121                     int maxloop = 50; 
    1122                     while (obj != null && maxloop-- > 0) { 
    1123                         String protoName = app.getPrototypeName(obj); 
    1124  
    1125                         if (handlerName.equalsIgnoreCase(protoName)) { 
    1126                             if (handlerCache != null) 
    1127                                 handlerCache.put(handlerName, obj); 
    1128                             return obj; 
    1129                         } 
    1130  
    1131                         obj = app.getParentElement(obj); 
    1132                     } 
    1133                 } 
    1134             } 
    1135  
     1108                // was called with this object - check this-object for matching prototype 
     1109                Prototype proto = app.getPrototype(thisObject); 
     1110 
     1111                if (proto != null && proto.isInstanceOf(handlerName)) { 
     1112                    return cacheHandler(handlerName, thisObject); 
     1113                } 
     1114            } 
     1115 
     1116            // next look in res.handlers 
    11361117            Map macroHandlers = reval.getResponse().getMacroHandlers(); 
    11371118            Object obj = macroHandlers.get(handlerName); 
    1138             if (handlerCache != null && obj != null) { 
    1139                 handlerCache.put(handlerName, obj); 
    1140             } 
    1141             return obj; 
    1142         } 
     1119            if (obj != null) { 
     1120                return cacheHandler(handlerName, obj); 
     1121            } 
     1122 
     1123            // finally walk down the this-object's parent chain 
     1124            if (thisObject != null) { 
     1125                obj = app.getParentElement(thisObject); 
     1126                // walk down parent chain to find handler object, 
     1127                // limiting to 50 passes to avoid infinite loops 
     1128                int maxloop = 50; 
     1129                while (obj != null && maxloop-- > 0) { 
     1130                    Prototype proto = app.getPrototype(obj); 
     1131 
     1132                    if (proto != null && proto.isInstanceOf(handlerName)) { 
     1133                        return cacheHandler(handlerName, obj); 
     1134                    } 
     1135 
     1136                    obj = app.getParentElement(obj); 
     1137                } 
     1138            } 
     1139 
     1140            return cacheHandler(handlerName, null); 
     1141        } 
     1142 
     1143        private Object cacheHandler(String name, Object handler) { 
     1144            if (handlerCache != null) { 
     1145                handlerCache.put(name, handler); 
     1146            } 
     1147            return handler; 
     1148        } 
     1149 
    11431150    } 
    11441151