portals-pluto-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From msnickl...@apache.org
Subject [22/22] portals-pluto git commit: Several changes: * Updated the Portlet Hub implementation to use the new URL encoding scheme * Updated the Portlet Hub API to return a promise that is fulfilled when the action is complete * Added a PH Parameter Test p
Date Mon, 16 Feb 2015 15:55:04 GMT
Several changes:
* Updated the Portlet Hub implementation to use the new URL encoding scheme
* Updated the Portlet Hub API to return a promise that is fulfilled when the
  action is complete
* Added a PH Parameter Test portlet that can be used to verify that
 parameters are correctly set and read through the Portlet Hub


Project: http://git-wip-us.apache.org/repos/asf/portals-pluto/repo
Commit: http://git-wip-us.apache.org/repos/asf/portals-pluto/commit/355084b0
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/355084b0
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/355084b0

Branch: refs/heads/V3Prototype
Commit: 355084b02f0c77c4049c9adf1807af577b438ce1
Parents: 11bb397
Author: Scott Nicklous <msnicklous@apache.org>
Authored: Mon Feb 16 16:24:28 2015 +0100
Committer: Scott Nicklous <msnicklous@apache.org>
Committed: Mon Feb 16 16:24:28 2015 +0100

----------------------------------------------------------------------
 .../src/main/java/basic/portlet/Constants.java  |   9 +
 .../java/basic/portlet/ParamTestPortlet.java    | 128 +++++++++++++
 .../src/main/webapp/WEB-INF/jsp/view-ptp.jsp    | 124 +++++++++++++
 .../src/main/webapp/WEB-INF/portlet.xml         |  21 +++
 pluto-portal/src/main/webapp/portlet.js         |  29 +--
 pluto-portal/src/main/webapp/portletHubImpl.js  | 183 ++++++++++---------
 portlet-api/src/main/javascript/portlet.js      |  35 ++--
 portlet-api/src/test/javascript/ActionTest.js   |  14 +-
 8 files changed, 425 insertions(+), 118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/PortletHubDemo/src/main/java/basic/portlet/Constants.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/Constants.java b/PortletHubDemo/src/main/java/basic/portlet/Constants.java
