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/25 13:50:13 UTC

[08/19] portals-pluto git commit: fixed defect in JSON generation on server. Implemented simple ajax action path in pluto portlet hub impl.

fixed defect in JSON generation on server. Implemented simple ajax action path in pluto portlet hub impl.


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

Branch: refs/heads/PortletHub
Commit: 92a8cb0c9c1208bafcf98602c379de7ca748d63b
Parents: e5e905a
Author: Scott Nicklous <ms...@apache.org>
Authored: Sun Nov 23 02:25:20 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sun Nov 23 02:25:20 2014 +0100

----------------------------------------------------------------------
 .../java/basic/portlet/MessageBoxPortlet.java   |   1 +
 .../org/apache/pluto/driver/util/PageState.java |  53 ++---
 pluto-portal/src/main/webapp/portlet.js         |   4 +-
 pluto-portal/src/main/webapp/portletHubImpl.js  | 199 +++++++++++--------
 4 files changed, 154 insertions(+), 103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92a8cb0c/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
index d9f6b80..a0976e8 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
@@ -102,6 +102,7 @@ public class MessageBoxPortlet extends GenericPortlet {
       writer.write("   \n");
       writer.write("   document.getElementById(clrButton).onclick = function () {\n");
       writer.write("      console.log(\"clear button clicked. \");\n");
+      writer.write("      portletInit.action();\n");
       writer.write("   }\n");
       writer.write("   \n");
       writer.write("   portlet.register(pid).then(function (pi) {\n");

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92a8cb0c/pluto-portal-driver/src/main/java/org/apache/pluto/driver/util/PageState.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/util/PageState.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/util/PageState.java
index 61708f2..5854b23 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/util/PageState.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/util/PageState.java
@@ -155,7 +155,7 @@ public class PageState {
          Enumeration<String> prps = pc.getPublicRenderParameterNames();
          while (prps.hasMoreElements()) {
             String prp = prps.nextElement();
-            prpstring.append(sep + "'" + prp + "'");
+            prpstring.append(sep + "\"" + prp + "\"");
             sep = ", ";
          }
       } catch (Exception e) {}
@@ -175,7 +175,7 @@ public class PageState {
          Set<PortletMode> allowedPMs = drvrConfig.getSupportedPortletModes(portletId);
          String sep = "";
          for (PortletMode pm : allowedPMs) {
-            pmstring.append(sep + "'" + pm.toString() + "'");
+            pmstring.append(sep + "\"" + pm.toString() + "\"");
             sep = ", ";
          }
       } catch (Exception e) {}
@@ -195,7 +195,7 @@ public class PageState {
          Set<WindowState> allowedWSs = drvrConfig.getSupportedWindowStates(portletId, "text/html");
          String sep = "";
          for (WindowState ws : allowedWSs) {
-            wsstring.append(sep + "'" + ws.toString() + "'");
+            wsstring.append(sep + "\"" + ws.toString() + "\"");
             sep = ", ";
          }
       } catch (Exception e) {}
@@ -249,23 +249,28 @@ public class PageState {
       Collection<PortalURLParameter> pups = getParameters();
       Map<String, String[]> pubparms = getPublicParameters();
       
+      boolean sep = false;
       for (String pid : getPortletIds()) {
-         json.append("   '" + getNameSpace(pid) + "' : {\n");
-         json.append("      'state' : {\n");
-         json.append("         'parameters' : {\n");
+         if (sep) {
+            json.append(",\n");
+         }
+         sep = true;
+         json.append("   \"" + getNameSpace(pid) + "\" : {\n");
+         json.append("      \"state\" : {\n");
+         json.append("         \"parameters\" : {\n");
 
          // Add the portlet parameters
-         String c1 = "            '";
+         String c1 = "            \"";
          for (PortalURLParameter pup : pups){
             if (pup.getWindowId().equals(pid)){
-               json.append(c1  + pup.getName() + "' : [");
+               json.append(c1  + pup.getName() + "\" : [");
                String c2 = "";
                for (String val : pup.getValues()) {
-                  json.append(c2 + " '" + val + "'");
+                  json.append(c2 + " \"" + val + "\"");
                   c2 = ",";
                }
                json.append("]");
-               c1 = ",\n            '";
+               c1 = ",\n            \"";
             }
          }
          
@@ -274,33 +279,33 @@ public class PageState {
          Set<String> prpnames = getPRPNames(pid);
          for (String prp : pubparms.keySet()) {
             if (prpnames.contains(prp)) {
-               json.append(c1 + prp + "' : [");
+               json.append(c1 + prp + "\" : [");
                String c2 = "";
                for (String val : (String[])pubparms.get(prp)) {
-                  json.append(c2 + " '" + val + "'");
+                  json.append(c2 + " \"" + val + "\"");
                   c2 = ",";
                }
                json.append("]");
-               c1 = ",\n            '";
+               c1 = ",\n            \"";
             }
          }
 
          json.append("         }, \n");
-         json.append("         'portletMode' : '" + getPortletMode(pid) + "', \n");
-         json.append("         'windowState' : '" + getWindowState(pid) + "'\n");
+         json.append("         \"portletMode\" : \"" + getPortletMode(pid) + "\", \n");
+         json.append("         \"windowState\" : \"" + getWindowState(pid) + "\"\n");
          json.append("      },\n");
-         json.append("      'pubParms' : [" + getPRPNamesAsString(pid) + "],\n");
-         json.append("      'allowedPM' : [" + getPortletModesAsString(pid) + "],\n");
-         json.append("      'allowedWS' : [" + getWindowStatesAsString(pid) + "],\n");
-         json.append("      'renderData' : {\n");
-         json.append("         'renderData' : null,\n");
-         json.append("         'mimeType' : \"text/plain\"\n");
+         json.append("      \"pubParms\" : [" + getPRPNamesAsString(pid) + "],\n");
+         json.append("      \"allowedPM\" : [" + getPortletModesAsString(pid) + "],\n");
+         json.append("      \"allowedWS\" : [" + getWindowStatesAsString(pid) + "],\n");
+         json.append("      \"renderData\" : {\n");
+         json.append("         \"renderData\" : null,\n");
+         json.append("         \"mimeType\" : \"text/plain\"\n");
          json.append("      },\n");
-         json.append("      'urlpid' : '" + pid + "'\n");
-         json.append("   },\n");
+         json.append("      \"urlpid\" : \"" + pid + "\"\n");
+         json.append("   }");
       }
       
-      json.append("}");
+      json.append("\n}");
       return json.toString();
    }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92a8cb0c/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 546efe8..f32be18 100644
--- a/pluto-portal/src/main/webapp/portlet.js
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -1436,7 +1436,9 @@ 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/92a8cb0c/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 a372c1f..1c2b66e 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -24,29 +24,8 @@
 
 /**
  * @fileOverview
- * This module provides mock data & functions for the mock portlet hub.
+ * This module provides the implementation for the Pluto portlet hub.
  * <p>
- * The functions encapsulate all mockup-specific implementation details.
- * The intention is that support for a different portal can added by 
- * reimplementing these functions.
- * <p>
- * To implement the portlet hub for your portal, implement the methods 
- * described under "portlet.impl".
- * In order to make the Jasmine tests work with your implementation, the
- * test functions will need to be modified appropiately as well.
- * <p>
- * Sets up data that is used by the Jasmine unit tests as well as by the 
- * portlet hub implementation. In particular, the Jasmine tests need initialization
- * data for the portlets on the page. The portlet hub requires this
- * data as well, so it is being provided through the global name space to be used both
- * by the hub and by the test code.
- * <p> 
- * Later, it should hopefully be possible to use the Jasmine tests with a "live" 
- * portlet hub implementation by making the portlet info on the page 
- * available to Jasmine through this mechanism.
- * <p>
- * A "real" portlet hub implementation would likely obtain this information in a 
- * different manner.
  * 
  * @author Scott Nicklous
  * @copyright IBM Corp., 2014
@@ -154,6 +133,51 @@ var portlet = portlet || {};
 
       return true;
    },
+   
+   
+   /**
+    * Returns true if input state differs from the current page state.
+    * Throws exception if input state is malformed.
+    */
+   stateChanged = function (nstate, pid) {
+      var ostate, nparm, oparm, result = false;
+      
+      ostate = pageState[pid].state;
+      
+      if (!nstate.portletMode || !nstate.windowState || !nstate.parameters) {
+         throw new Error ("Error decoding state: " + nstate);
+      }
+      
+      if (nstate.portletMode !== ostate.portletMode) {
+         result = true;
+      } else {
+         if (nstate.windowState != ostate.windowState) {
+            result = true;
+         } else {
+            
+            // Has a parameter changed or been added?
+            for (nparm in nstate.parameters) {
+               if (nstate.parameters.hasOwnProperty(nparm)) {
+                  oparm = ostate.parameters[nparm];
+                  if (!_isParmEqual(nparm, oparm)) {
+                     result = true;
+                  }
+               }
+            }
+            
+            // make sure no parameter was deleted
+            for (oparm in ostate.parameters) {
+               if (ostate.parameters.hasOwnProperty(oparm)) {
+                  if (!nstate.parameters[oparm]) {
+                     result = true;
+                  }
+               }
+            }
+         }
+      }
+      
+      return result;
+   },
 
    /**
     * Compares the values of the named parameter in the new portlet state
@@ -366,7 +390,6 @@ var portlet = portlet || {};
    /**
     * performs the actual action.
     * 
-    * @param   {string}    type     The URL type
     * @param   {string}    pid      The portlet ID
     * @param   {PortletParameters}    parms      
     *                Additional parameters. May be <code>null</code>
@@ -375,34 +398,44 @@ var portlet = portlet || {};
     * @private 
     */
    executeAction = function (pid, parms, element) {
-      var states, ustr, tpid, state, upids = [];
-   
-      // pretend to create a url, etc. ... for the mockup
-      // we don't need the parms or element
-   
-      // get the mockup data update string and make it into an object.
-      // update each affected portlet client. Makes use of a 
-      // test function for decoding. 
-      
-      ustr = portlet.test.data.updateStrings[pid];
-      upids = updatePageStateFromString(ustr, pid);
-      
-      // Use Promise to allow for potential server communication - 
+      var url;
+
+      console.log("impl: executing action. parms=" + parms + ", element=" + element)
+
+      // create & return promise to caller. 
+
       return new Promise(function (resolve, reject) {
-         var simval = '';
-         if (pid === 'SimulateCommError' && (parms)) {
-            simval = parms.SimulateError;
-            if (simval) {
-               simval = simval[0];
+
+         // 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();
             }
-         }
+         });
             
-         // reject promise of an error is to be simulated
-         if (simval === 'reject') {
-            reject(new Error("Simulated error occurred during action!"));
-         } else {
-            resolve(upids);
-         }
       });
 
    },
