Author: mschulte
Date: Wed Jul  4 12:27:47 2007
New Revision: 553306

URL: http://svn.apache.org/viewvc?view=rev&rev=553306
Log:
Better fix for TAPESTRY-1202

Added:
    
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
Removed:
    
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/util/io/JSONAdaptor.java
Modified:
    
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
    
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
    
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
    
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
    
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
    tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js

Modified: 
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
 (original)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/descriptor/META-INF/tapestry.data.xml
 Wed Jul  4 12:27:47 2007
@@ -94,7 +94,6 @@
     <adaptor object="service:SerializableAdaptor"/>
     <adaptor object="instance:ShortAdaptor"/>
     <adaptor object="instance:StringAdaptor"/>
-    <adaptor object="instance:JSONAdaptor"/>
   </contribution>
 
 </module>

Modified: 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
 (original)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/ComponentEvent.script
 Wed Jul  4 12:27:47 2007
@@ -17,25 +17,18 @@
         <if expression="events">
             <foreach expression="events" key="event">
                 tapestry.cleanConnect(dojo.byId("${clientId}"), "${event[0]}", 
"event${event[1]}");
-                tapestry.event${event[1]}=function( inv ){
-                    result = inv.proceed();
+                tapestry.event${event[1]}=function( event ){
                     
                     var content={beventname:"${event[0]}"};
-                    var event = inv.args[0];
-                    tapestry.event.buildEventProperties( event, content);      
              
+                   
+                    tapestry.event.buildEventProperties( event, content, 
arguments);                    
                     if (!content["beventtarget.id"]) {
                        content["beventtarget.id"]="${clientId}";
-                    }
-                    
-                    if (! dojo.event.browser.isEvent(event)){
-                       tapestry.event.buildMethodInterceptionProperties( 
inv.args, content );
-                    }
+                    }                                 
                     
                     tapestry.bind("${url}", content);
-
-                    return result;
                 };
-                dojo.event.connect("around", dojo.byId("${clientId}"), 
"${event[0]}", tapestry, "event${event[1]}");
+                dojo.event.connect(dojo.byId("${clientId}"), "${event[0]}", 
tapestry, "event${event[1]}");
             </foreach>
         </if>
         <if expression="formEvents">
@@ -44,7 +37,7 @@
                                      "${formEvent[0]}", 