index e36609c..3d607b1 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/Constants.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/Constants.java
@@ -47,4 +47,13 @@ public class Constants {
    public final static String ATTRIB_MSGS = "msgs";
    
    public final static String DELIM = ";%;";
+
+   public final static String PARAM_NAME = "pName";
+   public final static String PARAM_VALUES = "pValues";
+   public final static String PARAM_REMTYPE = "remType";
+   public final static String PARAM_REMTYPE_REM = "remPRP";
+   public final static String PARAM_REMTYPE_SET = "setRP";
+   public final static String PARAM_SETTYPE = "setType";
+   public final static String PARAM_SETTYPE_VAL = "setVal";
+   public final static String PARAM_SETTYPE_VARRAY = "setVals";
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
new file mode 100644
index 0000000..ab5b242
--- /dev/null
+++ b/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
@@ -0,0 +1,128 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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 basic.portlet;
+
+import static basic.portlet.Constants.*;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+
+/**
+ * A purtlet hub portlet that allows parameter names & values to be entered and set.
+ * 
+ * @author Scott Nicklous
+ */
+public class ParamTestPortlet extends GenericPortlet {
+
+   // Set up logging
+   private static final String LOG_CLASS = ParamTestPortlet.class.getName();
+   @SuppressWarnings("unused")
+   private final Logger logger = Logger.getLogger(LOG_CLASS);
+   
+   private final HashSet<String> prpNames = new HashSet<String>();
+   
+   @Override
+   public void init() throws PortletException {
+      super.init();
+      Enumeration<String> names = getPublicRenderParameterNames();
+      for (String name : Collections.list(names)) {
+         prpNames.add(name);
+      }
+   }
+
+   protected void doView(RenderRequest req, RenderResponse resp)
+         throws PortletException, IOException {
+
+      
+      resp.setContentType("text/html");
+
+      PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
+            "/WEB-INF/jsp/view-ptp.jsp");
+      rd.include(req, resp);
+
+   }
+   
+   /* (non-Javadoc)
+    * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
+    */
+   @SuppressWarnings("deprecation")
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp)
+         throws PortletException, IOException {
+      
+      resp.setContentType("text/html");
+      PrintWriter writer = resp.getWriter();
+      
+      StringBuilder txt = new StringBuilder();
+      String style = "style='min-width: 100px;'";
+      List<String> pnList = Collections.list(req.getParameterNames());
+      
+      // don't display the control  params
+      pnList.remove(PARAM_SETTYPE);
+      pnList.remove(PARAM_REMTYPE);
+      
+      for (String pn : pnList) {
+         // try to test all parameter apis
+         String val = req.getParameter(pn);
+         String[] vals = req.getParameterValues(pn);
+         txt.append("      <tr><td " + style + ">Name: ")
+            .append(pn)
+            .append("</td><td " + style + ">Val: ")
+            .append(val)
+            .append("</td><td " + style + ">Len: ")
+            .append(vals.length)
+            .append("</td><td " + style + ">Values: ")
+            .append(Arrays.toString(vals))
+            .append("</td></tr>\n");
+      }
+      
+      writer.write("<h3>Currently set render parameters:</h3>\n");
+      writer.write("<p>\n");
+      writer.write("   <table>");
+      writer.write(txt.toString());
+      writer.write("   </table>");
+      writer.write("</p>\n");
+
+      writer.write("<p><hr/></p>\n");
+      
+   }
+
+   // nothing to do in processAction
+   public void processAction(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ptp.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ptp.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ptp.jsp
new file mode 100644
index 0000000..f4a429b
--- /dev/null
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ptp.jsp
@@ -0,0 +1,124 @@
+<%--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+--%>
+<%@ page session="false" %>
+<%@ taglib uri="http://java.sun.com/portlet_2_0"  prefix="portlet" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ page import="static basic.portlet.Constants.*" %>
+
+<portlet:defineObjects />
+
+<h3>Parameter Tester</h3><hr/>
+<p>Enter parameter name and value and click 'send'.
+To enter multiple values, separate values with a ',' character.
+Entering 'null' as a value will cause the corresponding value in the values array to be set
to null.
+Entering 'null' by itself will cause the parameter to be set to null (removed).
+Entering 'empty' by itself will set the parameter to an empty array.
+Leaving the value field empty will set the parameter to an array containing a single empty
string.
+<p/>
+<p><hr/></p>
+<FORM id='<portlet:namespace/>-setParams' METHOD='POST' onsubmit='return false;'
enctype='application/x-www-form-urlencoded' accept-charset='UTF-8'>
+   <table><tr><td align='left'>
+      Parameter Name:
+   </td><td colspan=2>
+   <input name='<portlet:namespace/>-pName' type='text' value='' size='50' maxlength='100'>
+   </td></tr><tr><td>
+      Parameter Values:
+   </td><td colspan=2>
+   <input name='<portlet:namespace/>-pVal' type='text' value='' size='50' maxlength='100'>
+   </td></tr><tr><td>
+   <INPUT VALUE='send' CLASS='portlet-form-button' TYPE='submit'>
+   </td></tr></table>
+</FORM>
+
+<p><hr/></p>
+<div id='<portlet:namespace/>-putResourceHere'></div>
+
+
+<script>
+(function () {
+   'use strict';
+    
+   var pid = '<portlet:namespace/>',
+       pnid = '<portlet:namespace/>-pName',
+       pvid = '<portlet:namespace/>-pVal',
+       msgdiv = '<portlet:namespace/>-putResourceHere',
+       formid = '<portlet:namespace/>-setParams',
+       currState,
+       hub,
+
+       
+   // Handler for onStateChange event
+   update = function (type, state) {
+      currState = state;
+      
+      hub.createResourceUrl().then(function (url) {
+         var xhr = new XMLHttpRequest();
+         console.log("PTP: got url: " + url);
+         xhr.onreadystatechange = function () {
+            if (xhr.readyState === 4 && xhr.status === 200) {
+               document.getElementById(msgdiv).innerHTML=xhr.responseText;
+            }
+         };
+         xhr.open("GET",url,true);
+         xhr.send();
+      });
+   };
+   
+
+   // Register portlet with Portlet Hub. Add listener for onStateChange event.
+   portlet.register(pid).then(function (pi) {
+      console.log("PTP Parameter Test Portlet: registered: " + pid);
+      hub = pi;
+      currState = hub.newState();
+      hub.addEventListener("portlet.onStateChange", update);
+   });
+   
+
+   // Handler for 'send' button click. Update parameters
+   document.getElementById(formid).addEventListener('submit', function (event) {
+      var pName = this[pnid].value,
+          pValue = this[pvid].value, 
+          nstate, vals, ii;
+      
+      console.log("PTP: updating parameters. PN=" + pName + ", PV=" + pValue);
+      
+      nstate = currState.clone();
+      if (pValue === 'null') {
+         nstate.p.remove(pName);
+      } else {
+         if (pValue === 'empty') {
+            nstate.parameters[pName] = [];
+         } else {
+            vals = pValue.split(",");
+            for (ii = 0; ii < vals.length; ii++) {
+               if (vals[ii] === 'null') {
+                  vals[ii] = null;
+               }
+            }
+            nstate.p.setValues(pName, vals);
+         }
+      }
+      
+      hub.setPortletState(nstate);
+      
+      event.preventDefault();
+   });
+      
+}());
+</script>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
index 9a516e3..9387fd7 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
@@ -112,6 +112,27 @@
 
       <supported-public-render-parameter>color</supported-public-render-parameter>
    </portlet>
+
+   <portlet>
+      <portlet-name>ParamTestPortlet</portlet-name>
+      <display-name>PH Parameter Test Portlet</display-name>
+      
+      <portlet-class>basic.portlet.ParamTestPortlet</portlet-class>
+
+      <supports>
+         <mime-type>text/html</mime-type>
+         <portlet-mode>VIEW</portlet-mode>
+      </supports>
+
+      <supported-locale>en</supported-locale>        
+
+      <portlet-info>
+         <title>PH Parameter Test Portlet</title>
+      </portlet-info>
+
+      <supported-public-render-parameter>imgName</supported-public-render-parameter>
+      <supported-public-render-parameter>color</supported-public-render-parameter>
+   </portlet>
    
    <event-definition>
       <qname>rp:Message</qname>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/pluto-portal/src/main/webapp/portlet.js
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/portlet.js b/pluto-portal/src/main/webapp/portlet.js
index edbb8e0..7173472 100644
--- a/pluto-portal/src/main/webapp/portlet.js
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -1082,8 +1082,8 @@ var portlet = portlet || {};
       // If an error occurred, post the error to the onError handler, if one is present.
 
       pi = _registeredPortlets[pid];
-      pi.executeAction(parms, element).then(function (upids) {
-         updatePageState(upids);
+      return pi.executeAction(parms, element).then(function (upids) {
+         return updatePageState(upids);
       }, function (err) {
          busy = false;
          if (oeListeners[pid]) {
@@ -1583,13 +1583,6 @@ var portlet = portlet || {};
              * submit the action to the server by executing a 'POST' with an action
              * URL containing any action parameters provided.
              * <p>
-             * A portlet action is a blocking operation.
-             * To allow for orderly state transitions, the portlet hub does not allow
-             * this function to be used while a blocking operation is in progress.
-             * A blocking operation is considered to be in progress
-             * from the initial call until the final onStateChange event for that
-             * operation has been fired. See {@link portlet} for further information.
-             * <p>
              * The parameters may be specified in either order, individually,
              * or not at all. Examples of valid calls:
              * <code>
@@ -1598,6 +1591,15 @@ var portlet = portlet || {};
              * <br>action(actParams);
              * <br>action(element);
              * </code>
+             * <p>
+             * A portlet action is a blocking operation.
+             * To allow for orderly state transitions, the portlet hub does not allow
+             * this function to be used while a blocking operation is in progress.
+             * A blocking operation is considered to be in progress
+             * from the initial call until the final onStateChange event for that
+             * operation has been fired. See {@link portlet} for further information.
+             * <p>
+             * 
              *
              * @param   {PortletParameters}  actParams   Action parameters to be
              *                                           added to the URL
@@ -1605,6 +1607,9 @@ var portlet = portlet || {};
              * @param   {HTMLFormElement}    element     DOM element of form to be submitted
              *                                           (optional)
              *
+             * @returns {Promise}   A Promise object that is resolved with no argument
+             * 						when the action request has completed.
+             *
              * @throws  {IllegalArgumentException}
              *                   Thrown if the input parameters are invalid
              * @throws  {AccessDeniedException}
@@ -1643,13 +1648,15 @@ var portlet = portlet || {};
                         throwIllegalArgumentException("too many parameters arguments.");
                      }
                      parms = arg;
-                  } else {
+                  } else 
+                  if (arg !== undefined) { 
                      throwIllegalArgumentException("Invalid argument type. Argument " + (ii
+ 1)
                             + " is of type " + type);
                   }
                }
                
                // if we're dealing with a form, verify method and enctype
+               console.log("form element", el);
                
                if (el) {
                   meth = el.method ? el.method.toUpperCase() : undefined;
@@ -1680,7 +1687,7 @@ var portlet = portlet || {};
          
                // everything ok, so do the action
          
-               setupAction(portletId, parms, el);
+               return setupAction(portletId, parms, el);
             },
          
             /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/pluto-portal/src/main/webapp/portletHubImpl.js
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/portletHubImpl.js b/pluto-portal/src/main/webapp/portletHubImpl.js
index 60eb8bf..89f0406 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -310,56 +310,42 @@ var portlet = portlet || {};
       return pageState.portlets[pid].state;
    },
    
-   /**
-    * Function to encode url tokens as Pluto likes it
-    */
-   plutoEncode = function (istr) {
-      var ENCODINGS = {
-            "_" :  "0x1",
-            "." :  "0x2",
-            "/" :  "0x3",
-            "\r" : "0x4",
-            "\n" : "0x5",
-            "<" :  "0x6",
-            ">" :  "0x7",
-            " " :  "0x8",
-            "#" :  "0x9",
-            "?" :  "0xa",
-            "\\" : "0xb",
-            "%" :  "0xc",
-            "|" :  "%7C"
-                      }, ii, ostr = "";
-      
-      for (ii=0; ii < istr.length; ii++) {
-         if (ENCODINGS[istr.charAt(ii)]) {
-            ostr += ENCODINGS[istr.charAt(ii)];
-         } else {
-            ostr += istr.charAt(ii);
-         }
-      }
-
-      return ostr;
-   },
-   
    
    // Constants used for URL Encoding/Decoding (copied from Pluto impl code)  ----------
-
+   
    PREFIX = "__",
-   DELIM = "_",
    PORTLET_ID = "pd",
-   ACTION = "ac",
-   RESOURCE = "rs",
    RESOURCE_ID = "ri",
    CACHE_LEVEL = "cl",
-   RENDER_PARAM = "rp",
-   PRIVATE_RENDER_PARAM = "pr",
-   PUBLIC_RENDER_PARAM = "sp",
    WINDOW_STATE = "ws",
    PORTLET_MODE = "pm",
-   VALUE_DELIM = "0x0",
+   
+   // The delimiter & special chars for the value encoding are chosen
+   // from the URL reserved delimiter characters that ARE ENCODED by the URLEncoder
+   // so that they will not appear encoded parameter names or values.
+   // See RFC 3986 & URLEncoder documentation.
+   VALUE_DELIM = ":",
+   VALUE_NULL = ",",
+   VALUE_ARRAY_EMPTY = "@",
+   DELIM = ";",
+   TOKEN_DELIM = "/",
+
+   ACTION = "ac",
+   RESOURCE = "rs",
+   AJAX_ACTION = "aa",       // new for portlet spec 3
+   PARTIAL_ACTION = "pa",    // new for portlet spec 3
+   RENDER = "re",            // new for portlet spec 3
+   
+   ACTION_PARAM = "av",      // new for portlet spec 3
+   RESOURCE_PARAM = "rv",    // new for portlet spec 3
+   RENDER_PARAM = "rp",
+   PUBLIC_RENDER_PARAM = "sp",
+   
+   
+   // constants for checking if portlet mode & window state have default values
+   VIEW = "VIEW",
+   NORMAL = "NORMAL",
 
-   AJAX_ACTION = "aa",              // new for portlet spec 3
-   PARTIAL_ACTION = "pa",           // new for portlet spec 3
    
    pidMap = {},
    
@@ -373,41 +359,61 @@ var portlet = portlet || {};
       for (ii = 0; ii < pids.length; ii++) {
          pid = pids[ii];
          pidMap[pid] = ii;
-         urlmap += "/" + PREFIX + PORTLET_ID;
-         urlmap += plutoEncode(pageState.portlets[pid].urlpid);
+         urlmap += TOKEN_DELIM + PREFIX + PORTLET_ID;
+         urlmap += encodeURIComponent(pageState.portlets[pid].urlpid);
          urlmap += DELIM + ii;
       }
       
       return urlmap;
    },
 
+   /**
+    * Helper for encoding a multivalued parameter
+    */
+   encodeParameter = function (name, vals) {
+	   var str = "", jj;
+	   if (vals) {
+		   str += encodeURIComponent(name);
+		   if (vals.length === 0) {
+			   str += VALUE_DELIM + VALUE_ARRAY_EMPTY;
+		   } else {
+			   for (jj=0; jj < vals.length; jj++) {
+				   if (vals[jj] === null) {
+					   str += VALUE_DELIM + VALUE_NULL;
+				   } else {
+					   str += VALUE_DELIM + encodeURIComponent(vals[jj]);
+				   }
+			   }
+		   }
+	   }
+	   return str;
+   },
    
    /**
     * Helper for generating parameter strings for the URL
     */
    genParmString = function (pid, name, type, group) {
-      var vals, jj, sep, str = "", wid = "", grpstr = "";
+      var vals, str = "", wid = "", grpstr = "";
       vals = pageState.portlets[pid].state.parameters[name];
       
-      // If encoding a render parameter, insert the pid in Pluto internal form 
-      // as opposed to namespace form -
-      
-      if (type === RENDER_PARAM || type === PUBLIC_RENDER_PARAM) {
-         wid = pidMap[pid];
-      }
-      
-      if (type === PUBLIC_RENDER_PARAM) {
-         grpstr = DELIM + plutoEncode(group);
-      }
-      
-      // If values are present, encode the multivalued parameter string
-      
-      if (vals) {
-         sep = VALUE_DELIM;
-         str += "/" + PREFIX + type + wid + grpstr + DELIM + encodeURIComponent(name);
-         for (jj=0; jj < vals.length; jj++) {
-            str += sep + encodeURIComponent(vals[jj]);
-         }
+      // if there are no values, return the empty string
+      if (vals !== undefined) {
+
+    	  // If encoding a render parameter, insert the pid in Pluto internal form 
+    	  // as opposed to namespace form -
+
+    	  if (type === RENDER_PARAM || type === PUBLIC_RENDER_PARAM
+    			  || type === ACTION_PARAM || type === RESOURCE_PARAM) {
+    		  wid = pidMap[pid];
+    	  }
+
+    	  if (type === PUBLIC_RENDER_PARAM) {
+    		  grpstr = DELIM + encodeURIComponent(group);
+    	  }
+
+    	  // If values are present, encode the multivalued parameter string
+
+    	  str += TOKEN_DELIM + PREFIX + type + wid + grpstr + DELIM + encodeParameter(name,
vals);
       }
       return str;
    },
@@ -421,8 +427,13 @@ var portlet = portlet || {};
           ws = pageState.portlets[pid].state.windowState, 
           wid = pidMap[pid], str = "";
 
-      str += "/" + PREFIX + PORTLET_MODE + wid + DELIM + encodeURIComponent(pm);
-      str += "/" + PREFIX + WINDOW_STATE + wid + DELIM + encodeURIComponent(ws);
+      // Only add PM & WS if the values are not default
+      if (pm.toUpperCase() !== VIEW) {
+    	  str += TOKEN_DELIM + PREFIX + PORTLET_MODE + wid + DELIM + encodeURIComponent(pm);
+      }
+      if (ws.toUpperCase() !== NORMAL) {
+    	  str += TOKEN_DELIM + PREFIX + WINDOW_STATE + wid + DELIM + encodeURIComponent(ws);
+      }
 
       return str;
    },
@@ -442,7 +453,7 @@ var portlet = portlet || {};
    getUrl = function (type, pid, parms, cache) {
    
       var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, isAction = false,
-          sep = "", name, names, vals, ii, str, id, ids, tpid, prpstrings, group;
+          name, names, ii, str, id, ids, tpid, prpstrings, group, ptype;
           
       url += getPidMap();
        
@@ -456,19 +467,22 @@ var portlet = portlet || {};
       
       if (type === "RESOURCE") {
          // If generating resource URL, add resource window & cacheability
-         url += "/" + PREFIX + RESOURCE + pidMap[pid];
+         url += TOKEN_DELIM + PREFIX + RESOURCE + pidMap[pid];
          if (cache) {
             ca = cache;
          }
-         url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
+         url += TOKEN_DELIM + PREFIX + CACHE_LEVEL + encodeURIComponent(ca);
+      } else if (type === "RENDER" && pid !== null) {
+         // Add Render window
+         url += TOKEN_DELIM + PREFIX + RENDER + pidMap[pid];
       } else if (type === "ACTION") {
-         // Add Ajax Action window
-         isAction = true;
-         url += "/" + PREFIX + AJAX_ACTION + pidMap[pid];
+          // Add Ajax Action window
+          isAction = true;
+          url += TOKEN_DELIM + PREFIX + AJAX_ACTION + pidMap[pid];
       } else if (type === "PARTIAL_ACTION") {
          // Add Partial Action window
          isAction = true;
-         url += "/" + PREFIX + PARTIAL_ACTION + pidMap[pid];
+         url += TOKEN_DELIM + PREFIX + PARTIAL_ACTION + pidMap[pid];
       }
       
       // Now add the state to the URL, taking into account cacheability if
@@ -500,7 +514,6 @@ var portlet = portlet || {};
          }
 
          // add the state for the target portlet for on-action urls.
-         // (Action URLs have only action parameters in the query string)
          // (for a render URL, pid can be null)
          if (!isAction && pid !== null) {
             url += genPMWSString(pid);  // portlet mode & window state
@@ -509,7 +522,7 @@ var portlet = portlet || {};
             for (name in names) {
                // Public render parameters are encoded separately
                if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
-                  str += genParmString(pid, name, PRIVATE_RENDER_PARAM);
+                  str += genParmString(pid, name, RENDER_PARAM);
                }
             }
             url += str;
@@ -537,19 +550,17 @@ var portlet = portlet || {};
 
       }
 
