You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pluto-scm@portals.apache.org by ms...@apache.org on 2014/12/03 16:01:30 UTC

[05/11] portals-pluto git commit: Made a number of changes towards completion of portlet hub functionality:

Made a number of changes towards completion of portlet hub functionality:

1) Added accessor helper functions to the PortletParameters and PortletState
objects
2) Modified portlet JavaScript code to use the new accessors
3) Used jslint to improve the portletHubImpl.js code
4) Worked on implementation of the portlet hub action functionality through
use of a supplied form element. The JavaScript implementation uses the XHR2
FormData object.
5) Moved Pluto to a dependency on servlet API v3.0 in preparation for
implementation of multipart form support (needed to support the XHR2
FormData form submission)


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

Branch: refs/heads/PortletHub
Commit: 14efad10a8a5a04f5627d3e8361d957f288b9ff6
Parents: 9f9547e
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Dec 2 16:43:33 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Dec 2 16:43:33 2014 +0100

----------------------------------------------------------------------
 PortletHubDemo/pom.xml                          |   2 +-
 .../java/basic/portlet/ResourcePortlet.java     |  14 +-
 .../src/main/webapp/WEB-INF/jsp/view-csp.jsp    | 108 ++++---
 .../src/main/webapp/WEB-INF/jsp/view-isp.jsp    |  33 +-
 .../src/main/webapp/WEB-INF/jsp/view-ivp.jsp    |  29 +-
 .../src/main/webapp/WEB-INF/jsp/view-mbp.jsp    |  16 +-
 .../src/main/webapp/WEB-INF/jsp/view-pap.jsp    |  26 +-
 pluto-container-api/pom.xml                     |   2 +-
 pluto-container-driver-api/pom.xml              |   2 +-
 pluto-container/pom.xml                         |   2 +-
 pluto-portal-driver-impl/pom.xml                |   2 +-
 pluto-portal-driver/pom.xml                     |   2 +-
 pluto-portal/pom.xml                            |   2 +-
 pluto-portal/src/main/webapp/portlet.js         |  39 ++-
 pluto-portal/src/main/webapp/portletHubImpl.js  | 312 +++++++++----------
 pluto-taglib/pom.xml                            |   2 +-
 pluto-testsuite/pom.xml                         |   2 +-
 pom.xml                                         |   4 +-
 portlet-api_2.0_spec/pom.xml                    |   2 +-
 19 files changed, 313 insertions(+), 288 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/pom.xml
----------------------------------------------------------------------
diff --git a/PortletHubDemo/pom.xml b/PortletHubDemo/pom.xml
index 8ab229d..6249d99 100644
--- a/PortletHubDemo/pom.xml
+++ b/PortletHubDemo/pom.xml
@@ -19,7 +19,7 @@
       </dependency>
       <dependency>
          <groupId>javax.servlet</groupId>
-         <artifactId>servlet-api</artifactId>
+         <artifactId>javax.servlet-api</artifactId>
          <scope>provided</scope>
       </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
index ea0d918..7dac46f 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
@@ -34,6 +34,7 @@ import javax.portlet.ActionResponse;
 import javax.portlet.GenericPortlet;
 import javax.portlet.PortletException;
 import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.PortletURL;
 import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
@@ -93,13 +94,24 @@ public class ResourcePortlet extends GenericPortlet {
       
       String clr = req.getParameter(PARAM_COLOR);
       clr = (clr == null) ? "#FFFFFF" : clr;
+      
+      // add action button if cacheability allows -
+      PortletURL aurl = null;
+      String bmu = "<p>Action URL could not be created.</p>";
+      try {
+         aurl = resp.createActionURL();
+      } catch (Exception e) {}
+      if (aurl != null) {
+         bmu = "<form  METHOD='POST' ACTION='" + aurl + "'><input id='<portlet:namespace/>-clear' type='submit' name='action' value='Action' /></form>";
+      }
 
       writer.write("<div style='background-color:" + clr + ";'>\n");
       writer.write("   <table style='background-color:" + clr + ";'>");
       writer.write("   <tr><td align='center' style='background-color:" + clr + ";'>");
       writer.write("   <img src='" + ctx + imgDir + "'" + imgStyle + ">\n");
       writer.write("   </td><td style='background-color:" + clr + ";'>");
-      writer.write("   Cacheability: " + ca);
+      writer.write("   <p>" + bmu + "</p>");
+      writer.write("   <p>Cacheability: " + ca + "</p>");
       writer.write("   </td></tr>");
       writer.write("   </table>");
       writer.write("</div>\n");

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-csp.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-csp.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-csp.jsp
index ecc389d..1e69cea 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-csp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-csp.jsp
@@ -42,34 +42,43 @@ limitations under the License.
       }
 %>
 
-<FORM id='<portlet:namespace/>-setParams'  onsubmit='return false;'>
+<form onsubmit='return false;'>
+  <table><tr>
+     <td align='left'>Enter background color (public param):</td>
+     <td>
+        <input id='<portlet:namespace/>-color' name='<%=PARAM_COLOR%>' type='text' value='<%=clr%>' size='10' maxlength='10'>
+     </td>
+     <td><div id='<portlet:namespace/>-putMsgHere'></div></td>
+  </tr></table>
+</form>
+<hr/>
+<FORM id='<portlet:namespace/>-setParams' method='POST'>
    <table><tr><td align='left'>
