r9828 - helma/helma/trunk/src/helma/framework/core

[email protected] Mon, 15 Jun 2009 15:25:36 +0200 (CEST)
Newsgroups gmane.comp.java.helma.cvs
Message-ID <20090615132536.E6F673D0E3@mia>
Author: hannes
Date: 2009-06-15 15:25:36 +0200 (Mon, 15 Jun 2009)
New Revision: 9828

Modified:
   helma/helma/trunk/src/helma/framework/core/Skin.java
Log:
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

Details at http://dev.helma.org/trac/helma/changeset/9828

Modified: helma/helma/trunk/src/helma/framework/core/Skin.java
===================================================================
--- helma/helma/trunk/src/helma/framework/core/Skin.java	2009-06-10 10:33:26 UTC (rev 9827)
+++ helma/helma/trunk/src/helma/framework/core/Skin.java	2009-06-15 13:25:36 UTC (rev 9828)
@@ -1102,44 +1102,51 @@
                 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);
 
-                    // 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);
+                if (proto != null && proto.isInstanceOf(handlerName)) {
+                    return cacheHandler(handlerName, thisObject);
+                }
+            }
 
-                        if (handlerName.equalsIgnoreCase(protoName)) {
-                            if (handlerCache != null)
-                                handlerCache.put(handlerName, obj);
-                            return obj;
-                        }
+            // next look in res.handlers
+            Map macroHandlers = reval.getResponse().getMacroHandlers();
+            Object obj = macroHandlers.get(handlerName);
+            if (obj != null) {
+                return cacheHandler(handlerName, obj);
+            }
 
-                        obj = app.getParentElement(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);
                 }
             }
 
-            Map macroHandlers = reval.getResponse().getMacroHandlers();
-            Object obj = macroHandlers.get(handlerName);
-            if (handlerCache != null && obj != null) {
-                handlerCache.put(handlerName, obj);
+            return cacheHandler(handlerName, null);
+        }
+
+        private Object cacheHandler(String name, Object handler) {
+            if (handlerCache != null) {
+                handlerCache.put(name, handler);
             }
-            return obj;
+            return handler;
         }
+
     }
 
     /**