-      // Encode resource or action parameters as query string
+      // Encode resource or action parameters
       if (parms) {
-         str = ""; sep = "?";
-         for (parm in parms) {
-            if (parms.hasOwnProperty(parm)) {
-               vals = parms[parm];
-               for (ii=0; ii < vals.length; ii++) {
-                  str += sep + encodeURIComponent(parm) + "=" + encodeURIComponent(vals[ii]);
-                  sep = "&";
-               }
-            }
-         }
-         url += str;
+    	  str = "";
+    	  ptype = isAction ? ACTION_PARAM : RESOURCE_PARAM;
+    	  for (parm in parms) {
+    		  if (parms.hasOwnProperty(parm)) {
+    	          str += TOKEN_DELIM + PREFIX + ptype + pidMap[pid] + DELIM;
+    			  str += encodeParameter(parm, parms[parm]);
+    		  }
+    	  }
+    	  url += str;
       }
 
       // Use Promise to allow for potential server communication - 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/portlet-api/src/main/javascript/portlet.js
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/javascript/portlet.js b/portlet-api/src/main/javascript/portlet.js
index 4dbb0a1..d68b54a 100644
--- a/portlet-api/src/main/javascript/portlet.js
+++ b/portlet-api/src/main/javascript/portlet.js
@@ -825,9 +825,9 @@ var portlet = portlet || {};
       if (upids.length === 0) {
          busy = false;
       } else {
-      for (ii = 0; ii < upids.length; ii++) {
-         _updateStateForPortlet(upids[ii]);
-      }
+    	  for (ii = 0; ii < upids.length; ii++) {
+    		  _updateStateForPortlet(upids[ii]);
+    	  }
       }
 
    },