-
-   Enter background color (public param):
-   </td><td colspan=3>
-   <input id='<portlet:namespace/>-color' name='" + PARAM_COLOR + "' type='text' value='<%=clr%>' size='10' maxlength='10'>
-   </td><td><div id='<portlet:namespace/>-putMsgHere'>
-   </div></td></tr><tr><td>
-
    Select active foreground colors:
    </td><td>
-   <input id='<portlet:namespace/>-red' name='" + PARAM_FG_COLOR + "' value='" + PARAM_FG_RED + "' type='checkbox' <%=r%>>
-   </td><td>Red
+   <input id='<portlet:namespace/>-red' name='<%=PARAM_FG_COLOR%>' value='<%=PARAM_FG_RED%>' type='checkbox' <%=r%>>
+   Red
    </td><td>
-   <input id='<portlet:namespace/>-green'  name='" + PARAM_FG_COLOR + "' value='" + PARAM_FG_GREEN + "' type='checkbox' <%=g%>>
-   </td><td>Green
+   <input id='<portlet:namespace/>-green'  name='<%=PARAM_FG_COLOR%>' value='<%=PARAM_FG_GREEN%>' type='checkbox' <%=g%>>
+   Green
    </td><td>
-   <input id='<portlet:namespace/>-blue'  name='" + PARAM_FG_COLOR + "' value='" + PARAM_FG_BLUE + "' type='checkbox' <%=b%>>
-   </td><td>Blue
+   <input id='<portlet:namespace/>-blue'  name='<%=PARAM_FG_COLOR%>' value='<%=PARAM_FG_BLUE%>' type='checkbox' <%=b%>>
+   Blue
 
    </td></tr><tr><td>
    Enter message:
-   </td><td colspan=6>
-   <input id='<portlet:namespace/>-msg' name='" + PARAM_MSG_INPUT + "' type='text' value='' size='50' maxlength='50'>
+   </td><td colspan=3>
+   <input id='<portlet:namespace/>-msg' name='<%=PARAM_MSG_INPUT%>' type='text' value='' size='50' maxlength='50'>
    </td><td>
 
    </td></tr><tr><td>
-   <INPUT id ='<portlet:namespace/>-send' VALUE='send' TYPE='button'>
+   Form submission:
+   </td><td>
+   <input id='<portlet:namespace/>sType-url' type='radio' name='sType' value='url' checked>URL
+   </td><td>
+   <input id='<portlet:namespace/>sType-form' type='radio' name='sType' value='form'>Form
+   </td><td>
+   <INPUT id ='<portlet:namespace/>-send' VALUE='send' TYPE='submit'>
    </td></tr></table>
 </FORM>
 <p><hr/></p>
@@ -86,16 +95,18 @@ limitations under the License.
        gid = '<portlet:namespace/>-green',
        bid = '<portlet:namespace/>-blue',
        mid = '<portlet:namespace/>-msg',
+       formid = '<portlet:namespace/>-setParams',
+       sidform = '<portlet:namespace/>sType-form',
        currState,
-       portletInit,
+       hub,
 
        
    // Handler for onStateChange event
    update = function (type, state) {
-      var oldColor = ((currState === undefined) || (currState.parameters.color === undefined)) ? '#FFFFFF' : currState.parameters.color[0],
-          newColor = (state.parameters.color === undefined) ? '#FFFFFF' : state.parameters.color[0];
+      var oldColor = currState.p.getValue('color'),
+          newColor = state.p.getValue('color', '#FFFFFF');
       console.log("CSP: state updated. Type=" + type + ", color=" + newColor);
-      if ((currState === undefined) || (newColor !== oldColor)) {
+      if (newColor !== oldColor) {
          document.getElementById(msgdiv).innerHTML = '';
          document.getElementById(colorEntry).value = newColor;
       }
@@ -106,8 +117,9 @@ limitations under the License.
    // Register portlet with Portlet Hub. Add listener for onStateChange event.
    portlet.register(pid).then(function (pi) {
       console.log("CSP Color Selection Portlet: registered: " + pid);
-      portletInit = pi;
-      portletInit.addEventListener("portlet.onStateChange", update);
+      hub = pi;
+      currState = hub.newState();
+      hub.addEventListener("portlet.onStateChange", update);
    });
    
 
@@ -119,32 +131,42 @@ limitations under the License.
          document.getElementById(msgdiv).innerHTML = 'Bad color. Enter #xxxxxx or #xxx.';
       } else {
          newState = currState.clone();
-         newState.parameters.color = [newColor];
-         portletInit.setPortletState(newState);
+         newState.p.setValue('color', newColor);
+         hub.setPortletState(newState);
       }
    };
    
 
    // Handler for 'send' button click. Perform partial action.