"formEvent${formEvent[4]}");
                 tapestry.formEvent${formEvent[4]}=function(e){
                     var content={beventname:"${formEvent[0]}"};
-                    tapestry.event.buildEventProperties(e, content);
+                    tapestry.event.buildEventProperties(e, content, arguments);
                     if (!content["beventtarget.id"]){
                        content["beventtarget.id"]="${clientId}";
                     }

Modified: 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
 (original)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/dojo/html/WidgetEvent.script
 Wed Jul  4 12:27:47 2007
@@ -19,7 +19,7 @@
                 tapestry.cleanConnect(dojo.widget.byId("${clientId}"), 
"${event[0]}", "event${event[1]}");
                 tapestry.event${event[1]}=function(e){
                     var content={beventname:"${event[0]}"};
-                    tapestry.event.buildEventProperties(e, content);
+                    tapestry.event.buildEventProperties(e, content, arguments);
                     if (!content["beventtarget.id"]) 
content["beventtarget.id"]="${clientId}";
                     tapestry.bind("${url}", content);
                 };
@@ -32,7 +32,7 @@
                                      "${formEvent[0]}", 
"formEvent${formEvent[4]}");
                 tapestry.formEvent${formEvent[4]}=function(e){
                     var content={beventname:"${formEvent[0]}"};
-                    tapestry.event.buildEventProperties(e, content);
+                    tapestry.event.buildEventProperties(e, content, arguments);
                     if (!content["beventtarget.id"]) 
content["beventtarget.id"]="${clientId}";
 
                   <foreach expression="formEvent[1]" key="formName">

Modified: 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
 (original)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/event/BrowserEvent.java
 Wed Jul  4 12:27:47 2007
@@ -13,13 +13,16 @@
 // limitations under the License.
 package org.apache.tapestry.event;
 
+import java.text.ParseException;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.hivemind.ApplicationRuntimeException;
 import org.apache.hivemind.util.Defense;
 import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.json.JSONArray;
 
 
 /**
@@ -41,6 +44,8 @@
     public static final String TARGET="beventtarget";
     public static final String TARGET_ATTR_ID="id";
     
+    public static final String METHOD_ARGUMENTS="methodArguments";
+    
     private String _name;
     private String _type;
     private String[] _keys;
@@ -51,6 +56,9 @@
     private String _layerY;
     private EventTarget _target;
     
+    private String _methodArguments;
+    private JSONArray _methodArgumentsArray;
+    
     /**
      * Creates a new browser event that will extract its own
      * parameters.
@@ -78,6 +86,8 @@
         if (targetId != null) {
             props.put(TARGET_ATTR_ID, targetId);
         }
+        
+        _methodArguments = cycle.getParameter(METHOD_ARGUMENTS);
     }
     
     /**
@@ -171,6 +181,33 @@
     {
         return _type;
     }
+    
+    
+    /**
+     * @return the method arguments of an intercepted method-call, if any. If 
none
+     *         are available, return an empty JSONArray, never null.
+     *         
+     * @throws ApplicationRuntimeException when the JSON-String could not be
+     *         parsed.
+     */
+    public JSONArray getMethodArguments() 
+    {   
+        if ( _methodArgumentsArray == null)
+        {
+            try 
+            {
+                _methodArgumentsArray =
+                        _methodArguments != null ?
+                                new JSONArray( _methodArguments )
+                              : new JSONArray();
+            } 
+            catch (ParseException ex) 
+            {
+                throw new ApplicationRuntimeException(ex);
+            }
+        }
+        return _methodArgumentsArray;
+    }
 
     /**
      * Utility method to check if the current request contains
@@ -198,6 +235,7 @@
         .append("layerX", _layerX)
         .append("layerY", _layerY)
         .append("target", _target)
+        .append("methodArguments", _methodArguments)
         .toString();
     }
 }

Modified: 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
 (original)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/java/org/apache/tapestry/html/ElementEvent.script
 Wed Jul  4 12:27:47 2007
@@ -18,7 +18,7 @@
                 tapestry.cleanConnect(dojo.byId("${target}"), "${event[0]}", 
"event${event[1]}");
                 tapestry.event${event[1]}=function(e){
                     var content={beventname:"${event[0]}"};
-                    tapestry.event.buildEventProperties(e, content);
+                    tapestry.event.buildEventProperties(e, content, arguments);
                     if (!content["beventtarget.id"]) 
content["beventtarget.id"]="${target}";
                     tapestry.bind("${url}", content);
                 };
@@ -31,7 +31,7 @@
                                      "${formEvent[0]}", 
"formEvent${formEvent[4]}");
                 tapestry.formEvent${formEvent[4]}=function(e){
                     var content={beventname:"${formEvent[0]}"};
-                    tapestry.event.buildEventProperties(e, content);
+                    tapestry.event.buildEventProperties(e, content, arguments);
                     if (!content["beventtarget.id"]) 
content["beventtarget.id"]="${target}";
                     
                     <foreach expression="formEvent[1]" key="formName">

Modified: tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js?view=diff&rev=553306&r1=553305&r2=553306
==============================================================================
--- tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js 
(original)
+++ tapestry/tapestry4/trunk/tapestry-framework/src/js/tapestry/core.js Wed Jul 
 4 12:27:47 2007
@@ -7,7 +7,8 @@
 dojo.require("dojo.io.BrowserIO");
 dojo.require("dojo.event.browser");
 dojo.require("dojo.html.style");
-dojo.require("dojo.json");
+
+
 
 // redirect logging calls to standard debug if logging not enabled
 if (dj_undef("logging", dojo)) {
@@ -532,7 +533,7 @@
        },
 
        _getContentAsStringIE:function(node){
-               var s="";
+               var s=" "; //blank works around an IE-bug
        for (var i = 0; i < node.childNodes.length; i++){
                s += node.childNodes[i].xml;
        }
@@ -600,59 +601,34 @@
         *                              browser event it will be ignored.
         *      props - The existing property object to set the values on, if 
it doesn't
         *                              exist one will be created.
+        *  args  - The arguments from an method-call interception 
         * Returns:
         *
         * The desired event properties bound to an object. Ie 
obj.target,obj.charCode, etc..
         */
-       buildEventProperties:function(event, props){
+       buildEventProperties:function(event, props, args){
                if (!props) props={};
-               if (!dojo.event.browser.isEvent(event)) return props;
-
-               if(event["type"]) props.beventtype=event.type;
-               if(event["keys"]) props.beventkeys=event.keys;
-               if(event["charCode"]) props.beventcharCode=event.charCode;
-               if(event["pageX"]) props.beventpageX=event.pageX;
-               if(event["pageY"]) props.beventpageY=event.pageY;
-               if(event["layerX"]) props.beventlayerX=event.layerX;
-               if(event["layerY"]) props.beventlayerY=event.layerY;
-
-               if (event["target"]) this.buildTargetProperties(props, 
event.target);
+               if (dojo.event.browser.isEvent(event)) {
 
+                       if(event["type"]) props.beventtype=event.type;
+                       if(event["keys"]) props.beventkeys=event.keys;
+                       if(event["charCode"]) 
props.beventcharCode=event.charCode;
+                       if(event["pageX"]) props.beventpageX=event.pageX;
+                       if(event["pageY"]) props.beventpageY=event.pageY;
+                       if(event["layerX"]) props.beventlayerX=event.layerX;
+                       if(event["layerY"]) props.beventlayerY=event.layerY;
+
+                       if (event["target"]) this.buildTargetProperties(props, 
event.target);
+
+               } else if ( args != undefined ) {
+               
+                       props.methodArguments = dojo.json.serialize( args );
+                       
+               }
                return props;
        },
        
        
-       /**
-        * Function: buildMethodInterceptionProperties
-        *
-        * Stuffs the parameters of an @EventListener-intercepted method into
-        * a property object suitable to be passed as the content-argument to 
-        * the bind-function. Arguments will be passed as service-parameters 
(sp)
-        * so that the usual listener-invocation mechanism can do its work. 
-        * String parameters are encoded as such (StringAdaptor, prefix "S")
-        * Other types/objects will be serialised to a JSON-String which is
-        * to be handled by the JSONAdaptor on the server side (prefix "J").  
-        *
-        * Parameters:
-        *
-        *      args - the arguments array.
-        *      props - The existing property object to set the values on, if 
it doesn't
-        *                              exist one will be created.
-        * Returns:
-        *
-        * The passed in properties object augmented in the way described above
-        */
-       buildMethodInterceptionProperties:function( args, props ){
-           if (!props) props={};
-           props.sp = new Array();
-               for ( var i=0; i < args.length; i++ ) {
-                       if ( typeof(args[i]) == "string" )
-                               props.sp[i] = "S"+String(args[i]);
-                       else
-                               props.sp[i] = "J"+dojo.json.serialize( args[i] 
);       
-               }
-               return props;
-       },
 
        /**
         * Function: buildTargetProperties
@@ -737,4 +713,134 @@
                }
                return true;
        }
-}
\ No newline at end of file
+}
+
+/*
+  ** dojo json support just dumped in here until we build dojo anew for T4 **
+
+       Copyright (c) 2004-2006, The Dojo Foundation
+       All Rights Reserved.
+
+       Licensed under the Academic Free License version 2.1 or above OR the
+       modified BSD license. For more information on Dojo licensing, see:
+
+               http://dojotoolkit.org/community/licensing.shtml
+*/
+
+
+
+dojo.require("dojo.lang.func");
+dojo.require("dojo.string.extras");
+
+dojo.AdapterRegistry = function (returnWrappers) {
+       this.pairs = [];
+       this.returnWrappers = returnWrappers || false;
+};
+dojo.lang.extend(dojo.AdapterRegistry, {register:function (name, check, wrap, 
directReturn, override) {
+       var type = (override) ? "unshift" : "push";
+       this.pairs[type]([name, check, wrap, directReturn]);
+}, match:function () {
+       for (var i = 0; i < this.pairs.length; i++) {
+               var pair = this.pairs[i];
+               if (pair[1].apply(this, arguments)) {
+                       if ((pair[3]) || (this.returnWrappers)) {
+                               return pair[2];
+                       } else {
+                               return pair[2].apply(this, arguments);
+                       }
+               }
+       }
+       throw new Error("No match found");
+}, unregister:function (name) {
+       for (var i = 0; i < this.pairs.length; i++) {
+               var pair = this.pairs[i];
+               if (pair[0] == name) {
+                       this.pairs.splice(i, 1);
+                       return true;
+               }
+       }
+       return false;
+}});
+
+
+dojo.json = {jsonRegistry:new dojo.AdapterRegistry(), register:function (name, 
check, wrap, override) {
+       dojo.json.jsonRegistry.register(name, check, wrap, override);
+}, evalJson:function (json) {
+       try {
+               return eval("(" + json + ")");
+       }
+       catch (e) {
+               dojo.debug(e);
+               return json;
+       }
+}, serialize:function (o) {
+       var objtype = typeof (o);
+       if (objtype == "undefined") {
+               return "undefined";
+       } else {
+               if ((objtype == "number") || (objtype == "boolean")) {
+                       return o + "";
+               } else {
+                       if (o === null) {
+                               return "null";
+                       }
+               }
+       }
+       if (objtype == "string") {
+               return dojo.string.escapeString(o);
+       }
+       var me = arguments.callee;
+       var newObj;
+       if (typeof (o.__json__) == "function") {
+               newObj = o.__json__();
+               if (o !== newObj) {
+                       return me(newObj);
+               }
+       }
+       if (typeof (o.json) == "function") {
+               newObj = o.json();
+               if (o !== newObj) {
+                       return me(newObj);
+               }
+       }
+       if (objtype != "function" && typeof (o.length) == "number") {
+               var res = [];
+               for (var i = 0; i < o.length; i++) {
+                       var val = me(o[i]);
+                       if (typeof (val) != "string") {
+                               val = "undefined";
+                       }
+                       res.push(val);
+               }
+               return "[" + res.join(",") + "]";
+       }
+       try {
+               window.o = o;
+               newObj = dojo.json.jsonRegistry.match(o);
+               return me(newObj);
+       }
+       catch (e) {
+       }
+       if (objtype == "function") {
+               return null;
+       }
+       res = [];
+       for (var k in o) {
+               var useKey;
+               if (typeof (k) == "number") {
+                       useKey = "\"" + k + "\"";
+               } else {
+                       if (typeof (k) == "string") {
+                               useKey = dojo.string.escapeString(k);
+                       } else {
+                               continue;
+                       }
+               }
+               val = me(o[k]);
+               if (typeof (val) != "string") {
+                       continue;
+               }
+               res.push(useKey + ":" + val);
+       }
+       return "{" + res.join(",") + "}";
+}};
\ No newline at end of file

Added: 
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java?view=auto&rev=553306
==============================================================================
--- 
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
 (added)
+++ 
tapestry/tapestry4/trunk/tapestry-framework/src/test/org/apache/tapestry/event/BrowserEventTest.java
 Wed Jul  4 12:27:47 2007
@@ -0,0 +1,93 @@
+// Copyright 2004, 2005 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package org.apache.tapestry.event;
+
+import static org.easymock.EasyMock.expect;
+
+import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.tapestry.BaseComponentTestCase;
+import org.apache.tapestry.IRequestCycle;
+import org.testng.annotations.Test;
+
+/**
+ * Tests how BrowserEvent extracts itself from the RequestCycle
+ * 
+ */
[EMAIL PROTECTED]
+public class BrowserEventTest extends BaseComponentTestCase
+{
+    public void testConstructAndReadMethodArguments() {
+        IRequestCycle cycle = newCycle();
+        
+        trainCycleForStandardBrowserEvent(cycle);
+
+        expect(cycle.getParameter(BrowserEvent.METHOD_ARGUMENTS))
+                .andReturn("[1,2]");
+        
+        replay();
+        
+        BrowserEvent event = new BrowserEvent(cycle);
+        
+        verify();
+        
+        assertEquals(1, event.getMethodArguments().getInt(0));
+        assertEquals(2, event.getMethodArguments().getInt(1));
+    }
+    
+    
+    
+    public void testUnparseableJSON() {
+        
+        IRequestCycle cycle = newCycle();
+        
+        trainCycleForStandardBrowserEvent(cycle);
+        
+        expect(cycle.getParameter(BrowserEvent.METHOD_ARGUMENTS))
+                .andReturn("*/utterRubbŸsh");
+        replay();
+        
+        BrowserEvent event = new BrowserEvent(cycle);
+        
+        verify();
+        
+        try {
+            event.getMethodArguments();
+            unreachable();
+        } catch( ApplicationRuntimeException e) {
+            //success.
+        }
+    }
+
+    /**
+     * @param cycle
+     */
+    private void trainCycleForStandardBrowserEvent(IRequestCycle cycle)
+    {
+        
expect(cycle.getParameter(BrowserEvent.NAME)).andReturn("onClick").anyTimes();
+        
+        expect(cycle.getParameter(BrowserEvent.TYPE)).andReturn("click");
+        expect(cycle.getParameters(BrowserEvent.KEYS)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.CHAR_CODE)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.PAGE_X)).andReturn("123");
+        expect(cycle.getParameter(BrowserEvent.PAGE_Y)).andReturn("1243");
+        expect(cycle.getParameter(BrowserEvent.LAYER_X)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.LAYER_Y)).andReturn(null);
+        
+        expect(cycle.getParameter(BrowserEvent.TARGET + "." + 
BrowserEvent.TARGET_ATTR_ID))
+        .andReturn("element1");
+    }
+    
+    
+
+}


Reply via email to