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/11/29 19:47:58 UTC

[3/5] portals-pluto git commit: Implemented Partial Action portlet. Tested Partial Action execution path in PortletHubImpl and in Pluto server. Implemented serveral fixes in the are of parameter handling in both client-side and server-side code.

Implemented Partial Action portlet. Tested Partial Action
execution path in PortletHubImpl and in Pluto server. Implemented serveral
fixes in the are of parameter handling in both client-side and server-side
code.


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

Branch: refs/heads/PortletHub
Commit: a27e40db3e2fd9ff28155915178f62a176ea5578
Parents: d4269e9
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Nov 28 12:12:24 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Nov 28 12:12:24 2014 +0100

----------------------------------------------------------------------
 .../src/main/java/basic/portlet/Constants.java  |   2 +
 .../basic/portlet/PartialActionPortlet.java     | 114 +++++++++++
 .../src/main/webapp/WEB-INF/jsp/view-ivp.jsp    |  10 +-
 .../src/main/webapp/WEB-INF/jsp/view-mbp.jsp    |  16 +-
 .../src/main/webapp/WEB-INF/jsp/view-pap.jsp    | 109 +++++++++++
 .../src/main/webapp/WEB-INF/portlet.xml         |  20 ++
 .../pluto/container/PortletContainer.java       |   3 +-
 .../container/PortletRequestContextService.java | 114 +++++------
 .../PortletResourceRequestContext.java          |  66 ++++---
 .../container/impl/PortletContainerImpl.java    |   5 +-
 .../container/impl/ResourceRequestImpl.java     |  38 +++-
 .../PortletRequestContextServiceImpl.java       | 189 ++++++++++---------
 .../PortletResourceRequestContextImpl.java      | 124 ++++++------
 .../pluto/driver/PortalDriverServlet.java       |  19 +-
 pluto-portal/src/main/webapp/portlet.js         |  17 +-
 pluto-portal/src/main/webapp/portletHubImpl.js  |  53 ++++--
 16 files changed, 619 insertions(+), 280 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 7b3ee48..a001d89 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/Constants.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/Constants.java