-   document.getElementById(sendbtn).onclick = function () {
-      var parms = {}, clrs = [];
-      console.log("CSP: sending message.");
-      parms.action = ['send'];
-      if (document.getElementById(rid).checked) {
-         clrs.push("red");
-      } 
-      if (document.getElementById(gid).checked) {
-         clrs.push("green");
-      } 
-      if (document.getElementById(bid).checked) {
-         clrs.push("blue");
-      } 
-      if (clrs.length > 0) {
-         parms.fgcolor = clrs;
+   document.getElementById(formid).addEventListener('submit', function (event) {
+      var parms, clrs = [], fel, submitForm = document.getElementById(sidform).checked;
+      
+      console.log("CSP: sending message. submitForm=" + submitForm);
+      
+      // decide how form is to be sent -
+      if (submitForm) {
+         fel = this;
+         hub.action(fel);
+      } else  {
+         parms = hub.newParameters();
+         parms.setValue('action', 'send');
+         if (document.getElementById(rid).checked) {
+            clrs.push("red");
+         } 
+         if (document.getElementById(gid).checked) {
+            clrs.push("green");
+         } 
+         if (document.getElementById(bid).checked) {
+            clrs.push("blue");
+         } 
+         if (clrs.length > 0) {
+            parms.setValue('fgcolor', clrs);
+         }
+         parms.setValue('imsg', document.getElementById(mid).value);
+         hub.action(parms);
       }
-      parms.imsg = [document.getElementById(mid).value];
-      portletInit.action(parms);
-   };
+      event.preventDefault();
+   });
       
 }());
 </script>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-isp.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-isp.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-isp.jsp
index 40bbfa6..5e60fd4 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-isp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-isp.jsp
@@ -51,8 +51,8 @@ limitations under the License.
        st_dropdown = '<portlet:namespace/>-dropdown',
        selBox = '<portlet:namespace/>-selBox',
    
-       currState,
-       portletInit,
+       currState = {},
+       hub,
    
    // Set image name PRP if radio button clicked - 
    handleImgRadio = function () {
@@ -60,8 +60,8 @@ limitations under the License.
       
       if (currState.parameters.imgName !== this.value) {
          var newState = currState.clone();
-         newState.parameters.imgName = [this.value];
-         portletInit.setPortletState(newState);
+         newState.p.setValue('imgName', this.value);
+         hub.setPortletState(newState);
       }
    },
    