@@ -516,7 +549,7 @@ var portlet = portlet || {};
    getUrl = function (type, pid, parms, cache) {
    
       var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, 
-          sep = "", name, names, val, vals, ii, jj, str, id, ids;
+          sep = "", name, names, val, vals, ii, jj, 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. 
@@ -576,12 +609,22 @@ var portlet = portlet || {};
          }
          url += str;
 
-         // Add the public render parameters
+         // Add the public render parameters for all portlets
+
          str = "";
-         names = pageState[pid].pubParms;
-         for (ii=0; ii < names.length; ii++) {
-            name = names[ii];
-            str += genParmString(pid, name, PUBLIC_RENDER_PARAM);
+         prpstrings = {};
+         for (tpid in pageState) {
+            if (pageState.hasOwnProperty(tpid)) {               
+               names = pageState[tpid].pubParms;
+               for (ii=0; ii < names.length; ii++) {
+                  name = names[ii];
+                  // only need to add parameter once, since it is shared
+                  if (!prpstrings.hasOwnProperty(name)) {
+                     prpstrings[name] = genParmString(tpid, name, PUBLIC_RENDER_PARAM);
+                     str += prpstrings[name];
+                  }
+               }
+            }
          }
          url += str;
 
@@ -623,33 +666,33 @@ var portlet = portlet || {};
    },
 
    