@@ -1082,8 +1082,8 @@ var portlet = portlet || {};
       // If an error occurred, post the error to the onError handler, if one is present.
 
       pi = _registeredPortlets[pid];
-      pi.executeAction(parms, element).then(function (upids) {
-         updatePageState(upids);
+      return pi.executeAction(parms, element).then(function (upids) {
+         return updatePageState(upids);
       }, function (err) {
          busy = false;
          if (oeListeners[pid]) {
@@ -1583,13 +1583,6 @@ var portlet = portlet || {};
              * submit the action to the server by executing a 'POST' with an action
              * URL containing any action parameters provided.
              * <p>
-             * A portlet action is a blocking operation.
-             * To allow for orderly state transitions, the portlet hub does not allow
-             * this function to be used while a blocking operation is in progress.
-             * A blocking operation is considered to be in progress
-             * from the initial call until the final onStateChange event for that
-             * operation has been fired. See {@link portlet} for further information.
-             * <p>
              * The parameters may be specified in either order, individually,
              * or not at all. Examples of valid calls:
              * <code>
@@ -1598,6 +1591,15 @@ var portlet = portlet || {};
              * <br>action(actParams);
              * <br>action(element);
              * </code>
+             * <p>
+             * A portlet action is a blocking operation.
+             * To allow for orderly state transitions, the portlet hub does not allow
+             * this function to be used while a blocking operation is in progress.
+             * A blocking operation is considered to be in progress
+             * from the initial call until the final onStateChange event for that
+             * operation has been fired. See {@link portlet} for further information.
+             * <p>
+             * 
              *
              * @param   {PortletParameters}  actParams   Action parameters to be
              *                                           added to the URL
@@ -1605,6 +1607,9 @@ var portlet = portlet || {};
              * @param   {HTMLFormElement}    element     DOM element of form to be submitted
              *                                           (optional)
              *
+             * @returns {Promise}   A Promise object that is resolved with no argument
+             * 						when the action request has completed.
+             *
              * @throws  {IllegalArgumentException}
              *                   Thrown if the input parameters are invalid
              * @throws  {AccessDeniedException}
@@ -1643,13 +1648,15 @@ var portlet = portlet || {};
                         throwIllegalArgumentException("too many parameters arguments.");
                      }
                      parms = arg;
-                  } else {
+                  } else 
+                  if (arg !== undefined) { 
                      throwIllegalArgumentException("Invalid argument type. Argument " + (ii
+ 1)
                             + " is of type " + type);
                   }
                }
                
                // if we're dealing with a form, verify method and enctype
+               console.log("form element", el);
                
                if (el) {
                   meth = el.method ? el.method.toUpperCase() : undefined;
@@ -1680,7 +1687,7 @@ var portlet = portlet || {};
          
                // everything ok, so do the action
          
-               setupAction(portletId, parms, el);
+               return setupAction(portletId, parms, el);
             },
          
             /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/355084b0/portlet-api/src/test/javascript/ActionTest.js
----------------------------------------------------------------------
diff --git a/portlet-api/src/test/javascript/ActionTest.js b/portlet-api/src/test/javascript/ActionTest.js
index 99fa385..f722597 100644
--- a/portlet-api/src/test/javascript/ActionTest.js
+++ b/portlet-api/src/test/javascript/ActionTest.js
@@ -187,13 +187,13 @@ describe('The portlet hub allows the portlet client to execute a portlet
action'
          expect(testFunc).toThrowCustomException("IllegalArgumentException");
       });
 
-      it('throws an IllegalArgumentException if action parameters is undefined',function(){
-         var el = document.createElement("form");
-         var testFunc = function () {
-            hubA.action(undefined, el);
-         }
-         expect(testFunc).toThrowCustomException("IllegalArgumentException");
-      });
+//       it('throws an IllegalArgumentException if action parameters is undefined',function(){
+//          var el = document.createElement("form");
+//          var testFunc = function () {
+//             hubA.action(undefined, el);
+//          }
+//          expect(testFunc).toThrowCustomException("IllegalArgumentException");
+//       });
 
       it('throws an IllegalArgumentException if action parameters is invalid',function(){
          var parms  = {rp1 : "resVal"};


Mime
View raw message