@@ -71,21 +71,21 @@ limitations under the License.
       
       if (currState.parameters.imgName !== this.value) {
          var newState = currState.clone();
-         newState.parameters.imgName = [this.value];
-         portletInit.setPortletState(newState);
+         newState.p.setValue('imgName', this.value);
+         hub.setPortletState(newState);
       }
    },
    
    // Handler for onStateChange event
    update = function (type, state) {
-      var oldST = ((currState === undefined) || (currState.parameters.selType === undefined)) ? undefined : currState.parameters.selType[0],
-          newST = (state.parameters.selType === undefined) ? undefined : state.parameters.selType[0],
-          newImg = (state.parameters.imgName === undefined) ? undefined : state.parameters.imgName[0];
+      var oldST = currState.p.getValue('selType'),
+          newST = state.p.getValue('selType', 'radio'),
+          newImg = state.p.getValue('imgName');
           
       console.log("ISP: state updated. type=" + type + ", selType=" + newST + ", imgName=" + newImg);
       
-      if ((currState === undefined) || (oldST !== newST)) {
-         portletInit.createResourceUrl({}).then(function (url) {
+      if (oldST !== newST) {
+         hub.createResourceUrl({}).then(function (url) {
             console.log("ISP: got url: " + url);
             var xhr = new XMLHttpRequest();
             xhr.onreadystatechange=function() {
@@ -94,7 +94,7 @@ limitations under the License.
 
                   // default is radio buttons
                   var ii, f = document.getElementById(fid);
-                  if ((newST === undefined) || (newST === 'radio')) {
+                  if (newST === 'radio') {
                      for (ii=0; ii < f.imgName.length; ii++) {
                         console.log("ISP: adding selection handler for: " + f.imgName[ii].value);
                         f.imgName[ii].onclick = handleImgRadio;
@@ -135,8 +135,8 @@ limitations under the License.
       console.log("ISP: select display type clicked: " + this.value);
       if (currState.parameters.selType !==  this.value) {
          var newState = currState.clone();
-         newState.parameters.selType = [this.value];
-         portletInit.setPortletState(newState);
+         newState.p.setValue('selType', this.value);
+         hub.setPortletState(newState);
       }
    };
    
@@ -147,8 +147,9 @@ limitations under the License.
    // Register with Portlet Hub, add listener for onStateChange event
    portlet.register(pid).then(function (pi) {
       console.log("ISP Image Selection Portlet: registered: " + pid);
-      portletInit = pi;
-      portletInit.addEventListener("portlet.onStateChange", update);
+      hub = pi;
+      currState = hub.newState();
+      hub.addEventListener("portlet.onStateChange", update);
    });
    
    

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
index 982a41e..e94462a 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
@@ -31,9 +31,9 @@ limitations under the License.
    <table><tr><td align='left'>
    Cacheability setting:
    </td><td>
-   <input id='<portlet:namespace/>-page' type='radio' name='cacheability' value='cacheLevelPage'>Page
-   <input id='<portlet:namespace/>-portlet' type='radio' name='cacheability' value='cacheLevelPortlet'>Portlet
-   <input id='<portlet:namespace/>-full' type='radio' name='cacheability' value='cacheLevelFull'>Full
+   <input id='<portlet:namespace/>-page' type='radio' name='cacheability' value='PAGE'>Page
+   <input id='<portlet:namespace/>-portlet' type='radio' name='cacheability' value='PORTLET'>Portlet
+   <input id='<portlet:namespace/>-full' type='radio' name='cacheability' value='FULL'>Full
    </td></tr><tr><td>
    Set border (resource parameter)
    </td><td>
@@ -58,14 +58,14 @@ limitations under the License.
        cntr = 1,
        
        resparms = {},
-       cacheability = 'cacheLevelPage',
-       portletInit,
+       cacheability,
+       hub,
    
    // Update function called by the Portlet Hub when an onStatechange event occurs. 
    update = function (type, state) {
       console.log("IVP: state updated. event type=" + type);
       
-      portletInit.createResourceUrl(resparms, cacheability).then(function (url) {
+      hub.createResourceUrl(resparms, cacheability).then(function (url) {
          var brdr = (resparms.border === undefined) ? undefined : resparms.border[0],
              xhr = new XMLHttpRequest();
          console.log("IVP: got url: " + url + ", res parm border=" + brdr);
@@ -81,9 +81,10 @@ limitations under the License.
    
    // Handler for cacheability radio buttons
    handleCA = function () {
-      console.log("IVP: cacheability button clicked: " + this.value);
-      if (cacheability !== this.value) {
-         cacheability = this.value;
+      var c = hub.constants[this.value];
+      console.log("IVP: cacheability button clicked: " + this.value + ", corresponding to constant value " + c);
+      if (cacheability !== c) {
+         cacheability = c;
          update();
       }
    };
@@ -98,9 +99,9 @@ limitations under the License.
    document.getElementById(border).onclick = function () {
       console.log("IVP: border checked: " + this.checked);
       if (this.checked) {
-         resparms.border = ['#00F'];
+         resparms.setValue('border', '#00F');;
       } else {
-         resparms = {};
+         resparms.remove('border');
       }
       update();
    };
@@ -109,8 +110,10 @@ limitations under the License.
    // the onStateChange event
    portlet.register(pid).then(function (pi) {
       console.log("IVP: registered: " + pid);
-      portletInit = pi;
-      portletInit.addEventListener("portlet.onStateChange", update);
+      hub = pi;
+      resparms = hub.newParameters();
+      cacheability = hub.constants.PAGE;
+      hub.addEventListener("portlet.onStateChange", update);
    });
    
    // Simple counter for demonstrating that page hasn't been refreshed.

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
index d204831..5e85af0 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
@@ -48,16 +48,16 @@ limitations under the License.
        clrButton = '<portlet:namespace/>-clear',
    
        state,
-       resparms = {},
-       cacheability = 'cacheLevelPage',
-       portletInit,
+       resparms,
+       cacheability,
+       hub,
    
    // Handler for onStateChange event
    update = function (type, s) {
       console.log("MBP: state updated. Event type = " + type);
       state = s;
       
-      portletInit.createResourceUrl(resparms, cacheability).then(function (url) {
+      hub.createResourceUrl(resparms, cacheability).then(function (url) {
          var xhr = new XMLHttpRequest();
          console.log("MBP: got url: " + url);
          xhr.onreadystatechange = function () {
@@ -73,14 +73,16 @@ limitations under the License.
    // Handler for "clear" button. execute an action which clears the stored messages
    document.getElementById(clrButton).onclick = function () {
       console.log("MBP: clear button clicked. ");
-      portletInit.action();
+      hub.action();
    };
    
    // Register portlet with Portlet Hub; add onStateChange listener 
    portlet.register(pid).then(function (pi) {
       console.log("MBP: Message Box portlet registered: " + pid);
-      portletInit = pi;
-      portletInit.addEventListener("portlet.onStateChange", update);
+      hub = pi;
+      resparms = hub.newParameters();
+      cacheability = hub.constants.PAGE;
+      hub.addEventListener("portlet.onStateChange", update);
    });
    
 }());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp
index 3e96ad1..12153ab 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp
@@ -44,33 +44,29 @@ limitations under the License.
        paButton = '<portlet:namespace/>-doPA',
    
        state,
-       actparms = {},
-       portletInit,
+       actparms,
+       hub,
    
    // Handler for onStateChange event
    update = function (type, s) {
       console.log("PAP: state updated. Event type = " + type);
       
-      if (state) {
-         // change background color for message box
-         if (state.parameters.color !== s.parameters.color) {
-            document.getElementById(resdiv).style.background = s.parameters.color;
-         }
+      // change background color for message box
+      if (state.p.getValue('color') !== s.p.getValue('color')) {
+         document.getElementById(resdiv).style.background = s.p.getValue('color');
       }
       state = s;
    };
    
    // Handler for "partial action" button. Perform partial action sequence.
    document.getElementById(paButton).onclick = function () {
-      var xhr = new XMLHttpRequest(), vals, pagestate = null, markup;
+      var xhr = new XMLHttpRequest(), vals, pagestate = null, markup; 
       console.log("PAP: Partial action button clicked.");
       
       // Add the render parameter counter as action parameter
-      if (state.parameters.numActions) {
-         actparms.numActions = state.parameters.numActions;
-      }
+      actparms.setValue('numActions', state.p.getValue('numActions'));
       
-      portletInit.startPartialAction(actparms).then(function (pai) {
+      hub.startPartialAction(actparms).then(function (pai) {
          
          console.log("PAP: got partial action init object. URL: " + pai.url);
          
@@ -101,8 +97,10 @@ limitations under the License.
    // Register portlet with Portlet Hub; add onStateChange listener 
    portlet.register(pid).then(function (pi) {
       console.log("PAP: registered: " + pid);
-      portletInit = pi;
-      portletInit.addEventListener("portlet.onStateChange", update);
+      hub = pi;
+      state = hub.newState();
+      actparms = hub.newParameters();
+      hub.addEventListener("portlet.onStateChange", update);
    });
    
 }());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-container-api/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-container-api/pom.xml b/pluto-container-api/pom.xml
index f2a5e9b..9885f69 100644
--- a/pluto-container-api/pom.xml
+++ b/pluto-container-api/pom.xml
@@ -41,7 +41,7 @@
 
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-container-driver-api/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/pom.xml b/pluto-container-driver-api/pom.xml
index ad12f24..0796116 100644
--- a/pluto-container-driver-api/pom.xml
+++ b/pluto-container-driver-api/pom.xml
@@ -41,7 +41,7 @@
     
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-container/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-container/pom.xml b/pluto-container/pom.xml
index 9697fff..ca5d8a0 100644
--- a/pluto-container/pom.xml
+++ b/pluto-container/pom.xml
@@ -56,7 +56,7 @@
 
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-portal-driver-impl/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/pom.xml b/pluto-portal-driver-impl/pom.xml
index cbfde1a..6191c83 100644
--- a/pluto-portal-driver-impl/pom.xml
+++ b/pluto-portal-driver-impl/pom.xml
@@ -84,7 +84,7 @@
 
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-portal-driver/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/pom.xml b/pluto-portal-driver/pom.xml
index 2aa8eca..9595722 100644
--- a/pluto-portal-driver/pom.xml
+++ b/pluto-portal-driver/pom.xml
@@ -64,7 +64,7 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-portal/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-portal/pom.xml b/pluto-portal/pom.xml
index 4e3051d..721797c 100644
--- a/pluto-portal/pom.xml
+++ b/pluto-portal/pom.xml
@@ -108,7 +108,7 @@
 	 </dependency>
     <dependency>
        <groupId>javax.servlet</groupId>
-       <artifactId>servlet-api</artifactId>
+       <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/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 5abdd2d..bfffb69 100644
--- a/pluto-portal/src/main/webapp/portlet.js
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -51,16 +51,18 @@
  * functions for accessing the parameter values.
  * <p>
  * @typedef    PortletParameters
- * @property   {string[]}  {string}   The parameters object may have
- *                                    multiple properties.
+ * @property   {string[]}  {string}    The parameters object may have
+ *                                     multiple properties.
  * @property   {function}   clone()          Returns a new copy of this object
  * @property   {function}   setValue(n,v)    Sets a parameter with name n and value v.
  *                                           The value v may be a string or an array.
  * @property   {function}   setValues(n,v)   Sets a parameter with name n and value v.
  *                                           The value v may be a string or an array.
- * @property   {function}   getValue(n)      Gets the string parameter value for the name n.
+ * @property   {function}   getValue(n,d)    Gets the string parameter value for the name n.
  *                                           If n designates a multi-valued parameter, this function returns the first value in the values array.
- * @property   {function}   getValues(n)     Gets the string array parameter value for the name n.
+ *                                           If parameter n is undefined, the function returns the optional default value d.
+ * @property   {function}   getValues(n,d)   Gets the string array parameter value for the name n.
+ *                                           If parameter n is undefined, the function returns the optional default value array d.
  * @property   {function}   remove(n)        Removes the parameter with name n.
  */
 
@@ -373,15 +375,22 @@ var portlet = portlet || {};
          delete this[name];
       }
    };
-   Parameters.prototype.getValue = function (name) {
+   Parameters.prototype.getValue = function (name, def) {
       var res = this[name];
       if (res) {
          res = res[0];
       }
+      if (res === undefined) {
+         res = def;
+      }
       return res;
    };
-   Parameters.prototype.getValues = function (name) {
-      return this[name];
+   Parameters.prototype.getValues = function (name, def) {
+      var res = this[name]; 
+      if (res === undefined) {
+         res = def;
+      }
+      return res;
    };
    
    function State (s) {
@@ -816,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]);
+      }
       }
 
    },
@@ -1087,13 +1096,14 @@ var portlet = portlet || {};
       if ((ustr === undefined) || ((ustr !== null) && (typeof ustr !== 'string'))) {
          throwIllegalArgumentException("Invalid update string: " + ustr);
       }
+
       // convert page state into an object.
       // update each affected portlet client. Makes use of a 
       // mockup-specific function for decoding. 
 
       pi = _registeredPortlets[pid];
       pi.decodeUpdateString(ustr).then(function (upids) {
-         updatePageState(upids);
+      updatePageState(upids);
       }, function (err) {
          busy = false;
          if (oeListeners[pid]) {
@@ -1377,8 +1387,8 @@ var portlet = portlet || {};
                updateState(portletId, state);
          
             },
-         
-         
+
+
             /**
              * Returns a promise for a resource URL with parameters set appropriately
              * for the page state according to the  resource parameters
@@ -1570,9 +1580,8 @@ var portlet = portlet || {};
              */
             action : function (actParams, element) {
                var ii, arg, type, parms = null, el = null;
-
+         
                console.log("Executing action for portlet: " + portletId);
-
                // check arguments. make sure there is a maximum of two
                // args and determine the types. Check values as possible.
                if (arguments.length > 2) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/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 913184a..6e22a99 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -58,11 +58,10 @@ var portlet = portlet || {};
    isValidId = function (pid) {
       var id;
       for (id in pageState) {
-         if (!pageState.hasOwnProperty(id)) {
-            continue;
-         }
-         if (pid === id) {
-            return true;
+         if (pageState.hasOwnProperty(id)) {
+            if (pid === id) {
+               return true;
+            }
          }
       }
       return false;
@@ -87,17 +86,6 @@ var portlet = portlet || {};
    getParmVal = function (pid, name) {
       return pageState[pid].state.parameters[name];
    },
-   
-   /**
-    * gets parameter value
-    */
-   setParmVal = function (pid, name, val) {
-      if (val === undefined) {
-         delete pageState[pid].state.parameters[name];
-      } else {
-         pageState[pid].state.parameters[name] = val.slice(0);
-      }
-   },
 
    /**
     * Compares the values of two parameters and returns true if they are equal
@@ -151,7 +139,7 @@ var portlet = portlet || {};
       if (nstate.portletMode !== ostate.portletMode) {
          result = true;
       } else {
-         if (nstate.windowState != ostate.windowState) {
+         if (nstate.windowState !== ostate.windowState) {
             result = true;
          } else {
             
@@ -262,7 +250,9 @@ var portlet = portlet || {};
       }, key, oldParams = aState.parameters;
    
       for (key in oldParams) {
-         newParams[key] = oldParams[key].slice(0); 
+         if (oldParams.hasOwnProperty(key)) {
+            newParams[key] = oldParams[key].slice(0);
+         }
       }
    
       return newState;
@@ -360,31 +350,36 @@ var portlet = portlet || {};
          }
       });
    },
+
    
-   
-   /**
-    * Update page state passed in after partial action. The list of 
-    * ID's of updated portlets is passed back through a promise in order
-    * to decouple the layers.
-    * 
-    * @param   {string}    ustr     The 
-    * @param   {string}    pid      The portlet ID
-    * @private 
-    */
-   updatePageState = function (ustr, pid) {
+   // decodes the update strings. The update string is 
+   // a JSON object containing the entire page state. This decoder 
+   // returns an object containing the state for portlets whose 
+   // state has changed as compared to the current page state.
+   decodeUpdateString = function (ustr) {
+      var states = {}, ostate, nstate, pid, ps, npids = 0, cpids = 0;
+
+      ps = JSON.parse(ustr);
+      for (pid in ps) {
+         if (ps.hasOwnProperty(pid)) {
+            npids++;
+            nstate = ps[pid].state;
+            ostate = pageState[pid].state;
             
-      // Use Promise to allow for potential server communication - 
-      return new Promise(function (resolve, reject) {
-         var upids;
-               
-         try {
-            upids = updatePageStateFromString(ustr, pid);
-            resolve(upids);
-         } catch (e) {
-            reject(new Error("Partial Action Action decode status: " + e.message));
+            if (!nstate || !ostate) {
+               throw new Error ("Invalid update string. ostate=" + ostate + ", nstate=" + nstate);
+            }
+            
+            if (stateChanged(nstate, pid)) {
+               states[pid] = cloneState(nstate);
+               cpids++;
+            }
          }
-      });
-
+      }
+      
+      console.log("decoded state for " + npids + " portlets. # changed = " + cpids);
+      
+      return states;
    },
 
       
@@ -412,57 +407,29 @@ var portlet = portlet || {};
 
       return upids;
    },
-
-      
+   
+   
    /**
-    * performs the actual action.
+    * Update page state passed in after partial action. The list of 
+    * ID's of updated portlets is passed back through a promise in order
+    * to decouple the layers.
     * 
+    * @param   {string}    ustr     The 
     * @param   {string}    pid      The portlet ID
-    * @param   {PortletParameters}    parms      
-    *                Additional parameters. May be <code>null</code>
-    * @param   {HTMLFormElement}    Form to be submitted
-    *                               May be <code>null</code> 
     * @private 
     */
-   executeAction = function (pid, parms, element) {
-      var url;
-
-      console.log("impl: executing action. parms=" + parms + ", element=" + element)
-
-      // create & return promise to caller. 
-
-      return new Promise(function (resolve, reject) {
-
-         // get the ajax action URL. The Pluto impl creates the URL in JS
-         // therefore no error handling 
-         getUrl("ACTION", pid, parms).then(function (url) {
-            var xhr, upids;
-
-            console.log("ajax action URL: " + url);
-            
-            if (element) {
-
-            } else {
-               xhr = new XMLHttpRequest();
-               xhr.onreadystatechange = function () {
-                  if (xhr.readyState==4) {
-                     if (xhr.status==200) {
-                        try {
-                           upids = updatePageStateFromString(xhr.responseText, pid);
-                           resolve(upids);
-                        } catch (e) {
-                           reject(new Error("Ajax Action decode status: " + e.message));
-                        }
-                     } else {
-                        reject(new Error("Ajax Action xhr status: " + xhr.statusText));
-                     }
-                  }
-               };
-               xhr.open("POST", url, true);
-                     xhr.send();
-            }
-         });
+   updatePageState = function (ustr, pid) {
             
+      // Use Promise to allow for potential server communication - 
+      return new Promise(function (resolve, reject) {
+         var upids;
+               
+         try {
+            upids = updatePageStateFromString(ustr, pid);
+            resolve(upids);
+         } catch (e) {
+            reject(new Error("Partial Action Action decode status: " + e.message));
+         }
       });
 
    },
@@ -530,7 +497,7 @@ var portlet = portlet || {};
       // as opposed to namespace form -
       
       if (type === RENDER_PARAM) {
-         wid = plutoEncode(pageState[pid].urlpid)
+         wid = plutoEncode(pageState[pid].urlpid);
       }
       
       // If values are present, encode the multivalued parameter string
@@ -576,7 +543,7 @@ var portlet = portlet || {};
    getUrl = function (type, pid, parms, cache) {
    
       var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, isAction = false,
-          sep = "", name, names, val, vals, ii, jj, str, id, ids, tpid, prpstrings;
+          sep = "", name, names, vals, ii, str, id, ids, tpid, prpstrings;
 
       // First add the appropriate window identifier according to URL type.
       // Note that no special window ID is added to a RENDER URL. 
@@ -678,54 +645,65 @@ var portlet = portlet || {};
       }
 
       // Use Promise to allow for potential server communication - 
-      return new Promise(function (resolve, reject) {
+      return new Promise(function (resolve) {
          resolve(url);
       });
    },
-   
-   
+
+      
    /**
-    * Exception thrown when a portlet hub method is provided with an invalid argument.
-    * @typedef    IllegalArgumentException 
-    * @property   {string}    name     The exception name, equal to "IllegalArgumentException"
-    * @property   {string}    message  An optional message that provides more detail about the exception
+    * performs the actual action.
+    * 
+    * @param   {string}    pid      The portlet ID
+    * @param   {PortletParameters}    parms      
+    *                Additional parameters. May be <code>null</code>
+    * @param   {HTMLFormElement}    Form to be submitted
+    *                               May be <code>null</code> 
+    * @private 
     */
-   throwIllegalArgumentException = function (msg) {
-      throw {
-         name : "IllegalArgumentException",
-         message : msg
-      };
-   },
+   executeAction = function (pid, parms, element) {
 
-   
-   // decodes the update strings. The update string is 
-   // a JSON object containing the entire page state. This decoder 
-   // returns an object containing the state for portlets whose 
-   // state has changed as compared to the current page state.
-   decodeUpdateString = function (ustr) {
-      var states = {}, ostate, nstate, pid, ps, npids = 0, cpids = 0;
+      console.log("impl: executing action. parms=" + parms + ", element=" + element);
 
-      ps = JSON.parse(ustr);
-      for (pid in ps) {
-         if (ps.hasOwnProperty(pid)) {
-            npids++;
-            nstate = ps[pid].state;
-            ostate = pageState[pid].state;
+      // create & return promise to caller. 
+
+      return new Promise(function (resolve, reject) {
+
+         // get the ajax action URL. The Pluto impl creates the URL in JS
+         // therefore no error handling 
+         getUrl("ACTION", pid, parms).then(function (url) {
+            var xhr, upids, fd;
+
+            console.log("ajax action URL: " + url);
             
-            if (!nstate || !ostate) {
-               throw new Error ("Invalid update string. ostate=" + ostate + ", nstate=" + nstate);
+            xhr = new XMLHttpRequest();
+            xhr.onreadystatechange = function () {
+               if (xhr.readyState === 4) {
+                  if (xhr.status === 200) {
+                     try {
+                        upids = updatePageStateFromString(xhr.responseText, pid);
+                        resolve(upids);
+                     } catch (e) {
+                        reject(new Error("Ajax Action decode status: " + e.message));
+                     }
+                  } else {
+                     reject(new Error("Ajax Action xhr status: " + xhr.statusText));
+                  }
+               }
+            };
+            xhr.open("POST", url, true);
+            if (element) {
+               fd = new FormData(element);
+               console.log("ajax action: POST using FormData object: " + fd);
+               xhr.send(fd);
+            } else {
+               console.log("ajax action: POST using URL with parameters");
+               xhr.send();
             }
+         });
             
-            if (stateChanged(nstate, pid)) {
-               states[pid] = cloneState(nstate);
-               cpids++;
-            }
-         }
-      }
-      
-      console.log("decoded state for " + npids + " portlets. # changed = " + cpids);
-      
-      return states;
+      });
+
    };
 
    
@@ -755,47 +733,47 @@ var portlet = portlet || {};
       // stubs for accessing data for this portlet
       var stubs = {
    
-			/**
-			 * Get allowed window states for portlet
-			 */
-			getAllowedWS : function () {return getAllowedWS(pid);},
-   
-			/**
-			 * Get allowed portlet modes for portlet
-			 */
-			getAllowedPM : function () {return getAllowedPM(pid);},
-   
-			/**
-			 * Get render data for portlet, if any
-			 */
-			getRenderData : function () {return getRenderData(pid);},
-   
-			/**
-			 * Get current portlet state
-			 */
-			getState : function () {return getState(pid);},
-   
-			/**
-			 * Set new portlet state. Returns promise fullfilled with an array of
-			 * IDs of portlets whose state have been modified.
-			 */
-			setState : function (state) {return setState(pid, state);},
-   
-			/**
-			 * Perform the Ajax action request
-			 */
-			executeAction : function (parms, element) {return executeAction(pid, parms, element);},
-   
-			/**
-			 * Get a URL of the specified type - resource or partial action
-			 */
-			getUrl : function (type, parms, cache) {return getUrl(type, pid, parms, cache);},
-   
-			/**
-			 * Decode the update string returned by the partial action request.
-			 * Returns array of IDs of portlets to be updated.
-			 */
-			decodeUpdateString : function (ustr) {return updatePageState(ustr, pid);},
+         /**
+          * Get allowed window states for portlet
+          */
+         getAllowedWS : function () {return getAllowedWS(pid);},
+   
+         /**
+          * Get allowed portlet modes for portlet
+          */
+         getAllowedPM : function () {return getAllowedPM(pid);},
+   
+         /**
+          * Get render data for portlet, if any
+          */
+         getRenderData : function () {return getRenderData(pid);},
+   
+         /**
+          * Get current portlet state
+          */
+         getState : function () {return getState(pid);},
+   
+         /**
+          * Set new portlet state. Returns promise fullfilled with an array of
+          * IDs of portlets whose state have been modified.
+          */
+         setState : function (state) {return setState(pid, state);},
+   
+         /**
+          * Perform the Ajax action request
+          */
+         executeAction : function (parms, element) {return executeAction(pid, parms, element);},
+   
+         /**
+          * Get a URL of the specified type - resource or partial action
+          */
+         getUrl : function (type, parms, cache) {return getUrl(type, pid, parms, cache);},
+   
+         /**
+          * Decode the update string returned by the partial action request.
+          * Returns array of IDs of portlets to be updated.
+          */
+         decodeUpdateString : function (ustr) {return updatePageState(ustr, pid);}
    
       };            
       
@@ -829,4 +807,4 @@ var portlet = portlet || {};
       getIds : getIds
    }; 
    
-})();
+}());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-taglib/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-taglib/pom.xml b/pluto-taglib/pom.xml
index 924c775..0e34d0f 100644
--- a/pluto-taglib/pom.xml
+++ b/pluto-taglib/pom.xml
@@ -40,7 +40,7 @@
     </dependency>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
     <dependency>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pluto-testsuite/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-testsuite/pom.xml b/pluto-testsuite/pom.xml
index 9b3d892..4eb285a 100644
--- a/pluto-testsuite/pom.xml
+++ b/pluto-testsuite/pom.xml
@@ -39,7 +39,7 @@
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
+            <artifactId>javax.servlet-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7cdafb4..8914183 100644
--- a/pom.xml
+++ b/pom.xml
@@ -257,7 +257,7 @@ generate mailto links. -->
     <javax.portlet.version.major>2</javax.portlet.version.major>
     <javax.portlet.version.minor>0</javax.portlet.version.minor>
     <portals.portlet2-api-spec.version>${project.version}</portals.portlet2-api-spec.version>
-    <servlet-api.version>2.4</servlet-api.version>
+    <servlet-api.version>3.0.1</servlet-api.version>
     <jsp-api.version>2.0</jsp-api.version>
     <jstl.version>1.1.2</jstl.version>
     <taglibs.standard.version>1.1.2</taglibs.standard.version>
@@ -324,7 +324,7 @@ TODO: Check if we need all of them. -->
       </dependency>
       <dependency>
         <groupId>javax.servlet</groupId>
-        <artifactId>servlet-api</artifactId>
+        <artifactId>javax.servlet-api</artifactId>
         <version>${servlet-api.version}</version>
       </dependency>
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/14efad10/portlet-api_2.0_spec/pom.xml
----------------------------------------------------------------------
diff --git a/portlet-api_2.0_spec/pom.xml b/portlet-api_2.0_spec/pom.xml
index ed01ebf..48fdcd9 100644
--- a/portlet-api_2.0_spec/pom.xml
+++ b/portlet-api_2.0_spec/pom.xml
@@ -40,7 +40,7 @@
   <dependencies>
     <dependency>
       <groupId>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
+      <artifactId>javax.servlet-api</artifactId>
       <scope>provided</scope>
     </dependency>
   </dependencies>