-   // decodes the update strings
+   // 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 = {}, state, pid, ii, ind,
-          pids = ustr.match(/~~&.*?&/g); // reluctant match
-      
-      // If there is no match, bad input data
-      if (pids === null) {
-         throwIllegalArgumentException("Invalid update string.");
-      }
-      
-      // For each portlet being updated, get the new data
-      ii = pids.length;
-      while ((ii = ii -1) >= 0) {
-         if (pids[ii].length < 5) {
-            // the portlet ID must be at least 1 character long
-            throwIllegalArgumentException("Invalid portlet ID in update string.");
+      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;
+            
+            if (!nstate || !ostate) {
+               throw new Error ("Invalid update string. ostate=" + ostate + ", nstate=" + nstate);
+            }
+            
+            if (stateChanged(nstate, pid)) {
+               states[pid] = cloneState(nstate);
+               cpids++;
+            }
          }
-         
-         // trim extra stuff off of the portlet id
-         ind = pids[ii].length - 1;
-         pid = pids[ii].substring(3, ind);
-      
-         state = portlet.test.action.getState(ustr, pid);
-         states[pid] = state;
-         
       }
       
+      console.log("decoded state for " + npids + " portlets. # changed = " + cpids);
+      
       return states;
    };
 
@@ -709,7 +752,7 @@ var portlet = portlet || {};
 			/**
 			 * Perform the Ajax action request
 			 */
-			executeAction : function (parms, element, callback, onError) {return executeAction(pid, parms, element, callback, onError);},
+			executeAction : function (parms, element) {return executeAction(pid, parms, element);},
    
 			/**
 			 * Get a URL of the specified type - resource or partial action