@@ -36,6 +36,8 @@ public class Constants {
    public final static String PARAM_FG_BLUE = "blue";
    public final static String PARAM_MSG_INPUT = "imsg";
    
+   public final static String PARAM_NUM_ACTIONS = "numActions";
+
    public final static String PARAM_NUM_MSGS = "numMsgs";
    public final static String ATTRIB_MSGS = "msgs";
    

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
new file mode 100644
index 0000000..eb5b6cb
--- /dev/null
+++ b/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
@@ -0,0 +1,114 @@
+/*  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.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.ResourceURL;
+
+/**
+ * A management portlet that displays the current deep link configuraion
+ */
+public class PartialActionPortlet extends GenericPortlet {
+
+   // Set up logging
+   private static final String LOG_CLASS = PartialActionPortlet.class.getName();
+   private final Logger logger = Logger.getLogger(LOG_CLASS);
+
+   protected void doView(RenderRequest req, RenderResponse resp)
+         throws PortletException, IOException {
+      
+      if (logger.isLoggable(Level.FINE)) {
+         logger.logp(Level.FINE, this.getClass().getName(), "doView", "Entry");
+      }
+      
+      resp.setContentType("text/html");
+
+      PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(
+            "/WEB-INF/jsp/view-pap.jsp");
+      rd.include(req, resp);
+
+   }
+
+   @Override
+   public void processAction(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+
+      // the only action for this portlet is to increment the execition counter
+
+      String val = req.getParameter(PARAM_NUM_ACTIONS);
+      int na = 1;
+      if (val != null) {
+         try {
+            na = Integer.parseInt(val) + 1;
+         } catch (Exception e) {}
+      }
+      
+      String actionName = req.getParameter("action");
+      logger.fine("PAP: executing partial action. action number = " + na + ", name =  " + actionName);
+
+      resp.setRenderParameter(PARAM_NUM_ACTIONS, Integer.toString(na));
+   }
+   
+   @Override
+   public void processEvent(EventRequest req, EventResponse resp) 
+         throws PortletException ,IOException {
+   };
+   
+   /* (non-Javadoc)
+    * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
+    */
+   @SuppressWarnings("unchecked")
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp)
+         throws PortletException, IOException {
+      
+      resp.setContentType("text/html");
+      PrintWriter writer = resp.getWriter();
+
+      String num = req.getParameter(PARAM_NUM_ACTIONS);
+      num = (num == null) ? "error" : num;
+      
+      String pageState = req.getPageState();
+      
+      writer.write("<p>Partial Action has been executed " + num + " times.</p>\n");
+      writer.write(";#delimiter#;");
+      writer.write(pageState);
+      
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 67c07d3..982a41e 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-ivp.jsp
@@ -63,12 +63,12 @@ limitations under the License.
    
    // Update function called by the Portlet Hub when an onStatechange event occurs. 
    update = function (type, state) {
-      console.log("Resource Portlet: state updated. event type=" + type);
+      console.log("IVP: state updated. event type=" + type);
       
       portletInit.createResourceUrl(resparms, cacheability).then(function (url) {
          var brdr = (resparms.border === undefined) ? undefined : resparms.border[0],
              xhr = new XMLHttpRequest();
-         console.log("Resource Portlet: got url: " + url + ", res parm border=" + brdr);
+         console.log("IVP: got url: " + url + ", res parm border=" + brdr);
          xhr.onreadystatechange = function () {
             if (xhr.readyState === 4 && xhr.status === 200) {
                document.getElementById(resdiv).innerHTML=xhr.responseText;
@@ -81,7 +81,7 @@ limitations under the License.
    
    // Handler for cacheability radio buttons
    handleCA = function () {
-      console.log("cacheability button clicked: " + this.value);
+      console.log("IVP: cacheability button clicked: " + this.value);
       if (cacheability !== this.value) {
          cacheability = this.value;
          update();
@@ -96,7 +96,7 @@ limitations under the License.
    // Handler for 'border' checkbox 
    document.getElementById(border).checked = false;
    document.getElementById(border).onclick = function () {
-      console.log("border checked: " + this.checked);
+      console.log("IVP: border checked: " + this.checked);
       if (this.checked) {
          resparms.border = ['#00F'];
       } else {
@@ -108,7 +108,7 @@ limitations under the License.
    // Register this portlet with the Portlet Hub and add event listener for 
    // the onStateChange event
    portlet.register(pid).then(function (pi) {
-      console.log("registered: " + pid);
+      console.log("IVP: registered: " + pid);
       portletInit = pi;
       portletInit.addEventListener("portlet.onStateChange", update);
    });

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 deda0c8..d204831 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-mbp.jsp
@@ -31,12 +31,11 @@ limitations under the License.
 %>
 
 <div style='clear:both;'>
-<div style='float:left;'><h3>Image Viewer</h3></div>
+<div style='float:left;'><h3>Message Box Portlet</h3></div>
 <div style='float:right;'>
 <form   onsubmit='return false;'><input id='<portlet:namespace/>-clear' type='submit' name='action' value='clear' /></form>
 </div>
 </div><div style='clear:both;'><hr/>
-<h3>Message Box Portlet</h3>
 <p>Messages that arrive via events from other portlets are displayed in this box.</p>
 <div id='<portlet:namespace/>-responseDiv' style="<%=style.toString()%>"></div>
 </div>
@@ -55,14 +54,13 @@ limitations under the License.
    
    // Handler for onStateChange event
    update = function (type, s) {
-      console.log("Resource Portlet: state updated. Event type = " + type);
+      console.log("MBP: state updated. Event type = " + type);
       state = s;
       
       portletInit.createResourceUrl(resparms, cacheability).then(function (url) {
-         var brdr = (resparms.border === undefined) ? undefined : resparms.border[0],
-             xhr = new XMLHttpRequest();
-         console.log("Resource Portlet: got url: " + url + ", res parm border=" + brdr);
-         xhr.onreadystatechange=function() {
+         var xhr = new XMLHttpRequest();
+         console.log("MBP: got url: " + url);
+         xhr.onreadystatechange = function () {
             if (xhr.readyState === 4 && xhr.status === 200) {
                document.getElementById(resdiv).innerHTML=xhr.responseText;
             }
@@ -74,13 +72,13 @@ limitations under the License.
    
    // Handler for "clear" button. execute an action which clears the stored messages
    document.getElementById(clrButton).onclick = function () {
-      console.log("clear button clicked. ");
+      console.log("MBP: clear button clicked. ");
       portletInit.action();
    };
    
    // Register portlet with Portlet Hub; add onStateChange listener 
    portlet.register(pid).then(function (pi) {
-      console.log("Message Box portlet registered: " + pid);
+      console.log("MBP: Message Box portlet registered: " + pid);
       portletInit = pi;
       portletInit.addEventListener("portlet.onStateChange", update);
    });

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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
new file mode 100644
index 0000000..3e96ad1
--- /dev/null
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/jsp/view-pap.jsp
@@ -0,0 +1,109 @@
+<%--
+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" %>
+
+<portlet:defineObjects />
+
+<%
+   StringBuffer style = new StringBuffer(256);
+   style.append("border-style:solid; border-width:3px;");
+   style.append(" padding:4px; overflow:auto;");
+   style.append(" border-color:#008800; min-height:30px;");
+   style.append(" background:#E0E0E0;");
+%>
+
+<h3>Partial Action Portlet</h3>
+<hr/>
+<p>This portlet exercises the Partial Action execution path.</p>
+<form onsubmit='return false;'><input id='<portlet:namespace/>-doPA' type='submit' name='action' value='Do Partial Action' /></form>
+<div id='<portlet:namespace/>-responseDiv' style="<%=style.toString()%>"></div>
+   
+<script>
+(function () {
+   'use strict';
+   var pid = '<portlet:namespace/>',
+       resdiv = '<portlet:namespace/>-responseDiv',
+       paButton = '<portlet:namespace/>-doPA',
+   
+       state,
+       actparms = {},
+       portletInit,
+   
+   // 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;
+         }
+      }
+      state = s;
+   };
+   
+   // Handler for "partial action" button. Perform partial action sequence.
+   document.getElementById(paButton).onclick = function () {
+      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;
+      }
+      
+      portletInit.startPartialAction(actparms).then(function (pai) {
+         
+         console.log("PAP: got partial action init object. URL: " + pai.url);
+         
+         xhr.onreadystatechange = function () {
+            if (xhr.readyState === 4) {
+               if (xhr.status === 200) {
+                  vals = xhr.responseText.split(";#delimiter#;");
+                  if (vals.length !== 2) {
+                     markup = "<p>Error parsing return data. # fields = " + vals.length + ".</p>";
+                  } else {
+                     markup = vals[0];
+                     pagestate = vals[1];
+                  }
+               } else {
+                  markup = "<p>Communication error. XHR status=" + xhr.statusText + "</p>";
+               } 
+               // Make sure setPageState is called even in error case in order to unblock the P.H.
+               pai.setPageState(pagestate);
+               document.getElementById(resdiv).innerHTML = markup;
+            }
+         };
+         xhr.open("POST",pai.url,true);
+         xhr.send();
+         
+      });
+   };
+   
+   // 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);
+   });
+   
+}());
+</script>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 124964b..ed46720 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
@@ -92,6 +92,26 @@
       </supported-publishing-event>
       <supported-public-render-parameter>color</supported-public-render-parameter>
    </portlet>
+
+   <portlet>
+      <portlet-name>PartialActionPortlet</portlet-name>
+      <display-name>Partial Action Portlet</display-name>
+      
+      <portlet-class>basic.portlet.PartialActionPortlet</portlet-class>
+
+      <supports>
+         <mime-type>text/html</mime-type>
+         <portlet-mode>VIEW</portlet-mode>
+      </supports>
+
+      <supported-locale>en</supported-locale>        
+
+      <portlet-info>
+         <title>PH Partial Action Portlet</title>
+      </portlet-info>
+
+      <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/a27e40db/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
index a0bdfc6..d96c066 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletContainer.java
@@ -84,6 +84,7 @@ public interface PortletContainer {
      * @param portletWindow the portlet Window
      * @param request               the servlet request
      * @param response              the servlet response
+     * @param pageState             the page state (used for Partial Action processing)
      * @throws PortletException          if one portlet has trouble fulfilling
      *                                   the request
      * @throws PortletContainerException if the portlet container implementation
@@ -91,7 +92,7 @@ public interface PortletContainer {
      */
     void doServeResource(PortletWindow portletWindow,
             HttpServletRequest request,
-            HttpServletResponse response)
+            HttpServletResponse response, String pageState)
     throws PortletException, IOException, PortletContainerException;
 
     /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
index 586f37d..51bf95a 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletRequestContextService.java
@@ -1,56 +1,58 @@
-/*
- * 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 org.apache.pluto.container;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-
-/**
- * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
- * @version $Id$
- */
-public interface PortletRequestContextService
-{
-    PortletRequestContext getPortletActionRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                         HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletRequestContext getPortletEventRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                        HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletResourceRequestContext getPortletResourceRequestContext(PortletContainer container,
-                                                                   HttpServletRequest containerRequest,
-                                                                   HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletRequestContext getPortletRenderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                         HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletActionResponseContext getPortletActionResponseContext(PortletContainer container,
-                                                                 HttpServletRequest containerRequest,
-                                                                 HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletEventResponseContext getPortletEventResponseContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                               HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletResourceResponseContext getPortletResourceResponseContext(PortletContainer container,
-                                                                     HttpServletRequest containerRequest,
-                                                                     HttpServletResponse containerResponse, PortletWindow window);
-
-    PortletRenderResponseContext getPortletRenderResponseContext(PortletContainer container,
-                                                                 HttpServletRequest containerRequest,
-                                                                 HttpServletResponse containerResponse, PortletWindow window);
-}
+/*
+ * 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 org.apache.pluto.container;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public interface PortletRequestContextService
+{
+    PortletRequestContext getPortletActionRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                         HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletRequestContext getPortletEventRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                        HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletResourceRequestContext getPortletResourceRequestContext(PortletContainer container,
+                                                                   HttpServletRequest containerRequest,
+                                                                   HttpServletResponse containerResponse, 
+                                                                   PortletWindow window,
+                                                                   String pageState);
+
+    PortletRequestContext getPortletRenderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                         HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletActionResponseContext getPortletActionResponseContext(PortletContainer container,
+                                                                 HttpServletRequest containerRequest,
+                                                                 HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletEventResponseContext getPortletEventResponseContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                               HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletResourceResponseContext getPortletResourceResponseContext(PortletContainer container,
+                                                                     HttpServletRequest containerRequest,
+                                                                     HttpServletResponse containerResponse, PortletWindow window);
+
+    PortletRenderResponseContext getPortletRenderResponseContext(PortletContainer container,
+                                                                 HttpServletRequest containerRequest,
+                                                                 HttpServletResponse containerResponse, PortletWindow window);
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
index d78df7a..8d601be 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/PortletResourceRequestContext.java
@@ -1,30 +1,36 @@
-/*
- * 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 org.apache.pluto.container;
-
-import java.util.Map;
-
-/**
- * @version $Id$
- *
- */
-public interface PortletResourceRequestContext extends PortletRequestContext
-{
-    String getResourceID();
-    String getCacheability();
-    Map<String, String[]> getPrivateRenderParameterMap();
-}
+/*
+ * 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 org.apache.pluto.container;
+
+import java.util.Map;
+
+/**
+ * @version $Id$
+ *
+ */
+public interface PortletResourceRequestContext extends PortletRequestContext
+{
+    String getResourceID();
+    String getCacheability();
+    Map<String, String[]> getPrivateRenderParameterMap();
+    
+    /**
+     * get page state when handling a partial action request
+     * @return
+     */
+    String getPageState();
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
index ac8bf7e..5c8128a 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContainerImpl.java
@@ -179,7 +179,8 @@ public class PortletContainerImpl implements PortletContainer
      */
     public void doServeResource(PortletWindow portletWindow,
             HttpServletRequest request,
-            HttpServletResponse response)
+            HttpServletResponse response,
+            String pageState)
     throws PortletException, IOException, PortletContainerException
     {
         ensureInitialized();
@@ -191,7 +192,7 @@ public class PortletContainerImpl implements PortletContainer
         PortletEnvironmentService envService = getContainerServices().getPortletEnvironmentService();
         PortletInvokerService invoker = getContainerServices().getPortletInvokerService();
 
-        PortletResourceRequestContext requestContext = rcService.getPortletResourceRequestContext(this, request, response, portletWindow);
+        PortletResourceRequestContext requestContext = rcService.getPortletResourceRequestContext(this, request, response, portletWindow, pageState);
         PortletResourceResponseContext responseContext = rcService.getPortletResourceResponseContext(this, request, response, portletWindow);
         ResourceRequest portletRequest = envService.createResourceRequest(requestContext, responseContext);
         ResourceResponse portletResponse = envService.createResourceResponse(responseContext, requestContext.getCacheability());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-container/src/main/java/org/apache/pluto/container/impl/ResourceRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/ResourceRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/ResourceRequestImpl.java
index 89c546a..4d87575 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/ResourceRequestImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/ResourceRequestImpl.java
@@ -26,9 +26,15 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.apache.pluto.container.PortletResourceRequestContext;
 import org.apache.pluto.container.PortletResourceResponseContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ResourceRequestImpl extends ClientDataRequestImpl implements ResourceRequest
 {
+
+   /** Internal logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(ResourceRequestImpl.class);
+
     private PortletResourceRequestContext requestContext;
     private CacheControl cacheControl;
     
@@ -81,10 +87,34 @@ public class ResourceRequestImpl extends ClientDataRequestImpl implements Resour
     * @see javax.portlet.ResourceRequest#getPageState()
     */
    public String getPageState() {
-      // The page state is provided by the driver servlet via a request attribute.
-      // The attribute is only set if a partial action request is being processed.
-      HttpServletRequest req = requestContext.getServletRequest();
-      String ps = (String) req.getAttribute("PartialActionPageState");
+      // The page state is provided through the request context.
+      String ps = requestContext.getPageState();
+      if (LOG.isDebugEnabled()) {
+         LOG.debug("ResourceRequest#getPageState called.");
+      }
       return ps;
    }
+   
+   // Debug code - intercept getParameter call & dump all parameters to trace
+   @Override
+   public String getParameter(String name) {
+      String val = super.getParameter(name);
+      if (LOG.isDebugEnabled()) {
+         Map<String, String[]> pmap = super.getParameterMap();
+         StringBuffer txt = new StringBuffer(1024);
+         txt.append("Resource Request parameter map dump:\n");
+         for (String n : pmap.keySet()) {
+            txt.append("Name: " + n + ", Values: ");
+            String[] vals = pmap.get(n);
+            String sep = "";
+            for (String v : vals) {
+               txt.append(sep + v);
+               sep = ", ";
+            }
+            txt.append("\n");
+         }
+         LOG.debug(txt.toString());
+      }
+      return val;
+   }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletRequestContextServiceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletRequestContextServiceImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletRequestContextServiceImpl.java
index 16510bb..2425d82 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletRequestContextServiceImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletRequestContextServiceImpl.java
@@ -1,94 +1,95 @@
-/*
- * 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 org.apache.pluto.driver.services.container;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.pluto.container.PortletActionResponseContext;
-import org.apache.pluto.container.PortletContainer;
-import org.apache.pluto.container.PortletEventResponseContext;
-import org.apache.pluto.container.PortletRenderResponseContext;
-import org.apache.pluto.container.PortletRequestContext;
-import org.apache.pluto.container.PortletRequestContextService;
-import org.apache.pluto.container.PortletResourceRequestContext;
-import org.apache.pluto.container.PortletResourceResponseContext;
-import org.apache.pluto.container.PortletWindow;
-
-/**
- * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
- * @version $Id$
- */
-public class PortletRequestContextServiceImpl implements PortletRequestContextService
-{
-    public PortletRequestContext getPortletActionRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                                HttpServletResponse containerResponse, PortletWindow window)
-    {
-        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, true);
-    }
-
-    public PortletActionResponseContext getPortletActionResponseContext(PortletContainer container,
-                                                                        HttpServletRequest containerRequest,
-                                                                        HttpServletResponse containerResponse,
-                                                                        PortletWindow window)
-    {
-        return new PortletActionResponseContextImpl(container, containerRequest, containerResponse, window);
-    }
-
-    public PortletRequestContext getPortletEventRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                               HttpServletResponse containerResponse, PortletWindow window)
-    {
-        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, false);
-    }
-
-    public PortletEventResponseContext getPortletEventResponseContext(PortletContainer container,
-                                                                      HttpServletRequest containerRequest,
-                                                                      HttpServletResponse containerResponse, PortletWindow window)
-    {
-        return new PortletEventResponseContextImpl(container, containerRequest, containerResponse, window);
-    }
-
-    public PortletRequestContext getPortletRenderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
-                                                                HttpServletResponse containerResponse, PortletWindow window)
-    {
-        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, false);
-    }
-
-    public PortletRenderResponseContext getPortletRenderResponseContext(PortletContainer container,
-                                                                        HttpServletRequest containerRequest,
-                                                                        HttpServletResponse containerResponse,
-                                                                        PortletWindow window)
-    {
-        return new PortletRenderResponseContextImpl(container, containerRequest, containerResponse, window);
-    }
-
-    public PortletResourceRequestContext getPortletResourceRequestContext(PortletContainer container,
-                                                                          HttpServletRequest containerRequest,
-                                                                          HttpServletResponse containerResponse,
-                                                                          PortletWindow window)
-    {
-        return new PortletResourceRequestContextImpl(container, containerRequest, containerResponse, window);
-    }
-
-    public PortletResourceResponseContext getPortletResourceResponseContext(PortletContainer container,
-                                                                            HttpServletRequest containerRequest,
-                                                                            HttpServletResponse containerResponse,
-                                                                            PortletWindow window)
-    {
-        return new PortletResourceResponseContextImpl(container, containerRequest, containerResponse, window);
-    }
-}
+/*
+ * 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 org.apache.pluto.driver.services.container;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.pluto.container.PortletActionResponseContext;
+import org.apache.pluto.container.PortletContainer;
+import org.apache.pluto.container.PortletEventResponseContext;
+import org.apache.pluto.container.PortletRenderResponseContext;
+import org.apache.pluto.container.PortletRequestContext;
+import org.apache.pluto.container.PortletRequestContextService;
+import org.apache.pluto.container.PortletResourceRequestContext;
+import org.apache.pluto.container.PortletResourceResponseContext;
+import org.apache.pluto.container.PortletWindow;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class PortletRequestContextServiceImpl implements PortletRequestContextService
+{
+    public PortletRequestContext getPortletActionRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                                HttpServletResponse containerResponse, PortletWindow window)
+    {
+        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, true);
+    }
+
+    public PortletActionResponseContext getPortletActionResponseContext(PortletContainer container,
+                                                                        HttpServletRequest containerRequest,
+                                                                        HttpServletResponse containerResponse,
+                                                                        PortletWindow window)
+    {
+        return new PortletActionResponseContextImpl(container, containerRequest, containerResponse, window);
+    }
+
+    public PortletRequestContext getPortletEventRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                               HttpServletResponse containerResponse, PortletWindow window)
+    {
+        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, false);
+    }
+
+    public PortletEventResponseContext getPortletEventResponseContext(PortletContainer container,
+                                                                      HttpServletRequest containerRequest,
+                                                                      HttpServletResponse containerResponse, PortletWindow window)
+    {
+        return new PortletEventResponseContextImpl(container, containerRequest, containerResponse, window);
+    }
+
+    public PortletRequestContext getPortletRenderRequestContext(PortletContainer container, HttpServletRequest containerRequest,
+                                                                HttpServletResponse containerResponse, PortletWindow window)
+    {
+        return new PortletRequestContextImpl(container, containerRequest, containerResponse, window, false);
+    }
+
+    public PortletRenderResponseContext getPortletRenderResponseContext(PortletContainer container,
+                                                                        HttpServletRequest containerRequest,
+                                                                        HttpServletResponse containerResponse,
+                                                                        PortletWindow window)
+    {
+        return new PortletRenderResponseContextImpl(container, containerRequest, containerResponse, window);
+    }
+
+    public PortletResourceRequestContext getPortletResourceRequestContext(PortletContainer container,
+                                                                          HttpServletRequest containerRequest,
+                                                                          HttpServletResponse containerResponse,
+                                                                          PortletWindow window,
+                                                                          String pageState)
+    {
+        return new PortletResourceRequestContextImpl(container, containerRequest, containerResponse, window, pageState);
+    }
+
+    public PortletResourceResponseContext getPortletResourceResponseContext(PortletContainer container,
+                                                                            HttpServletRequest containerRequest,
+                                                                            HttpServletResponse containerResponse,
+                                                                            PortletWindow window)
+    {
+        return new PortletResourceResponseContextImpl(container, containerRequest, containerResponse, window);
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
index ae93da8..97bce7c 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/container/PortletResourceRequestContextImpl.java
@@ -1,55 +1,69 @@
-/*
- * 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 org.apache.pluto.driver.services.container;
-
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.pluto.container.PortletContainer;
-import org.apache.pluto.container.PortletResourceRequestContext;
-import org.apache.pluto.container.PortletWindow;
-
-/**
- * @version $Id$
- *
- */
-public class PortletResourceRequestContextImpl extends PortletRequestContextImpl implements
-                PortletResourceRequestContext
-{
-    public PortletResourceRequestContextImpl(PortletContainer container, HttpServletRequest containerRequest,
-                                             HttpServletResponse containerResponse, PortletWindow window)
-    {
-        super(container, containerRequest, containerResponse, window, true);
-    }
-
-    public String getCacheability()
-    {
-        return getPortalURL().getCacheability();
-    }
-
-    public Map<String, String[]> getPrivateRenderParameterMap()
-    {
-        return getPortalURL().getPrivateRenderParameters();
-    }
-
-    public String getResourceID()
-    {
-        return getPortalURL().getResourceID();
-    }
-}
+/*
+ * 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 org.apache.pluto.driver.services.container;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.pluto.container.PortletContainer;
+import org.apache.pluto.container.PortletResourceRequestContext;
+import org.apache.pluto.container.PortletWindow;
+
+/**
+ * @version $Id$
+ *
+ */
+public class PortletResourceRequestContextImpl extends PortletRequestContextImpl implements
+                PortletResourceRequestContext
+{
+   private String pageState;
+   
+    public PortletResourceRequestContextImpl(PortletContainer container, HttpServletRequest containerRequest,
+                                             HttpServletResponse containerResponse, PortletWindow window,
+                                             String pageState)
+    {
+       // if pageState != null, we're dealing with a Partial Action request, so 
+       // the servlet parameters are not to be used. Otherwise, resource params could be
+       // passed as servlet parameters.
+        super(container, containerRequest, containerResponse, window, (pageState==null));
+        this.pageState = pageState;
+    }
+
+    public String getCacheability()
+    {
+        return getPortalURL().getCacheability();
+    }
+
+    public Map<String, String[]> getPrivateRenderParameterMap()
+    {
+        return getPortalURL().getPrivateRenderParameters();
+    }
+
+    public String getResourceID()
+    {
+        return getPortalURL().getResourceID();
+    }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.PortletResourceRequestContext#getPageState()
+    */
+   public String getPageState() {
+      return pageState;
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverServlet.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverServlet.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverServlet.java
index 810c7b7..041c950 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverServlet.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/PortalDriverServlet.java
@@ -1,5 +1,5 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
+  * 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
@@ -184,13 +184,18 @@ public class PortalDriverServlet extends HttpServlet {
           }
           try {
              container.doAction(portletWindow, request, response, false);
-             // The page state is made available to the ResourceRequest via a 
-             // request attribute
+             
+             // The page state is made available to the ResourceRequest by passing 
+             // it through all layers, which allows for special case processing at
+             // some points.
+             
              PageState ps = new PageState(request);
              String jsondata = ps.toJSONString();
-             LOG.debug("Partial Action: adding page state attribute to servlet request: " + jsondata);
-             request.setAttribute("PartialActionPageState", jsondata);
-             container.doServeResource(portletWindow, request, response);
+             if (LOG.isDebugEnabled()) {
+                LOG.debug("Partial Action: dump page state:\n" + jsondata);
+             }
+             
+             container.doServeResource(portletWindow, request, response, jsondata);
           } catch (PortletContainerException ex) {
              LOG.error(ex.getMessage(), ex);
              throw new ServletException(ex);
@@ -213,7 +218,7 @@ public class PortalDriverServlet extends HttpServlet {
                    + portletWindow.getId().getStringId());
           }
           try {
-             container.doServeResource(portletWindow, request, response);
+             container.doServeResource(portletWindow, request, response, null);
           } catch (PortletContainerException ex) {
              LOG.error(ex.getMessage(), ex);
              throw new ServletException(ex);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 5b5fb2d..98b898f 100644
--- a/pluto-portal/src/main/webapp/portlet.js
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -956,18 +956,23 @@ var portlet = portlet || {};
     * @callback   setPageState
     */
    setPageState = function (pid, ustr) {
-      var upids, pi;
-
-      // check for exactly 2 arguments of type 'string'
-      checkArguments(arguments, 2, 2, [ 'string', 'string' ]);
+      var pi;
 
       // convert page state into an object.
       // update each affected portlet client. Makes use of a 
       // mockup-specific function for decoding. 
 
       pi = _registeredPortlets[pid];
-      upids = pi.decodeUpdateString(ustr);
-      updatePageState(upids);
+      pi.decodeUpdateString(ustr).then(function (upids) {
+         updatePageState(upids);
+      }, function (err) {
+         busy = false;
+         if (oeListeners[pid]) {
+            delay( function () {
+               oeListeners[pid].callback('portlet.onError', err);
+            }, 0);
+         }
+      });
 
    };
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a27e40db/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 2b76efb..913184a 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -360,6 +360,32 @@ 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) {
+            
+      // 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));
+         }
+      });
+
+   },
 
       
    /**
@@ -549,7 +575,7 @@ var portlet = portlet || {};
     */
    getUrl = function (type, pid, parms, cache) {
    
-      var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, 
+      var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, isAction = false,
           sep = "", name, names, val, vals, ii, jj, str, id, ids, tpid, prpstrings;
 
       // First add the appropriate window identifier according to URL type.
@@ -564,9 +590,11 @@ var portlet = portlet || {};
          url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
       } else if (type === "ACTION") {
          // Add Ajax Action window
+         isAction = true;
          url += "/" + PREFIX + AJAX_ACTION + plutoEncode(pageState[pid].urlpid);
       } else if (type === "PARTIAL_ACTION") {
          // Add Partial Action window
+         isAction = true;
          url += "/" + PREFIX + PARTIAL_ACTION + plutoEncode(pageState[pid].urlpid);
       }
       
@@ -598,17 +626,20 @@ var portlet = portlet || {};
 
          }
 
-         // add the state for the target portlet
-         url += genPMWSString(pid);  // portlet mode & window state
-         str = "";
-         names = pageState[pid].state.parameters;
-         for (name in names) {
-            // Public render parameters are encoded separately
-            if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
-               str += genParmString(pid, name, PRIVATE_RENDER_PARAM);
+         // add the state for the target portlet for on-action urls.
+         // (Action URLs have only action parameters in the query string)
+         if (!isAction) {
+            url += genPMWSString(pid);  // portlet mode & window state
+            str = "";
+            names = pageState[pid].state.parameters;
+            for (name in names) {
+               // Public render parameters are encoded separately
+               if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
+                  str += genParmString(pid, name, PRIVATE_RENDER_PARAM);
+               }
             }
+            url += str;
          }
-         url += str;
 
          // Add the public render parameters for all portlets
 
@@ -764,7 +795,7 @@ var portlet = portlet || {};
 			 * Decode the update string returned by the partial action request.
 			 * Returns array of IDs of portlets to be updated.
 			 */
-			decodeUpdateString : function (ustr) {return updatePageStateFromString(ustr, pid);},
+			decodeUpdateString : function (ustr) {return updatePageState(ustr, pid);},
    
       };