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/19 17:42:17 UTC

[01/15] portals-pluto git commit: removed the mistakenly committed portlet-tck_3.0/xml-resources directory and files contained therein

Repository: portals-pluto
Updated Branches:
  refs/heads/PortletHub [created] 909e23763


removed the mistakenly committed portlet-tck_3.0/xml-resources directory and files contained therein


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

Branch: refs/heads/PortletHub
Commit: 2b4c55999a11f77848c46eb972d3baf1f4ebeb1e
Parents: cdaa9cd
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Oct 10 09:41:18 2014 +0200
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Oct 10 09:41:18 2014 +0200

----------------------------------------------------------------------
 .../xml-resources/plutoMultiPortletPage.xsl     | 85 --------------------
 .../xml-resources/plutoSinglePortletPage.xsl    | 80 ------------------
 portlet-tck_3.0/xml-resources/test.xsl          | 78 ------------------
 3 files changed, 243 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2b4c5599/portlet-tck_3.0/xml-resources/plutoMultiPortletPage.xsl
----------------------------------------------------------------------
diff --git a/portlet-tck_3.0/xml-resources/plutoMultiPortletPage.xsl b/portlet-tck_3.0/xml-resources/plutoMultiPortletPage.xsl
deleted file mode 100644
index 9364e2e..0000000
--- a/portlet-tck_3.0/xml-resources/plutoMultiPortletPage.xsl
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-    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.	   
--->
-
-<!--
-   This stylesheet generates a valid page configuration file for pluto by
-   transforming the portlet.xml file. The servlet context is provided through
-   a parameter. The page name is set to the portlet name, which is also a
-   test case name.
-   
-   It places all portlets from the portlet application on the same page.
--->
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pa="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
-  <xsl:strip-space elements="pa:portlet-app"/>
-  <xsl:output method="xml" indent="yes"/>
-  <xsl:param name="portlet-app-context"/>
-  <xsl:variable name="pageName" select="pa:portlet-app/@id"/>
-  <xsl:template match="/">
-  <pluto-portal-driver
-    xmlns="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd
-                        http://portals.apache.org/pluto/pluto-portal/1.1/pluto-portal-driver-config.xsd"
-    version="1.1">
-
-
-    <portal-name>pluto-portal-driver</portal-name>
-    <portal-version>2.1.0-SNAPSHOT</portal-version>
-    <container-name>Pluto Portal Driver</container-name>
-
-    <supports>
-      <portlet-mode>view</portlet-mode>
-      <portlet-mode>edit</portlet-mode>
-      <portlet-mode>help</portlet-mode>
-      <portlet-mode>config</portlet-mode>
-
-      <window-state>normal</window-state>
-      <window-state>maximized</window-state>
-      <window-state>minimized</window-state>
-    </supports>
-    <xsl:element name="render-config">
-      <xsl:attribute name="default">About Apache Pluto</xsl:attribute>
-    <page name="About Apache Pluto" uri="/WEB-INF/themes/pluto-default-theme.jsp">
-      <portlet context="/pluto" name="AboutPortlet"/>
-    </page>
-         <xsl:apply-templates/>
-    </xsl:element>
-    </pluto-portal-driver>
-  </xsl:template>
-
-  <xsl:template match="pa:portlet-app">
-      <xsl:element name="page">
-        <xsl:attribute name="name"><xsl:value-of select="$pageName"/></xsl:attribute>
-        <xsl:attribute name="uri">/WEB-INF/themes/pluto-default-theme.jsp</xsl:attribute>
-         <xsl:apply-templates/>
-      </xsl:element>    
-  </xsl:template>
-
-  <xsl:template match="pa:portlet">
-          <xsl:element name="portlet">
-            <xsl:attribute name="context">/<xsl:value-of select='$portlet-app-context'/></xsl:attribute>
-            <xsl:attribute name="name"><xsl:value-of select="pa:portlet-name"/></xsl:attribute>
-          </xsl:element>
-  </xsl:template>
-  
-  <!-- ignore all other children of pa:portlet-app -->
-  <xsl:template match="pa:portlet-app/*[not(pa:portlet-name)]"/>
-
-</xsl:stylesheet>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2b4c5599/portlet-tck_3.0/xml-resources/plutoSinglePortletPage.xsl
----------------------------------------------------------------------
diff --git a/portlet-tck_3.0/xml-resources/plutoSinglePortletPage.xsl b/portlet-tck_3.0/xml-resources/plutoSinglePortletPage.xsl
deleted file mode 100644
index 6e5610f..0000000
--- a/portlet-tck_3.0/xml-resources/plutoSinglePortletPage.xsl
+++ /dev/null
@@ -1,80 +0,0 @@
-<!--
-    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.	   
--->
-
-<!--
-   This stylesheet generates a valid page configuration file for pluto by
-   transforming the portlet.xml file. The servlet context is provided through
-   a parameter. The page name is set to the portlet name, which is also a
-   test case name.
-   
-   It places each portlet from the portlet application on a separate page.
--->
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pa="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
-  <xsl:strip-space elements="pa:portlet-app"/>
-  <xsl:output method="xml" indent="yes"/>
-  <xsl:param name="portlet-app-context"/>
-  <xsl:template match="/">
-  <pluto-portal-driver
-    xmlns="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://portals.apache.org/pluto/xsd/pluto-portal-driver-config.xsd
-                        http://portals.apache.org/pluto/pluto-portal/1.1/pluto-portal-driver-config.xsd"
-    version="1.1">
-
-
-    <portal-name>pluto-portal-driver</portal-name>
-    <portal-version>2.1.0-SNAPSHOT</portal-version>
-    <container-name>Pluto Portal Driver</container-name>
-
-    <supports>
-      <portlet-mode>view</portlet-mode>
-      <portlet-mode>edit</portlet-mode>
-      <portlet-mode>help</portlet-mode>
-      <portlet-mode>config</portlet-mode>
-
-      <window-state>normal</window-state>
-      <window-state>maximized</window-state>
-      <window-state>minimized</window-state>
-    </supports>
-    <xsl:element name="render-config">
-      <xsl:attribute name="default">About Apache Pluto</xsl:attribute>
-    <page name="About Apache Pluto" uri="/WEB-INF/themes/pluto-default-theme.jsp">
-      <portlet context="/pluto" name="AboutPortlet"/>
-    </page>
-      <xsl:apply-templates/>
-    </xsl:element>
-    </pluto-portal-driver>
-  </xsl:template>
-
-  <xsl:template match="pa:portlet-app/pa:portlet">
-      <xsl:element name="page">
-        <xsl:attribute name="name"><xsl:value-of select="pa:portlet-name"/></xsl:attribute>
-        <xsl:attribute name="uri">/WEB-INF/themes/pluto-default-theme.jsp</xsl:attribute>
-          <xsl:element name="portlet">
-            <xsl:attribute name="context">/<xsl:value-of select='$portlet-app-context'/></xsl:attribute>
-            <xsl:attribute name="name"><xsl:value-of select="pa:portlet-name"/></xsl:attribute>
-          </xsl:element>
-      </xsl:element>    
-  </xsl:template>
-  
-  <!-- ignore all other children of pa:portlet-app -->
-  <xsl:template match="pa:portlet-app/*[not(pa:portlet-name)]"/>
-
-</xsl:stylesheet>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2b4c5599/portlet-tck_3.0/xml-resources/test.xsl
----------------------------------------------------------------------
diff --git a/portlet-tck_3.0/xml-resources/test.xsl b/portlet-tck_3.0/xml-resources/test.xsl
deleted file mode 100644
index 63d45d3..0000000
--- a/portlet-tck_3.0/xml-resources/test.xsl
+++ /dev/null
@@ -1,78 +0,0 @@
-<!--
-    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.	   
--->
-
-<!--
-   This stylesheet creates a list of test cases from the portlet.xml file.
-   
-   A naming convention is used in order to be able to automatically create a
-   properties file containing test case names mapping to the page to be accessed
-   to execute the test. The test case name is used as the portlet name and as 
-   the page name for the test.
-   
-   Note that the test case name must be unique within the TCK.
-   
-   In addition, an additional file containing test case name - page name mappings
-   can be provided. This allows a page and portlet to contain multiple test cases
-   that the test driver will execute sequentially. The parameter "additionalTCs"
-   must be set in the project pom with an absolute URI to the file. If the 
-   parameter is not set, no additional test cases will be added.
--->
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pa="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
-  <xsl:output method="xml" indent="yes" doctype-system="http://java.sun.com/dtd/properties.dtd"/> 
-  <xsl:strip-space elements="pa:portlet-app"/>
-  <xsl:param name="additionalTCs"/>
-  <xsl:param name="copyOnly"/>
-  <xsl:template match="/">
-    <xsl:element name="properties">
-      <xsl:if test="$copyOnly!='true'">
-         <xsl:apply-templates/>
-      </xsl:if>
-      <xsl:if test="$additionalTCs!='false'">
-         <xsl:variable name="addi" select="document($additionalTCs)"/>
-         <xsl:for-each select="$addi//entry">
-            <xsl:element name="entry">
-               <xsl:attribute name="key"><xsl:value-of select="@key"/></xsl:attribute>
-               <xsl:value-of select="."/>
-            </xsl:element>
-         </xsl:for-each>
-      </xsl:if>
-    </xsl:element>
-  </xsl:template>
- 
-  <!-- Create entry element for every portlet. For each entry: 
-       key attribute    = test case name                                
-       value            = page to be addressed to execute the TC
-       
-       The test driver will use the name / value pairs along with the context
-       base to construct URLs of the following form for test case execution:
-       
-       http://<test.server.host>:<test.server.port>/<test.context.base><value>
-  -->
-  <xsl:template match="pa:portlet-app/pa:portlet">
-    <xsl:element name="entry">
-      <xsl:attribute name="key"><xsl:value-of select="pa:portlet-name"/></xsl:attribute>
-      <xsl:value-of select="pa:portlet-name"/>
-    </xsl:element>
-  </xsl:template>
-  
-  <!-- ignore all other children of pa:portlet-app -->
-  <xsl:template match="pa:portlet-app/*[not(pa:portlet-name)]"/>
-
-</xsl:stylesheet>


[15/15] portals-pluto git commit: Fixed bug in PortletHubDemo pom

Posted by ms...@apache.org.
Fixed bug in PortletHubDemo pom


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

Branch: refs/heads/PortletHub
Commit: 909e237636f7029149470b20347614fec75d9b0d
Parents: cdebb54
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Nov 19 17:39:23 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Nov 19 17:39:23 2014 +0100

----------------------------------------------------------------------
 pluto-PortletHubDemo/pom.xml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/909e2376/pluto-PortletHubDemo/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/pom.xml b/pluto-PortletHubDemo/pom.xml
index 506726f..9f5efb4 100644
--- a/pluto-PortletHubDemo/pom.xml
+++ b/pluto-PortletHubDemo/pom.xml
@@ -8,7 +8,6 @@
     </parent>
 
 	<artifactId>PortletHubDemo</artifactId>
-	<version>0.0.1-SNAPSHOT</version>
 	<packaging>war</packaging>
 
 	<dependencies>
@@ -104,12 +103,12 @@
 					<plugin>
 						<groupId>org.apache.portals.pluto</groupId>
 						<artifactId>maven-pluto-plugin</artifactId>
-						<version>2.0.3</version>
+						<version>${project.version}</version>
 						<dependencies>
 							<dependency>
 								<groupId>org.apache.portals.pluto</groupId>
 								<artifactId>pluto-util</artifactId>
-								<version>2.0.3</version>
+								<version>${project.version}</version>
 								<scope>runtime</scope>
 							</dependency>
 						</dependencies>


[07/15] portals-pluto git commit: Improved code structure of portlet hub impl URL generation code

Posted by ms...@apache.org.
Improved code structure of portlet hub impl URL generation 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/066d667b
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/066d667b
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/066d667b

Branch: refs/heads/PortletHub
Commit: 066d667b9c2f93624242f86f780232306a81b83d
Parents: de9b04e
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Nov 11 23:19:24 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Nov 11 23:19:24 2014 +0100

----------------------------------------------------------------------
 pluto-portal/src/main/webapp/portletHubImpl.js | 103 ++++++++++----------
 1 file changed, 53 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/066d667b/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 e041829..1b9cf1c 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -439,6 +439,51 @@ var portlet = portlet || {};
    },
    
    
+   // Constants used for URL Encoding/Decoding (copied from Pluto impl code)  ----------
+
+   PREFIX = "__",
+   DELIM = "_",
+   PORTLET_ID = "pd",
+   ACTION = "ac",
+   RESOURCE = "rs",
+   RESOURCE_ID = "ri",
+   CACHE_LEVEL = "cl",
+   RENDER_PARAM = "rp",
+   PRIVATE_RENDER_PARAM = "pr",
+   PUBLIC_RENDER_PARAM = "sp",
+   WINDOW_STATE = "ws",
+   PORTLET_MODE = "pm",
+   VALUE_DELIM = "0x0",
+   
+   
+   /**
+    * Helper for generating parameter strings for the URL
+    */
+   genParmString = function (pid, name, type) {
+      var vals, jj, sep, str = "", wid = "";
+      vals = pageState[pid].state.parameters[name];
+      
+      // If encoding a render parameter, insert the pid in Pluto internal form 
+      // as opposed to namespace form -
+      
+      if (type === RENDER_PARAM) {
+         wid = plutoEncode(pageState[pid].urlpid)
+      }
+      
+      // If values are present, encode the multivalued parameter string
+      
+      if (vals) {
+         sep = "";
+         str += "/" + PREFIX + type + wid + DELIM + encodeURIComponent(name) + "/";
+         for (jj=0; jj < vals.length; jj++) {
+            str += sep + encodeURIComponent(vals[jj]);
+            sep = VALUE_DELIM;
+         }
+      }
+      return str;
+   },
+   
+   
    /**
     * Returns a URL of the specified type.
     * 
@@ -453,23 +498,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,
-      
-      // Constants used for Encoding/Decoding (copied from Pluto impl code)  ----------
-
-      PREFIX = "__",
-      DELIM = "_",
-      PORTLET_ID = "pd",
-      ACTION = "ac",
-      RESOURCE = "rs",
-      RESOURCE_ID = "ri",
-      CACHE_LEVEL = "cl",
-      RENDER_PARAM = "rp",
-      PRIVATE_RENDER_PARAM = "pr",
-      PUBLIC_RENDER_PARAM = "sp",
-      WINDOW_STATE = "ws",
-      PORTLET_MODE = "pm",
-      VALUE_DELIM = "0x0";
+          sep = "", name, names, val, vals, ii, jj, str, id, ids;
 
       if (type === "RESOURCE") {
          
@@ -483,10 +512,10 @@ var portlet = portlet || {};
          url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
          
          // Put the private & public parameters on the URL if cacheability != FULL
-         if (cache !== "cacheLevelFull") {
+         if (ca !== "cacheLevelFull") {
             
             // If cacheability = PAGE, add the state for the non-target portlets
-            if (cache === "cacheLevelPage") {
+            if (ca === "cacheLevelPage") {
                
                ids = getIds();
                for (ii = 0; ii < ids.length; ii++) {
@@ -495,18 +524,9 @@ var portlet = portlet || {};
                      str = "";
                      names = pageState[id].state.parameters;
                      for (name in names) {
+                        // Public render parameters are encoded separately
                         if (names.hasOwnProperty(name) && !isPRP(id, name)) {
-                           vals = pageState[id].state.parameters[name];
-                           // might not be set yet ...
-                           if (vals) {
-                              sep = "";
-                              str += "/" + PREFIX + RENDER_PARAM + plutoEncode(pageState[id].urlpid)
-                                     + DELIM + encodeURIComponent(name) + "/";
-                              for (jj=0; jj < vals.length; jj++) {
-                                 str += sep + encodeURIComponent(vals[jj]);
-                                 sep = VALUE_DELIM;
-                              }
-                           }
+                           str += genParmString(id, name, RENDER_PARAM);
                         }
                      }
                      url += str;
@@ -520,17 +540,9 @@ var portlet = portlet || {};
             str = "";
             names = pageState[pid].state.parameters;
             for (name in names) {
+               // Public render parameters are encoded separately
                if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
-                  vals = pageState[pid].state.parameters[name];
-                  // might not be set yet ...
-                  if (vals) {
-                     sep = "";
-                     str += "/" + PREFIX + PRIVATE_RENDER_PARAM + DELIM + encodeURIComponent(name) + "/";
-                     for (jj=0; jj < vals.length; jj++) {
-                        str += sep + encodeURIComponent(vals[jj]);
-                        sep = VALUE_DELIM;
-                     }
-                  }
+                  str += genParmString(pid, name, PRIVATE_RENDER_PARAM);
                }
             }
             url += str;
@@ -540,16 +552,7 @@ var portlet = portlet || {};
             names = pageState[pid].pubParms;
             for (ii=0; ii < names.length; ii++) {
                name = names[ii];
-               vals = pageState[pid].state.parameters[name];
-               // might not be set yet ...
-               if (vals) {
-                  sep = "";
-                  str += "/" + PREFIX + PUBLIC_RENDER_PARAM + DELIM + encodeURIComponent(name) + "/";
-                  for (jj=0; jj < vals.length; jj++) {
-                     str += sep + encodeURIComponent(vals[jj]);
-                     sep = VALUE_DELIM;
-                  }
-               }
+               str += genParmString(pid, name, PUBLIC_RENDER_PARAM);
             }
             url += str;
 


[02/15] portals-pluto git commit: Started adding portlet hub prototype to pluto

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1eeac9c3/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
new file mode 100644
index 0000000..befa84e
--- /dev/null
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -0,0 +1,645 @@
+/*  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.
+ */
+
+/*
+ * This source code implements specifications defined by the Java
+ * Community Process. In order to remain compliant with the specification
+ * DO NOT add / change / or delete method signatures!
+ */
+
+/**
+ * @fileOverview
+ * This module provides mock data & functions for the mock 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
+ */
+var portlet = portlet || {};
+
+(function () {
+   'use strict';
+
+   var isInitialized = false,
+
+   /**
+    * The object holding the portlet data for each portlet on the page.
+    * This an object indexed by portlet ID.
+    * @property   {PortletData} {string}  
+    *    The object holds one portlet data object for each portlet. The string
+    *    property name is the portlet ID.
+    * @private
+    */
+   pageState,
+   
+   
+   /**
+    * Determines if the specified portlet ID is present.
+    * @param   {string}    pid      The portlet ID
+    * @returns {boolean}            true if the portlet ID can be found
+    * @function
+    * @private
+    */
+   isValidId = function (pid) {
+      var id;
+      for (id in pageState) {
+         if (!pageState.hasOwnProperty(id)) {
+            continue;
+         }
+         if (pid === id) {
+            return true;
+         }
+      }
+      return false;
+   },
+
+   /**
+    * get the available portlet IDs in an array 
+    */
+   getIds = function () {
+      var id, ids = [];
+      for (id in pageState) {
+         if (pageState.hasOwnProperty(id)) {
+            ids.push(id);
+         }
+      }
+      return ids;
+   },
+      
+   /**
+    * gets parameter value
+    */
+   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
+    *
+    * @param {string[]} parm1 First parameter
+    * @param {string[]} parm2 2nd parameter
+    * @returns {boolean} true if the new parm value is equal to the current value
+    * @private
+    */
+   _isParmEqual = function(parm1, parm2) {
+      var ii;
+
+      // The values are either string arrays or undefined.
+
+      if ((parm1 === undefined) && (parm2 === undefined)) {
+         return true;
+      }
+      
+      if ((parm1 === undefined) || (parm2 === undefined)) {
+         return false;
+      }
+      
+      if (parm1.length !== parm2.length) {
+         return false;
+      }
+      
+      
+      for (ii = parm1.length - 1; ii >= 0; ii--) {
+         if (parm1[ii] !== parm2[ii]) {
+            return false;
+         }
+      }
+
+      return true;
+   },
+
+   /**
+    * Compares the values of the named parameter in the new portlet state
+    * with the values of that parameter in the current state.
+    *
+    * @param      {string}       pid      The portlet ID
+    * @param      {PortletState} state    The new portlet state
+    * @param      {string}       name     The parameter name to check
+    * @returns    {boolean}               true if the new parm value is different
+    *                                     from the current value
+    * @private
+    */
+   isParmInStateEqual = function (pid, state, name) {
+      var newVal = state.parameters[name], oldVal = getParmVal(pid, name);
+
+      return _isParmEqual(newVal, oldVal);
+   },
+      
+   /**
+    * gets defeined PRPs for the portlet
+    */
+   getPRPNames = function (pid) {
+      return pageState[pid].pubParms;
+   },
+
+   /**
+    * Gets the updated public parameters for the given portlet
+    * ID and new portlet state.
+    * Returns an object whose properties are the names of the
+    * updated public parameters. The values are the new public
+    * parameter values.
+    *
+    * @param      {string}       pid      The portlet ID
+    * @param      {PortletState} state    The new portlet state
+    * @returns    {object}                object containing the updated PRPs
+    * @private
+    */
+   getUpdatedPRPs = function (pid, state) {
+      var prps = {}, ii = 0, prpNames = getPRPNames(pid), name;
+
+      for (ii = 0; ii < prpNames.length; ii++) {
+         name = prpNames[ii];
+         if (isParmInStateEqual(pid, state, name) === false) {
+            prps[name] = state.parameters[name];
+         }
+      }
+
+      return prps;
+   },
+
+      
+   /**
+    * Returns a deep-copy clone of the input portlet state object.
+    * Used to provide the portlet client with a copy of the current 
+    * state data rather than a reference to the live state itself.
+    * 
+    * @param      {PortletState} state    The portlet state object to check
+    * @returns    {PortletState}          Clone of the input portlet state
+    * @private
+    */
+   cloneState = function (aState) {
+      var newParams = {},
+      newState = {
+            portletMode : aState.portletMode,
+            windowState : aState.windowState,
+            parameters : newParams
+      }, key, oldParams = aState.parameters;
+   
+      for (key in oldParams) {
+         newParams[key] = oldParams[key].slice(0); 
+      }
+   
+      return newState;
+   },
+
+   /**
+    * Get allowed window states for portlet
+    */
+   getAllowedWS = function (pid) {
+      return pageState[pid].allowedWS.slice(0);
+   },
+   
+   /**
+    * Get allowed portlet modes for portlet
+    */
+   getAllowedPM = function (pid) {
+      return pageState[pid].allowedPM.slice(0);
+   },
+   
+   
+   /**
+    * gets render data for the portlet
+    */
+   getRenderData = function (pid) {
+      return pageState[pid].renderData;
+   },
+         
+   /**
+    * gets state for the portlet
+    */
+   getState = function (pid) {
+      return pageState[pid].state;
+   },
+   
+   /**
+    * sets state for the portlet. returns
+    * array of IDs for portlets that were affected by the change, 
+    * taking into account the public render parameters.
+    */
+   setState = function (pid, state) {
+      var pids, prps = getUpdatedPRPs(pid, state), prp, ii, tpid, upids = [], newVal, oldVal, prpNames;
+         
+      // For each updated PRP for the
+      // initiating portlet, update that PRP in the other portlets.
+      for (prp in prps) {
+         if (prps.hasOwnProperty(prp)) {
+      
+            newVal = prps[prp];
+            
+            // process each portlet ID
+            pids = getIds();
+            for (ii = 0; ii < pids.length; ii++) {
+               tpid = pids[ii];
+               
+               // don't update for initiating portlet. that's done after the loop
+               if (tpid !== pid) {
+            
+                  oldVal = getParmVal(tpid, prp);
+                  prpNames = getPRPNames(tpid);
+                  
+                  // check for public parameter and if the value has changed
+                  if ((prpNames.indexOf(prp) >= 0) && 
+                      (_isParmEqual(oldVal, newVal) === false)) {
+                  
+                     if (newVal === undefined) {
+                        delete pageState[tpid].state.parameters[prp];
+                     } else {
+                        pageState[tpid].state.parameters[prp] = newVal.slice(0);
+                     }
+                     upids.push(tpid);
+                     
+                  }
+               }
+            }
+         }
+      }
+      
+      // update state for the initiating portlet
+      pageState[pid].state = state;
+      upids.push(pid);
+
+      
+      // Use Promise to allow for potential server communication - 
+      return new Promise(function (resolve, reject) {
+         var simval = '';
+         if (pid === 'SimulateCommError' && state.parameters.SimulateError !== undefined) {
+            simval = state.parameters.SimulateError[0];
+         }
+
+         // reject promise of an error is to be simulated
+         if (simval === 'reject') {
+            reject(new Error("Simulated error occurred when setting state!"));
+         } else {
+            resolve(upids);
+         }
+      });
+   },
+
+      
+   /**
+    * updates page state from string and returns array of portlet IDs
+    * to be updated.
+    * 
+    * @param   {string}    ustr     The 
+    * @param   {string}    pid      The portlet ID
+    * @private 
+    */
+   updatePageStateFromString = function (ustr, pid) {
+      var states, tpid, state, upids = [];
+
+      states = decodeUpdateString(ustr, pid);
+
+      // Update states and collect IDs of affected portlets. 
+      for (tpid in states) {
+         if (states.hasOwnProperty(tpid)) {
+            state = states[tpid];
+            pageState[tpid].state = state;
+            upids.push(tpid);
+         }
+      }
+
+      return upids;
+   },
+
+      
+   /**
+    * 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>
+    * @param   {HTMLFormElement}    Form to be submitted
+    *                               May be <code>null</code> 
+    * @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 - 
+      return new Promise(function (resolve, reject) {
+         var simval = '';
+         if (pid === 'SimulateCommError' && (parms)) {
+            simval = parms.SimulateError;
+            if (simval) {
+               simval = simval[0];
+            }
+         }
+            
+         // reject promise of an error is to be simulated
+         if (simval === 'reject') {
+            reject(new Error("Simulated error occurred during action!"));
+         } else {
+            resolve(upids);
+         }
+      });
+
+   },
+   
+   
+   /**
+    * Returns a URL of the specified type.
+    * 
+    * @param   {string}    type     The URL type
+    * @param   {string}    pid      The portlet ID
+    * @param   {PortletParameters}    parms      
+    *                Additional parameters. May be <code>null</code>
+    * @param   {string}    cache    Cacheability. Must be present if 
+    *                type = "RESOURCE". May be <code>null</code> 
+    * @private 
+    */
+   getUrl = function (type, pid, parms, cache) {
+   
+      var url = "http://www.dummyportal.com/some/context/";
+          var qparms = [], rparms, qp, state, tpid, val, pids, ii, jj;
+          
+      // for a mockup, should be good enough ...
+      // optimized for easy parsing by the test code. 
+      // see "portlet.test" below.
+      
+      // This is how it should look:
+      //  http://www.dummyportal.com/some/context/PortletA/ACTION/PAGE/?&rp1=resVal&RENDERPARMS
+      //  &~~~&PortletA&mode=VIEW&ws=NORMAL&parm1=Fred&parm2=Wilma&parm2=Pebbles&parm3=Barney&parm3=Betty&parm3=Bam%20Bam
+      //  &~~~&PortletB&mode=VIEW&ws=NORMAL&parm1=val1&pubparm1=pubval1&parm2=val2&parm2=val3
+      //  &~~~&PortletC&mode=VIEW&ws=NORMAL&parm1=val1&pubparm1=pubval1&pubparm2=pubval2&parm2=val2&parm2=val3
+      //  &~~~&PortletD&mode=VIEW&ws=NORMAL&pubparm1=private_val1&pubparm2=pubval2&parm2=val2&parm2=val3
+      //  &~~~&PortletE&mode=VIEW&ws=NORMAL&parm1=val1&parm2=val2&parm2=val3&pubparm1=pubval1&pubparm2=pubval2
+      //  &~~~&PortletF&mode=VIEW&ws=NORMAL&~~~
+      
+      url += pid + "/" + type + "/"; 
+      url += (((cache===undefined)||(cache===null))?"cacheLevelPage":cache) + "/?";
+          
+      // put the additional parameters on the URL
+      if (parms !== null) {
+         for (qp in parms) {
+            for (var ii=0; ii<parms[qp].length; ii++) {
+               val = (parms[qp][ii] === null) ? "" : "=" + encodeURIComponent(parms[qp][ii]);
+               qparms.push(encodeURIComponent(qp) + val);
+            }
+         }
+      }
+   
+      qparms.push("RENDERPARMS")
+      qparms.push("~~~")
+   
+      // Don't put any render parameters on it cache=cacheLevelFull
+      if ((type !== "RESOURCE") || 
+          ((type === "RESOURCE") && (cache !== "cacheLevelFull"))) {
+         
+         pids = getIds();
+         jj = pids.length;
+         while ((jj = jj - 1) >= 0) {
+            tpid = pids[jj];
+            
+            // If cache=cacheLevelPortlet, only put on the parms for that portlet
+            if ((type === "RESOURCE") && (cache === "cacheLevelPortlet") && (pid !== tpid)) {
+               continue;
+            }
+            
+            // put the portlet state parameters on the URL
+            state = getState(tpid);
+            
+            qparms.push(encodeURIComponent(tpid));
+            qparms.push("mode=" + state.portletMode);
+            qparms.push("ws=" + state.windowState);
+         
+            rparms = state.parameters;
+            for (qp in rparms) {
+               for (ii=0; ii<rparms[qp].length; ii++) {
+                  val = (rparms[qp][ii] === null) ? "" : "=" + encodeURIComponent(rparms[qp][ii]);
+                  qparms.push(encodeURIComponent(qp) + val);
+               }
+            }
+            qparms.push("~~~");
+            
+         }
+      }
+      
+      // put on the query parms
+      while (qparms.length > 0) {
+         url += "&" + qparms.shift();
+      }
+      
+      // Use Promise to allow for potential server communication - 
+      return new Promise(function (resolve, reject) {
+         var simval = '';
+         if (pid === 'SimulateCommError' && (parms)) {
+            simval = parms.SimulateError;
+            if (simval) {
+               simval = simval[0];
+            }
+         }
+            
+         // reject promise of an error is to be simulated
+         if (simval === 'reject') {
+            reject(new Error("Simulated error occurred when getting a URL!"));
+         } else {
+            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
+    */
+   throwIllegalArgumentException = function (msg) {
+      throw {
+         name : "IllegalArgumentException",
+         message : msg
+      };
+   },
+
+   
+   // decodes the update strings
+   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.");
+         }
+         
+         // 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;
+         
+      }
+      
+      return states;
+   };
+
+   
+   /**
+    * Register a portlet. The impl is passed the portlet ID for the portlet.
+    * The impl must retrieve the information for the portlet in an appropriate
+    * manner. It must return a Promise that is fulfilled when data for the 
+    * portlet becomes available and is rejected if an error occurs or if the
+    * portlet ID is invalid.
+    * 
+    * @param   {string}    pid      Portlet ID
+    * 
+    * @returns {Promise}            fulfilled when data is available
+    * 
+    * @function
+    * @private
+    */
+   portlet.impl = portlet.impl || {};
+   portlet.impl.register = function (pid) {
+
+      // take care of moc data initialization      
+      if (!isInitialized) {
+         pageState = portlet.impl.getInitData();
+         isInitialized = true;
+      }
+
+      // 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, callback, onError) {return executeAction(pid, parms, element, callback, onError);},
+   
+			/**
+			 * 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 updatePageStateFromString(ustr, pid);},
+   
+      };            
+      
+      return new Promise(
+         function(resolve, reject) {
+            
+            // verify the input pid 
+            if (isValidId(pid)) {
+               
+               switch(pid) {
+               case 'SimulateLongWait':
+                  window.setTimeout(function () {resolve(stubs);}, 500);
+                  break;
+               case 'SimulateError':
+                  window.setTimeout(function () {reject(new Error("Bad error happened!"));}, 100);
+                  break;
+               default:
+                  window.setTimeout(function () {resolve(stubs);}, 10);
+               }
+               
+            } else {
+               reject(new Error("Invalid portlet ID: " + pid));
+            }
+         }
+      );
+   };
+   
+   // Expose some internal functions for test purposes - 
+   
+   portlet.test = {
+      getIds : getIds
+   }; 
+   
+})();


[10/15] portals-pluto git commit: Added allowed window states to portlet hub init data

Posted by ms...@apache.org.
Added allowed window states to portlet hub init data


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

Branch: refs/heads/PortletHub
Commit: 90c5fda2295a80e2518ed07ceff3650f8faa870d
Parents: fa52b5a
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Nov 18 13:47:19 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Nov 18 13:47:19 2014 +0100

----------------------------------------------------------------------
 pluto-portal/pom.xml                            | 409 ++++++++++---------
 .../WEB-INF/themes/pluto-default-theme.jsp      |  12 +-
 2 files changed, 223 insertions(+), 198 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/90c5fda2/pluto-portal/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-portal/pom.xml b/pluto-portal/pom.xml
index d1205ab..2d2a0f2 100644
--- a/pluto-portal/pom.xml
+++ b/pluto-portal/pom.xml
@@ -1,197 +1,212 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.apache.portals.pluto</groupId>
-    <artifactId>pluto</artifactId>
-    <version>2.1.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>pluto-portal</artifactId>
-  <packaging>war</packaging>
-  <name>Apache Pluto Portal</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.portals.pluto</groupId>
-      <artifactId>pluto-container</artifactId>
-      <version>${project.version}</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.apache.portals.pluto</groupId>
-          <artifactId>pluto-container-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>jsp-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>org.apache.portals</groupId>
-          <artifactId>portlet-api_2.0_spec</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.portals.pluto</groupId>
-      <artifactId>pluto-portal-driver</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>jsp-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.portals.pluto</groupId>
-      <artifactId>pluto-portal-driver-impl</artifactId>
-      <version>${project.version}</version>
-      <scope>compile</scope>
-      <exclusions>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>jsp-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>javax.servlet</groupId>
-          <artifactId>servlet-api</artifactId>
-        </exclusion>
-        <exclusion>
-          <groupId>xml-apis</groupId>
-          <artifactId>xml-apis</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-
-    <dependency>
-      <groupId>org.slf4j</groupId>
-	 	<artifactId>slf4j-api</artifactId>
-	 	<scope>${dependency.scope}</scope>
-	 </dependency>
-	 <dependency>
-	 	<groupId>org.slf4j</groupId>
-      <artifactId>slf4j-jdk14</artifactId>
-	 	<scope>${dependency.scope}</scope>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>jcl-over-slf4j</artifactId>
-      <scope>compile</scope>
-    </dependency>
-
-    <dependency>
-      <artifactId>junit</artifactId>
-      <groupId>junit</groupId>
-    </dependency>
-
-  </dependencies>
-
-  <build>
-
-    <plugins>
-      <plugin>
-      	<groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-war-plugin</artifactId>
-        <configuration>
-          <webResources>
-            <resource>
-              <filtering>true</filtering>
-              <directory>${pom.basedir}/src/main/resources</directory>
-              <includes>
-                <include>pluto-portal-driver-config.xml</include>
-              </includes>
-              <targetPath>WEB-INF</targetPath>
-            </resource>
-          </webResources>
-        </configuration>
-      </plugin>
-      <!-- workaround for war processing of m-r-r-plugin causing the generated NOTICE and LICENSE file to be put under WEB-INF/classes/META-INF -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-remote-resources-plugin</artifactId>
-        <executions>
-          <execution>
-            <goals>
-              <goal>process</goal>
-            </goals>
-            <configuration>
-              <outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
-              <attached>false</attached>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-      <!-- Don't attach source or javadoc archive -->
-      <plugin>
-        <artifactId>maven-source-plugin</artifactId>
-        <configuration>
-          <attach>false</attach>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-javadoc-plugin</artifactId>
-        <configuration>
-          <skip>true</skip>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-  <profiles>
-    <profile>
-      <id>rat</id>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.rat</groupId>
-            <artifactId>apache-rat-plugin</artifactId>
-            <configuration>
-              <excludes combine.children="append">
-                <exclude>src/main/webapp/META-INF/SLF4J-LICENSE</exclude>
-                <exclude>src/main/webapp/META-INF/JAXB-LICENSE</exclude>
-              </excludes>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-    </profile>
-  </profiles>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.portals.pluto</groupId>
+    <artifactId>pluto</artifactId>
+    <version>2.1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>pluto-portal</artifactId>
+  <packaging>war</packaging>
+  <name>Apache Pluto Portal</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.portals.pluto</groupId>
+      <artifactId>pluto-container</artifactId>
+      <version>${project.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>org.apache.portals.pluto</groupId>
+          <artifactId>pluto-container-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>jsp-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>servlet-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.apache.portals</groupId>
+          <artifactId>portlet-api_2.0_spec</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>xml-apis</groupId>
+          <artifactId>xml-apis</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.portals.pluto</groupId>
+      <artifactId>pluto-portal-driver</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>jsp-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>servlet-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>xml-apis</groupId>
+          <artifactId>xml-apis</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.portals.pluto</groupId>
+      <artifactId>pluto-portal-driver-impl</artifactId>
+      <version>${project.version}</version>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>jsp-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>javax.servlet</groupId>
+          <artifactId>servlet-api</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>xml-apis</groupId>
+          <artifactId>xml-apis</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+       <groupId>javax.servlet</groupId>
+	   <artifactId>jsp-api</artifactId>
+	   <scope>provided</scope>
+	 </dependency>
+    <dependency>
+       <groupId>javax.servlet</groupId>
+       <artifactId>servlet-api</artifactId>
+       <scope>provided</scope>
+    </dependency>
+    <dependency>
+       <groupId>org.apache.portals</groupId>
+       <artifactId>portlet-api_2.0_spec</artifactId>
+       <scope>provided</scope>
+    </dependency>
+    <dependency>
+       <groupId>org.slf4j</groupId>
+       <artifactId>slf4j-api</artifactId>
+       <scope>${dependency.scope}</scope>
+    </dependency>
+	 <dependency>
+	 	<groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+	 	<scope>${dependency.scope}</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>compile</scope>
+    </dependency>
+
+    <dependency>
+      <artifactId>junit</artifactId>
+      <groupId>junit</groupId>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+
+    <plugins>
+      <plugin>
+      	<groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <webResources>
+            <resource>
+              <filtering>true</filtering>
+              <directory>${pom.basedir}/src/main/resources</directory>
+              <includes>
+                <include>pluto-portal-driver-config.xml</include>
+              </includes>
+              <targetPath>WEB-INF</targetPath>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+      <!-- workaround for war processing of m-r-r-plugin causing the generated NOTICE and LICENSE file to be put under WEB-INF/classes/META-INF -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
+              <attached>false</attached>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <!-- Don't attach source or javadoc archive -->
+      <plugin>
+        <artifactId>maven-source-plugin</artifactId>
+        <configuration>
+          <attach>false</attach>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-javadoc-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>rat</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <configuration>
+              <excludes combine.children="append">
+                <exclude>src/main/webapp/META-INF/SLF4J-LICENSE</exclude>
+                <exclude>src/main/webapp/META-INF/JAXB-LICENSE</exclude>
+              </excludes>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/90c5fda2/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index fb4c9c4..c674a20 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -85,6 +85,16 @@ group (the left column) displays portlets with odd IDs, while the second group
                       }
                    } catch (Exception e) {}
                    
+                   StringBuffer pmstring = new StringBuffer();
+                   try {
+                      Set<PortletMode> allowedPMs = dc.getSupportedPortletModes(pid);
+                      sep = "";
+                      for (PortletMode pm : allowedPMs) {
+                         pmstring.append(sep + "'" + pm.toString() + "'");
+                         sep = ", ";
+                      }
+                   } catch (Exception e) {}
+                   
                    String pm = pu.getPortletMode(pid).toString();
                    String ws = pu.getWindowState(pid).toString();
                 %>
@@ -126,7 +136,7 @@ group (the left column) displays portlets with odd IDs, while the second group
                       'windowState' : '<%=ws%>'
                    },
                    'pubParms' : [<%=prpstring.toString()%>],
-                   'allowedPM' : ['view'],
+                   'allowedPM' : [<%=pmstring.toString()%>],
                    'allowedWS' : ['normal'],
                    'renderData' : {
                       'renderData' : null,


[12/15] portals-pluto git commit: Added PageState utility class to pull together the state information for all portlets on the page.

Posted by ms...@apache.org.
Added PageState utility class to pull together the state information for all portlets on the page.


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

Branch: refs/heads/PortletHub
Commit: 9b23599fb8d137b3a0b712670f8c07b2c614fcdb
Parents: 59cd72e
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Nov 19 11:11:59 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Nov 19 11:11:59 2014 +0100

----------------------------------------------------------------------
 .../org/apache/pluto/driver/util/PageState.java | 300 +++++++++++++++++++
 .../apache/pluto/driver/util/package-info.java  |  25 ++
 .../WEB-INF/themes/pluto-default-theme.jsp      |  79 ++---
 3 files changed, 344 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9b23599f/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
new file mode 100644
index 0000000..6403de7
--- /dev/null
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
@@ -0,0 +1,300 @@
+/*  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.util;
+
+import static java.util.logging.Level.*;
+
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletURL;
+import javax.portlet.WindowState;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.pluto.driver.AttributeKeys;
+import org.apache.pluto.driver.config.DriverConfiguration;
+import org.apache.pluto.driver.core.PortalRequestContext;
+import org.apache.pluto.driver.services.portal.PageConfig;
+import org.apache.pluto.driver.url.PortalURL;
+import org.apache.pluto.driver.url.PortalURLParameter;
+
+/**
+ * @author Scott Nicklous
+ * 
+ * This is a utility class that collects all data needed by the portlet
+ * hub in one location. The data is formatted appropriately for transmission to 
+ * the client.
+ *
+ */
+public class PageState {
+   private static final String LOG_CLASS = PageState.class.getName();
+   private final Logger        LOGGER    = Logger.getLogger(LOG_CLASS);
+
+   private DriverConfiguration   drvrConfig;
+   private PageConfig            pageConfig;
+   private PortalRequestContext  portalRC;
+   private PortalURL             portalUrl;
+   private ServletContext        servletContext;
+   
+   /**
+    * Constructor. Access the classes containing the necessary data.
+    *  
+    * @param request
+    */
+   public PageState(HttpServletRequest request) {
+      portalRC = PortalRequestContext.getContext(request);
+      portalUrl = portalRC.getRequestedPortalURL(); 
+      drvrConfig = (DriverConfiguration) portalRC.getServletContext()
+            .getAttribute(AttributeKeys.DRIVER_CONFIG);
+      servletContext = portalRC.getServletContext();
+      pageConfig = portalUrl.getPageConfig(servletContext);
+   }
+   
+   /**
+    * Returns the portal URL parameters that are set on the current URL.
+    * 
+    * @return
+    */
+   public Collection<PortalURLParameter> getParameters() {
+      return portalUrl.getParameters();
+   }
+   
+   /**
+    * Returns the public render parameters set on the current URL.
+    * 
+    * @return
+    */
+   public Map<String, String[]> getPublicParameters() {
+      return portalUrl.getPublicParameters();
+   }
+   
+   /**
+    * Returns a collection containing the portlet IDs for the portlets on the page.
+    * 
+    * @return
+    */
+   public Collection<String> getPortletIds() {
+      return pageConfig.getPortletIds();
+   }
+   
+   /**
+    * Returns a Pluto namespace string for the input portlet ID.
+    * @param   portletId
+    * @return  namespace string for the portlet ID
+    */
+   public String getNameSpace(String portletId) {
+      StringBuffer ns = new StringBuffer("Pluto_");
+      for (int ii=0; ii < portletId.length(); ii++) {
+         if (Character.isJavaIdentifierPart(portletId.charAt(ii))) {
+            ns.append(portletId.charAt(ii));
+         } else {
+            ns.append("_");
+         }
+      }
+      ns.append("_");
+      return ns.toString();
+   }
+   
+   /**
+    * Returns the public render parameter names for the portlet ID as a set.
+    * @param   portletId  
+    * @return  Set of string public render parameter names
+    */
+   public Set<String> getPRPNames(String portletId) {
+      Set<String> prpnames = new HashSet<String>();
+      PortletConfig pc = null;
+
+      try {
+         pc = drvrConfig.getPortletConfig(portletId);
+         Enumeration<String> prps = pc.getPublicRenderParameterNames();
+         while (prps.hasMoreElements()) {
+            String prp = prps.nextElement();
+            prpnames.add(prp);
+         }
+      } catch (Exception e) {}
+      return prpnames;
+   }
+   
+   /**
+    * Returns the public render parameter names for the portlet ID as a 
+    * delimited string that can be used in a JSON array.
+    * @param   portletId  
+    * @return  Delimited string of public render parameter names
+    */
+   public String getPRPNamesAsString(String portletId) {
+      PortletConfig pc = null;
+      StringBuffer prpstring = new StringBuffer();;
+
+      String sep = "";
+      try {
+         pc = drvrConfig.getPortletConfig(portletId);
+         Enumeration<String> prps = pc.getPublicRenderParameterNames();
+         while (prps.hasMoreElements()) {
+            String prp = prps.nextElement();
+            prpstring.append(sep + "'" + prp + "'");
+            sep = ", ";
+         }
+      } catch (Exception e) {}
+      return prpstring.toString();
+   }
+   
+   
+   /**
+    * Returns the supported portlet mode names for the portlet ID as a 
+    * delimited string that can be used in a JSON array.
+    * @param   portletId  
+    * @return  Delimited string of portlet mode names
+    */
+   public String getPortletModesAsString(String portletId) {
+      StringBuffer pmstring = new StringBuffer();
+      try {
+         Set<PortletMode> allowedPMs = drvrConfig.getSupportedPortletModes(portletId);
+         String sep = "";
+         for (PortletMode pm : allowedPMs) {
+            pmstring.append(sep + "'" + pm.toString() + "'");
+            sep = ", ";
+         }
+      } catch (Exception e) {}
+      return pmstring.toString();
+   }
+   
+   
+   /**
+    * Returns the supported window state names for the portlet ID as a 
+    * delimited string that can be used in a JSON array.
+    * @param   portletId  
+    * @return  Delimited string of window state names
+    */
+   public String getWindowStatesAsString(String portletId) {
+      StringBuffer wsstring = new StringBuffer();
+      try {
+         Set<WindowState> allowedWSs = drvrConfig.getSupportedWindowStates(portletId, "text/html");
+         String sep = "";
+         for (WindowState ws : allowedWSs) {
+            wsstring.append(sep + "'" + ws.toString() + "'");
+            sep = ", ";
+         }
+      } catch (Exception e) {}
+      return wsstring.toString();
+   }
+   
+   /**
+    * Returns the current portlet mode for the portlet
+    * 
+    * @param portletId
+    * @return
+    */
+   public String getPortletMode(String portletId) {
+      return portalUrl.getPortletMode(portletId).toString();
+   }
+   
+   /**
+    * Returns the current window state for the portlet
+    * 
+    * @param portletId
+    * @return
+    */
+   public String getWindowState(String portletId) {
+      return portalUrl.getWindowState(portletId).toString();
+   }
+   
+   /**
+    * Returns a relative base base as needed by the portlet hub to generate
+    * URLs. Must be encoded by the caller.
+    * 
+    * @return
+    */
+   public String getUrlBase() {
+      StringBuffer ub = new StringBuffer();
+      ub.append(portalUrl.getServletPath().startsWith("/")?"":"/")
+        .append(portalUrl.getServletPath())
+        .append(portalUrl.getRenderPath());
+      return ub.toString();
+   }
+   
+   public String toJSONString() {
+      StringBuffer json = new StringBuffer(1024);
+      json.append("{");
+      
+      Collection<PortalURLParameter> pups = getParameters();
+      Map<String, String[]> pubparms = getPublicParameters();
+      
+      for (String pid : getPortletIds()) {
+         json.append("   '" + getNameSpace(pid) + "' : {");
+         json.append("      'state' : {");
+         json.append("         'parameters' : {");
+
+         // Add the portlet parameters
+         String c1 = "            '";
+         for (PortalURLParameter pup : pups){
+            if (pup.getWindowId().equals(pid)){
+               json.append(c1  + pup.getName() + "' : [");
+               String c2 = "";
+               for (String val : pup.getValues()) {
+                  json.append(c2 + " '" + val + "'");
+                  c2 = ",";
+               }
+               json.append("]");
+               c1 = ",\n            '";
+            }
+         }
+         
+         // Add the public render parameter values for this portlet
+         
+         Set<String> prpnames = getPRPNames(pid);
+         for (String prp : pubparms.keySet()) {
+            if (prpnames.contains(prp)) {
+               json.append(c1 + prp + "' : [");
+               String c2 = "";
+               for (String val : (String[])pubparms.get(prp)) {
+                  json.append(c2 + " '" + val + "'");
+                  c2 = ",";
+               }
+               json.append("]");
+               c1 = ",\n            '";
+            }
+         }
+
+         json.append("         }, ");
+         json.append("         'portletMode' : '" + getPortletMode(pid) + "', ");
+         json.append("         'windowState' : '" + getWindowState(pid) + "'");
+         json.append("      },");
+         json.append("      'pubParms' : [" + getPRPNamesAsString(pid) + "],");
+         json.append("      'allowedPM' : [" + getPortletModesAsString(pid) + "],");
+         json.append("      'allowedWS' : [" + getWindowStatesAsString(pid) + "],");
+         json.append("      'renderData' : {");
+         json.append("         'renderData' : null,");
+         json.append("         'mimeType' : \"text/plain\"");
+         json.append("      },");
+         json.append("      'urlpid' : '" + pid + "'");
+         json.append("   },");
+      }
+      
+      json.append("}");
+      return json.toString();
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9b23599f/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/package-info.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/package-info.java
new file mode 100644
index 0000000..faa0d9b
--- /dev/null
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/package-info.java
@@ -0,0 +1,25 @@
+/*  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.
+ */
+
+/**
+ * @author Scott Nicklous
+ *
+ * Package containing utility classes used by the impl, primarily for
+ * providing the necessary server-side support for the client-side portlet hub.
+ */
+package org.apache.pluto.driver.util;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9b23599f/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index 25870f8..6972a29 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -22,6 +22,7 @@ limitations under the License.
 <%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %>
 <%@ page import="java.util.*,javax.portlet.*,org.apache.pluto.driver.url.*" %>
 <%@ page import="org.apache.pluto.driver.config.*,org.apache.pluto.driver.*" %>
+<%@ page import="org.apache.pluto.driver.util.*" %>
 <%@ page import="org.apache.pluto.container.*,javax.servlet.jsp.*" %>
 <% pageContext.setAttribute("now", new java.util.Date()); %>
 
@@ -50,63 +51,27 @@ group (the left column) displays portlets with odd IDs, while the second group
        portlet.impl.getInitData = function () {
           return {       
              <%
-                PortalRequestContext prc = PortalRequestContext.getContext(request);
-                PortalURL pu = prc.getRequestedPortalURL(); 
-                Collection<PortalURLParameter> pups = pu.getParameters();
-                Map<String, String[]> pubparms = pu.getPublicParameters();
-                DriverConfiguration dc = (DriverConfiguration) prc.getServletContext()
-                      .getAttribute(AttributeKeys.DRIVER_CONFIG);
+                PageState ps = new PageState(request);
+                Collection<String> poids = ps.getPortletIds();
+             
+                Collection<PortalURLParameter> pups = ps.getParameters();
+                Map<String, String[]> pubparms = ps.getPublicParameters();
              %>
              <c:forEach var="pid" items="${currentPage.portletIds}">
                 <%
-                   StringBuffer ns = new StringBuffer("Pluto_");
                    String pid = (String)pageContext.getAttribute("pid");
-                   for (int ii=0; ii < pid.length(); ii++) {
-                      if (Character.isJavaIdentifierPart(pid.charAt(ii))) {
-                         ns.append(pid.charAt(ii));
-                      } else {
-                         ns.append("_");
-                      }
-                   }
-                   ns.append("_");
-
-                   PortletConfig pc = null;
-                   StringBuffer prpstring = new StringBuffer();
-                   Set<String> prpnames = new HashSet<String>();
-                   String sep = "";
-                   try {
-                      pc = dc.getPortletConfig(pid);
-                      Enumeration<String> prps = pc.getPublicRenderParameterNames();
-                      while (prps.hasMoreElements()) {
-                         String prp = prps.nextElement();
-                         prpnames.add(prp);
-                         prpstring.append(sep + "'" + prp + "'");
-                         sep = ", ";
-                      }
-                   } catch (Exception e) {}
                    
-                   StringBuffer pmstring = new StringBuffer();
-                   try {
-                      Set<PortletMode> allowedPMs = dc.getSupportedPortletModes(pid);
-                      sep = "";
-                      for (PortletMode pm : allowedPMs) {
-                         pmstring.append(sep + "'" + pm.toString() + "'");
-                         sep = ", ";
-                      }
-                   } catch (Exception e) {}
+                   String ns = ps.getNameSpace(pid);
+
+                   String prpstring = ps.getPRPNamesAsString(pid);
+                   Set<String> prpnames = ps.getPRPNames(pid);
+                   
+                   String pmstring = ps.getPortletModesAsString(pid);
                    
-                   StringBuffer wsstring = new StringBuffer();
-                   try {
-                      Set<WindowState> allowedWSs = dc.getSupportedWindowStates(pid, "text/html");
-                      sep = "";
-                      for (WindowState ws : allowedWSs) {
-                         wsstring.append(sep + "'" + ws.toString() + "'");
-                         sep = ", ";
-                      }
-                   } catch (Exception e) {}
+                   String wsstring = ps.getWindowStatesAsString(pid);
                    
-                   String pm = pu.getPortletMode(pid).toString();
-                   String ws = pu.getWindowState(pid).toString();
+                   String pm = ps.getPortletMode(pid);
+                   String ws = ps.getWindowState(pid);
                 %>
                 '<%=ns%>' : {
                    'state' : {
@@ -145,9 +110,9 @@ group (the left column) displays portlets with odd IDs, while the second group
                       'portletMode' : '<%=pm%>', 
                       'windowState' : '<%=ws%>'
                    },
-                   'pubParms' : [<%=prpstring.toString()%>],
-                   'allowedPM' : [<%=pmstring.toString()%>],
-                   'allowedWS' : [<%=wsstring.toString()%>],
+                   'pubParms' : [<%=prpstring%>],
+                   'allowedPM' : [<%=pmstring%>],
+                   'allowedWS' : [<%=wsstring%>],
                    'renderData' : {
                       'renderData' : null,
                       'mimeType' : "text/plain"
@@ -158,13 +123,7 @@ group (the left column) displays portlets with odd IDs, while the second group
           }
        }
        <%
-          StringBuffer ub = new StringBuffer();
-          //ub.append(request.getScheme()).append("://").append(request.getServerName());
-          //ub.append(request.getServerPort());
-          ub.append(pu.getServletPath().startsWith("/")?"":"/")
-            .append(pu.getServletPath())
-            .append(pu.getRenderPath());
-          String urlBase = response.encodeURL(ub.toString());
+          String urlBase = response.encodeURL(ps.getUrlBase());
        %>
        portlet.impl.getUrlBase = function () {
           return '<%=urlBase%>';


[03/15] portals-pluto git commit: Started adding portlet hub prototype to pluto

Posted by ms...@apache.org.
Started adding portlet hub prototype to pluto


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

Branch: refs/heads/PortletHub
Commit: 1eeac9c3526349a7e9bbe2cd14e3fd51ad1c2a8c
Parents: cdaa9cd
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Nov 10 16:50:46 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Nov 10 16:50:46 2014 +0100

----------------------------------------------------------------------
 .../WEB-INF/themes/pluto-default-theme.jsp      |  265 +--
 pluto-portal/src/main/webapp/portlet.js         | 1685 ++++++++++++++++++
 pluto-portal/src/main/webapp/portletHubImpl.js  |  645 +++++++
 3 files changed, 2483 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1eeac9c3/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index 9e6cd22..bbb9a47 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -1,112 +1,153 @@
-<%--
-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.
---%>
-<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
-<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
-<%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %>
-<% pageContext.setAttribute("now", new java.util.Date()); %>
-
-<!--
-Portal page template for default theme used by the Pluto Portal Driver.
-This template divides all portlets into two groups (div blocks): the first
-group (the left column) displays portlets with odd IDs, while the second group
-(the right column) displays portlets with even IDs.
--->
-
-<html>
-
-<head>
-    <title>Pluto Portal</title>
-    <style type="text/css" title="currentStyle" media="screen">
-        @import "<c:out value="${pageContext.request.contextPath}"/>/pluto.css";
-        @import "<c:out value="${pageContext.request.contextPath}"/>/portlet-spec-1.0.css";
-        @import "<c:out value="${pageContext.request.contextPath}"/>/portlet-spec-2.0.css";
-    </style>
-    <script type="text/javascript"
-            src="<c:out value="${pageContext.request.contextPath}"/>/pluto.js">
-    </script>
-</head>
-
-<body>
-
-<div id="portal">
-
-    <!-- Header block: the Apache Pluto banner image and description -->
-    <div id="header">
-        <h1>Apache Pluto</h1>
-
-        <p>An Apache Portals Project</p>
-    </div>
-
-    <!-- Logout link -->
-    <div id="logout">
-        <a href="<c:url value='/Logout'/>">Logout</a>
-    </div>
-
-    <!-- Navigation block: links to portal pages -->
-    <jsp:include page="navigation.jsp"/>
-
-    <!-- Content block: portlets are divided into two columns/groups -->
-    <div id="content">
-        <pluto:isMaximized var="isMax"/>
-
-        <!-- Left column -->
-        <c:choose>
-            <c:when test="${isMax}">
-                    <c:forEach var="portlet" varStatus="status"
-                               items="${currentPage.portletIds}">
-                        <c:set var="portlet" value="${portlet}" scope="request"/>
-                        <jsp:include page="portlet-skin.jsp"/>
-                    </c:forEach>
-             </c:when>
-
-            <c:otherwise>
-                <div id="portlets-left-column">
-                    <c:forEach var="portlet" varStatus="status"
-                               items="${currentPage.portletIds}" step="2">
-                        <c:set var="portlet" value="${portlet}" scope="request"/>
-                        <jsp:include page="portlet-skin.jsp"/>
-                    </c:forEach>
-                </div>
-
-                <!-- Right column -->
-                <div id="portlets-right-column">
-                    <c:forEach var="portlet" varStatus="status"
-                               items="${currentPage.portletIds}" begin="1" step="2">
-                        <c:set var="portlet" value="${portlet}" scope="request"/>
-                        <jsp:include page="portlet-skin.jsp"/>
-                    </c:forEach>
-                </div>
-
-            </c:otherwise>
-        </c:choose>
-
-    </div>
-
-    <!-- Footer block: copyright -->
-    <div id="footer">
-       &copy; 2003-<fmt:formatDate value="${now}" pattern="yyyy"/> Apache Software Foundation
-    </div>
-
-</div>
-
-</body>
-
-</html>
-
-
+<%--
+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.
+--%>
+<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
+<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
+<%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %>
+<%@ page import="javax.portlet.*" %>
+<% pageContext.setAttribute("now", new java.util.Date()); %>
+
+<!--
+Portal page template for default theme used by the Pluto Portal Driver.
+This template divides all portlets into two groups (div blocks): the first
+group (the left column) displays portlets with odd IDs, while the second group
+(the right column) displays portlets with even IDs.
+-->
+
+<html>
+
+<head>
+    <title>Pluto Portal</title>
+    <style type="text/css" title="currentStyle" media="screen">
+        @import "<c:out value="${pageContext.request.contextPath}"/>/pluto.css";
+        @import "<c:out value="${pageContext.request.contextPath}"/>/portlet-spec-1.0.css";
+        @import "<c:out value="${pageContext.request.contextPath}"/>/portlet-spec-2.0.css";
+    </style>
+    <script type="text/javascript">
+       /**
+        * Initialization code for portlet hub
+        */
+       var portlet = portlet || {};
+       portlet.impl = portlet.impl || {};
+       portlet.impl.getInitData = function () {
+          return {       
+             <c:forEach var="pid" items="${currentPage.portletIds}">
+                <%
+                   StringBuffer ns = new StringBuffer("Pluto_");
+                   String pid = (String)pageContext.getAttribute("pid");
+                   for (int ii=0; ii < pid.length(); ii++) {
+                      if (Character.isJavaIdentifierPart(pid.charAt(ii))) {
+                         ns.append(pid.charAt(ii));
+                      } else {
+                         ns.append("_");
+                      }
+                   }
+                   ns.append("_");
+                %>
+                '<%= ns.toString() %>' : {
+                   'state' : {
+                      'parameters' : {
+                      }, 
+                      'portletMode' : 'VIEW', 
+                      'windowState' : 'NORMAL'
+                   },
+                   'pubParms' : ['imgName', 'color'],
+                   'allowedPM' : ['VIEW'],
+                   'allowedWS' : ['NORMAL'],
+                   'renderData' : {
+                      'renderData' : null,
+                      'mimeType' : "text/plain"
+                   }
+                },
+             </c:forEach>
+          }
+       }
+    </script>
+    <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/pluto.js"></script>
+    <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/portletHubImpl.js"></script>
+    <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/portlet.js"></script>
+</head>
+
+<body>
+
+<div id="portal">
+
+    <!-- Header block: the Apache Pluto banner image and description -->
+    <div id="header">
+        <h1>Apache Pluto</h1>
+
+        <p>An Apache Portals Project</p>
+    </div>
+
+    <!-- Logout link -->
+    <div id="logout">
+        <a href="<c:url value='/Logout'/>">Logout</a>
+    </div>
+
+    <!-- Navigation block: links to portal pages -->
+    <jsp:include page="navigation.jsp"/>
+
+    <!-- Content block: portlets are divided into two columns/groups -->
+    <div id="content">
+        <pluto:isMaximized var="isMax"/>
+
+        <!-- Left column -->
+        <c:choose>
+            <c:when test="${isMax}">
+                    <c:forEach var="portlet" varStatus="status"
+                               items="${currentPage.portletIds}">
+                        <c:set var="portlet" value="${portlet}" scope="request"/>
+                        <jsp:include page="portlet-skin.jsp"/>
+                    </c:forEach>
+             </c:when>
+
+            <c:otherwise>
+                <div id="portlets-left-column">
+                    <c:forEach var="portlet" varStatus="status"
+                               items="${currentPage.portletIds}" step="2">
+                        <c:set var="portlet" value="${portlet}" scope="request"/>
+                        <jsp:include page="portlet-skin.jsp"/>
+                    </c:forEach>
+                </div>
+
+                <!-- Right column -->
+                <div id="portlets-right-column">
+                    <c:forEach var="portlet" varStatus="status"
+                               items="${currentPage.portletIds}" begin="1" step="2">
+                        <c:set var="portlet" value="${portlet}" scope="request"/>
+                        <jsp:include page="portlet-skin.jsp"/>
+                    </c:forEach>
+                </div>
+
+            </c:otherwise>
+        </c:choose>
+
+    </div>
+
+    <!-- Footer block: copyright -->
+    <div id="footer">
+       &copy; 2003-<fmt:formatDate value="${now}" pattern="yyyy"/> Apache Software Foundation
+    </div>
+
+</div>
+
+</body>
+
+</html>
+
+

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/1eeac9c3/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
new file mode 100644
index 0000000..345044f
--- /dev/null
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -0,0 +1,1685 @@
+/*jslint browser: true, devel: true, plusplus: true, unparam: true, white: true, indent: 3 */
+/*  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.
+ */
+
+/*
+ * This source code implements specifications defined by the Java
+ * Community Process. In order to remain compliant with the specification
+ * DO NOT add / change / or delete method signatures!
+ */
+
+/**
+ * @fileOverview
+ * This module provides JavaScript functions for portlets.
+ *
+ * @author Scott Nicklous
+ * @copyright IBM Corp., 2014
+ */
+
+/**
+ * Represents a portlet parameter.
+ * <p>
+ * Each object property represents a parameter name.
+ * The object may also contain no property names,
+ * which represents the case of the portlet having no parameters.
+ * <p>
+ * If properties are present,
+ * each property must refer to a array of string values.
+ * The array length must be at least 1, because each parameter must have
+ * a value.
+ * However, a value of 'null' may appear in any array entry.
+ * <p>
+ * To represent the parameter having a <code>null</code> value, the
+ * property value must equal [null].
+ * <p>
+ * @typedef    PortletParameter
+ * @property   {string[]}  {string}   The parameters object may have
+ *                                    multiple properties.
+ */
+
+/**
+ * Represents the portlet state.
+ * @typedef    PortletState
+ * @property   {PortletParameter}   parameters     The portlet parameters
+ * @property   {string}             portletMode    The portlet mode
+ * @property   {string}             windowState    The window state
+ */
+
+/**
+ * Optional render data that may be provided by the portlet hub when
+ * a portlet state change occurs.
+ *
+ * @typedef    RenderData
+ * @property   {string}             renderData     The render data
+ * @property   {string}             mimeType       The mime type
+ */
+
+/**
+ * The onStateChange callback function that each portlet client
+ * participating in the portlet hub Ajax support must implement.
+ * <p>
+ * The portlet client registers an onStateChange callback by adding a
+ * listener for the portlet.onStateChange
+ * event type through the {@link addEventListener} function.
+ * <p>
+ * When the portlet hub calls the onStateChange callback, it will pass
+ * a copy of the current portlet state as a parameter.
+ * The portlet client can make changes to the PortletState object
+ * without affecting the actual portlet state, which is maintained by the
+ * portlet hub.
+ * The portlet client uses the {@link setPortletState} method to
+ * make changes to the local copy of the PortletState object active.
+ * <p>
+ * Optionally, the portlet hub will make a RenderData object available
+ * to the portlet client.
+ * When the RenderData object is available, it contains the same data
+ * as would be available through a portlet resource request using the
+ * current portlet state with no additional resource parameters and with
+ * the resource URL cacheability option set to "PAGE".
+ * <p>
+ * The portlet client may not call portlet hub functions that can
+ * cause state to be updated ({@link action}, {@link updatePortletState},
+ * {@link startPartialAction})
+ * during onStateChange execution.
+ *
+ * @name       onStateChange
+ * @callback   onStateChange
+ * @param      {string}       type           The event type "portlet.onStateChange".
+ * @param      {PortletState} portletState   The portlet state
+ * @param      {RenderData}   renderData     The render data.
+ *                                           Optionally provided by the portlet hub.
+ */
+
+/**
+ * This data is returned to the portlet client by the {@link startPartialAction}
+ * function.
+ * <p>
+ * The portlet client can use the partial action URL to initiate processing.
+ * During processing, the portal will perform action and event processing.
+ * It will generate a string representing the new page state and pass it to the
+ * portlet's serveResource method.
+ * <p>
+ * The portlet is responsible for transmitting the page state string to the
+ * client and for calling the {@link setPageState} callback function.
+ * <p>
+ * The portlet hub will be blocked until the portlet calls the setPageState
+ * function and the portlet hub has successfully performed the state change.
+ *
+ * @typedef    PartialActionInit
+ * @property   {string}             url               The partial action URL
+ * @property   {function}           setPageState      Callback function
+ */
+
+/**
+ * Provides the name of an error that occurred along with an optional
+ * message that provide more detail.
+ * @typedef    ErrorData
+ * @property   {string}    name     The error name
+ * @property   {string}    message  An optional message that provides more detail about the error
+ */
+
+/**
+ * The onError callback function that a portlet client
+ * participating in the portlet hub Ajax support may implement.
+ * Typically the callback will be used to provide the portlet client with
+ * information about asynchronous errors that occurred during processing.
+ * <p>
+ * The portlet client registers an onError callback by adding a listener for the portlet.onError
+ * event type through the {@link addEventListener} function.
+ * @name       onError
+ * @callback   onError
+ * @param      {string}       type           The event type "portlet.onError".
+ * @param      {ErrorData}    errorData      Provides information about the error.
+ */
+
+
+/**
+ * The "portlet" namespace is reserved for use by portal
+ * JavaScript support implementations.
+ * <p>
+ * Portlet Specification 2.0 (JSR 286) provided Ajax support for portlets by
+ * adding a resource URL, resource request, and serveResource() method to allow
+ * portlet JavaScript code to retrieve data directly from the portlet.
+ * Portlet Specification 3.0 (JSR 362) expands on that by providing capability
+ * allowing a portlet to change its state through JavaScript functions.
+ * <p>
+ * Portlet Specification 3.0 introduces a JavaScript component called the
+ * Portlet Hub that manages the state of all portlets on a portal page.
+ * <p>
+ * Some terminology:
+ * <dl>
+ * <dt>
+ * Portlet Hub
+ * </dt>
+ * <dd>JavaScript component that manages the state of all portlets on a portal
+ * page.
+ * It is considered to be part of the portal implementation.
+ * This document describes its JavaScript interfaces and behavior.
+ * <p>
+ * Portlet JavaScript code can use the Portlet Hub programming interface to modify
+ * its state by setting private and public render parameters to submit forms while
+ * remaining in the Ajax application paradigm.
+ * <p>
+ * Many portlets can be present on the page and the portlets are in general independent
+ * of one another and they are not aware of the state of other portlets,
+ * so they are unable to generate URLs properly representing
+ * the complete page state.
+ * The Portlet Hub provides methods that allow portlets to obtain URLs
+ * representing the current portal page state.
+ * <p>
+ * The programming interface and behavior of this component is standardized by JSR 362.
+ * </dd>
+ * <dt>
+ * Portlet Client
+ * </dt>
+ * <dd>
+ * JavaScript code written by the portlet developer that uses the portlet hub
+ * to manage its state and to obtain URLs for retrieving data.
+ * </dd>
+ * </dl>
+ * <h5>
+ * Changing the Portlet State
+ * </h5>
+ * <p>
+ * The portlet client can use portlet hub functions to initiate state changes.
+ * <p>
+ * The portlet client can set public
+ * and private render parameters as well as the portlet mode and window state.
+ * <p>
+ * In addition, the portlet client can submit a
+ * portlet action request that uses HTTP POST semantics.
+ * The portal will execute the portlet Action Phase and Event Phase processing on
+ * the server and return the updated page state to the portlet hub.
+ * <p>
+ * After the requested state change has been performed, the portlet hub will usually
+ * provide each affected portlet client with its updated state information.
+ * <p>
+ * However, regardless of whether the state change was initiated by setting
+ * parameters or through a portlet action, the portal may respond by completely
+ * refreshing the page.
+ * The portal may do so in order to support portlets that are affected by the state
+ * change but do not participate in the portlet client-side support, or for
+ * implementation-specific reasons.
+ * <p>
+ * If the portal responds to a state change request by refreshing the page, the
+ * portlets will not be updated with new page state information before the
+ * page refresh is carried out.
+ * <h5>
+ * Receiving Portlet State Updates
+ * </h5>
+ * <p>
+ * When a state change occurs that affects a portlet, the portlet hub informs the
+ * affected portlet client of its new state through use of a
+ * callback function.
+ * The change causing the update does not necessarily need to be initiated by the
+ * portlet client itself.
+ * <p>
+ * For example, when portlet A changes a
+ * public render parameter used by portlet B, the portlet
+ * hub will inform both the portlet A and the portlet B clients of that change.
+ * <h5>
+ * Portlet Client Events
+ * </h5>
+ * <p>
+ * Portlet client events consist of an event type and an event payload. Both are defined by
+ * by the portlet clients themselves.
+ * <p>
+ * Portlet client events have no connection to the server-side portlet event mechanism.
+ * <p>
+ * The portlet hub provides utility functions that enable the portlet client
+ * to dispatch and listen for portlet client events.
+ * <h5>
+ * Error Handling
+ * </h5>
+ * <p>
+ * When the portlet hub can recognize an error during function execution, the error will
+ * be reported to the portlet client through an exception.
+ * <p>
+ * However, some methods initiate work that is performed asynchronously.
+ * Errors that occur during asynchronous processing will be reported to the portelt
+ * client through the {@link onError} callback function.
+ * <h5>
+ * Important Considerations
+ * </h5>
+ * <p>
+ * The portlet hub calls the portlet client callback functions in several situations as described
+ * above.
+ * When the portlet hub calls the portlet client, the portlet client may navigate
+ * to a different page or may initiate another change to the portlet state
+ * that could potentially cause a page refresh.
+ * <p>
+ * Due to this behavior, the delivery of neither portlet state updates nor
+ * portlet client events can be guaranteed.
+ * <p>
+ * The portlet hub provides for orderly state transitions by allowing only a
+ * single blocking operation ({@link action}, {@link setPortletState},
+ * {@link startPartialAction}) to be active at any one time.
+ * <p>
+ * The state transition is considered to be active from the initial portlet
+ * client call to one of the blocking operations until the portlet
+ * hub has performed the requested state change and has informed all of
+ * the affected portlet clients by firing the corresponding onStateChange
+ * events.
+ * <p>
+ * This has the following implications:
+ * <ol>
+ * <li>
+ * It is not possible to initiate a sequence of blocking operations.
+ * <p>
+ * For example, once a portlet client calls the {@link setPortletState} method,
+ * it cannot call any additional blocking method until after its
+ * onStateChange listener function has been called.
+ * </li>
+ * <li>
+ * It is not possible to initiate a blocking operation during
+ * execution of the onStateChange listener function, since execution of
+ * that function belongs to the preceeding state change operation.
+ * </li>
+ * </ol>
+ * <hr>
+ * @namespace
+ */
+var portlet = portlet || {};
+
+
+(function () {
+   'use strict';
+
+   // If module has already been loaded, don't load again
+   if (typeof portlet.register === 'function') {
+      return;
+   }
+
+   // variable declarations
+   var portletRegex = "^portlet[.].*",
+
+   /**
+    * Portlet Hub Mockup internal structure defining the data held
+    * for each portlet
+    *
+    * @typedef    PortletData
+    * @property   {PortletState} state       The current PortletState object
+    * @property   {string[]}     pubParms    String array declaring the public
+    *                                        parameters for the portlet
+    * @property   {RenderData}   renderData  Render data for the portlet
+    * @private
+    */
+
+
+   // Helper functions
+
+   wnd = window,
+   delay = function(aCallback, aTimeout) {
+      wnd.setTimeout(aCallback, aTimeout);
+   },
+
+
+   // ~~~~~~~~~~~~~~~~~~~~~~ Exceptions ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+   /**
+    * 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
+    */
+   throwIllegalArgumentException = function (msg) {
+      throw {
+         name : "IllegalArgumentException",
+         message : msg
+      };
+   },
+
+   /**
+    * Exception thrown when a portlet client is not allowed to access a data element
+    * @typedef    AccessDeniedException
+    * @property   {string}    name     The exception name, equal to "AccessDeniedException"
+    * @property   {string}    message  An optional message that provides more detail about the exception
+    */
+   throwAccessDeniedException = function (msg) {
+      throw {
+         name : "AccessDeniedException",
+         message : msg
+      };
+   },
+
+   /**
+    * Thrown when a portlet attempts to use the API without comleting the intialization
+    * process.
+    * In general, this means that the onStateChange listener has not been added.
+    *
+    * @typedef    NotInitializedException
+    * @property   {string}    name     The exception name, equal to "NotInitializedException"
+    * @property   {string}    message  An optional message that provides more detail about the exception
+    */
+   throwNotInitializedException = function (msg) {
+      throw {
+         name : "NotInitializedException",
+         message : msg
+      };
+   },
+
+   /**
+    * Maps from the the ID of the registered portlet to the implementation callback
+    */
+   _registeredPortlets = {},
+
+   /**
+    * Shortcut for Object.keys
+    *
+    * @const
+    * @type {function(Object):Array}
+    */
+   _getKeys = Object.keys,
+
+   /**
+    * Shortcut for the Array.isArray
+    *
+    * @const
+    * @type {function(*):boolean}
+    */
+   _isArray = Array.isArray,
+
+   /**
+    * Checks if the object is an object
+    *
+    * @param {*} obj object
+    * @return {boolean}
+    */
+   _isObject = function(obj) {
+      return typeof obj === "object";
+   },
+
+   /**
+    * Constructs a deep copy of the object
+    *
+    * @param {Object|Array} data
+    * @return {Object|Array}
+    */
+   _clone = function(data) {
+      // some helpers down the road
+      var result, i, key, keys;
+      // the array case
+      if (_isArray(data)) {
+         // construct a new array
+         result = [];
+         // fill the array
+         for (i = data.length - 1; i >= 0; --i) {
+            result[i] = _clone(data[i]);
+         }
+      } else if (_isObject(data)) {
+         // construct a new object
+         result = {};
+         keys = _getKeys(data);
+         for (i = keys.length - 1; i >= 0; --i) {
+            key = keys[i];
+            result[key] = _clone(data[key]);
+         }
+      } else {
+         // just use the object as is
+         result = data;
+      }
+      // ok
+      return result;
+   },
+
+   // ~~~~~~~~~~~~~~~~~~~~~~ Event Handling ~~~~~~~~~~~~~~~~~~~~~~~~~~
+   // for event handling
+   handleCtr = 0,                         // used to generate handles returned by addEventListener
+
+   // System listeners (onStateChange and onError). Associative arrays indexed by portletID
+   oscListeners = {}, oeListeners = {}, 
+
+   // Portlet Client Event listeners. Associative array indexed by handle
+   pcListeners = {},                      // portlet client event listeners
+
+   // the portlet hub can only execute a single blocking operation
+   // at a time. At the beginning of the operation, this flag is set to
+   // true to prevent other blocking operations from beginning.
+   // It is reset after the last onStateChange event resulting from the
+   // state change has been fired.
+   // (or also if a communication error occurs.)
+   busy = false,
+
+   // queue for the portlet ID's that need updating
+   updateQueue = [],
+
+
+   /**
+    * Add an event listener of the given type to the specified
+    * portlet client listener storage object.
+    * <p>
+    * The portlet client event listeners are stored in associative arrays (objects)
+    * indexed by the event listener handle.
+    *
+    * @param      {object}    list        The object where the listener will be stored
+    * @param      {string}    pid         The portletID
+    * @param      {string}    etype       The event type
+    * @param      {function}  func        The the listener function to be called
+    * @private
+    */
+   addPCListener = function (list, pid, etype, func) {
+      var hand = "handle-" + (++handleCtr);
+      list[hand] = {
+                     handle   : hand,
+                     id       : pid,
+                     type     : etype,
+                     callback : func
+                   };
+      return hand;
+   },
+
+
+   /**
+    * Removes an event listener identified by the portletId and handle from the
+    * portlet client listener storage object
+    * @param      {object}    list     The object where the listener will be stored
+    * @param      {string}    pid      The portletID
+    * @param      {object}    handle   The event listener handle
+    * @returns    {boolean}            <code>true</code> if the listener was removed
+    * @throws     {AccessDeniedException}
+    *                   Thrown if the event listener associated with this handle
+    *                   was registered by a different portlet
+    * @private
+    */
+   removePCListener = function (list, pid, handle) {
+      if (typeof list[handle] === 'object') {
+
+         // the listener was found, so if the portlet ID matches, remove it.
+         if (list[handle].id === pid) {
+            delete list[handle];
+         } else {
+            throwAccessDeniedException("Invalid handle for portlet ID=" + pid);
+         }
+         return true;
+      }
+      return false;
+   },
+
+
+   /**
+    * Add an event listener of the given type to the specified system event listener
+    * storage object.
+    * <p>
+    * The system event listeners are stored in associative arrays (objects) indexed
+    * by portlet ID.
+    *
+    * @param      {object}    list        The object where the listener will be stored
+    * @param      {string}    pid         The portletID
+    * @param      {string}    etype       The event type
+    * @param      {function}  func        The the listener function to be called
+    * @private
+    */
+   addSystemListener = function(list, pid, etype, func) {
+
+      console.log("addSystemListener", pid);
+
+      // A system listener can only be added once
+      if (list[pid] !== undefined) {
+         throwIllegalArgumentException("Duplicate system event listener. Type: " + etype);
+      }
+
+      // add the listener
+      var hand = "handle-" + (++handleCtr);
+      list[pid] = {
+                     handle   : hand,
+                     id       : pid,
+                     type     : etype,
+                     callback : func
+                   };
+      return hand;
+   },
+
+
+   /**
+    * Removes an event listener identified by the portletId and handle from the
+    * system listener storage object
+    * @param      {object}    list     The object where the listener will be stored
+    * @param      {string}    pid      The portletID
+    * @param      {object}    handle   The event listener handle
+    * @returns    {boolean}            <code>true</code> if the listener was removed
+    * @private
+    */
+   removeSystemListener = function (list, pid, handle) {
+      var ii;
+      if (typeof list[pid] === 'object') {
+
+         // the listener was found, so if the portlet ID matches, remove it.
+         if (list[pid].handle === handle) {
+            delete list[pid];
+
+            // purge any pending notifications -
+            ii = updateQueue.length;
+            while (ii-- >= 0) {
+               if (updateQueue[ii] === pid) {
+                  updateQueue.splice(ii, 1);
+               }
+            }
+
+            return true;
+         }
+      }
+      return false;
+   },
+
+
+   // ~~~~~~~~~~~~~~~~~~~~~~ State handling ~~~~~~~~~~~~~~~~~~~~~~~~~~
+   //
+
+   /**
+    * Calls the portlet onStateChange method in an asynchronous manner
+    * in order to decouple the public API.
+    * This method is intended for use after a portlet client registers an
+    * onStateChange listener.
+    * <p>
+    * In a real implementation, the
+    * portlet hub might need to communicate with the portal server to obtain
+    * data.
+    * @param      {string}    pid      The portlet ID
+    * @private
+    */
+   _updateStateForPortlet = function (pid) {
+
+      console.log("_updateStateForPortlet", pid);
+
+      // only enqueue each portlet once, and only for portlets with a callback
+      if ((updateQueue.indexOf(pid) >= 0) || (oscListeners[pid] === undefined)) {
+         return;
+      }
+
+      updateQueue.push(pid);
+
+      if (updateQueue.length === 1) {
+         delay (function () {
+            var p, state, data, callback, pi;
+
+            // The busy flag is usually set by the caller.
+            // but ... need more thought here. When the onStateChange
+            // listener is added, the busy flag isn't set in order to avoid
+            // blocking the state changes, since adding a listener doesn't
+            // change the state. So it's set here, before onStateChange is
+            // called so that the state change functions are blocked.
+            busy = true;
+
+            while (updateQueue.length > 0) {
+
+               // get the next portlet ID and call its
+               // onStateChange function
+               p = updateQueue.shift();
+
+               pi = _registeredPortlets[p];
+
+               state = _clone(pi.getState());
+               data = pi.getRenderData();
+               callback = oscListeners[p].callback;
+
+               if ((data !== undefined) && (data !== null) && 
+                   (data.renderData !== undefined) && (data.renderData !== null)) {
+                  callback ("portlet.onStateChange", state, data);
+               } else {
+                  callback ("portlet.onStateChange", state);
+               }
+            }
+            busy = false;
+         }, 0);
+      }
+   },
+
+   // queue for client events
+   ceQueue = [],
+
+   /**
+    * dispatches the client events.
+    *
+    * @param      {string}    type      The portlet ID
+    * @param      {function}  callback  Callback function
+    * @param      {any}       payload   Event payload
+    * @private
+    */
+   dispatchCE = function (type, callback, payload) {
+      var evt = [];
+
+      evt.push(callback);
+      evt.push(type);
+      evt.push(payload);
+
+      ceQueue.push(evt);
+
+      if (ceQueue.length === 1) {
+         delay (function () {
+            var event, aType, aCallback, aPayload;
+
+            while (ceQueue.length > 0) {
+
+               // dispatch next event
+               event = ceQueue.shift();
+
+               aCallback = event[0];
+               aType = event[1];
+               aPayload = event[2];
+
+               aCallback(aType, aPayload);
+            }
+         }, 0);
+      }
+   },
+
+   /**
+    * Accepts an object containing changed portlet states. Updates
+    * the state for each portlet present.
+    *
+    * @param    {string}   upids  array of portlet IDs to be updated 
+    * @private
+    */
+   updatePageState = function (upids) {
+      var ii;
+      
+      for (ii = 0; ii < upids.length; ii++) {
+         _updateStateForPortlet(upids[ii]);
+      }
+
+   },
+
+   /**
+    * Updates the portlet state, taking the public render
+    * parameters into account.
+    * The portlet client requesting the change, represented
+    * by the supplied portelt ID, is updated, along with each portlet
+    * that has a public render parameter update.
+    *
+    * @param      {string}       pid      The portlet ID
+    * @param      {PortletState} state    The new portlet state
+    * @throws  {AccessDeniedException}
+    *                   Thrown if a blocking operation is
+    *                   already in progress.
+    * @throws  {NotInitializedException}
+    *                   Thrown if a portlet ID is provided, but no onStateChange
+    *                   listener has been registered.
+    * @private
+    */
+   updateState = function (pid, state) {
+      var pi;
+
+      // do necessary checks
+
+      if (busy === true) {
+         throwAccessDeniedException("Operation in progress");
+      } else if (oscListeners[pid] === undefined) {
+         throwNotInitializedException("No onStateChange listener registered for portlet: " + pid);
+      }
+
+      busy = true;
+      
+      // Set state in the implementation. The setState function returns an array of portlet
+      // IDs for portlets that need to be updated. Update the page state using this info.
+      // If an error occurred, post the error to the onError handler, if one is present.
+      
+      pi = _registeredPortlets[pid];
+      pi.setState(state).then(function (upids) {
+         updatePageState(upids);
+      }, function (err) {
+         if (oeListeners[pid]) {
+            delay( function () {
+               oeListeners[pid].callback('portlet.onError', err);
+            }, 0);
+         }
+      });
+       
+   },
+
+
+   // ~~~~~~~~~~~~~~~~~~~~~~ Other functions ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+   /**
+    * Used by the portlet hub methods to check the number and types of
+    * the arguments.
+    *
+    * @private
+    * @param   {string[]}  parms    The argument list to be checked
+    * @param   {number}    minParms The minimum number of arguments
+    * @param   {number}    maxParms The maximum number of arguments.
+    *                               If this value is undefined, the function can take any
+    *                               number of arguments greater than numArgs
+    * @param   {string[]}  types    An array containing the expected parameter types
+    *                               in the order of occurrance in the argument array
+    * @throws  {IllegalArgumentException}
+    *                               Thrown if the parameters are in some manner incorrect
+    */
+   checkArguments = function (parms, minParms, maxParms, types) {
+
+      // Check for the minimum number of arguments
+      if (parms.length < minParms) {
+         throwIllegalArgumentException("Too few arguments provided. Number of arguments: " + parms.length);
+
+         // check for maximum number of arguments
+      } else if ((typeof maxParms === 'number') && (parms.length > maxParms)) {
+         throwIllegalArgumentException("Too many arguments provided: " + [].join.call(parms, ', '));
+
+         // check if the argument types are as expected if provided with types
+      } else if (types) {
+
+         var ii;
+         for (ii = Math.min(parms.length, types.length) - 1; ii >= 0; ii = ii - 1) {
+            if (typeof parms[ii] !== types[ii]) {
+               throwIllegalArgumentException("Parameter " + ii + " is of type " + (typeof parms[ii])
+                     + " rather than the expected type " + types[ii]);
+            }
+
+            // If checking for types, also make sure the arguments are neither
+            // null nor undefined.
+            if ((parms[ii] === null) || (parms[ii] === undefined)) {
+               throwIllegalArgumentException("Argument is " + (typeof parms[ii]));
+            }
+         }
+      }
+   },
+
+   /**
+    * Verifies that the input parameters are in valid format.
+    * <p>
+    * Parameters must be an object containing parameter names.
+    * It may also contain no property names which represents the case of having
+    * no parameters.
+    * <p>
+    * If properties are present,
+    * each property must refer to a array of string values.
+    * The array length must be at least 1, because each parameter must have
+    * a value.
+    * However, a value of 'null' may appear in any array entry.
+    * <p>
+    * To represent a <code>null</code> value, the property value must equal
+    * [null].
+    *
+    * @param      {PortletParameter} parms    The parameters to check
+    * @private
+    * @throws  {IllegalArgumentException}
+    *             Thrown if the parameters are incorrect
+    */
+   validateParms = function (parms) {
+      var parm;
+
+      // check for null or undefined argument
+      if ((parms === null) || (parms === undefined)) {
+         throwIllegalArgumentException("The parameters object is " + (typeof parms));
+      }
+
+      for (parm in parms) {
+         if (parms.hasOwnProperty(parm)) {
+            if (Object.prototype.toString.call(parms[parm]) !== '[object Array]') {
+               throwIllegalArgumentException("Invalid parameters. The value of " +
+                  parm + " is " + Object.prototype.toString.call(parm) +
+                  " rather than '[object Array]'");
+            } else if (parms[parm].length === 0) {
+               throwIllegalArgumentException("Invalid parameters. The value of " +
+                  parm + " is " + "an array with length 0.");
+            }
+         }
+      }
+   },
+
+   /**
+    * Tests whether the given portlet mode is allowed
+    */
+   _isAllowedPM = function(pid, pm) {
+      var pi = _registeredPortlets[pid];
+      return (pi.getAllowedPM().indexOf(pm) >= 0);
+   },
+
+   /**
+    * Tests whether the given window state is allowed
+    */
+   _isAllowedWS = function(pid, ws) {
+      var pi = _registeredPortlets[pid];
+      return (pi.getAllowedWS().indexOf(ws) >= 0);
+   },
+
+   /**
+    * Verifies that the input parameters are in valid format,
+    * that the portlet mode and window state values are allowed
+    * for the portlet.
+    *
+    * @param      {string}       pid      The portlet ID
+    * @param      {PortletState} state    The portlet state object to check
+    * @private
+    * @throws  {IllegalArgumentException}
+    *             Thrown if any component of the state is incorrect
+    */
+   validateState = function (pid, state) {
+      var pi = _registeredPortlets[pid];
+
+      validateParms(state.parameters);
+
+      // see if the portlet mode is a string and is a value allowed for the
+      // portlet
+      if ((state.portletMode === undefined) || (typeof state.portletMode !== 'string')) {
+         throwIllegalArgumentException("Invalid parameters. portletMode is " + (typeof state.portletMode));
+      } else if (!_isAllowedPM(pid, state.portletMode)) {
+         throwIllegalArgumentException("Invalid portletMode=" + state.portletMode + " is not in "
+            + pi.getAllowedPM());
+      }
+      
+      // see if the windowState is a string and is a value allowed for the
+      // portlet
+      if ((state.windowState === undefined) || (typeof state.windowState !== 'string')) {
+         throwIllegalArgumentException("Invalid parameters. windowState is " + (typeof state.windowState));
+      } else if (!_isAllowedWS(pid, state.windowState)) {
+         throwIllegalArgumentException("Invalid windowState=" + state.windowState + " is not in "
+            + pi.getAllowedWS());
+      }
+
+   },
+
+
+   /**
+    * sets up for the action.
+    *
+    * @param   {string}    type     The URL type
+    * @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>
+    * @throws  {AccessDeniedException}
+    *                   Thrown if a blocking operation is
+    *                   already in progress.
+    * @throws  {NotInitializedException}
+    *                   Thrown if a portlet ID is provided, but no onStateChange
+    *                   listener has been registered.
+    * @private
+    */
+   setupAction = function (pid, parms, element) {
+      var pi;
+      
+      // do necessary checks
+
+      if (busy === true) {
+         throwAccessDeniedException("Operation in progress");
+      } else if (!oscListeners[pid]) {
+         throwNotInitializedException("No onStateChange listener registered for portlet: " + pid);
+      }
+
+      busy = true;
+
+      // execute the action. The promise is fulfilled with an array of IDs of portlets to be updated.
+      // If an error occurred, post the error to the onError handler, if one is present.
+
+      pi = _registeredPortlets[pid];
+      pi.executeAction(parms, element).then(function (upids) {
+         updatePageState(upids);
+      }, function (err) {
+         if (oeListeners[pid]) {
+            delay( function () {
+               oeListeners[pid].callback('portlet.onError', err);
+            }, 0);
+         }
+      });
+
+   },
+
+   /**
+    * Callback function that must be called after a 
+    * partial action has been started.
+    * <p>
+    * The page state is generated by the portal and transmitted to the 
+    * client by the portlet.
+    * The portlet client that initiated the partial action must 
+    * pass the page state string to this function.
+    * <p>
+    * The callback should only be called once to conclude a partial
+    * action sequence. 
+    * 
+    * @param   {string}    pid      The portlet ID for operation
+    * @param   {string}    ustr     The new page state in string form
+    * @throws  {IllegalArgumentException} 
+    *                      Thrown if the parameter is not a string
+    * @name       setPageState
+    * @callback   setPageState
+    */
+   setPageState = function (pid, ustr) {
+      var upids, pi;
+
+      // check for exactly 2 arguments of type 'string'
+      checkArguments(arguments, 2, 2, [ 'string', 'string' ]);
+
+      // 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);
+
+   };
+
+   /**
+    * Registers a portlet client with the portlet hub.
+    * <p>
+    * The portlet client calling this method must provide a valid portlet ID.
+    * The portlet ID is identical to the unique namespace provided by the
+    * portal server for the portlet.
+    *
+    * @param   {string}    portletId   The unique portlet identifier
+    * @returns {Promise}   A Promise object. Returns an 
+    *                      {@link PortletInit} object containing functions
+    *                      for use by the portlet client on successful resolution.
+    *                      Returns an Error object containing a descriptive   
+    *                      message on failure.
+    */
+   portlet.register = function (portletId) {
+
+      console.log("register", portletId);
+
+      // check for exactly 1 argument of type 'string'
+      checkArguments(arguments, 1, 1, ['string']);
+
+      /**
+       * Dispatched to the implementation. The promise will
+       * be fulfilled as soon as the implementation has assembled
+       * the required information. From that point on it is valid
+       * to call into other functions on the implementation. These other
+       * functions as passed in as an argument
+       */
+      return portlet.impl
+            .register(portletId)
+            .then(
+                  function(portletImpl) {
+
+                     console.log("register implementation is ready ...", portletImpl);
+
+                     /**
+                      * Keep track of the callback functions for our portlets
+                      */
+                     _registeredPortlets[portletId] = portletImpl;
+
+                     /**
+                      * Returned by the {@link portlet.register} method to
+                      * provide functions for use by the portlet client.
+                      * @namespace PortletInit
+                      */
+                     return {
+         
+         
+            /**
+             * A string array containing the portlet modes that are defined for the
+             * portlet.
+             * <p>
+             * Note that even if a portlet mode is defined, it may not be allowed,
+             * depending on access rights or other conditions.
+             *
+             * @property   {string[]}  portletModes   The defined portlet mode values
+             * @memberOf         PortletInit
+             */
+            portletModes : portletImpl.getAllowedPM(),
+         
+         
+            /**
+             * A string array containing the window states that are defined for the
+             * portlet.
+             * <p>
+             * Note that even if a window state is defined, it may not be allowed,
+             * depending on access rights or other conditions.
+             *
+             * @property   {string[]}  windowStates   The defined window state values
+             * @memberOf         PortletInit
+             */
+            windowStates : portletImpl.getAllowedWS(),
+         
+            /**
+             * Adds a listener function for specified event type.
+             * <p>
+             * The portlet hub defines two classes of events - System Events and Portlet Client events:
+             * <dl>
+             * <dt>System Events</dt>
+             * <dd>
+             * Events that are generated by the portlet hub.
+             * They are used to pass portlet-specific information to the registered portlet client.
+             * The parameters passed to the system event callback functions are defined by the
+             * portlet hub.
+             * <p>
+             * Event types prefixed with "portlet." are reserved for system events.
+             * System event types may not be specified with a regular expression or wildcard.
+             * However, the same event listener may be added for both types of system events.
+             * <p>
+             * Only one listener for each type of system event may be added.
+             * <p>
+             * The following system event types are defined:
+             * <dl>
+             * <dt>portlet.onStateChange</dt>
+             * <dd>
+             * Fired when the portlet state changes.
+             * In order to participate in the portlet Ajax support, a portlet client must register
+             * an {@link onStateChange} event listener for this event type.
+             * <p>
+             * After the portlet client adds an event listener for the onStateChange
+             * event, the portlet hub will call the onStateChange callback function
+             * to provide the portlet client with its initial state information.
+             * However, this will not occur before the call to addEventListener returns.
+             * </dd>
+             * <dt>portlet.onError</dt>
+             * <dd>
+             * Fired when an error occurs that cannot be communicated through an exception.
+             * In general, this will be some type of asynchronous communication error.
+             * In order to receive notification about errors, a portlet must register
+             * an {@link onError} event listener for this event type.
+             * </dd>
+             * </dl>
+             * </dd>
+             * <dt>Portlet Client Events</dt>
+             * <dd>
+             * Events initiated by the portlet client through the dispatch method.
+             * <p>
+             * When adding a listener for a portlet client event, the event type may be specified
+             * by a regular expression string.
+             * The listener will be called for every event type that the regular expression
+             * string matches.
+             * <p>
+             * Example:
+             * <br>
+             * myHub.addEventListener("^myCompany\..*", myListener);    // registers myListener for all event types beginning with "myCompany."
+             * </dd>
+             * </dl>
+             * <p>
+             * An event listener can be added for multiple event types.
+             * This function returns a handle to identify the unique listener
+             * for the event type and for the portlet client associated with the function.
+             *
+             * @param   {string}    type     The type of listener
+             * @param   {function}  func     Function called when event occurs
+             *
+             * @returns {object}             A handle that can be used to remove the event listener
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             *
+             * @memberOf            PortletInit
+             */
+            addEventListener: function (type, func) {
+         
+               // check for exactly 2 arguments of type 'string' and 'function'
+               checkArguments(arguments, 2, 2, [ 'string', 'function' ]);
+         
+               var handle, listeners;
+         
+               if (type.match(portletRegex)) {
+         
+                  // Handle adding system event listener.
+                  // if it is neither a portlet.onStateChange nor a portlet.onError event, throw
+                  if ((type !== "portlet.onStateChange") && (type !== "portlet.onError")) {
+                     throwIllegalArgumentException("The system event type is invalid: " + type);
+                  }
+         
+                  if (type === "portlet.onStateChange") {
+                     listeners = oscListeners;    // add the onStateChange listener
+                  } else {
+                     listeners = oeListeners;     // add the onError listener
+                  }
+         
+                  // will throw an exception if the listener has already been added
+                  handle = addSystemListener(listeners, portletId, type, func);
+         
+                  // If just added an onStateChange listener, update the state
+                  if (type === "portlet.onStateChange") {
+                     _updateStateForPortlet(portletId);
+                  }
+         
+               } else {
+         
+                  // Portlet client event listener
+                  handle = addPCListener(pcListeners, portletId, type, func);
+               }
+         
+               return handle;
+            },
+         
+            /**
+             * Removes a previously added listener function designated by the handle.
+             * The handle must be the same object previously returned by the addEventListener
+             * function.
+             *
+             * @param   {object}    handle   The handle of the listener to be removed
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             * @throws  {AccessDeniedException}
+             *                   Thrown if the event listener associated with this handle
+             *                   was registered by a different portlet
+             *
+             * @memberOf            PortletInit
+             */
+            removeEventListener: function (handle) {
+         
+               // check for exactly 1 argument. Don't check the argument type.
+               checkArguments(arguments, 1, 1, []);
+         
+               // check for null or undefined argument
+               if ((handle === null) || (handle === undefined)) {
+                  throwIllegalArgumentException("The argument provided is " + (typeof handle));
+               }
+         
+               // Try to remove the listener from each of the listener arrays
+               // one after the other. If not successful, the handle was invalid
+               // (or an exception will be thrown by removePCListener), so throw.
+         
+               if ((removePCListener(pcListeners, portletId, handle) === false)
+                     && (removeSystemListener(oscListeners, portletId, handle) === false)
+                     && (removeSystemListener(oeListeners, portletId, handle) === false)) {
+         
+                  throwIllegalArgumentException("The event listener handle doesn't match any listeners.");
+               }
+            },
+         
+            /**
+             * Sets the portlet state, which consists of the public and private
+             * render parameters, the portlet mode, and the window state.
+             * <p>
+             * When the portlet state has been successfully set, a copy of the portlet state
+             * will be provided to the portlet client
+             * through the {@link onStateChange} listener function.
+             * A portlet client can modify this state object and pass it to the
+             * setPortletState function to update the portlet state.
+             * <p>
+             * However, it is also possible for the portal to completely refresh the
+             * page as a response to setting the portlet state.
+             * This may occur in order to support portlets on the page that do not participate
+             * in the Portlet 3.0 Ajax support or due to configuration settings, for example.
+             * <p>
+             * If the page is completely refreshed, it will be rendered according to
+             * render parameters set on the server.
+             * <p>
+             * Setting the portlet state is a blocking operation.
+             * To allow for orderly state transitions, the portlet hub does not allow
+             * this function to be used while a blocking operation is in progress.
+             * A blocking operation is considered to be in progress
+             * from the initial call until the final onStateChange event for that
+             * operation has been fired. See {@link portlet} for further information.
+             *
+             * @param   {PortletState}    state    The new state to be set
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             * @throws  {AccessDeniedException}
+             *                   Thrown if a blocking operation is
+             *                   already in progress.
+             * @throws  {NotInitializedException}
+             *                   Thrown if a portlet ID is provided, but no onStateChange
+             *                   listener has been registered.
+             *
+             * @memberOf   PortletInit
+             */
+            setPortletState : function (state) {
+
+               console.log("setPortletState", state);
+
+               // check for exactly 1 argument of type 'object'
+               // make sure an onStateChange listener is registered by providing portlet ID
+               checkArguments(arguments, 1, 1, ['object']);
+         
+               // validate portlet state & throw exception if incorrect
+               validateState(portletId, state);
+         
+               // Ok so far, so do the update. Throws if busy or no callback registered
+               updateState(portletId, state);
+         
+            },
+         
+         
+            /**
+             * Utility function to perform a deep copy of the state object.
+             *
+             * @param   {PortletState}    state    The state to be cloned
+             *
+             * @memberOf   PortletInit
+             */
+            cloneState : _clone,
+
+            /**
+             * Returns a promise for a resource URL with parameters set appropriately
+             * for the page state according to the  resource parameters
+             * and cacehability option provided.
+             * <p>
+             * The portlet client may use the resource URL with any appropriate
+             * javascript framework to retrieve content from the portlet through
+             * the server-side serveResource method.
+             * <p>
+             * Resource parameters are optional parameters attached to a resource
+             * URL in addition to any portlet state values that may be present.
+             * Resource parameters do not influence the portlet state.
+             * <p>
+             * The resource parameters must be an object containing properties
+             * representing parameter names whose values must be an array of string
+             * values, as described under {@link PortletParameter}.
+             * All of the resource parameters will be attached to the URL.
+             * Use of resource parameters is optional.
+             * <p>
+             * The cacheability option designates the degree to which the content to be
+             * served can be cached and influences the type of content that can be served.
+             * There are three possible values:
+             * <dl>
+             * <dd>"FULL"</dd>
+             * <dt>
+             * Most cacheable, because the URL contains no portlet-specific or
+             * page-specific information.
+             * </dt>
+             * <dd>"PORTLET"</dd>
+             * <dt>
+             * More cacheable, because the URL contains only portlet-specific but no
+             * page-specific information.
+             * </dt>
+             * <dd>"PAGE"</dd>
+             * <dt>
+             * Least cacheable because the URL contains portlet-specific and
+             * page-specific information.
+             * <p>
+             * However, cacheability must be set to "PAGE" if the content to be served contains
+             * portal URLs.
+             * </dt>
+             * </dl>
+             * <p>
+             * Specification of cacheability is optional.
+             * If the cacheability is not specified, cacheability for the URL
+             * will be set to "PAGE".
+             * <p>
+             * The parameters may be specified in either order, individually,
+             * or not at all. Examples of valid calls:
+             * <code>
+             * <br>createResourceUrl();
+             * <br>createResourceUrl(resParams, cache);
+             * <br>createResourceUrl(resParams);
+             * <br>createResourceUrl(cache);
+             * </code>
+             *
+             * @param   {PortletParameters}  resParams   Resource parameters to be
+             *                                           added to the URL
+             * @param   {string}             cache       Cacheability option
+             *
+             * @returns {Promise}   A Promise object. Returns a string representing the 
+             *                      resource URL on successful resolution.
+             *                      Returns an Error object containing a descriptive
+             *                      message on failure.
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             *
+             * @memberOf   PortletInit
+             */
+            createResourceUrl : function (resParams, cache) {
+               var ii, arg, parms=null, cacheability=null, pi;
+         
+               // check arguments. make sure there is a maximum of two
+               // args and determine the types. Check values as possible.
+               if (arguments.length > 2) {
+                              throwIllegalArgumentException("Too many arguments. 2 arguments are allowed.");
+               }
+         
+               ii = arguments.length;
+               while (--ii >=0) {
+                  arg = arguments[ii];
+                  if (typeof arg === 'string') {
+                     switch (arg) {
+                     case "cacheLevelPage":
+                     case "cacheLevelPortlet":
+                     case "cacheLevelFull":
+                        if (cacheability=== null) {
+                           cacheability = arg;
+                        } else {
+                     throwIllegalArgumentException("too many string arguments: " + arg
+                             + ", " + cacheability);
+                        }
+                        break;
+                     default:
+                        throwIllegalArgumentException("Invalid cacheability argument: " + arg);
+                     }
+                   } else if (typeof arg === 'object') {
+                      validateParms(arg);     // throws if parms are invalid
+                      if (parms !== null) {
+                         throwIllegalArgumentException("too many parameters arguments.");
+                      }
+                      parms = arg;
+                   } else {
+                      throwIllegalArgumentException("Invalid argument type. argument " + ii
+                            + " is of type" + (typeof arg));
+                  }
+               }
+               
+               // fallback to page level cacheability
+               if (!cacheability) {
+                  cacheability = "cacheLevelPage";
+               }
+         
+               // everything ok, so get URL from the impl
+               pi = _registeredPortlets[portletId];
+               return pi.getUrl("RESOURCE", parms, cacheability);
+            },
+         
+            /**
+             * Initiates a portlet action using the specified action parameters and element
+             * arguments.
+             * <p>
+             * When the action has successfully completed, a copy of the portlet state
+             * will be provided to the portlet client
+             * through the {@link onStateChange} listener function.
+             * A portlet client can modify this state object and pass it to the
+             * setPortletState function to update the portlet state.
+             * <p>
+             * However, it is also possible for the portal to completely refresh the
+             * page as a response to the action.
+             * This may occur in order to support portlets on the page that do not participate
+             * in the Portlet 3.0 Ajax support or due to configuration settings, for example.
+             * <p>
+             * If the page is completely refreshed, it will be rendered according to
+             * render parameters set on the server.
+             * <p>
+             * Action parameters are optional parameters attached to a action
+             * URL in addition to any portlet state values that may be present.
+             * Action parameters do not influence the portlet state.
+             * <p>
+             * The action parameters must be an object containing properties
+             * representing parameter names whose values must be an array of string
+             * values, as described under {@link PortletParameter}.
+             * All of the action parameters will be attached to the URL.
+             * Use of action parameters is optional.
+             * <p>
+             * If the <code>element</code> argument is present, it must refer to
+             * an HTML form to be submitted.
+             * The portlet hub will use this form to execute the action.
+             * <p>
+             * Specification of <code>element</code> is optional.
+             * If the <code>element</code> is not specified, the portlet hub will
+             * submit the action to the server in an appropriate manner.
+             * <p>
+             * A portlet action is a blocking operation.
+             * To allow for orderly state transitions, the portlet hub does not allow
+             * this function to be used while a blocking operation is in progress.
+             * A blocking operation is considered to be in progress
+             * from the initial call until the final onStateChange event for that
+             * operation has been fired. See {@link portlet} for further information.
+             * <p>
+             * The parameters may be specified in either order, individually,
+             * or not at all. Examples of valid calls:
+             * <code>
+             * <br>action();
+             * <br>action(actParams, element);
+             * <br>action(actParams);
+             * <br>action(element);
+             * </code>
+             *
+             * @param   {PortletParameters}  actParams   Action parameters to be
+             *                                           added to the URL
+             *                                           (optional)
+             * @param   {HTMLFormElement}    element     DOM element of form to be submitted
+             *                                           (optional)
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             * @throws  {AccessDeniedException}
+             *                   Thrown if a blocking operation is
+             *                   already in progress.
+             * @throws  {NotInitializedException}
+             *                   Thrown if a portlet ID is provided, but no onStateChange
+             *                   listener has been registered.
+             *
+             * @memberOf   PortletInit
+             */
+            action : function (actParams, element) {
+               var ii, arg, type, parms = null, el = null;
+         
+               // check arguments. make sure there is a maximum of two
+               // args and determine the types. Check values as possible.
+               if (arguments.length > 2) {
+                  throwIllegalArgumentException("Too many arguments. 2 arguments are allowed.");
+               }
+         
+               ii = arguments.length;
+               while (--ii >=0) {
+                  arg = arguments[ii];
+                  type = Object.prototype.toString.call(arg);
+                  if (type === '[object HTMLFormElement]') {
+                     if (el === null) {
+                        el = arg;
+                     } else {
+                        throwIllegalArgumentException("too many [object HTMLFormElement] arguments: "
+                               + arg + ", " + el);
+                     }
+                  } else if (type === '[object Object]') {
+                     validateParms(arg);     // throws if parms are invalid
+                     if (parms !== null) {
+                        throwIllegalArgumentException("too many parameters arguments.");
+                     }
+                     parms = arg;
+                  } else {
+                     throwIllegalArgumentException("Invalid argument type. Argument " + (ii + 1)
+                            + " is of type " + type);
+                  }
+               }
+         
+               // everything ok, so do the action
+         
+               setupAction(portletId, parms, el);
+            },
+         
+            /**
+             * Starts partial action processing and returns a {@link PartialActionInit}
+             * object to the caller.
+             * The <code>PartialActionInit</code> object contains a partial action
+             * URL and an {@setPageState}.
+             * The partial action URL can be used to initiate an action request.
+             * The {@setPageState} callback function allows the
+             * portlet client to complete the partial action operation by updating the
+             * state of all portlet clients on the page that are affected by
+             * action and event processing on the server resulting from the partial action.
+             * <p>
+             * After the <code>setPageState</code> function has been called,
+             * a copy of the portlet state will be provided to each affected portlet client
+             * through the {@link onStateChange} listener function.
+             * <p>
+             * However, it is also possible for the portal to completely refresh the
+             * page as a response to the action.
+             * This may occur in order to support portlets on the page that do not participate
+             * in the Portlet 3.0 Ajax support or due to configuration settings, for example.
+             * <p>
+             * If the page is completely refreshed, it will be rendered according to
+             * render parameters set on the server.
+             * <p>
+             * Action parameters are optional parameters attached to a action
+             * URL in addition to any portlet state values that may be present.
+             * Action parameters do not influence the portlet state.
+             * <p>
+             * The action parameters must be an object containing properties
+             * representing parameter names whose values must be an array of string
+             * values, as described under {@link PortletParameter}.
+             * All of the action parameters will be attached to the URL.
+             * Use of action parameters is optional.
+             * <p>
+             * A partial action is a blocking operation.
+             * To allow for orderly state transitions, the portlet hub does not allow
+             * this function to be used while a blocking operation is in progress.
+             * A blocking operation is considered to be in progress
+             * from the initial call until the final onStateChange event for that
+             * operation has been fired. See {@link portlet} for further information.
+             *
+             * @param   {PortletParameters}  actParams   Action parameters to be
+             *                                           added to the URL
+             *                                           (optional)
+             *
+             * @returns {Promise}   A Promise object. Returns a {PortletActionInit}
+             *                      object containing a partial action URL and
+             *                      the setPageState callback function on successful
+             *                      resolution. Returns an Error object containing
+             *                      a descriptive message on failure.
+             *
+             * @throws  {IllegalArgumentException}
+             *                   Thrown if the input parameters are invalid
+             * @throws  {AccessDeniedException}
+             *                   Thrown if a blocking operation is
+             *                   already in progress.
+             * @throws  {NotInitializedException}
+             *                   Thrown if a portlet ID is provided, but no onStateChange
+             *                   listener has been registered.
+             *
+             * @memberOf   PortletInit
+             */
+            startPartialAction : function (actParams) {
+               var  parms = null, paObj = {}, pi;
+         
+               // check arguments. make sure there is a maximum of two
+               // args and determine the types. Check values as possible.
+               if (arguments.length > 1) {
+                  throwIllegalArgumentException("Too many arguments. 1 arguments are allowed.");
+               } else if (actParams !== undefined) {
+                  if (typeof actParams === 'object') {
+                     validateParms(actParams);     // throws if parms are invalid
+                     parms = actParams;
+                  } else {
+                     throwIllegalArgumentException("Invalid argument type. Argument is of type " 
+                           + (typeof actParams));
+                  }
+               }
+         
+               // make sure operation is allowed
+               if (busy === true) {
+                  throwAccessDeniedException("Operation in progress");
+               } else if (oscListeners[portletId] === undefined) {
+                  throwNotInitializedException("No onStateChange listener registered for portlet: "
+                        + portletId);
+               }
+         
+               busy = true;
+         
+               // Create the PartialActionInit object fulfill promise by passing it.
+               // let errors propagate to caller.
+               
+               pi = _registeredPortlets[portletId];
+               return pi.getUrl("PARTIALACTION", parms).then(function (url) {
+                  paObj.url = url;
+                  paObj.setPageState = function (ustr) {setPageState(portletId, ustr);};
+                  return paObj;
+               });
+         
+            },
+         
+            /**
+             * Tests whether a blocking operation is in progress.
+             * <p>
+             * The portlet client can use this function to test whether a
+             * state change is in progress before initiating a blocking operation.
+             * <p>
+             * Note that if the portlet client uses this function to implement
+             * a waiting function, the portlet state may be changed during the
+             * time that the portlet client waits.
+             * Also note that the portal may choose to refresh the page as a response
+             * to a blocking operation, in which case the waiting function would not
+             * complete.
+             * <p>
+             * The portlet hub provides for orderly state transitions by allowing only a
+             * single blocking operation ({@link action}, {@link setPortletState},
+             * {@link startPartialAction}) to be active at any one time.
+             * <p>
+             * The state transition is considered to be active from the initial portlet
+             * client call to one of the blocking operations until the portlet
+             * hub has performed the requested state change and has informed all of
+             * the affected portlet clients by firing the corresponding onStateChange
+             * events.
+             * <p>
+             * See {@link portlet} for further information.
+             *
+             * @returns    {boolean}   <code>true</code> if a blocking operation
+             *                         is in progress
+             *
+             * @memberOf   PortletInit
+             */
+            isInProgress : function () {
+               return busy;
+            },
+         
+            /**
+             * Dispatches a client event.
+             * <p>
+             * Client events of the specified type are queued for delivery
+             * to registered event listeners of that type.
+             * <p>
+             * The event type is matched against the type strings associated with
+             * registered event listeners.
+             * An event will be dispatched for each matching listener.
+             * The number of matching listeners will be returned.
+             * <p>
+             * The event payload is defined by the dispatcher of the event.
+             * It must be present, but may be of any type or value.
+             * <p>
+             * The portlet Client may not dispatch event types beginning
+             * with the reserved string "portlet.".
+             * <p>
+             * The client is responsible for preventing race conditions.
+             * For example, a race condition can occur if portlet A dispatches
+             * an event to portlet B, causing an event to portlet A, which
+             * dispatches again to portlet B, etc.
+             * <p>
+             * Event delivery cannot be guaranteed, and may vary according to
+             * the situation.
+             * <p>
+             * Take for example a scenario where a portlet issues an event to
+             * several other portlets, perhaps including itself.
+             * Due to the event, each portlet updates parameters
+             * through use of the {@link setPortletState} function.
+             * <p>
+             * The <code>setPortletState</code> function can cause a page refresh
+             * depending on the situation.
+             * If all portlets on the page participate in the JSR 362 Ajax support,
+             * the portlet hub might not cause a page refresh.
+             * However, if there are legacy portlets to be supported, the portal
+             * or portlet hub might choose to refresh the page.
+             * <p>
+             * In the latter case, this means that the first portlet receiving the
+             * event will be able to successfully update its parameters, but the
+             * remaining portlets will not.
+             * This can have unintentional consequences.
+             *
+             * @param   {string}    type     The type of listener
+             * @param   {any}       payload  The payload to be delivered
+             *
+             * @returns {number}             The number of events queued for delivery
+             *
+             * @memberOf   PortletInit
+             */
+            dispatchClientEvent : function (type, payload) {
+               var cnt = 0, li;
+         
+               // check for 2  arguments, the first of which must be a string
+               checkArguments(arguments, 2, 2, [ 'string' ]);
+         
+               // disallow use of reserved name for system event types
+               if (type.match(portletRegex)) {
+                  throwIllegalArgumentException("The event type is invalid: " + type);
+               }
+         
+               for (li in pcListeners) {
+                  if (pcListeners.hasOwnProperty(li)) {
+         
+                     if (type.match(pcListeners[li].type) !== null) {
+                        dispatchCE(type, pcListeners[li].callback, payload);
+                        cnt++;
+                     }
+                  }
+               }
+         
+               return cnt;
+            }
+         
+         };
+      });
+   };
+
+})();


[08/15] portals-pluto git commit: Completed basic implementation of pluto url generation code

Posted by ms...@apache.org.
Completed basic implementation of pluto url generation 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/bc34e25a
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/bc34e25a
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/bc34e25a

Branch: refs/heads/PortletHub
Commit: bc34e25a20562b5369a176a2eb5a33a490eb995c
Parents: 066d667
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Nov 12 07:17:53 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Nov 12 07:17:53 2014 +0100

----------------------------------------------------------------------
 pluto-portal/src/main/webapp/portlet.js        |   2 +-
 pluto-portal/src/main/webapp/portletHubImpl.js | 145 ++++++++++++--------
 2 files changed, 87 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/bc34e25a/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 345044f..546efe8 100644
--- a/pluto-portal/src/main/webapp/portlet.js
+++ b/pluto-portal/src/main/webapp/portlet.js
@@ -1563,7 +1563,7 @@ var portlet = portlet || {};
                // let errors propagate to caller.
                
                pi = _registeredPortlets[portletId];
-               return pi.getUrl("PARTIALACTION", parms).then(function (url) {
+               return pi.getUrl("PARTIAL_ACTION", parms).then(function (url) {
                   paObj.url = url;
                   paObj.setPageState = function (ustr) {setPageState(portletId, ustr);};
                   return paObj;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/bc34e25a/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 1b9cf1c..a372c1f 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -454,7 +454,10 @@ var portlet = portlet || {};
    WINDOW_STATE = "ws",
    PORTLET_MODE = "pm",
    VALUE_DELIM = "0x0",
-   
+
+   AJAX_ACTION = "aa",              // new for portlet spec 3
+   PARTIAL_ACTION = "pa",           // new for portlet spec 3
+
    
    /**
     * Helper for generating parameter strings for the URL
@@ -485,6 +488,21 @@ var portlet = portlet || {};
    
    
    /**
+    * Helper for generating portlet mode & window state strings for the URL
+    */
+   genPMWSString = function (pid) {
+      var pm = pageState[pid].state.portletMode, 
+          ws = pageState[pid].state.windowState, 
+          wid = plutoEncode(pageState[pid].urlpid), str = "";
+
+      str += "/" + PREFIX + PORTLET_MODE + wid + DELIM + encodeURIComponent(pm);
+      str += "/" + PREFIX + WINDOW_STATE + wid + DELIM + encodeURIComponent(ws);
+
+      return str;
+   },
+   
+   
+   /**
     * Returns a URL of the specified type.
     * 
     * @param   {string}    type     The URL type
@@ -500,81 +518,90 @@ var portlet = portlet || {};
       var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, 
           sep = "", name, names, val, vals, ii, jj, str, id, ids;
 
+      // First add the appropriate window identifier according to URL type.
+      // Note that no special window ID is added to a RENDER URL. 
+      
       if (type === "RESOURCE") {
-         
-         // Add the resource window
+         // If generating resource URL, add resource window & cacheability
          url += "/" + PREFIX + RESOURCE + plutoEncode(pageState[pid].urlpid);
-         
-         // Add cacheability
          if (cache) {
             ca = cache;
          }
          url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
-         
-         // Put the private & public parameters on the URL if cacheability != FULL
-         if (ca !== "cacheLevelFull") {
-            
-            // If cacheability = PAGE, add the state for the non-target portlets
-            if (ca === "cacheLevelPage") {
-               
-               ids = getIds();
-               for (ii = 0; ii < ids.length; ii++) {
-                  id = ids[ii];
-                  if (id !== pid) {  // only for non-target portlets
-                     str = "";
-                     names = pageState[id].state.parameters;
-                     for (name in names) {
-                        // Public render parameters are encoded separately
-                        if (names.hasOwnProperty(name) && !isPRP(id, name)) {
-                           str += genParmString(id, name, RENDER_PARAM);
-                        }
+      } else if (type === "ACTION") {
+         // Add Ajax Action window
+         url += "/" + PREFIX + AJAX_ACTION + plutoEncode(pageState[pid].urlpid);
+      } else if (type === "PARTIAL_ACTION") {
+         // Add Partial Action window
+         url += "/" + PREFIX + PARTIAL_ACTION + plutoEncode(pageState[pid].urlpid);
+      }
+      
+      // Now add the state to the URL, taking into account cacheability if
+      // we're dealing with a resource URL. 
+
+      // Put the private & public parameters on the URL if cacheability != FULL
+      if ((type !== "RESOURCE") || (ca !== "cacheLevelFull")) {
+
+         // If cacheability = PAGE, add the state for the non-target portlets
+         if ((type !== "RESOURCE") || (ca === "cacheLevelPage")) {
+
+            ids = getIds();
+            for (ii = 0; ii < ids.length; ii++) {
+               id = ids[ii];
+               if (id !== pid) {  // only for non-target portlets
+                  url += genPMWSString(id);  // portlet mode & window state
+                  str = "";
+                  names = pageState[id].state.parameters;
+                  for (name in names) {
+                     // Public render parameters are encoded separately
+                     if (names.hasOwnProperty(name) && !isPRP(id, name)) {
+                        str += genParmString(id, name, RENDER_PARAM);
                      }
-                     url += str;
                   }
+                  url += str;
                }
-               
             }
-            
-            // add the private parameters for the target portlet
-            
-            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;
-            
-            // Add the public render parameters
-            str = "";
-            names = pageState[pid].pubParms;
-            for (ii=0; ii < names.length; ii++) {
-               name = names[ii];
-               str += genParmString(pid, name, PUBLIC_RENDER_PARAM);
-            }
-            url += str;
 
          }
 
-         // Encode resource parameters as query string
-         if (parms) {
-            str = "?"; sep = "";
-            for (parm in parms) {
-               if (parms.hasOwnProperty(parm)) {
-                  vals = parms[parm];
-                  for (ii=0; ii < vals.length; ii++) {
-                     str += sep + encodeURIComponent(parm) + "=" + encodeURIComponent(vals[ii]);
-                     sep = "&";
-                  }
+         // 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);
+            }
+         }
+         url += str;
+
+         // Add the public render parameters
+         str = "";
+         names = pageState[pid].pubParms;
+         for (ii=0; ii < names.length; ii++) {
+            name = names[ii];
+            str += genParmString(pid, name, PUBLIC_RENDER_PARAM);
+         }
+         url += str;
+
+      }
+
+      // Encode resource or action parameters as query string
+      if (parms) {
+         str = "?"; sep = "";
+         for (parm in parms) {
+            if (parms.hasOwnProperty(parm)) {
+               vals = parms[parm];
+               for (ii=0; ii < vals.length; ii++) {
+                  str += sep + encodeURIComponent(parm) + "=" + encodeURIComponent(vals[ii]);
+                  sep = "&";
                }
             }
-            url += str;
          }
-         
+         url += str;
       }
-      
+
       // Use Promise to allow for potential server communication - 
       return new Promise(function (resolve, reject) {
          resolve(url);


[05/15] portals-pluto git commit: Got basic portlet hub functionality for setting state and getting updates working on Pluto

Posted by ms...@apache.org.
Got basic portlet hub functionality for setting state and getting updates working on Pluto


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

Branch: refs/heads/PortletHub
Commit: e449363c5ebb8e5dafffbc16aa21937935b62181
Parents: 1eeac9c
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Nov 11 16:08:50 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Nov 11 16:08:50 2014 +0100

----------------------------------------------------------------------
 .../WEB-INF/themes/pluto-default-theme.jsp      |  72 +++++-
 pluto-portal/src/main/webapp/portletHubImpl.js  | 224 +++++++++++++------
 2 files changed, 218 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/e449363c/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index bbb9a47..2ddea41 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -16,10 +16,11 @@ implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 --%>
+<%@page import="org.apache.pluto.driver.core.PortalRequestContext"%>
 <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
 <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %>
-<%@ page import="javax.portlet.*" %>
+<%@ page import="java.util.*,javax.portlet.*,org.apache.pluto.driver.url.*" %>
 <% pageContext.setAttribute("now", new java.util.Date()); %>
 
 <!--
@@ -46,6 +47,19 @@ group (the left column) displays portlets with odd IDs, while the second group
        portlet.impl = portlet.impl || {};
        portlet.impl.getInitData = function () {
           return {       
+             <%
+                PortalRequestContext prc = PortalRequestContext.getContext(request);
+                PortalURL pu = prc.getRequestedPortalURL(); 
+                Collection<PortalURLParameter> pups = pu.getParameters();
+                // on the URL at least, prps are not differentiated by portlet ID
+                Map<String, String[]> prps = pu.getPublicParameters();
+                StringBuffer prpnames = new StringBuffer();
+                String c0 = "";
+                for (String prp : prps.keySet()) {
+                   prpnames.append(c0 + "'" + prp + "'");
+                   c0 = ", ";
+                }
+             %>
              <c:forEach var="pid" items="${currentPage.portletIds}">
                 <%
                    StringBuffer ns = new StringBuffer("Pluto_");
@@ -58,25 +72,69 @@ group (the left column) displays portlets with odd IDs, while the second group
                       }
                    }
                    ns.append("_");
+                   
+                   String pm = pu.getPortletMode(pid).toString();
+                   String ws = pu.getWindowState(pid).toString();
                 %>
-                '<%= ns.toString() %>' : {
+                '<%=ns%>' : {
                    'state' : {
                       'parameters' : {
+                      <%
+                         String c1 = "";
+                         for (PortalURLParameter pup : pups){
+                            if (pup.getWindowId().equals(pid)){
+                               out.write(c1 + "   '" + pup.getName() + "' : [");
+                               String c2 = "";
+                               for (String val : pup.getValues()) {
+                                  out.write(c2 + " '" + val + "'");
+                                  c2 = ", ";
+                               }
+                               out.write("]");
+                               c1 = ",\n                      ";
+                            }
+                         }
+                         // this is a hack, but just add all public parms for all portlets on page
+                         for (String prp : prps.keySet()) {
+                            out.write(c1 + "   '" + prp + "' : [");
+                            String c2 = "";
+                            for (String val : (String[])prps.get(prp)) {
+                               out.write(c2 + " '" + val + "'");
+                               c2 = ",";
+                            }
+                            out.write("]");
+                            c1 = ",\n                      ";
+                            
+                         }
+                      %>
                       }, 
-                      'portletMode' : 'VIEW', 
-                      'windowState' : 'NORMAL'
+                      'portletMode' : '<%=pm%>', 
+                      'windowState' : '<%=ws%>'
                    },
+                   // 'pubParms' : [<%=prpnames.toString()%>],
                    'pubParms' : ['imgName', 'color'],
-                   'allowedPM' : ['VIEW'],
-                   'allowedWS' : ['NORMAL'],
+                   'allowedPM' : ['view'],
+                   'allowedWS' : ['normal'],
                    'renderData' : {
                       'renderData' : null,
                       'mimeType' : "text/plain"
-                   }
+                   },
+                   'urlpid' : '<%=pid%>'
                 },
              </c:forEach>
           }
        }
+       <%
+          StringBuffer ub = new StringBuffer();
+          //ub.append(request.getScheme()).append("://").append(request.getServerName());
+          //ub.append(request.getServerPort());
+          ub.append(pu.getServletPath().startsWith("/")?"":"/")
+            .append(pu.getServletPath())
+            .append(pu.getRenderPath());
+          String urlBase = response.encodeURL(ub.toString());
+       %>
+       portlet.impl.getUrlBase = function () {
+          return '<%=urlBase%>';
+       }
     </script>
     <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/pluto.js"></script>
     <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/portletHubImpl.js"></script>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/e449363c/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 befa84e..e041829 100644
--- a/pluto-portal/src/main/webapp/portletHubImpl.js
+++ b/pluto-portal/src/main/webapp/portletHubImpl.js
@@ -178,6 +178,20 @@ var portlet = portlet || {};
    getPRPNames = function (pid) {
       return pageState[pid].pubParms;
    },
+   
+   /**
+    * function for checking if the parameter is private
+    */
+   isPRP = function (pid, name) {
+      var ii, result = false;
+      for (ii = 0; ii < pageState[pid].pubParms.length; ii++) {
+         if (name === pageState[pid].pubParms[ii]) {
+            result = true;
+         }
+      }
+      return result;
+   },
+
 
    /**
     * Gets the updated public parameters for the given portlet
@@ -393,6 +407,37 @@ var portlet = portlet || {};
 
    },
    
+   /**
+    * Function to encode url tokens as Pluto likes it
+    */
+   plutoEncode = function (istr) {
+      var ENCODINGS = {
+            "_" :  "0x1",
+            "." :  "0x2",
+            "/" :  "0x3",
+            "\r" : "0x4",
+            "\n" : "0x5",
+            "<" :  "0x6",
+            ">" :  "0x7",
+            " " :  "0x8",
+            "#" :  "0x9",
+            "?" :  "0xa",
+            "\\" : "0xb",
+            "%" :  "0xc",
+            "|" :  "%7C"
+                      }, ii, ostr = "";
+      
+      for (ii=0; ii < istr.length; ii++) {
+         if (ENCODINGS[istr.charAt(ii)]) {
+            ostr += ENCODINGS[istr.charAt(ii)];
+         } else {
+            ostr += istr.charAt(ii);
+         }
+      }
+
+      return ostr;
+   },
+   
    
    /**
     * Returns a URL of the specified type.
@@ -407,92 +452,129 @@ var portlet = portlet || {};
     */
    getUrl = function (type, pid, parms, cache) {
    
-      var url = "http://www.dummyportal.com/some/context/";
-          var qparms = [], rparms, qp, state, tpid, val, pids, ii, jj;
-          
-      // for a mockup, should be good enough ...
-      // optimized for easy parsing by the test code. 
-      // see "portlet.test" below.
-      
-      // This is how it should look:
-      //  http://www.dummyportal.com/some/context/PortletA/ACTION/PAGE/?&rp1=resVal&RENDERPARMS
-      //  &~~~&PortletA&mode=VIEW&ws=NORMAL&parm1=Fred&parm2=Wilma&parm2=Pebbles&parm3=Barney&parm3=Betty&parm3=Bam%20Bam
-      //  &~~~&PortletB&mode=VIEW&ws=NORMAL&parm1=val1&pubparm1=pubval1&parm2=val2&parm2=val3
-      //  &~~~&PortletC&mode=VIEW&ws=NORMAL&parm1=val1&pubparm1=pubval1&pubparm2=pubval2&parm2=val2&parm2=val3
-      //  &~~~&PortletD&mode=VIEW&ws=NORMAL&pubparm1=private_val1&pubparm2=pubval2&parm2=val2&parm2=val3
-      //  &~~~&PortletE&mode=VIEW&ws=NORMAL&parm1=val1&parm2=val2&parm2=val3&pubparm1=pubval1&pubparm2=pubval2
-      //  &~~~&PortletF&mode=VIEW&ws=NORMAL&~~~
+      var url = portlet.impl.getUrlBase(), ca = 'cacheLevelPage', parm, 
+          sep = "", name, names, val, vals, ii, jj, str, id, ids,
       
-      url += pid + "/" + type + "/"; 
-      url += (((cache===undefined)||(cache===null))?"cacheLevelPage":cache) + "/?";
-          
-      // put the additional parameters on the URL
-      if (parms !== null) {
-         for (qp in parms) {
-            for (var ii=0; ii<parms[qp].length; ii++) {
-               val = (parms[qp][ii] === null) ? "" : "=" + encodeURIComponent(parms[qp][ii]);
-               qparms.push(encodeURIComponent(qp) + val);
-            }
+      // Constants used for Encoding/Decoding (copied from Pluto impl code)  ----------
+
+      PREFIX = "__",
+      DELIM = "_",
+      PORTLET_ID = "pd",
+      ACTION = "ac",
+      RESOURCE = "rs",
+      RESOURCE_ID = "ri",
+      CACHE_LEVEL = "cl",
+      RENDER_PARAM = "rp",
+      PRIVATE_RENDER_PARAM = "pr",
+      PUBLIC_RENDER_PARAM = "sp",
+      WINDOW_STATE = "ws",
+      PORTLET_MODE = "pm",
+      VALUE_DELIM = "0x0";
+
+      if (type === "RESOURCE") {
+         
+         // Add the resource window
+         url += "/" + PREFIX + RESOURCE + plutoEncode(pageState[pid].urlpid);
+         
+         // Add cacheability
+         if (cache) {
+            ca = cache;
          }
-      }
-   
-      qparms.push("RENDERPARMS")
-      qparms.push("~~~")
-   
-      // Don't put any render parameters on it cache=cacheLevelFull
-      if ((type !== "RESOURCE") || 
-          ((type === "RESOURCE") && (cache !== "cacheLevelFull"))) {
+         url += "/" + PREFIX + CACHE_LEVEL + plutoEncode(ca);
          
-         pids = getIds();
-         jj = pids.length;
-         while ((jj = jj - 1) >= 0) {
-            tpid = pids[jj];
+         // Put the private & public parameters on the URL if cacheability != FULL
+         if (cache !== "cacheLevelFull") {
             
-            // If cache=cacheLevelPortlet, only put on the parms for that portlet
-            if ((type === "RESOURCE") && (cache === "cacheLevelPortlet") && (pid !== tpid)) {
-               continue;
+            // If cacheability = PAGE, add the state for the non-target portlets
+            if (cache === "cacheLevelPage") {
+               
+               ids = getIds();
+               for (ii = 0; ii < ids.length; ii++) {
+                  id = ids[ii];
+                  if (id !== pid) {  // only for non-target portlets
+                     str = "";
+                     names = pageState[id].state.parameters;
+                     for (name in names) {
+                        if (names.hasOwnProperty(name) && !isPRP(id, name)) {
+                           vals = pageState[id].state.parameters[name];
+                           // might not be set yet ...
+                           if (vals) {
+                              sep = "";
+                              str += "/" + PREFIX + RENDER_PARAM + plutoEncode(pageState[id].urlpid)
+                                     + DELIM + encodeURIComponent(name) + "/";
+                              for (jj=0; jj < vals.length; jj++) {
+                                 str += sep + encodeURIComponent(vals[jj]);
+                                 sep = VALUE_DELIM;
+                              }
+                           }
+                        }
+                     }
+                     url += str;
+                  }
+               }
+               
             }
             
-            // put the portlet state parameters on the URL
-            state = getState(tpid);
+            // add the private parameters for the target portlet
             
-            qparms.push(encodeURIComponent(tpid));
-            qparms.push("mode=" + state.portletMode);
-            qparms.push("ws=" + state.windowState);
-         
-            rparms = state.parameters;
-            for (qp in rparms) {
-               for (ii=0; ii<rparms[qp].length; ii++) {
-                  val = (rparms[qp][ii] === null) ? "" : "=" + encodeURIComponent(rparms[qp][ii]);
-                  qparms.push(encodeURIComponent(qp) + val);
+            str = "";
+            names = pageState[pid].state.parameters;
+            for (name in names) {
+               if (names.hasOwnProperty(name) && !isPRP(pid, name)) {
+                  vals = pageState[pid].state.parameters[name];
+                  // might not be set yet ...
+                  if (vals) {
+                     sep = "";
+                     str += "/" + PREFIX + PRIVATE_RENDER_PARAM + DELIM + encodeURIComponent(name) + "/";
+                     for (jj=0; jj < vals.length; jj++) {
+                        str += sep + encodeURIComponent(vals[jj]);
+                        sep = VALUE_DELIM;
+                     }
+                  }
                }
             }
-            qparms.push("~~~");
+            url += str;
             
+            // Add the public render parameters
+            str = "";
+            names = pageState[pid].pubParms;
+            for (ii=0; ii < names.length; ii++) {
+               name = names[ii];
+               vals = pageState[pid].state.parameters[name];
+               // might not be set yet ...
+               if (vals) {
+                  sep = "";
+                  str += "/" + PREFIX + PUBLIC_RENDER_PARAM + DELIM + encodeURIComponent(name) + "/";
+                  for (jj=0; jj < vals.length; jj++) {
+                     str += sep + encodeURIComponent(vals[jj]);
+                     sep = VALUE_DELIM;
+                  }
+               }
+            }
+            url += str;
+
          }
-      }
-      
-      // put on the query parms
-      while (qparms.length > 0) {
-         url += "&" + qparms.shift();
+
+         // Encode resource parameters as query string
+         if (parms) {
+            str = "?"; sep = "";
+            for (parm in parms) {
+               if (parms.hasOwnProperty(parm)) {
+                  vals = parms[parm];
+                  for (ii=0; ii < vals.length; ii++) {
+                     str += sep + encodeURIComponent(parm) + "=" + encodeURIComponent(vals[ii]);
+                     sep = "&";
+                  }
+               }
+            }
+            url += str;
+         }
+         
       }
       
       // Use Promise to allow for potential server communication - 
       return new Promise(function (resolve, reject) {
-         var simval = '';
-         if (pid === 'SimulateCommError' && (parms)) {
-            simval = parms.SimulateError;
-            if (simval) {
-               simval = simval[0];
-            }
-         }
-            
-         // reject promise of an error is to be simulated
-         if (simval === 'reject') {
-            reject(new Error("Simulated error occurred when getting a URL!"));
-         } else {
-            resolve(url);
-         }
+         resolve(url);
       });
    },
    


[11/15] portals-pluto git commit: Added methods to retrieve the allowed window states for a given portelt ID / markup type

Posted by ms...@apache.org.
Added methods to retrieve the allowed window states for a given portelt ID / markup type


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

Branch: refs/heads/PortletHub
Commit: 59cd72e2956fbab9aab3ab5e47189c7e725bede6
Parents: 90c5fda
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Nov 19 00:37:20 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Nov 19 00:37:20 2014 +0100

----------------------------------------------------------------------
 .../config/impl/DriverConfigurationImpl.java    | 365 +++++++--------
 .../SupportedWindowStateServiceImpl.java        | 449 ++++++++++---------
 .../driver/config/DriverConfiguration.java      | 219 ++++-----
 .../portal/SupportedWindowStateService.java     | 124 ++---
 .../WEB-INF/themes/pluto-default-theme.jsp      |  12 +-
 5 files changed, 627 insertions(+), 542 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/59cd72e2/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/config/impl/DriverConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/config/impl/DriverConfigurationImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/config/impl/DriverConfigurationImpl.java
index 43c13c8..48f48c8 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/config/impl/DriverConfigurationImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/config/impl/DriverConfigurationImpl.java
@@ -1,180 +1,185 @@
-/*
- * 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.config.impl;
-
-import java.util.Collection;
-import java.util.Set;
-
-import javax.portlet.PortletConfig;
-import javax.portlet.PortletMode;
-
-import org.apache.pluto.container.PortletContainerException;
-import org.apache.pluto.container.PortletPreferencesService;
-import org.apache.pluto.driver.config.DriverConfiguration;
-import org.apache.pluto.driver.services.portal.PageConfig;
-import org.apache.pluto.driver.services.portal.PropertyConfigService;
-import org.apache.pluto.driver.services.portal.RenderConfigService;
-import org.apache.pluto.driver.services.portal.SupportedModesService;
-import org.apache.pluto.driver.services.portal.SupportedWindowStateService;
-import org.apache.pluto.driver.url.PortalURLParser;
-
-/**
- * Encapsulation of the Pluto Driver ResourceConfig.
- *
- * @version 1.0
- * @since Sep 23, 2004
- */
-public class DriverConfigurationImpl
-    implements DriverConfiguration {
-
-    private final PortalURLParser portalUrlParser;
-    private final PropertyConfigService propertyService;
-    private final RenderConfigService renderService;
-    private final SupportedModesService supportedModesService;
-    private final SupportedWindowStateService supportedWindowStateService;
-
-    // Container Services
-    private PortletPreferencesService portletPreferencesService;
-    
-    public DriverConfigurationImpl(PortalURLParser portalUrlParser,
-                                   PropertyConfigService propertyService,
-                                   RenderConfigService renderService,
-                                   SupportedModesService supportedModesService,
-                                   SupportedWindowStateService supportedWindowStateService) {
-
-        this.portalUrlParser = portalUrlParser;
-        this.propertyService = propertyService;
-        this.renderService = renderService;
-        this.supportedModesService = supportedModesService;
-        this.supportedWindowStateService = supportedWindowStateService;
-    }
-
-    /**
-     * Standard Getter.
-     * @return the name of the portal.
-     */
-    public String getPortalName() {
-        return propertyService.getPortalName();
-    }
-
-    /**
-     * Standard Getter.
-     * @return the portal version.
-     */
-    public String getPortalVersion() {
-        return propertyService.getPortalVersion();
-    }
-
-    /**
-     * Standard Getter.
-     * @return the name of the container.
-     */
-    public String getContainerName() {
-        return propertyService.getContainerName();
-    }
-
-    /**
-     * Standard Getter.
-     * @return the names of the supported portlet modes.
-     */
-    public Collection getSupportedPortletModes() {
-        return propertyService.getSupportedPortletModes();
-    }
-
-    /**
-     * Standard Getter.
-     * @return the names of the supported window states.
-     */
-    public Collection getSupportedWindowStates() {
-        return propertyService.getSupportedWindowStates();
-    }
-
-    /**
-     * Standard Getter.
-     * @return the render configuration.
-     */
-    public Collection getPages() {
-        return renderService.getPages();
-    }
-
-    public PageConfig getPageConfig(String pageId) {
-        return renderService.getPage(pageId);
-    }
-    
-    public boolean isPortletModeSupportedByPortal(String mode) {
-        return supportedModesService.isPortletModeSupportedByPortal(mode);
-    }
-    
-    public boolean isPortletModeSupportedByPortlet(String portletId, String mode) {
-        return supportedModesService.isPortletModeSupportedByPortlet(portletId, mode);
-    }
-    
-    public boolean isPortletModeSupported(String portletId, String mode) {
-        return supportedModesService.isPortletModeSupported(portletId, mode);
-    }
-
-//
-// Portal Driver Services
-//
-
-    public PortalURLParser getPortalUrlParser() {
-        return portalUrlParser;
-    }
-
-//
-// Container Services
-//
-    public PortletPreferencesService getPortletPreferencesService() {
-        return portletPreferencesService;
-    }
-
-    public void setPortletPreferencesService(PortletPreferencesService portletPreferencesService) {
-        this.portletPreferencesService = portletPreferencesService;
-    }
-
-    public boolean isWindowStateSupported(String portletId, String windowState)
-    {
-        return supportedWindowStateService.isWindowStateSupported(portletId, windowState);
-    }
-
-    public boolean isWindowStateSupportedByPortal(String windowState)
-    {
-        return supportedWindowStateService.isWindowStateSupportedByPortal(windowState);
-    }
-
-    public boolean isWindowStateSupportedByPortlet(String portletId, String windowState)
-    {
-        return supportedWindowStateService.isWindowStateSupportedByPortlet(portletId, windowState);
-    }
-    
-    public RenderConfigService getRenderConfigService(){
-    	return renderService;
-    }
-
-    public Set<PortletMode> getSupportedPortletModes(String portletId) throws PortletContainerException {
-    	return supportedModesService.getSupportedPortletModes(portletId);
-    }
-
-	public boolean isPortletManagedMode(String portletId, String mode) {
-		return supportedModesService.isPortletManagedMode(portletId, mode);
-	}
-	
-    public PortletConfig getPortletConfig(String portletId)  throws PortletContainerException {
-    	return supportedModesService.getPortletConfig(portletId);
-    }
-}
-
+/*
+ * 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.config.impl;
+
+import java.util.Collection;
+import java.util.Set;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+
+import org.apache.pluto.container.PortletContainerException;
+import org.apache.pluto.container.PortletPreferencesService;
+import org.apache.pluto.driver.config.DriverConfiguration;
+import org.apache.pluto.driver.services.portal.PageConfig;
+import org.apache.pluto.driver.services.portal.PropertyConfigService;
+import org.apache.pluto.driver.services.portal.RenderConfigService;
+import org.apache.pluto.driver.services.portal.SupportedModesService;
+import org.apache.pluto.driver.services.portal.SupportedWindowStateService;
+import org.apache.pluto.driver.url.PortalURLParser;
+
+/**
+ * Encapsulation of the Pluto Driver ResourceConfig.
+ *
+ * @version 1.0
+ * @since Sep 23, 2004
+ */
+public class DriverConfigurationImpl
+    implements DriverConfiguration {
+
+    private final PortalURLParser portalUrlParser;
+    private final PropertyConfigService propertyService;
+    private final RenderConfigService renderService;
+    private final SupportedModesService supportedModesService;
+    private final SupportedWindowStateService supportedWindowStateService;
+
+    // Container Services
+    private PortletPreferencesService portletPreferencesService;
+    
+    public DriverConfigurationImpl(PortalURLParser portalUrlParser,
+                                   PropertyConfigService propertyService,
+                                   RenderConfigService renderService,
+                                   SupportedModesService supportedModesService,
+                                   SupportedWindowStateService supportedWindowStateService) {
+
+        this.portalUrlParser = portalUrlParser;
+        this.propertyService = propertyService;
+        this.renderService = renderService;
+        this.supportedModesService = supportedModesService;
+        this.supportedWindowStateService = supportedWindowStateService;
+    }
+
+    /**
+     * Standard Getter.
+     * @return the name of the portal.
+     */
+    public String getPortalName() {
+        return propertyService.getPortalName();
+    }
+
+    /**
+     * Standard Getter.
+     * @return the portal version.
+     */
+    public String getPortalVersion() {
+        return propertyService.getPortalVersion();
+    }
+
+    /**
+     * Standard Getter.
+     * @return the name of the container.
+     */
+    public String getContainerName() {
+        return propertyService.getContainerName();
+    }
+
+    /**
+     * Standard Getter.
+     * @return the names of the supported portlet modes.
+     */
+    public Collection getSupportedPortletModes() {
+        return propertyService.getSupportedPortletModes();
+    }
+
+    /**
+     * Standard Getter.
+     * @return the names of the supported window states.
+     */
+    public Collection getSupportedWindowStates() {
+        return propertyService.getSupportedWindowStates();
+    }
+
+    /**
+     * Standard Getter.
+     * @return the render configuration.
+     */
+    public Collection getPages() {
+        return renderService.getPages();
+    }
+
+    public PageConfig getPageConfig(String pageId) {
+        return renderService.getPage(pageId);
+    }
+    
+    public boolean isPortletModeSupportedByPortal(String mode) {
+        return supportedModesService.isPortletModeSupportedByPortal(mode);
+    }
+    
+    public boolean isPortletModeSupportedByPortlet(String portletId, String mode) {
+        return supportedModesService.isPortletModeSupportedByPortlet(portletId, mode);
+    }
+    
+    public boolean isPortletModeSupported(String portletId, String mode) {
+        return supportedModesService.isPortletModeSupported(portletId, mode);
+    }
+
+//
+// Portal Driver Services
+//
+
+    public PortalURLParser getPortalUrlParser() {
+        return portalUrlParser;
+    }
+
+//
+// Container Services
+//
+    public PortletPreferencesService getPortletPreferencesService() {
+        return portletPreferencesService;
+    }
+
+    public void setPortletPreferencesService(PortletPreferencesService portletPreferencesService) {
+        this.portletPreferencesService = portletPreferencesService;
+    }
+
+    public boolean isWindowStateSupported(String portletId, String windowState)
+    {
+        return supportedWindowStateService.isWindowStateSupported(portletId, windowState);
+    }
+
+    public boolean isWindowStateSupportedByPortal(String windowState)
+    {
+        return supportedWindowStateService.isWindowStateSupportedByPortal(windowState);
+    }
+
+    public boolean isWindowStateSupportedByPortlet(String portletId, String windowState)
+    {
+        return supportedWindowStateService.isWindowStateSupportedByPortlet(portletId, windowState);
+    }
+
+    public Set<WindowState> getSupportedWindowStates(String portletId, String contentType) throws PortletContainerException {
+      return supportedWindowStateService.getSupportedWindowStates(portletId, contentType);
+    }
+    
+    public RenderConfigService getRenderConfigService(){
+    	return renderService;
+    }
+
+    public Set<PortletMode> getSupportedPortletModes(String portletId) throws PortletContainerException {
+    	return supportedModesService.getSupportedPortletModes(portletId);
+    }
+
+	public boolean isPortletManagedMode(String portletId, String mode) {
+		return supportedModesService.isPortletManagedMode(portletId, mode);
+	}
+	
+    public PortletConfig getPortletConfig(String portletId)  throws PortletContainerException {
+    	return supportedModesService.getPortletConfig(portletId);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/59cd72e2/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/SupportedWindowStateServiceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/SupportedWindowStateServiceImpl.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/SupportedWindowStateServiceImpl.java
index 8bc9293..88638be 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/SupportedWindowStateServiceImpl.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/services/impl/resource/SupportedWindowStateServiceImpl.java
@@ -1,200 +1,249 @@
-/*
- * 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.impl.resource;
-
-import org.apache.pluto.container.PortletContainerException;
-import org.apache.pluto.container.driver.PortletRegistryService;
-import org.apache.pluto.container.om.portlet.CustomWindowState;
-import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
-import org.apache.pluto.driver.config.DriverConfigurationException;
-import org.apache.pluto.driver.services.portal.PortletWindowConfig;
-import org.apache.pluto.driver.services.portal.PropertyConfigService;
-import org.apache.pluto.driver.services.portal.SupportedWindowStateService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.portlet.WindowState;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-public class SupportedWindowStateServiceImpl implements
-        SupportedWindowStateService
-{
-
-    /**
-     * Logger *
-     */
-    private static final Logger LOG = LoggerFactory.getLogger(SupportedWindowStateServiceImpl.class);
-
-    /**
-     * PropertyConfigService is injected by Spring.  We
-     * use it to obtain the window states that the portal
-     * supports.  It is protected only so that the unit
-     * tests have access to the field.
-     */
-    protected final PropertyConfigService propertyService;
-
-    /**
-     * PortletRegistry is obtained from the PortletContainer on
-     * this service's initialization.  It is protected only
-     * so that the unit tests have access to the field.
-     * <p/>
-     * Note that it is an optional container service, but
-     * this implmentation requires it.
-     */
-    protected final PortletRegistryService portletRegistry;
-
-    /**
-     * Contains String objects of window states supported
-     * by the portal (obtained from PropertyConfigService).
-     * It is protected only so that the unit tests have
-     * access to the field.
-     */
-    protected Set portalSupportedWindowStates = new HashSet(3);
-
-    /**
-     * Window States that are specified in PLT.9
-     */
-    protected static final Set JSR168_WINDOW_STATES;
-
-    static
-    {
-        JSR168_WINDOW_STATES = new HashSet(3);
-        JSR168_WINDOW_STATES.add(WindowState.MAXIMIZED);
-        JSR168_WINDOW_STATES.add(WindowState.MINIMIZED);
-        JSR168_WINDOW_STATES.add(WindowState.NORMAL);
-    }
-
-    public SupportedWindowStateServiceImpl(PropertyConfigService propertyService, PortletRegistryService portletRegistry)
-    {
-        this.propertyService = propertyService;
-        this.portletRegistry = portletRegistry;
-        LOG.debug("Initializing SupportedWindowStateService... ");
-
-        portalSupportedWindowStates = propertyService.getSupportedWindowStates();
-        if (LOG.isDebugEnabled())
-        {
-            StringBuffer msg = new StringBuffer();
-
-            if (portalSupportedWindowStates != null)
-            {
-                msg.append("Portal supports [" + portalSupportedWindowStates.size() + "] window states.  ");
-                for (Iterator i = portalSupportedWindowStates.iterator(); i.hasNext();)
-                {
-                    msg.append("[" + i.next() + "]");
-                    if (i.hasNext())
-                    {
-                        msg.append(", ");
-                    }
-                }
-                LOG.debug(msg.toString());
-            }
-        }
-
-        if (portalSupportedWindowStates == null)
-        {
-            final String msg = "Portal supported window states is null!";
-            LOG.error(msg);
-            throw new DriverConfigurationException(msg);
-        }
-        LOG.debug("SupportedWindowStateService initialized.");
-    }
-
-    public boolean isWindowStateSupported(String portletId, String state)
-    {
-        // If the supplied window state is a JSR 168 window state,
-        // we can return immediately
-        if (JSR168_WINDOW_STATES.contains(state))
-        {
-            return true;
-        }
-
-        // Otherwise we need to check for custom window states
-
-        return isWindowStateSupportedByPortal(state) &&
-                isWindowStateSupportedByPortlet(portletId, state);
-    }
-
-    public boolean isWindowStateSupportedByPortal(String state)
-    {
-        return portalSupportedWindowStates.contains(state);
-    }
-
-    public boolean isWindowStateSupportedByPortlet(String portletId, String state)
-    {
-        if (portletId == null ||
-                state == null ||
-                portletId.trim().equals("") ||
-                state.trim().equals(""))
-        {
-            StringBuffer errMsg = new StringBuffer("Cannot determine supported window " +
-                    "states for portletId [" + portletId + "] and window state [" + state + "].  ");
-            String msg = errMsg.append("One or both of the arguments is empty or null.").toString();
-            LOG.error(msg);
-            throw new IllegalArgumentException(msg);
-        }
-
-        // We can short-circut the registry lookup if the window state is
-        // one from PLT.9
-        if (JSR168_WINDOW_STATES.contains(new WindowState(state)))
-        {
-            return true;
-        }
-
-        // If the supplied window state isn't a JSR 168 window state,
-        // we look to see if it is a custom window state.
-
-        String appId = PortletWindowConfig.parseContextPath(portletId);
-        String applicationName = appId;
-        PortletApplicationDefinition portletAppDD = null;
-
-        if (portletRegistry == null)
-        {
-            return false;
-        }
-
-        try
-        {
-            portletAppDD = portletRegistry.getPortletApplication(applicationName);
-        }
-        catch (PortletContainerException e)
-        {
-            StringBuffer errMsg = new StringBuffer("Cannot determine supported window " +
-                    "states for portletId [" + portletId + "] and window state [" + state + "].  ");
-            String msg = errMsg.append("Unable to access the Portlet Registry Service.").toString();
-            LOG.error(msg, e);
-        }
-
-        List customWindowStates = portletAppDD.getCustomWindowStates();
-        if (customWindowStates != null)
-        {
-            for (Iterator i = customWindowStates.iterator(); i.hasNext();)
-            {
-                CustomWindowState customState = (CustomWindowState) i.next();
-                if (customState.getWindowState().equals(state))
-                {
-                    return true;
-                }
-            }
-        }
-
-        return false;
-    }
-
-}
+/*
+ * 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.impl.resource;
+
+import org.apache.pluto.container.PortletContainerException;
+import org.apache.pluto.container.driver.PortletRegistryService;
+import org.apache.pluto.container.om.portlet.CustomWindowState;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.Supports;
+import org.apache.pluto.driver.config.DriverConfigurationException;
+import org.apache.pluto.driver.services.portal.PortletWindowConfig;
+import org.apache.pluto.driver.services.portal.PropertyConfigService;
+import org.apache.pluto.driver.services.portal.SupportedWindowStateService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.portlet.WindowState;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+public class SupportedWindowStateServiceImpl implements
+      SupportedWindowStateService {
+
+   /**
+    * Logger *
+    */
+   private static final Logger             LOG                         = LoggerFactory
+                                                                             .getLogger(SupportedWindowStateServiceImpl.class);
+
+   /**
+    * PropertyConfigService is injected by Spring. We use it to obtain the
+    * window states that the portal supports. It is protected only so that the
+    * unit tests have access to the field.
+    */
+   protected final PropertyConfigService   propertyService;
+
+   /**
+    * PortletRegistry is obtained from the PortletContainer on this service's
+    * initialization. It is protected only so that the unit tests have access to
+    * the field.
+    * <p/>
+    * Note that it is an optional container service, but this implmentation
+    * requires it.
+    */
+   protected final PortletRegistryService  portletRegistry;
+
+   /**
+    * Contains String objects of window states supported by the portal (obtained
+    * from PropertyConfigService). It is protected only so that the unit tests
+    * have access to the field.
+    */
+   protected Set<String>                   portalSupportedWindowStates = new HashSet<String>(
+                                                                             3);
+
+   /**
+    * Window States that are specified in PLT.9
+    */
+   protected static final Set<WindowState> JSR168_WINDOW_STATES;
+
+   static {
+      JSR168_WINDOW_STATES = new HashSet<WindowState>(3);
+      JSR168_WINDOW_STATES.add(WindowState.MAXIMIZED);
+      JSR168_WINDOW_STATES.add(WindowState.MINIMIZED);
+      JSR168_WINDOW_STATES.add(WindowState.NORMAL);
+   }
+
+   public SupportedWindowStateServiceImpl(
+         PropertyConfigService propertyService,
+         PortletRegistryService portletRegistry) {
+      this.propertyService = propertyService;
+      this.portletRegistry = portletRegistry;
+      LOG.debug("Initializing SupportedWindowStateService... ");
+
+      portalSupportedWindowStates = propertyService.getSupportedWindowStates();
+      if (LOG.isDebugEnabled()) {
+         StringBuffer msg = new StringBuffer();
+
+         if (portalSupportedWindowStates != null) {
+            msg.append("Portal supports [" + portalSupportedWindowStates.size()
+                  + "] window states.  ");
+            for (Iterator<String> i = portalSupportedWindowStates.iterator(); i
+                  .hasNext();) {
+               msg.append("[" + i.next() + "]");
+               if (i.hasNext()) {
+                  msg.append(", ");
+               }
+            }
+            LOG.debug(msg.toString());
+         }
+      }
+
+      if (portalSupportedWindowStates == null) {
+         final String msg = "Portal supported window states is null!";
+         LOG.error(msg);
+         throw new DriverConfigurationException(msg);
+      }
+      LOG.debug("SupportedWindowStateService initialized.");
+   }
+
+   public boolean isWindowStateSupported(String portletId, String state) {
+      // If the supplied window state is a JSR 168 window state,
+      // we can return immediately
+      if (JSR168_WINDOW_STATES.contains(state)) {
+         return true;
+      }
+
+      // Otherwise we need to check for custom window states
+
+      return isWindowStateSupportedByPortal(state)
+            && isWindowStateSupportedByPortlet(portletId, state);
+   }
+
+   public boolean isWindowStateSupportedByPortal(String state) {
+      return portalSupportedWindowStates.contains(state);
+   }
+
+   public boolean isWindowStateSupportedByPortlet(String portletId, String state) {
+      if (portletId == null || state == null || portletId.trim().equals("")
+            || state.trim().equals("")) {
+         StringBuffer errMsg = new StringBuffer(
+               "Cannot determine supported window " + "states for portletId ["
+                     + portletId + "] and window state [" + state + "].  ");
+         String msg = errMsg.append(
+               "One or both of the arguments is empty or null.").toString();
+         LOG.error(msg);
+         throw new IllegalArgumentException(msg);
+      }
+
+      // We can short-circut the registry lookup if the window state is
+      // one from PLT.9
+      if (JSR168_WINDOW_STATES.contains(new WindowState(state))) {
+         return true;
+      }
+
+      // If the supplied window state isn't a JSR 168 window state,
+      // we look to see if it is a custom window state.
+
+      String appId = PortletWindowConfig.parseContextPath(portletId);
+      String applicationName = appId;
+      PortletApplicationDefinition portletAppDD = null;
+
+      if (portletRegistry == null) {
+         return false;
+      }
+
+      try {
+         portletAppDD = portletRegistry.getPortletApplication(applicationName);
+      } catch (PortletContainerException e) {
+         StringBuffer errMsg = new StringBuffer(
+               "Cannot determine supported window " + "states for portletId ["
+                     + portletId + "] and window state [" + state + "].  ");
+         String msg = errMsg.append(
+               "Unable to access the Portlet Registry Service.").toString();
+         LOG.error(msg, e);
+      }
+
+      List<? extends CustomWindowState> customWindowStates = portletAppDD
+            .getCustomWindowStates();
+      if (customWindowStates != null) {
+         for (Iterator<? extends CustomWindowState> i = customWindowStates
+               .iterator(); i.hasNext();) {
+            CustomWindowState customState = (CustomWindowState) i.next();
+            if (customState.getWindowState().equals(state)) {
+               return true;
+            }
+         }
+      }
+
+      return false;
+   }
+
+   /*
+    * (non-Javadoc)
+    * 
+    * @see org.apache.pluto.driver.services.portal.SupportedWindowStateService#
+    * getSupportedWindowStates(java.lang.String)
+    */
+   public Set<WindowState> getSupportedWindowStates(String portletId, String contentType)
+         throws PortletContainerException {
+      
+      Set<WindowState> wstates = new HashSet<WindowState>();
+      Set<WindowState> cstates = new HashSet<WindowState>();
+      wstates.addAll(JSR168_WINDOW_STATES);
+
+      // Get the custom states for the portlet & portlet app. see if custom states need
+      // to be added
+
+      String appId = PortletWindowConfig.parseContextPath(portletId);
+      String applicationName = appId;
+      PortletApplicationDefinition portletAppDD = null;
+      String portletName = PortletWindowConfig.parsePortletName(portletId);
+
+      if (portletRegistry == null) {
+         return wstates;
+      }
+
+      try {
+
+         portletAppDD = portletRegistry.getPortletApplication(applicationName);
+
+//          // get custom window states defined for portlet app
+//          
+//          List<? extends CustomWindowState> customWindowStates = portletAppDD
+//                .getCustomWindowStates();
+//          for (CustomWindowState cws : customWindowStates) {
+//             cstates.add(new WindowState(cws.getWindowState()));
+//          }
+         
+         // get window states defined for portlet & specified content type
+         
+         for (PortletDefinition pd : portletAppDD.getPortlets()) {
+            if (portletName.equals(pd.getPortletName())) {
+               for (Supports sup : pd.getSupports()) {
+                  if (sup.getMimeType().equals(contentType)) {
+                     for (String ws : sup.getWindowStates()) {
+                        cstates.add(new WindowState(ws));
+                     }
+                  }
+               }
+            }
+         }
+         
+         wstates.addAll(cstates);
+         
+      } catch (PortletContainerException e) { 
+      }
+
+      return wstates;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/59cd72e2/pluto-portal-driver/src/main/java/org/apache/pluto/driver/config/DriverConfiguration.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/config/DriverConfiguration.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/config/DriverConfiguration.java
index 174ec77..aa68321 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/config/DriverConfiguration.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/config/DriverConfiguration.java
@@ -1,108 +1,111 @@
-/*
- * 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.config;
-
-import java.util.Collection;
-import java.util.Set;
-
-import javax.portlet.PortletConfig;
-import javax.portlet.PortletMode;
-
-import org.apache.pluto.container.PortletContainerException;
-import org.apache.pluto.container.PortletPreferencesService;
-import org.apache.pluto.driver.services.portal.PageConfig;
-import org.apache.pluto.driver.services.portal.RenderConfigService;
-import org.apache.pluto.driver.url.PortalURLParser;
-
-/**
- * Interface defining a means for retrieving driver services
- * based upon configuration information. Within the portal,
- * an implementation of this interface should be bound to
- * the portal's ServletContext.
- *
- *
- * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
- * @since Sep 2, 2005
- *
- */
-public interface DriverConfiguration {
-
-//
-// Service / Configuration Methods
-//
-
-    /**
-     * Retrieve the name of the portal
-     * as should be returned in
-     * {@link javax.portlet.PortalContext#getPortalInfo()}
-     * @return the name of the portal.
-     */
-    String getPortalName();
-
-    /**
-     * Retrieve the version of the portal
-     * as should be returned in
-     * {@link javax.portlet.PortalContext#getPortalInfo()}
-     * @return the portal version.
-     */
-    String getPortalVersion();
-
-    /**
-     * Retrieves the name of the container which
-     * pluto should create and embed.
-     * @return the container name.
-     */
-    String getContainerName();
-
-    Collection getSupportedPortletModes();
-
-    Collection getSupportedWindowStates();
-    
-//    Collection getPortletApplications();
-
-    Collection getPages();
-
-    PageConfig getPageConfig(String pageId);
-    
-    boolean isPortletModeSupportedByPortal(String mode);
-    
-    boolean isPortletModeSupportedByPortlet(String portletId, String mode);
-    
-    boolean isPortletModeSupported(String portletId, String mode);
-
-    boolean isWindowStateSupportedByPortal(String windowState);
-
-    boolean isWindowStateSupportedByPortlet(String portletId, String windowState);
-
-    boolean isWindowStateSupported(String portletId, String windowState);
-
-//
-// Utility methods for the container
-//
-    PortletPreferencesService getPortletPreferencesService();
-
-    PortalURLParser getPortalUrlParser();
-    
-    public RenderConfigService getRenderConfigService();
-
-    public Set<PortletMode> getSupportedPortletModes(String portletId) throws PortletContainerException; 
-    
-    public PortletConfig getPortletConfig(String portletId)  throws PortletContainerException;
-
-	public boolean isPortletManagedMode(String portletId, String mode);
-    
-}
+/*
+ * 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.config;
+
+import java.util.Collection;
+import java.util.Set;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+
+import org.apache.pluto.container.PortletContainerException;
+import org.apache.pluto.container.PortletPreferencesService;
+import org.apache.pluto.driver.services.portal.PageConfig;
+import org.apache.pluto.driver.services.portal.RenderConfigService;
+import org.apache.pluto.driver.url.PortalURLParser;
+
+/**
+ * Interface defining a means for retrieving driver services
+ * based upon configuration information. Within the portal,
+ * an implementation of this interface should be bound to
+ * the portal's ServletContext.
+ *
+ *
+ * @author <a href="mailto:ddewolf@apache.org">David H. DeWolf</a>
+ * @since Sep 2, 2005
+ *
+ */
+public interface DriverConfiguration {
+
+//
+// Service / Configuration Methods
+//
+
+    /**
+     * Retrieve the name of the portal
+     * as should be returned in
+     * {@link javax.portlet.PortalContext#getPortalInfo()}
+     * @return the name of the portal.
+     */
+    String getPortalName();
+
+    /**
+     * Retrieve the version of the portal
+     * as should be returned in
+     * {@link javax.portlet.PortalContext#getPortalInfo()}
+     * @return the portal version.
+     */
+    String getPortalVersion();
+
+    /**
+     * Retrieves the name of the container which
+     * pluto should create and embed.
+     * @return the container name.
+     */
+    String getContainerName();
+
+    Collection getSupportedPortletModes();
+
+    Collection getSupportedWindowStates();
+    
+//    Collection getPortletApplications();
+
+    Collection getPages();
+
+    PageConfig getPageConfig(String pageId);
+    
+    boolean isPortletModeSupportedByPortal(String mode);
+    
+    boolean isPortletModeSupportedByPortlet(String portletId, String mode);
+    
+    boolean isPortletModeSupported(String portletId, String mode);
+
+    boolean isWindowStateSupportedByPortal(String windowState);
+
+    boolean isWindowStateSupportedByPortlet(String portletId, String windowState);
+
+    boolean isWindowStateSupported(String portletId, String windowState);
+
+    public Set<WindowState> getSupportedWindowStates(String portletId, String contentType) throws PortletContainerException; 
+
+//
+// Utility methods for the container
+//
+    PortletPreferencesService getPortletPreferencesService();
+
+    PortalURLParser getPortalUrlParser();
+    
+    public RenderConfigService getRenderConfigService();
+
+    public Set<PortletMode> getSupportedPortletModes(String portletId) throws PortletContainerException; 
+    
+    public PortletConfig getPortletConfig(String portletId)  throws PortletContainerException;
+
+	public boolean isPortletManagedMode(String portletId, String mode);
+    
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/59cd72e2/pluto-portal-driver/src/main/java/org/apache/pluto/driver/services/portal/SupportedWindowStateService.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/services/portal/SupportedWindowStateService.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/services/portal/SupportedWindowStateService.java
index b258d60..dd3af9a 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/services/portal/SupportedWindowStateService.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/services/portal/SupportedWindowStateService.java
@@ -1,53 +1,71 @@
-/*
- * 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.portal;
-
-/**
- * Allows clients to see if a particular WindowState is supported by
- * the portal, a particular portlet, or both.
- *
- * @since Feb 27, 2007
- * @version $Id$
- * @see javax.portlet.WindowState
- */
-public interface SupportedWindowStateService {
-
-    /**
-     * Returns true if the portlet and the portal support the supplied
-     * window state.
-     * @param portletId the id uniquely identifying the portlet
-     * @param state the portlet window state
-     * @return true if the portlet and portal both support the supplied window state
-     */
-    boolean isWindowStateSupported( String portletId, String state );
-
-    /**
-     * Returns true if the portal supports the supplied window state.
-     * @param state the portlet window state
-     * @return true if the portal supports the supplied window state
-     */
-    boolean isWindowStateSupportedByPortal( String state );
-
-    /**
-     * Returns true if the portlet supports the supplied window state.
-     * @param portletId the id uniquely identifying the portlet
-     * @param state the window state
-     * @return true if the portlet support the supplied state
-     */
-    boolean isWindowStateSupportedByPortlet( String portletId, String state );
-
-}
+/*
+ * 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.portal;
+
+import java.util.Set;
+
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+
+import org.apache.pluto.container.PortletContainerException;
+
+/**
+ * Allows clients to see if a particular WindowState is supported by
+ * the portal, a particular portlet, or both.
+ *
+ * @since Feb 27, 2007
+ * @version $Id$
+ * @see javax.portlet.WindowState
+ */
+public interface SupportedWindowStateService {
+
+    /**
+     * Returns true if the portlet and the portal support the supplied
+     * window state.
+     * @param portletId the id uniquely identifying the portlet
+     * @param state the portlet window state
+     * @return true if the portlet and portal both support the supplied window state
+     */
+    boolean isWindowStateSupported( String portletId, String state );
+
+    /**
+     * Returns true if the portal supports the supplied window state.
+     * @param state the portlet window state
+     * @return true if the portal supports the supplied window state
+     */
+    boolean isWindowStateSupportedByPortal( String state );
+
+    /**
+     * Returns true if the portlet supports the supplied window state.
+     * @param portletId the id uniquely identifying the portlet
+     * @param state the window state
+     * @return true if the portlet support the supplied state
+     */
+    boolean isWindowStateSupportedByPortlet( String portletId, String state );
+
+    /**
+     * Gets all window states supported by a portlet according to the deployment descriptor. 
+     * in portlet.xml.
+     * 
+     * @param portletId Id of the portlet of interest
+     * @param The content type, in general will be "text/html"
+     * @return all window states supported by a portlet.
+     * @throws PortletContainerException
+      */
+     Set<WindowState> getSupportedWindowStates(String portletId, String contentType) throws PortletContainerException;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/59cd72e2/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index c674a20..25870f8 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -95,6 +95,16 @@ group (the left column) displays portlets with odd IDs, while the second group
                       }
                    } catch (Exception e) {}
                    
+                   StringBuffer wsstring = new StringBuffer();
+                   try {
+                      Set<WindowState> allowedWSs = dc.getSupportedWindowStates(pid, "text/html");
+                      sep = "";
+                      for (WindowState ws : allowedWSs) {
+                         wsstring.append(sep + "'" + ws.toString() + "'");
+                         sep = ", ";
+                      }
+                   } catch (Exception e) {}
+                   
                    String pm = pu.getPortletMode(pid).toString();
                    String ws = pu.getWindowState(pid).toString();
                 %>
@@ -137,7 +147,7 @@ group (the left column) displays portlets with odd IDs, while the second group
                    },
                    'pubParms' : [<%=prpstring.toString()%>],
                    'allowedPM' : [<%=pmstring.toString()%>],
-                   'allowedWS' : ['normal'],
+                   'allowedWS' : [<%=wsstring.toString()%>],
                    'renderData' : {
                       'renderData' : null,
                       'mimeType' : "text/plain"


[14/15] portals-pluto git commit: Added portlet hub demo portlets to pluto build

Posted by ms...@apache.org.
Added portlet hub demo portlets to pluto build


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

Branch: refs/heads/PortletHub
Commit: cdebb5462b4be222909e7f607613a66ec891e9ec
Parents: 9b23599
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Nov 19 15:00:11 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Nov 19 15:00:11 2014 +0100

----------------------------------------------------------------------
 pluto-PortletHubDemo/pom.xml                    |  146 ++
 .../java/basic/portlet/ColorSelPortlet.java     |  140 ++
 .../src/main/java/basic/portlet/Constants.java  |   32 +
 .../java/basic/portlet/ImageSelPortlet.java     |  234 ++++
 .../java/basic/portlet/ResourcePortlet.java     |  202 +++
 .../src/main/webapp/WEB-INF/jsp/view.jsp        |   27 +
 .../src/main/webapp/WEB-INF/portlet.xml         |   77 ++
 .../src/main/webapp/WEB-INF/web.xml             |    4 +
 .../src/main/webapp/resources/css/styles.css    |   16 +
 .../main/webapp/resources/images/FullMoon.gif   |  Bin 0 -> 38190 bytes
 .../webapp/resources/images/baseball-trans.gif  |  Bin 0 -> 8307 bytes
 .../webapp/resources/images/fussball-trans.gif  |  Bin 0 -> 8733 bytes
 .../webapp/resources/images/golfball-trans.gif  |  Bin 0 -> 9359 bytes
 .../org/apache/pluto/driver/util/PageState.java |   40 +-
 .../WEB-INF/themes/pluto-default-theme.jsp      |   81 +-
 pom.xml                                         | 1261 +++++++++---------
 16 files changed, 1538 insertions(+), 722 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/pom.xml b/pluto-PortletHubDemo/pom.xml
new file mode 100644
index 0000000..506726f
--- /dev/null
+++ b/pluto-PortletHubDemo/pom.xml
@@ -0,0 +1,146 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.portals.pluto</groupId>
+        <artifactId>pluto</artifactId>
+        <version>2.1.0-SNAPSHOT</version>
+    </parent>
+
+	<artifactId>PortletHubDemo</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>war</packaging>
+
+	<dependencies>
+		<dependency>
+			<groupId>javax.portlet</groupId>
+			<artifactId>portlet-api</artifactId>
+			<version>2.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<!-- for eclipse JSP tooling purposes -->
+		<dependency>
+			<groupId>javax.servlet.jsp</groupId>
+			<artifactId>jsp-api</artifactId>
+			<version>2.1</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>jstl</artifactId>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.portals.pluto</groupId>
+			<artifactId>pluto-taglib</artifactId>
+			<version>2.1.0-M3</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<finalName>PortletHubDemo</finalName>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.6</source>
+					<target>1.6</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<configuration>
+					<archiveClasses>true</archiveClasses>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<profiles>
+		<profile>
+			<id>pluto</id>
+         <activation>
+           <property>
+             <name>!alwaysActivate</name>
+           </property>
+         </activation>
+    
+			<dependencies>
+                <dependency>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>jstl</artifactId>
+                    <scope>compile</scope>
+                    <exclusions>
+                        <exclusion>
+                            <groupId>javax.servlet</groupId>
+                            <artifactId>jsp-api</artifactId>
+                        </exclusion>
+                    </exclusions>
+                </dependency>
+                <dependency>
+                    <groupId>taglibs</groupId>
+                    <artifactId>standard</artifactId>
+                    <scope>compile</scope>
+                </dependency>
+			</dependencies>
+			
+			<build>
+				<plugins>
+               <plugin>
+                 <artifactId>maven-war-plugin</artifactId>
+                 <configuration>
+                   <webXml>${project.build.directory}/pluto-resources/web.xml</webXml>
+                 </configuration>
+               </plugin>
+               <!-- bind 'pluto:assemble' goal to 'generate-resources' lifecycle -->
+					<plugin>
+						<groupId>org.apache.portals.pluto</groupId>
+						<artifactId>maven-pluto-plugin</artifactId>
+						<version>2.0.3</version>
+						<dependencies>
+							<dependency>
+								<groupId>org.apache.portals.pluto</groupId>
+								<artifactId>pluto-util</artifactId>
+								<version>2.0.3</version>
+								<scope>runtime</scope>
+							</dependency>
+						</dependencies>
+						<executions>
+							<execution>
+								<phase>generate-resources</phase>
+								<goals>
+									<goal>assemble</goal>
+								</goals>
+							</execution>
+						</executions>
+					</plugin>
+               <!-- workaround for war processing of m-r-r-plugin causing the generated NOTICE and LICENSE file to be put under WEB-INF/classes/META-INF -->
+               <plugin>
+                   <groupId>org.apache.maven.plugins</groupId>
+                   <artifactId>maven-remote-resources-plugin</artifactId>
+                   <executions>
+                       <execution>
+                           <goals>
+                               <goal>process</goal>
+                           </goals>
+                           <configuration>
+                               <outputDirectory>${project.build.directory}/${project.build.finalName}</outputDirectory>
+                               <attached>false</attached>
+                           </configuration>
+                       </execution>
+                   </executions>
+               </plugin>
+				</plugins>
+			</build>
+		</profile>
+	</profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java b/pluto-PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
new file mode 100644
index 0000000..eecb659
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
@@ -0,0 +1,140 @@
+/*  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.PARAM_COLOR;
+import static basic.portlet.Constants.PARAM_ERRMSG;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+
+/**
+ * A management portlet that displays the current deep link configuraion
+ */
+public class ColorSelPortlet extends GenericPortlet {
+
+   // Set up logging
+   // private static final String LOG_CLASS = ColorSelPortlet.class.getName();
+   // private final Logger logger = Logger.getLogger(LOG_CLASS);
+
+   protected void doView(RenderRequest req, RenderResponse resp)
+         throws PortletException, IOException {
+
+      
+      resp.setContentType("text/html");
+      PrintWriter writer = resp.getWriter();
+      writer.write("<h3>Image Background Color Selector</h3><hr/>\n");
+      
+      String pid = resp.getNamespace();
+      
+      String clr = req.getParameter(PARAM_COLOR);
+      clr = (clr == null) ? "#FFFFFF" : clr;
+      
+      writer.write("<FORM id='" + pid + "-setParams'  onsubmit='return false;'>");
+      writer.write("   <table><tr><td align='left'>");
+      writer.write("   Enter color (public param):");
+      writer.write("   </td><td>");
+      writer.write("   <input id='" + pid + "-color' name='" + PARAM_COLOR + "' type='text' value='' size='10' maxlength='10'>");
+      writer.write("   </td><td>");
+      writer.write("   <div id='" + pid + "-putMsgHere' style='color: #B00'></div>\n");
+      writer.write("   </td></tr></table>");
+      writer.write("</FORM>");
+      writer.write("<p><hr/></p>\n");
+
+      writer.write("<script>\n");
+      writer.write("(function () {\n");
+      writer.write("   var pid = '" + pid + "',\n");
+      writer.write("       colorEntry = '" + pid + "-color',\n");
+      writer.write("       msgdiv = '" + pid + "-putMsgHere',\n");
+      writer.write("       currState,\n");
+      writer.write("       portletInit;\n");
+
+      writer.write("   var update = function (type, state) {\n");
+      writer.write("      var oldColor = ((currState === undefined) || (currState.parameters.color === undefined)) ? '#FFFFFF' : currState.parameters.color[0];\n");
+      writer.write("      var newColor = (state.parameters.color === undefined) ? '#FFFFFF' : state.parameters.color[0];\n");
+      writer.write("      console.log(\"CSP: state updated. color=\" + newColor);\n");
+      writer.write("      if ((currState === undefined) || (newColor !== oldColor)) {\n");
+      writer.write("         document.getElementById(msgdiv).innerHTML = '';\n");
+      writer.write("         document.getElementById(colorEntry).value = newColor;\n");
+      writer.write("      }\n");
+      writer.write("      currState = state;\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+
+      writer.write("   var handleEntry = function () {\n");
+      writer.write("      var oldColor = ((currState === undefined) || (currState.parameters.color === undefined)) ? '#FFFFFF' : currState.parameters.color[0];\n");
+      writer.write("      var newColor = this.value;\n");
+      writer.write("      console.log(\"CSP: entry field updated. color=\" + newColor);\n");
+      writer.write("      if ((newColor === undefined) || (newColor === null) || !newColor.match(\"^#(?:[A-Fa-f0-9]{3}){1,2}$\")) {\n");
+      writer.write("         document.getElementById(msgdiv).innerHTML = 'Bad color. Enter #xxxxxx or #xxx.';\n");
+      writer.write("      } else {\n");
+      writer.write("         var newState = portletInit.cloneState(currState);\n");
+      writer.write("         newState.parameters.color = [newColor];\n");
+      writer.write("         portletInit.setPortletState(newState);\n");
+      writer.write("      }\n");
+      writer.write("   }\n");
+      writer.write("   document.getElementById(colorEntry).onchange = handleEntry;\n");
+      writer.write("   \n");
+
+      writer.write("   portlet.register(pid).then(function (pi) {\n");
+      writer.write("      console.log(\"CSP Color Selection Portlet: registered: \" + pid);\n");
+      writer.write("      portletInit = pi;\n");
+      writer.write("      portletInit.addEventListener(\"portlet.onStateChange\", update);\n");
+      writer.write("   });\n");
+      writer.write("   \n");
+      writer.write("   \n");
+      writer.write("})();\n");
+      writer.write("</script>\n");
+}
+   
+   /* (non-Javadoc)
+    * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
+    */
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp)
+         throws PortletException, IOException {
+   }
+
+   public void processAction(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+      
+      // pass the action params from the form submission as render parameters
+      resp.setRenderParameter(PARAM_ERRMSG, "");
+      String val = req.getParameter(PARAM_COLOR);
+      if (val != null) {
+         if (val.matches("^#(?:[A-Fa-f0-9]{3}){1,2}$")) {
+            resp.setRenderParameter(PARAM_COLOR, val);
+         } else {
+            resp.setRenderParameter(PARAM_ERRMSG, "bad color. try again.");
+         }
+      } else {
+         resp.setRenderParameter(PARAM_ERRMSG, "enter color #xxxxxx or #xxx.");
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/java/basic/portlet/Constants.java
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/java/basic/portlet/Constants.java b/pluto-PortletHubDemo/src/main/java/basic/portlet/Constants.java
new file mode 100644
index 0000000..367ffc5
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/java/basic/portlet/Constants.java
@@ -0,0 +1,32 @@
+package basic.portlet;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Constants {
+   
+   // maps the names of the images to the paths to the images -
+   public final static Map<String, String> imgMap = new HashMap<String, String>() {
+      private static final long serialVersionUID = 1L;
+   {
+      put("baseball", "/resources/images/baseball-trans.gif");
+      put("golfball", "/resources/images/golfball-trans.gif");
+      put("fussball", "/resources/images/fussball-trans.gif");
+   }};
+
+   public final static String DEFAULT_IMAGE = "/resources/images/FullMoon.gif";
+
+   public final static String PARAM_SELTYPE = "selType";
+   public final static String PARAM_SELTYPE_RADIO = "radio";
+   public final static String PARAM_SELTYPE_DROPDOWN = "dropdown";
+   
+   public final static String PARAM_IMGNAME = "imgName";
+   public final static String PARAM_COLOR = "color";
+   public final static String PARAM_ERRMSG = "errmsg";
+   public final static String PARAM_BORDER = "bo";
+   public final static String PARAM_BORDER_COLOR = "border";
+   public final static String PARAM_CACHE = "ca";
+   public final static String PARAM_CACHE_PAGE = "pa";
+   public final static String PARAM_CACHE_PORTLET = "po";
+   public final static String PARAM_CACHE_FULL = "fu";
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java b/pluto-PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
new file mode 100644
index 0000000..4ed5c7b
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
@@ -0,0 +1,234 @@
+/*  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.PARAM_IMGNAME;
+import static basic.portlet.Constants.PARAM_SELTYPE;
+import static basic.portlet.Constants.PARAM_SELTYPE_RADIO;
+import static basic.portlet.Constants.imgMap;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+
+/**
+ * A management portlet that displays the current deep link configuraion
+ */
+public class ImageSelPortlet extends GenericPortlet {
+
+   // Set up logging
+   private static final String LOG_CLASS = ImageSelPortlet.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");
+      PrintWriter writer = resp.getWriter();
+      writer.write("<h3>Image Selector</h3><hr/>\n");
+      
+      String pid = resp.getNamespace();
+      String selType = req.getParameter(PARAM_SELTYPE);
+      selType = (selType == null) ? PARAM_SELTYPE_RADIO : selType;
+      String imgName = req.getParameter(PARAM_IMGNAME);
+      imgName = (imgName == null) ? "default" : imgName;
+      
+      writer.write("<FORM id='" + pid + "-setParams' onsubmit='return false;'>");
+      writer.write("   <table><tr><td align='left'>");
+      writer.write("   Selection type (private param):");
+      writer.write("   </td><td>");
+      writer.write("   <input id='" + pid + "-radio' type='radio' name='selType' value='radio'>Radio Button");
+      writer.write("   <input id='" + pid + "-dropdown' type='radio' name='selType' value='dropdown'>Drop Down");
+      writer.write("   </td></tr><tr><td>");
+      writer.write("   Select Image (public param):");
+      writer.write("   </td><td>");
+
+      writer.write("   <div id='" + pid + "-putResourceHere'></div>\n");
+
+      writer.write("   </td></tr></table>");
+      writer.write("</FORM>");
+      writer.write("<p><hr/></p>\n");
+
+      writer.write("<script>\n");
+      writer.write("(function () {\n");
+      writer.write("   var pid = '" + pid + "',\n");
+      writer.write("       fid = '" + pid + "-setParams',\n");
+      writer.write("       resdiv = '" + pid + "-putResourceHere',\n");
+      writer.write("       st_radio = '" + pid + "-radio',\n");
+      writer.write("       st_dropdown = '" + pid + "-dropdown',\n");
+      writer.write("       selBox = '" + pid + "-selBox',\n");
+      writer.write("   \n");
+      writer.write("       last_st = 'radio',\n");
+      writer.write("       lastImg = 'default',\n");
+      writer.write("       currState,\n");
+      writer.write("       portletInit;\n");
+      writer.write("   \n");
+      writer.write("   // Set image name PRP if radio button clicked - \n");
+      writer.write("   var handleImgRadio = function () {\n");
+      writer.write("      console.log(\"ISP: image selected (radio): \" + this.value);\n");
+      writer.write("      \n");
+      writer.write("      if (currState.parameters.imgName !== this.value) {\n");
+      writer.write("         var newState = portletInit.cloneState(currState);\n");
+      writer.write("         newState.parameters.imgName = [this.value];\n");
+      writer.write("         portletInit.setPortletState(newState);\n");
+      writer.write("      }\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+      writer.write("   // Set image name PRP if image selected in selection box - \n");
+      writer.write("   var handleImgDropdown = function () {\n");
+      writer.write("      console.log(\"ISP: image selected (dropdown): \" + this.value);\n");
+      writer.write("      \n");
+      writer.write("      if (currState.parameters.imgName !== this.value) {\n");
+      writer.write("         var newState = portletInit.cloneState(currState);\n");
+      writer.write("         newState.parameters.imgName = [this.value];\n");
+      writer.write("         portletInit.setPortletState(newState);\n");
+      writer.write("      }\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+      writer.write("   var update = function (type, state) {\n");
+      writer.write("      var oldST = ((currState === undefined) || (currState.parameters.selType === undefined)) ? undefined : currState.parameters.selType[0];\n");
+      writer.write("      var newST = (state.parameters.selType === undefined) ? undefined : state.parameters.selType[0];\n");
+      writer.write("      var newImg = (state.parameters.imgName === undefined) ? undefined : state.parameters.imgName[0];\n");
+      writer.write("      console.log(\"ISP: state updated. selType=\" + newST + \", imgName=\" + newImg);\n");
+      writer.write("      \n");
+      writer.write("      if ((currState === undefined) || (oldST !== newST)) {");
+      writer.write("         portletInit.createResourceUrl({}).then(function (url) {\n");
+      writer.write("            console.log(\"ISP: got url: \" + url);\n");
+//      writer.write("            document.getElementById(resdiv).innerHTML=\"Waiting for update.\";\n");
+      writer.write("            var xhr = new XMLHttpRequest();\n");
+      writer.write("            xhr.onreadystatechange=function() {\n");
+      writer.write("               if (xhr.readyState==4 && xhr.status==200) {\n");
+      writer.write("                  document.getElementById(resdiv).innerHTML=xhr.responseText;\n");
+
+      writer.write("                  // default is radio buttons\n");
+      writer.write("                  var ii, f = document.getElementById(fid);\n");
+      writer.write("                  if ((newST === undefined) || (newST === 'radio')) {\n");
+      writer.write("                     for (ii=0; ii < f.imgName.length; ii++) {\n");
+      writer.write("                        console.log(\"ISP: adding selection handler for: \" + f.imgName[ii].value);\n");
+      writer.write("                        f.imgName[ii].onclick = handleImgRadio;\n");
+      writer.write("                        if (f.imgName[ii].value === newImg) {\n");
+      writer.write("                           console.log(\"ISP: image clicked: \" + newImg);\n");
+      writer.write("                           f.imgName[ii].clicked = true;\n");
+      writer.write("                        }\n");
+      writer.write("                     }\n");
+      writer.write("                  } else if (newST === 'dropdown') {\n");
+      writer.write("                     console.log(\"ISP: adding selection handler to dropdown list element: \" + selBox);\n");
+      writer.write("                     document.getElementById(selBox).onchange = handleImgDropdown;\n");
+      writer.write("                     for (ii=0; ii < f.imgName.length; ii++) {\n");
+      writer.write("                        if (f.imgName[ii].value === newImg) {\n");
+      writer.write("                           console.log(\"ISP: image selected: \" + newImg);\n");
+      writer.write("                           f.imgName[ii].selected = true;\n");
+      writer.write("                        }\n");
+      writer.write("                     }\n");
+      writer.write("                  }\n");
+
+      writer.write("               }\n");
+      writer.write("            };\n");
+      writer.write("            xhr.open(\"GET\",url,true);\n");
+      writer.write("            xhr.send();\n");
+      writer.write("         });\n");
+      writer.write("      }\n");
+
+      writer.write("      if (newST === 'dropdown') {\n");
+      writer.write("         document.getElementById(st_dropdown).checked = true;\n");
+      writer.write("      } else {\n");
+      writer.write("         document.getElementById(st_radio).checked = true;\n");
+      writer.write("      }\n");
+
+      writer.write("      currState=state;\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+      writer.write("   // set private parameter selType to store the selection display type\n");
+      writer.write("   var handleST = function () {\n");
+      writer.write("      console.log(\"ISP: select display type clicked: \" + this.value);\n");
+      writer.write("      if (currState.parameters.selType !==  this.value) {\n");
+      writer.write("         var newState = portletInit.cloneState(currState);\n");
+      writer.write("         newState.parameters.selType = [this.value];\n");
+      writer.write("         portletInit.setPortletState(newState);\n");
+      writer.write("      }\n");
+      writer.write("   }\n");
+      writer.write("   document.getElementById(st_radio).onclick = handleST;\n");
+      writer.write("   document.getElementById(st_dropdown).onclick = handleST;\n");
+      writer.write("   \n");
+      writer.write("   portlet.register(pid).then(function (pi) {\n");
+      writer.write("      console.log(\"ISP Image Selection Portlet: registered: \" + pid);\n");
+      writer.write("      portletInit = pi;\n");
+      writer.write("      portletInit.addEventListener(\"portlet.onStateChange\", update);\n");
+      writer.write("   });\n");
+      writer.write("   \n");
+      writer.write("   \n");
+      writer.write("})();\n");
+      writer.write("</script>\n");
+
+   }
+   
+   /* (non-Javadoc)
+    * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
+    */
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp)
+         throws PortletException, IOException {
+
+	      resp.setContentType("text/html");
+	      PrintWriter writer = resp.getWriter();
+
+	      String pid = resp.getNamespace();
+	      Set<String> names = imgMap.keySet();
+	      String selType = req.getParameter(PARAM_SELTYPE);
+	      selType = (selType == null) ? PARAM_SELTYPE_RADIO : selType;
+	      String imgName = req.getParameter(PARAM_IMGNAME);
+	      imgName = (imgName == null) ? "default" : imgName;
+
+	      if (selType.equals(PARAM_SELTYPE_RADIO)) {
+	         for (String name : names) {
+	            writer.write("   <input type='radio' name='" + PARAM_IMGNAME + "' value='" + 
+	               name + "'" + (name.equals(imgName) ? "checked" : "") + ">" + name);
+	         }
+	      } else {
+	         writer.write("<select id='" + pid + "-selBox' name='" + PARAM_IMGNAME + "' size='1'>");
+	         writer.write("   <option value='default' " + 
+	               ("default".equals(imgName) ? "selected" : "") + ">-</option>");
+	         for (String name : names) {
+	            writer.write("   <option value='" + name + "'" + 
+	               (name.equals(imgName) ? "selected" : "") + ">" + name + "</option>");
+	         }
+	         writer.write("</select>");
+	      }
+	}
+
+   public void processAction(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java b/pluto-PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
new file mode 100644
index 0000000..e9bcf63
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
@@ -0,0 +1,202 @@
+/*  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.PARAM_BORDER_COLOR;
+import static basic.portlet.Constants.PARAM_COLOR;
+import static basic.portlet.Constants.PARAM_IMGNAME;
+import static basic.portlet.Constants.imgMap;
+import static basic.portlet.Constants.DEFAULT_IMAGE;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+
+/**
+ * A management portlet that displays the current deep link configuraion
+ */
+public class ResourcePortlet extends GenericPortlet {
+
+   // Set up logging
+   private static final String LOG_CLASS = ResourcePortlet.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");
+      PrintWriter writer = resp.getWriter();
+
+      String pid = resp.getNamespace();
+
+      writer.write("<div style='clear:both;'>\n");
+      writer.write("<div style='float:left;'><h3>Image Viewer</h3></div>\n");
+      writer.write("<div id=" + pid + "-counter style='float:right; font-size:250%; color:#0B0;'>1</div>\n");
+      writer.write("</div><div style='clear:both;'><hr/>\n");
+      
+      writer.write("<FORM id='" + pid + "-setParams'  onsubmit='return false;'>");
+      writer.write("   <table><tr><td align='left'>");
+      writer.write("   Cacheability setting:");
+      writer.write("   </td><td>");
+      writer.write("   <input id='" + pid + "-page' type='radio' name='cacheability' value='cacheLevelPage'>Page");
+      writer.write("   <input id='" + pid + "-portlet' type='radio' name='cacheability' value='cacheLevelPortlet'>Portlet");
+      writer.write("   <input id='" + pid + "-full' type='radio' name='cacheability' value='cacheLevelFull'>Full");
+      writer.write("   </td></tr><tr><td>");
+      writer.write("   Set border (resource parameter)");
+      writer.write("   </td><td>");
+      writer.write("   <input id='" + pid + "-border' type='checkbox' name='border' value='border'>");
+      writer.write("   </td></tr></table>");
+      writer.write("</FORM><hr/>");
+
+      writer.write("<div id='" + pid + "-putResourceHere'></div>\n");
+      
+      writer.write("<script>\n");
+      writer.write("(function () {\n");
+      writer.write("   var pid = '" + pid + "',\n");
+      writer.write("       resdiv = '" + pid + "-putResourceHere',\n");
+      writer.write("       border = '" + pid + "-border',\n");
+      writer.write("       ca_page = '" + pid + "-page',\n");
+      writer.write("       ca_portlet = '" + pid + "-portlet',\n");
+      writer.write("       ca_full = '" + pid + "-full',\n");
+      writer.write("   \n");
+      writer.write("       state,\n");
+      writer.write("       resparms = {},\n");
+      writer.write("       cacheability = 'cacheLevelPage',\n");
+      writer.write("       portletInit;\n");
+      writer.write("   \n");
+      writer.write("   var update = function (type, state) {\n");
+      writer.write("      console.log(\"Resource Portlet: state updated.\");\n");
+      writer.write("      \n");
+      writer.write("      portletInit.createResourceUrl(resparms, cacheability).then(function (url) {\n");
+      writer.write("         var brdr = (resparms.border == undefined) ? undefined : resparms.border[0];\n");
+      writer.write("         console.log(\"Resource Portlet: got url: \" + url + \", res parm border=\" + brdr);\n");
+//      writer.write("         document.getElementById(resdiv).innerHTML=\"Waiting for update.\";\n");
+      writer.write("         var xhr = new XMLHttpRequest();\n");
+      writer.write("         xhr.onreadystatechange=function() {\n");
+      writer.write("            if (xhr.readyState==4 && xhr.status==200) {\n");
+      writer.write("               document.getElementById(resdiv).innerHTML=xhr.responseText;\n");
+      writer.write("            }\n");
+      writer.write("         };\n");
+      writer.write("         xhr.open(\"GET\",url,true);\n");
+      writer.write("         xhr.send();\n");
+      writer.write("      });\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+      writer.write("   document.getElementById(border).checked = false;\n");
+      writer.write("   document.getElementById(border).onclick = function () {\n");
+      writer.write("      console.log(\"border checked: \" + this.checked);\n");
+      writer.write("      if (this.checked) {\n");
+      writer.write("         resparms.border = ['#00F'];\n");
+      writer.write("      } else {\n");
+      writer.write("         resparms = {};\n");
+      writer.write("      }\n");
+      writer.write("      update();\n");
+      writer.write("   }\n");
+      writer.write("   \n");
+      writer.write("   document.getElementById(ca_page).checked = true;\n");
+      writer.write("   var handleCA = function () {\n");
+      writer.write("      console.log(\"cacheability button clicked: \" + this.value);\n");
+      writer.write("      if (cacheability !== this.value) {\n");
+      writer.write("         cacheability = this.value;\n");
+      writer.write("         update();\n");
+      writer.write("      }\n");
+      writer.write("   }\n");
+      writer.write("   document.getElementById(ca_page).onclick = handleCA;\n");
+      writer.write("   document.getElementById(ca_portlet).onclick = handleCA;\n");
+      writer.write("   document.getElementById(ca_full).onclick = handleCA;\n");
+      writer.write("   \n");
+      writer.write("   portlet.register(pid).then(function (pi) {\n");
+      writer.write("      console.log(\"registered: \" + pid);\n");
+      writer.write("      portletInit = pi;\n");
+      writer.write("      portletInit.addEventListener(\"portlet.onStateChange\", update);\n");
+      writer.write("   });\n");
+      writer.write("   \n");
+      writer.write("   var cntrId = '" + pid + "-counter', cntr = 1;\n");
+      writer.write("   window.setInterval(function () {\n");
+      writer.write("      document.getElementById(cntrId).innerHTML = ++cntr;\n");
+      writer.write("   }, 1000);\n");
+      writer.write("   \n");
+      writer.write("})();\n");
+      writer.write("</script>\n");
+
+      writer.write("<p><hr/></p></div>\n");
+
+   }
+   
+   /* (non-Javadoc)
+    * @see javax.portlet.GenericPortlet#serveResource(javax.portlet.ResourceRequest, javax.portlet.ResourceResponse)
+    */
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp)
+         throws PortletException, IOException {
+
+      String key = req.getParameter(PARAM_IMGNAME);
+      String imgDir = DEFAULT_IMAGE;
+      if ((key != null) && imgMap.containsKey(key)) {
+         imgDir = imgMap.get(key);
+      }
+      
+      String bc = req.getParameter(PARAM_BORDER_COLOR);
+      String imgStyle = "";
+      if (bc != null) {
+         imgStyle = " style='border:1px solid " + bc + ";' ";
+      }
+      
+      String ctx = req.getContextPath();
+      String ca = req.getCacheability();
+      
+      resp.setContentType("text/html");
+      PrintWriter writer = resp.getWriter();
+      
+      String clr = req.getParameter(PARAM_COLOR);
+      clr = (clr == null) ? "#FFFFFF" : clr;
+
+      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("   </td></tr>");
+      writer.write("   </table>");
+      writer.write("</div>\n");
+
+
+   }
+
+   public void processAction(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/WEB-INF/jsp/view.jsp
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/WEB-INF/jsp/view.jsp b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/jsp/view.jsp
new file mode 100644
index 0000000..b0ba96c
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/jsp/view.jsp
@@ -0,0 +1,27 @@
+<%@ 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 />
+
+<H3>PRP Resource Portlet</H3>
+<P>Sample Resource Portlet application that demonstrates image loading based on a public render parameter.</P>
+
+<!-- Display a button that causes some parameters to be set -->
+<FORM METHOD="POST" ACTION="<portlet:actionURL/>">
+	<INPUT NAME='action' VALUE='setParms' TYPE="hidden">
+    <INPUT VALUE="Set Parameters" CLASS="portlet-form-button" TYPE="submit">
+</FORM>
+
+<!-- Display the parameters for the portlet -->
+<P>Parameters:</P>
+<UL>
+<c:forEach var="name" items="${renderRequest.getParameterNames()}">
+   <c:forEach var="value" items="${renderRequest.getParameterValues(name)}">
+      <LI>
+         Name: ${name}, Val: ${value}
+      </LI>
+   </c:forEach>
+</c:forEach>
+</UL>
+

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
new file mode 100644
index 0000000..4f8379a
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
@@ -0,0 +1,77 @@
+<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" 
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+		     xmlns:rp="http://www.ibm.com/xmlns/prod/websphere/portal/publicparams/ResourcePortlet"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" 
+             version="2.0"
+    		id="ph.resource.portlet">
+   <portlet>
+      <portlet-name>PH-ResourcePortlet-PRP</portlet-name>
+      <display-name>PH Resource Portlet</display-name>
+      
+      <portlet-class>basic.portlet.ResourcePortlet</portlet-class>
+
+      <supports>
+         <mime-type>text/html</mime-type>
+         <portlet-mode>VIEW</portlet-mode>
+      </supports>
+
+      <supported-locale>en</supported-locale>        
+
+      <portlet-info>
+         <title>PH Resource Portlet</title>
+      </portlet-info>
+
+      <supported-public-render-parameter>imgName</supported-public-render-parameter>
+      <supported-public-render-parameter>color</supported-public-render-parameter>
+   </portlet>
+
+   <portlet>
+      <portlet-name>PH-ImageSelPortlet</portlet-name>
+      <display-name>PH Image Selection Portlet</display-name>
+      
+      <portlet-class>basic.portlet.ImageSelPortlet</portlet-class>
+
+      <supports>
+         <mime-type>text/html</mime-type>
+         <portlet-mode>VIEW</portlet-mode>
+      </supports>
+
+      <supported-locale>en</supported-locale>        
+
+      <portlet-info>
+         <title>PH Image Selection Portlet</title>
+      </portlet-info>
+
+      <supported-public-render-parameter>imgName</supported-public-render-parameter>
+   </portlet>
+
+   <portlet>
+      <portlet-name>PH-ColorSelPortlet</portlet-name>
+      <display-name>PH Color Selection Portlet</display-name>
+      
+      <portlet-class>basic.portlet.ColorSelPortlet</portlet-class>
+
+      <supports>
+         <mime-type>text/html</mime-type>
+         <portlet-mode>VIEW</portlet-mode>
+         <portlet-mode>HELP</portlet-mode>
+      </supports>
+
+      <supported-locale>en</supported-locale>        
+
+      <portlet-info>
+         <title>PH Color Selection Portlet</title>
+      </portlet-info>
+
+      <supported-public-render-parameter>color</supported-public-render-parameter>
+   </portlet>
+   
+   <public-render-parameter>
+      <identifier>imgName</identifier>
+      <qname>rp:ph-imgName</qname>
+   </public-render-parameter>
+   <public-render-parameter>
+      <identifier>color</identifier>
+      <qname>rp:ph-color</qname>
+   </public-render-parameter>
+ </portlet-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/WEB-INF/web.xml b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..5cf9329
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+	<display-name>PRP Resource Portlet</display-name>
+</web-app>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/resources/css/styles.css
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/resources/css/styles.css b/pluto-PortletHubDemo/src/main/webapp/resources/css/styles.css
new file mode 100644
index 0000000..9029874
--- /dev/null
+++ b/pluto-PortletHubDemo/src/main/webapp/resources/css/styles.css
@@ -0,0 +1,16 @@
+.emphasis {
+   font-style: italic;
+   font-size: 1.3em;
+}
+
+.basicJSFApp {
+   padding: 5px;
+   background-color: #DDFFDD;
+   border: thin solid #66DD66;
+}
+
+.infoBox {
+   padding: 5px;
+   background-color: #DDDDFF;
+   border: thin solid #6666DD;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/resources/images/FullMoon.gif
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/resources/images/FullMoon.gif b/pluto-PortletHubDemo/src/main/webapp/resources/images/FullMoon.gif
new file mode 100644
index 0000000..a85ee1a
Binary files /dev/null and b/pluto-PortletHubDemo/src/main/webapp/resources/images/FullMoon.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/resources/images/baseball-trans.gif
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/resources/images/baseball-trans.gif b/pluto-PortletHubDemo/src/main/webapp/resources/images/baseball-trans.gif
new file mode 100644
index 0000000..31c2100
Binary files /dev/null and b/pluto-PortletHubDemo/src/main/webapp/resources/images/baseball-trans.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/resources/images/fussball-trans.gif
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/resources/images/fussball-trans.gif b/pluto-PortletHubDemo/src/main/webapp/resources/images/fussball-trans.gif
new file mode 100644
index 0000000..97bde92
Binary files /dev/null and b/pluto-PortletHubDemo/src/main/webapp/resources/images/fussball-trans.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-PortletHubDemo/src/main/webapp/resources/images/golfball-trans.gif
----------------------------------------------------------------------
diff --git a/pluto-PortletHubDemo/src/main/webapp/resources/images/golfball-trans.gif b/pluto-PortletHubDemo/src/main/webapp/resources/images/golfball-trans.gif
new file mode 100644
index 0000000..4ec86ce
Binary files /dev/null and b/pluto-PortletHubDemo/src/main/webapp/resources/images/golfball-trans.gif differ

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
index 6403de7..61708f2 100644
--- a/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
+++ b/pluto-portal-driver-impl/src/main/java/org/apache/pluto/driver/util/PageState.java
@@ -236,17 +236,23 @@ public class PageState {
       return ub.toString();
    }
    
+   /**
+    * Returns the page state needed by the portlet hub as a JSON string suitable
+    * for transport to the client.
+    * 
+    * @return  JSON string representing the current page state
+    */
    public String toJSONString() {
       StringBuffer json = new StringBuffer(1024);
-      json.append("{");
+      json.append("{\n");
       
       Collection<PortalURLParameter> pups = getParameters();
       Map<String, String[]> pubparms = getPublicParameters();
       
       for (String pid : getPortletIds()) {
-         json.append("   '" + getNameSpace(pid) + "' : {");
-         json.append("      'state' : {");
-         json.append("         'parameters' : {");
+         json.append("   '" + getNameSpace(pid) + "' : {\n");
+         json.append("      'state' : {\n");
+         json.append("         'parameters' : {\n");
 
          // Add the portlet parameters
          String c1 = "            '";
@@ -279,19 +285,19 @@ public class PageState {
             }
          }
 
-         json.append("         }, ");
-         json.append("         'portletMode' : '" + getPortletMode(pid) + "', ");
-         json.append("         'windowState' : '" + getWindowState(pid) + "'");
-         json.append("      },");
-         json.append("      'pubParms' : [" + getPRPNamesAsString(pid) + "],");
-         json.append("      'allowedPM' : [" + getPortletModesAsString(pid) + "],");
-         json.append("      'allowedWS' : [" + getWindowStatesAsString(pid) + "],");
-         json.append("      'renderData' : {");
-         json.append("         'renderData' : null,");
-         json.append("         'mimeType' : \"text/plain\"");
-         json.append("      },");
-         json.append("      'urlpid' : '" + pid + "'");
-         json.append("   },");
+         json.append("         }, \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("      },\n");
+         json.append("      'urlpid' : '" + pid + "'\n");
+         json.append("   },\n");
       }
       
       json.append("}");

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index 6972a29..9be7243 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -46,87 +46,16 @@ group (the left column) displays portlets with odd IDs, while the second group
        /**
         * Initialization code for portlet hub
         */
+       <%
+          PageState ps = new PageState(request);
+       %>
        var portlet = portlet || {};
        portlet.impl = portlet.impl || {};
        portlet.impl.getInitData = function () {
-          return {       
-             <%
-                PageState ps = new PageState(request);
-                Collection<String> poids = ps.getPortletIds();
-             
-                Collection<PortalURLParameter> pups = ps.getParameters();
-                Map<String, String[]> pubparms = ps.getPublicParameters();
-             %>
-             <c:forEach var="pid" items="${currentPage.portletIds}">
-                <%
-                   String pid = (String)pageContext.getAttribute("pid");
-                   
-                   String ns = ps.getNameSpace(pid);
-
-                   String prpstring = ps.getPRPNamesAsString(pid);
-                   Set<String> prpnames = ps.getPRPNames(pid);
-                   
-                   String pmstring = ps.getPortletModesAsString(pid);
-                   
-                   String wsstring = ps.getWindowStatesAsString(pid);
-                   
-                   String pm = ps.getPortletMode(pid);
-                   String ws = ps.getWindowState(pid);
-                %>
-                '<%=ns%>' : {
-                   'state' : {
-                      'parameters' : {
-                      <%
-                         String c1 = "";
-                         for (PortalURLParameter pup : pups){
-                            if (pup.getWindowId().equals(pid)){
-                               out.write(c1 + "   '" + pup.getName() + "' : [");
-                               String c2 = "";
-                               for (String val : pup.getValues()) {
-                                  out.write(c2 + " '" + val + "'");
-                                  c2 = ", ";
-                               }
-                               out.write("]");
-                               c1 = ",\n                      ";
-                            }
-                         }
-                         
-                         // Add the public render parameter values for this portlet
-                         
-                         for (String prp : pubparms.keySet()) {
-                            if (prpnames.contains(prp)) {
-                               out.write(c1 + "   '" + prp + "' : [");
-                               String c2 = "";
-                               for (String val : (String[])pubparms.get(prp)) {
-                                  out.write(c2 + " '" + val + "'");
-                                  c2 = ",";
-                               }
-                               out.write("]");
-                               c1 = ",\n                      ";
-                            }
-                         }
-                      %>
-                      }, 
-                      'portletMode' : '<%=pm%>', 
-                      'windowState' : '<%=ws%>'
-                   },
-                   'pubParms' : [<%=prpstring%>],
-                   'allowedPM' : [<%=pmstring%>],
-                   'allowedWS' : [<%=wsstring%>],
-                   'renderData' : {
-                      'renderData' : null,
-                      'mimeType' : "text/plain"
-                   },
-                   'urlpid' : '<%=pid%>'
-                },
-             </c:forEach>
-          }
+          return <%=ps.toJSONString()%>;
        }
-       <%
-          String urlBase = response.encodeURL(ps.getUrlBase());
-       %>
        portlet.impl.getUrlBase = function () {
-          return '<%=urlBase%>';
+          return '<%=response.encodeURL(ps.getUrlBase())%>';
        }
     </script>
     <script type="text/javascript" src="<c:out value="${pageContext.request.contextPath}"/>/pluto.js"></script>


[09/15] portals-pluto git commit: More work on portlet hub initialization. Added the configured public render parameters to the output.

Posted by ms...@apache.org.
More work on portlet hub initialization. Added the configured public render parameters to the output.


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

Branch: refs/heads/PortletHub
Commit: fa52b5a519452b27be2c938f08e9af8e419b4fca
Parents: bc34e25
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Nov 17 16:34:42 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Nov 17 16:34:42 2014 +0100

----------------------------------------------------------------------
 .../WEB-INF/themes/pluto-default-theme.jsp      | 54 ++++++++++++--------
 1 file changed, 34 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fa52b5a5/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
----------------------------------------------------------------------
diff --git a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
index 2ddea41..fb4c9c4 100644
--- a/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
+++ b/pluto-portal/src/main/webapp/WEB-INF/themes/pluto-default-theme.jsp
@@ -21,6 +21,8 @@ limitations under the License.
 <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
 <%@ taglib uri="http://portals.apache.org/pluto" prefix="pluto" %>
 <%@ page import="java.util.*,javax.portlet.*,org.apache.pluto.driver.url.*" %>
+<%@ page import="org.apache.pluto.driver.config.*,org.apache.pluto.driver.*" %>
+<%@ page import="org.apache.pluto.container.*,javax.servlet.jsp.*" %>
 <% pageContext.setAttribute("now", new java.util.Date()); %>
 
 <!--
@@ -51,14 +53,9 @@ group (the left column) displays portlets with odd IDs, while the second group
                 PortalRequestContext prc = PortalRequestContext.getContext(request);
                 PortalURL pu = prc.getRequestedPortalURL(); 
                 Collection<PortalURLParameter> pups = pu.getParameters();
-                // on the URL at least, prps are not differentiated by portlet ID
-                Map<String, String[]> prps = pu.getPublicParameters();
-                StringBuffer prpnames = new StringBuffer();
-                String c0 = "";
-                for (String prp : prps.keySet()) {
-                   prpnames.append(c0 + "'" + prp + "'");
-                   c0 = ", ";
-                }
+                Map<String, String[]> pubparms = pu.getPublicParameters();
+                DriverConfiguration dc = (DriverConfiguration) prc.getServletContext()
+                      .getAttribute(AttributeKeys.DRIVER_CONFIG);
              %>
              <c:forEach var="pid" items="${currentPage.portletIds}">
                 <%
@@ -72,6 +69,21 @@ group (the left column) displays portlets with odd IDs, while the second group
                       }
                    }
                    ns.append("_");
+
+                   PortletConfig pc = null;
+                   StringBuffer prpstring = new StringBuffer();
+                   Set<String> prpnames = new HashSet<String>();
+                   String sep = "";
+                   try {
+                      pc = dc.getPortletConfig(pid);
+                      Enumeration<String> prps = pc.getPublicRenderParameterNames();
+                      while (prps.hasMoreElements()) {
+                         String prp = prps.nextElement();
+                         prpnames.add(prp);
+                         prpstring.append(sep + "'" + prp + "'");
+                         sep = ", ";
+                      }
+                   } catch (Exception e) {}
                    
                    String pm = pu.getPortletMode(pid).toString();
                    String ws = pu.getWindowState(pid).toString();
@@ -93,25 +105,27 @@ group (the left column) displays portlets with odd IDs, while the second group
                                c1 = ",\n                      ";
                             }
                          }
-                         // this is a hack, but just add all public parms for all portlets on page
-                         for (String prp : prps.keySet()) {
-                            out.write(c1 + "   '" + prp + "' : [");
-                            String c2 = "";
-                            for (String val : (String[])prps.get(prp)) {
-                               out.write(c2 + " '" + val + "'");
-                               c2 = ",";
+                         
+                         // Add the public render parameter values for this portlet
+                         
+                         for (String prp : pubparms.keySet()) {
+                            if (prpnames.contains(prp)) {
+                               out.write(c1 + "   '" + prp + "' : [");
+                               String c2 = "";
+                               for (String val : (String[])pubparms.get(prp)) {
+                                  out.write(c2 + " '" + val + "'");
+                                  c2 = ",";
+                               }
+                               out.write("]");
+                               c1 = ",\n                      ";
                             }
-                            out.write("]");
-                            c1 = ",\n                      ";
-                            
                          }
                       %>
                       }, 
                       'portletMode' : '<%=pm%>', 
                       'windowState' : '<%=ws%>'
                    },
-                   // 'pubParms' : [<%=prpnames.toString()%>],
-                   'pubParms' : ['imgName', 'color'],
+                   'pubParms' : [<%=prpstring.toString()%>],
                    'allowedPM' : ['view'],
                    'allowedWS' : ['normal'],
                    'renderData' : {


[06/15] portals-pluto git commit: Merge branch 'PortletHub' of j:\git\pluto-git into PortletHub

Posted by ms...@apache.org.
Merge branch 'PortletHub' of j:\git\pluto-git into PortletHub


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

Branch: refs/heads/PortletHub
Commit: de9b04ecd06ca6f79024d9bb11b76a2356a68d29
Parents: 210f7bc e449363
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Nov 11 22:08:58 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Nov 11 22:08:58 2014 +0100

----------------------------------------------------------------------
 .../WEB-INF/themes/pluto-default-theme.jsp      |  72 +++++-
 pluto-portal/src/main/webapp/portletHubImpl.js  | 224 +++++++++++++------
 2 files changed, 218 insertions(+), 78 deletions(-)
----------------------------------------------------------------------



[04/15] portals-pluto git commit: Merge branch 'PortletHub' of j:\git\pluto-git into PortletHub

Posted by ms...@apache.org.
Merge branch 'PortletHub' of j:\git\pluto-git into PortletHub


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

Branch: refs/heads/PortletHub
Commit: 210f7bce78a9dbf3fecf747e72f89ca67035cea6
Parents: 2b4c559 1eeac9c
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Nov 10 19:22:17 2014 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Nov 10 19:22:17 2014 +0100

----------------------------------------------------------------------
 .../WEB-INF/themes/pluto-default-theme.jsp      |  265 +--
 pluto-portal/src/main/webapp/portlet.js         | 1685 ++++++++++++++++++
 pluto-portal/src/main/webapp/portletHubImpl.js  |  645 +++++++
 3 files changed, 2483 insertions(+), 112 deletions(-)
----------------------------------------------------------------------



[13/15] portals-pluto git commit: Added portlet hub demo portlets to pluto build

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/cdebb546/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8d504df..fcab70e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,629 +1,632 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  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.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-  <parent>
-    <groupId>org.apache.portals</groupId>
-    <artifactId>portals-pom</artifactId>
-    <version>1.3</version>
-  </parent>
-
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.apache.portals.pluto</groupId>
-  <artifactId>pluto</artifactId>
-  <packaging>pom</packaging>
-  <name>Apache Pluto</name>
-  <!--
- Any version changes need to be changed in:
- 1. All poms of children modules
- 2. pluto.container.version.minor property in environment.properties in
- pluto-container module (src/main/resources/org/apache/pluto).
- 3. portal-version element in pluto-portal-driver-config.xml in pluto-portal module
- (src/main/webapp/WEB-INF)
- 4. expected.serverInfo and expected.portalInfo properties in expectedResults.properties
- in testsuite module (src/main/webapp/WEB-INF/classes)
- 5. pluto.version in Ant build file dist-build.xml.
-  -->
-  <version>2.1.0-SNAPSHOT</version>
-  <!-- Due to a bug in maven 2.0, the description must not contain any line breaks or tabs. -->
-  <description>Apache Pluto is the Reference Implementation of the Java Portlet Specification.</description>
-  <url>http://portals.apache.org/pluto</url>
-
-  <issueManagement>
-    <system>jira</system>
-    <url>http://issues.apache.org/jira/secure/BrowseProject.jspa?id=10560</url>
-  </issueManagement>
-  <inceptionYear>2003</inceptionYear>
-
-
-  <!-- Mailing Lists ======================================================= -->
-
-  <mailingLists>
-    <mailingList>
-      <name>Pluto User List</name>
-      <subscribe>pluto-user-subscribe@portals.apache.org</subscribe>
-      <unsubscribe>pluto-user-unsubscribe@portals.apache.org</unsubscribe>
-      <post>pluto-user@portals.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-user</archive>
-    </mailingList>
-    <mailingList>
-      <name>Pluto Developer List</name>
-      <subscribe>pluto-dev-subscribe@portals.apache.org</subscribe>
-      <unsubscribe>pluto-dev-unsubscribe@portals.apache.org</unsubscribe>
-      <post>pluto-dev@portals.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-dev</archive>
-    </mailingList>
-    <mailingList>
-      <name>Pluto SCM List</name>
-      <subscribe>pluto-scm-subscribe@portals.apache.org</subscribe>
-      <unsubscribe>pluto-scm-unsubscribe@portals.apache.org</unsubscribe>
-      <post>pluto-scm@portals.apache.org</post>
-      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-scm</archive>
-    </mailingList>
-  </mailingLists>
-
-
-  <!-- Pluto Committers ==================================================== -->
-
-  <!-- Email format: [name]#a@T#[domain].d0t.[extension]
-'@' and '.' characters are added because m2 seems to need them to
-generate mailto links. -->
-
-  <developers>
-
-    <developer>
-      <name>Michael Blum</name>
-      <id>blumm</id>
-      <email>blumm#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>Carsten Ziegeler</name>
-      <id>cziegeler</id>
-      <email>cziegeler#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>David DeWolf</name>
-      <id>ddewolf</id>
-      <email>ddewolf@apache.org</email>
-      <timezone>-4</timezone>
-      <url>http://www.daviddewolf.com</url>
-      <organization>Three Pillar Software, Inc.</organization>
-      <organizationUrl>http://www.threepillarsoftware.com</organizationUrl>
-      <roles>
-        <role>Java Developer</role>
-      </roles>
-    </developer>
-
-    <developer>
-      <name>Scott Nicklous</name>
-      <id>msnicklous</id>
-      <email>msnicklous#a@T#apache.d0t.org</email>
-      <timezone>+1</timezone>
-      <organization>IBM Corporation</organization>
-      <organizationUrl>http://www.ibm.com</organizationUrl>
-      <roles>
-        <role>Specification Lead, JSR 362 Portlet Specification 3.0</role>
-        <role>Java Developer</role>
-      </roles>
-    </developer>
-
-    <developer>
-      <name>Nick Lothian</name>
-      <id>nlothian</id>
-      <email>nlothian#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>Craig Doremus</name>
-      <id>cdoremus</id>
-      <email>cdoremus#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>Zhong Zheng</name>
-      <id>zheng</id>
-      <email>zheng#a@T#apache.d0t.org</email>
-      <timezone>+1</timezone>
-      <organization />
-      <roles>
-        <role>Java Developer</role>
-      </roles>
-    </developer>
-
-    <developer>
-      <name>Santiago Gala</name>
-      <id>sgala</id>
-      <email>sgala#a@T#hisitech.d0t.com</email>
-      <organization />
-    </developer>
-
-    <developer>
-      <name>Raphael Luta</name>
-      <id>raphael</id>
-      <email>raphael#a@T#apache.d0t.org</email>
-      <organization />
-    </developer>
-
-    <developer>
-      <name>David S. Taylor</name>
-      <id>taylor</id>
-      <email>david#a@T#bluesunrise.d0t.com</email>
-      <organization />
-    </developer>
-
-    <developer>
-      <name>Scott T. Weaver</name>
-      <id>weaver</id>
-      <email>weaver#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>Stefan Hepper</name>
-      <id>sthepper</id>
-      <email>sthepper#a@T#apache.d0t.org</email>
-    </developer>
-
-    <developer>
-      <name>Elliot Metsger</name>
-      <id>esm</id>
-      <email>esm#a@T#apache.d0t.org</email>
-      <timezone>-4</timezone>
-      <url>http://uppertank.net/blog</url>
-      <organization>Johns Hopkins University, Sheridan Libraries</organization>
-      <organizationUrl>http://www.library.jhu.edu</organizationUrl>
-    </developer>
-
-    <developer>
-      <name>Ate Douma</name>
-      <id>ate</id>
-      <email>ate#aT#apache.d0t.org</email>
-      <timezone>+2</timezone>
-      <organization>Hippo</organization>
-      <organizationUrl>http://www.onehippo.com</organizationUrl>
-      <roles>
-        <role>Java Developer</role>
-      </roles>
-    </developer>
-
-    <developer>
-      <name>David Jencks</name>
-      <id>djencks</id>
-      <email>djencks#aT#apache.d0t.org</email>
-      <timezone>-7</timezone>
-    </developer>
-
-  </developers>
-
-
-  <!-- Pluto Contributors ================================================== -->
-
-  <contributors>
-    <contributor>
-      <name>Michael Westbay</name>
-      <email>westbay#a@T#users.d0t.sourceforge.d0t.net</email>
-    </contributor>
-    <contributor>
-      <name>Ken Weiner</name>
-      <email>kweiner#a@T#unicon.d0t.net</email>
-    </contributor>
-    <contributor>
-      <name>Ken Atherton</name>
-      <email>katherto#a@T#visa.d0t.com</email>
-    </contributor>
-    <contributor>
-      <name>David Hay</name>
-    </contributor>
-
-    <contributor>
-
-    </contributor>
-  </contributors>
-
-  <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/portals/pluto/trunk</connection>
-    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/portals/pluto/trunk</developerConnection>
-    <url>http://svn.apache.org/viewcvs.cgi/portals/pluto/trunk</url>
-  </scm>
-
-  <!-- Dependency Version Properties ======================================= -->
-
-  <!--
-  NOTE:
-
-  Modification of these properties affects:
-  1)  maven-pluto-plugin/src/main/resources/versions.properties as well!
-  -->
-  <properties>
-    <pluto.container.name>Pluto</pluto.container.name>
-    <javax.portlet.version.major>2</javax.portlet.version.major>
-    <javax.portlet.version.minor>0</javax.portlet.version.minor>
-    <portals.portlet2-api-spec.version>1.0</portals.portlet2-api-spec.version>
-    <servlet-api.version>2.4</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>
-    <jaxb.version>2.1</jaxb.version>
-    <jaxb-impl.version>2.1.9</jaxb-impl.version>
-    <stax.impl.version>1.2.0</stax.impl.version>
-    <commons-digester.version>1.8</commons-digester.version>
-    <commons-cli.version>1.0</commons-cli.version>
-    <slf4j.version>1.7.5</slf4j.version>
-    <springframework.version>2.0.2</springframework.version>
-    <maven.version>2.0.5</maven.version>
-    <ant.version>1.6.5</ant.version>
-    <commons-io.version>1.3.1</commons-io.version>
-    <ccpp-api.version>1.0</ccpp-api.version>
-    <junit.version>4.0</junit.version>
-    <jmock.version>1.2.0</jmock.version>
-    <xmlunit.version>1.1</xmlunit.version>
-
-    <!-- The following properties are not directly used as maven
-dependencies, they're used by the maven pluto plugin for
-handling installation dependencies
-TODO: Check if we need all of them. -->
-    <xerces.version>2.6.2</xerces.version>
-    <xalan.version>2.7.0</xalan.version>
-    <castor.version>1.1.1</castor.version>
-    <commons-collections.version>3.2</commons-collections.version>
-    <commons-httpclient.version>3.0</commons-httpclient.version>
-    <commons-beanutils.version>1.7.0</commons-beanutils.version>
-    <log4j.version>1.2.14</log4j.version>
-    <activation.version>1.1</activation.version>
-    <ccpp-ri.version>1.0</ccpp-ri.version>
-    <rdffilter.version>1.0</rdffilter.version>
-    <jena.version>1.4.0</jena.version>
-
-    <!-- scope of certain dependencies is "compile" for deployment on tomcat, 
-         but "provided" for deployment on tomee. See tomee profile. -->
-    <dependency.scope>compile</dependency.scope>
-  </properties>
-
-  <dependencyManagement>
-    <dependencies>
-      <!-- Logging =========================================== -->
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-api</artifactId>
-        <version>${slf4j.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>slf4j-jdk14</artifactId>
-        <version>${slf4j.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.slf4j</groupId>
-        <artifactId>jcl-over-slf4j</artifactId>
-        <version>${slf4j.version}</version>
-      </dependency>
-
-      <!-- Specification Libraries =========================================== -->
-      <dependency>
-        <groupId>org.apache.portals</groupId>
-        <artifactId>portlet-api_2.0_spec</artifactId>
-        <version>${portals.portlet2-api-spec.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>javax.servlet</groupId>
-        <artifactId>servlet-api</artifactId>
-        <version>${servlet-api.version}</version>
-      </dependency>
-
-      <dependency>
-        <groupId>javax.xml.bind</groupId>
-        <artifactId>jaxb-api</artifactId>
-        <version>${jaxb.version}</version>
-      </dependency>
-
-      <dependency>
-        <groupId>com.sun.xml.bind</groupId>
-        <artifactId>jaxb-impl</artifactId>
-        <version>${jaxb-impl.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>stax</groupId>
-        <artifactId>stax</artifactId>
-        <version>${stax.impl.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>stax</groupId>
-            <artifactId>stax-api</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-
-      <!--  CCPP Libraries -->
-      <dependency>
-        <groupId>javax.ccpp</groupId>
-        <artifactId>ccpp</artifactId>
-        <version>${ccpp-api.version}</version>
-      </dependency>
-
-      <!-- Testing Libraries ================================================= -->
-      <dependency>
-        <groupId>junit</groupId>
-        <artifactId>junit</artifactId>
-        <version>${junit.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>jmock</groupId>
-        <artifactId>jmock</artifactId>
-        <version>${jmock.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>jmock</groupId>
-        <artifactId>jmock-cglib</artifactId>
-        <version>${jmock.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <dependency>
-        <groupId>xmlunit</groupId>
-        <artifactId>xmlunit</artifactId>
-        <version>${xmlunit.version}</version>
-        <scope>test</scope>
-      </dependency>
-      <!-- Misc ================================================= -->
-      <dependency>
-        <groupId>ant</groupId>
-        <artifactId>ant</artifactId>
-        <version>${ant.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.maven</groupId>
-        <artifactId>maven-core</artifactId>
-        <version>${maven.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.maven</groupId>
-        <artifactId>maven-artifact</artifactId>
-        <version>${maven.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.maven</groupId>
-        <artifactId>maven-model</artifactId>
-        <version>${maven.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.maven</groupId>
-        <artifactId>maven-project</artifactId>
-        <version>${maven.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.apache.maven</groupId>
-        <artifactId>maven-plugin-api</artifactId>
-        <version>${maven.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>javax.servlet</groupId>
-        <artifactId>jsp-api</artifactId>
-        <version>${jsp-api.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>javax.servlet</groupId>
-        <artifactId>jstl</artifactId>
-        <version>${jstl.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>taglibs</groupId>
-        <artifactId>standard</artifactId>
-        <version>${taglibs.standard.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-core</artifactId>
-        <version>${springframework.version}</version>
-        <scope>compile</scope>
-        <exclusions>
-          <exclusion>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-beans</artifactId>
-        <version>${springframework.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>org.springframework</groupId>
-        <artifactId>spring-web</artifactId>
-        <version>${springframework.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>commons-io</groupId>
-        <artifactId>commons-io</artifactId>
-        <version>${commons-io.version}</version>
-      </dependency>
-      <dependency>
-        <groupId>commons-digester</groupId>
-        <artifactId>commons-digester</artifactId>
-        <version>${commons-digester.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-      <dependency>
-        <groupId>commons-cli</groupId>
-        <artifactId>commons-cli</artifactId>
-        <version>${commons-cli.version}</version>
-        <exclusions>
-          <exclusion>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-          </exclusion>
-          <exclusion>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-          </exclusion>
-        </exclusions>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
-  <build>
-    <pluginManagement>
-      <plugins>
-        <plugin>
-          <groupId>org.apache.portals.pluto</groupId>
-          <artifactId>maven-pluto-plugin</artifactId>
-          <version>${project.version}</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-war-plugin</artifactId>
-          <version>2.4</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.rat</groupId>
-          <artifactId>apache-rat-plugin</artifactId>
-          <version>0.10</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-antrun-plugin</artifactId>
-          <version>1.7</version>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-compiler-plugin</artifactId>
-          <configuration>
-            <source>1.5</source>
-            <target>1.5</target>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.felix</groupId>
-          <artifactId>maven-bundle-plugin</artifactId>
-          <version>2.0.1</version>
-          <extensions>true</extensions>
-          <configuration>
-            <instructions>
-              <Implementation-Title>${project.name}</Implementation-Title>
-              <Specification-Version>${project.version}</Specification-Version>
-              <Implementation-Version>${project.version}</Implementation-Version>
-              <Bundle-DocURL>${project.url}</Bundle-DocURL>
-            </instructions>
-          </configuration>
-        </plugin>
-        <plugin>
-          <groupId>org.apache.maven.plugins</groupId>
-          <artifactId>maven-release-plugin</artifactId>
-          <configuration>
-            <!-- During release (prepare) the org.apache.felix maven-bundle-plugin needs classpath access to just build dependent artifacts
-                 like the pluto-container-api to determine the needed OSGi imports.
-                 However, the default maven-release-plugin goals (clean verify) somehow don't provide those.
-                 To fix that, the default release plugin set of preparationGoals is changed to do an "install" instead of just "verify".
-            -->
-            <preparationGoals>clean install</preparationGoals>
-            <mavenExecutorId>forked-path</mavenExecutorId>
-            <autoVersionSubmodules>true</autoVersionSubmodules>
-          </configuration>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-      </plugin>
-    </plugins>
-  </build>
-
-  <profiles>
-    <profile>
-      <id>all</id>
-      <activation>
-        <activeByDefault>true</activeByDefault>
-        <!-- profile must also be activated when building for tomee -->
-        <property>
-          <name>tomee</name>
-        </property>
-      </activation>
-      
-      <!-- Pluto Modules ======================================================= -->
-      <modules>
-        <!-- Pluto Container API -->
-        <module>pluto-container-api</module>
-
-        <!-- Pluto Core Modules -->
-        <module>pluto-container</module>
-        <module>pluto-taglib</module>
-
-        <!-- Pluto Portal and Testsuite Modules -->
-        <module>pluto-container-driver-api</module>
-        <module>pluto-portal-driver</module>
-        <module>pluto-portal-driver-impl</module>
-        <module>pluto-portal</module>
-        <module>pluto-testsuite</module>
-
-        <!-- Pluto Utilities, Maven Plugins and Ant Tasks -->
-        <module>pluto-util</module>
-        <module>maven-pluto-plugin</module>
-        <module>pluto-ant-tasks</module>
-        <module>pluto-site-skin</module>
-      </modules>
-    </profile>
-    
-    <profile>
-      <id>website</id>
-      <!-- For building website documentation, there's no need to include modules. -->
-      <modules />
-    </profile>
-    
-    <!-- To build Pluto for deployment on tomee, activate this profile -->
-    <!-- Activate using the tomee property: mvn clean install -Dtomee -->
-    <profile>
-      <id>tomee</id>
-      <activation>
-        <property>
-          <name>tomee</name>
-        </property>
-      </activation>
-      <properties>
-         <!-- scope of certain dependencies is "compile" for deployment on tomcat, 
-              but "provided" for deployment on tomee. See tomee profile. -->
-		  <dependency.scope>provided</dependency.scope>
-      </properties>
-    </profile>
-
-  </profiles>
-
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.portals</groupId>
+    <artifactId>portals-pom</artifactId>
+    <version>1.3</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.portals.pluto</groupId>
+  <artifactId>pluto</artifactId>
+  <packaging>pom</packaging>
+  <name>Apache Pluto</name>
+  <!--
+ Any version changes need to be changed in:
+ 1. All poms of children modules
+ 2. pluto.container.version.minor property in environment.properties in
+ pluto-container module (src/main/resources/org/apache/pluto).
+ 3. portal-version element in pluto-portal-driver-config.xml in pluto-portal module
+ (src/main/webapp/WEB-INF)
+ 4. expected.serverInfo and expected.portalInfo properties in expectedResults.properties
+ in testsuite module (src/main/webapp/WEB-INF/classes)
+ 5. pluto.version in Ant build file dist-build.xml.
+  -->
+  <version>2.1.0-SNAPSHOT</version>
+  <!-- Due to a bug in maven 2.0, the description must not contain any line breaks or tabs. -->
+  <description>Apache Pluto is the Reference Implementation of the Java Portlet Specification.</description>
+  <url>http://portals.apache.org/pluto</url>
+
+  <issueManagement>
+    <system>jira</system>
+    <url>http://issues.apache.org/jira/secure/BrowseProject.jspa?id=10560</url>
+  </issueManagement>
+  <inceptionYear>2003</inceptionYear>
+
+
+  <!-- Mailing Lists ======================================================= -->
+
+  <mailingLists>
+    <mailingList>
+      <name>Pluto User List</name>
+      <subscribe>pluto-user-subscribe@portals.apache.org</subscribe>
+      <unsubscribe>pluto-user-unsubscribe@portals.apache.org</unsubscribe>
+      <post>pluto-user@portals.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-user</archive>
+    </mailingList>
+    <mailingList>
+      <name>Pluto Developer List</name>
+      <subscribe>pluto-dev-subscribe@portals.apache.org</subscribe>
+      <unsubscribe>pluto-dev-unsubscribe@portals.apache.org</unsubscribe>
+      <post>pluto-dev@portals.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-dev</archive>
+    </mailingList>
+    <mailingList>
+      <name>Pluto SCM List</name>
+      <subscribe>pluto-scm-subscribe@portals.apache.org</subscribe>
+      <unsubscribe>pluto-scm-unsubscribe@portals.apache.org</unsubscribe>
+      <post>pluto-scm@portals.apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/portals-pluto-scm</archive>
+    </mailingList>
+  </mailingLists>
+
+
+  <!-- Pluto Committers ==================================================== -->
+
+  <!-- Email format: [name]#a@T#[domain].d0t.[extension]
+'@' and '.' characters are added because m2 seems to need them to
+generate mailto links. -->
+
+  <developers>
+
+    <developer>
+      <name>Michael Blum</name>
+      <id>blumm</id>
+      <email>blumm#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>Carsten Ziegeler</name>
+      <id>cziegeler</id>
+      <email>cziegeler#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>David DeWolf</name>
+      <id>ddewolf</id>
+      <email>ddewolf@apache.org</email>
+      <timezone>-4</timezone>
+      <url>http://www.daviddewolf.com</url>
+      <organization>Three Pillar Software, Inc.</organization>
+      <organizationUrl>http://www.threepillarsoftware.com</organizationUrl>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+
+    <developer>
+      <name>Scott Nicklous</name>
+      <id>msnicklous</id>
+      <email>msnicklous#a@T#apache.d0t.org</email>
+      <timezone>+1</timezone>
+      <organization>IBM Corporation</organization>
+      <organizationUrl>http://www.ibm.com</organizationUrl>
+      <roles>
+        <role>Specification Lead, JSR 362 Portlet Specification 3.0</role>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+
+    <developer>
+      <name>Nick Lothian</name>
+      <id>nlothian</id>
+      <email>nlothian#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>Craig Doremus</name>
+      <id>cdoremus</id>
+      <email>cdoremus#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>Zhong Zheng</name>
+      <id>zheng</id>
+      <email>zheng#a@T#apache.d0t.org</email>
+      <timezone>+1</timezone>
+      <organization />
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+
+    <developer>
+      <name>Santiago Gala</name>
+      <id>sgala</id>
+      <email>sgala#a@T#hisitech.d0t.com</email>
+      <organization />
+    </developer>
+
+    <developer>
+      <name>Raphael Luta</name>
+      <id>raphael</id>
+      <email>raphael#a@T#apache.d0t.org</email>
+      <organization />
+    </developer>
+
+    <developer>
+      <name>David S. Taylor</name>
+      <id>taylor</id>
+      <email>david#a@T#bluesunrise.d0t.com</email>
+      <organization />
+    </developer>
+
+    <developer>
+      <name>Scott T. Weaver</name>
+      <id>weaver</id>
+      <email>weaver#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>Stefan Hepper</name>
+      <id>sthepper</id>
+      <email>sthepper#a@T#apache.d0t.org</email>
+    </developer>
+
+    <developer>
+      <name>Elliot Metsger</name>
+      <id>esm</id>
+      <email>esm#a@T#apache.d0t.org</email>
+      <timezone>-4</timezone>
+      <url>http://uppertank.net/blog</url>
+      <organization>Johns Hopkins University, Sheridan Libraries</organization>
+      <organizationUrl>http://www.library.jhu.edu</organizationUrl>
+    </developer>
+
+    <developer>
+      <name>Ate Douma</name>
+      <id>ate</id>
+      <email>ate#aT#apache.d0t.org</email>
+      <timezone>+2</timezone>
+      <organization>Hippo</organization>
+      <organizationUrl>http://www.onehippo.com</organizationUrl>
+      <roles>
+        <role>Java Developer</role>
+      </roles>
+    </developer>
+
+    <developer>
+      <name>David Jencks</name>
+      <id>djencks</id>
+      <email>djencks#aT#apache.d0t.org</email>
+      <timezone>-7</timezone>
+    </developer>
+
+  </developers>
+
+
+  <!-- Pluto Contributors ================================================== -->
+
+  <contributors>
+    <contributor>
+      <name>Michael Westbay</name>
+      <email>westbay#a@T#users.d0t.sourceforge.d0t.net</email>
+    </contributor>
+    <contributor>
+      <name>Ken Weiner</name>
+      <email>kweiner#a@T#unicon.d0t.net</email>
+    </contributor>
+    <contributor>
+      <name>Ken Atherton</name>
+      <email>katherto#a@T#visa.d0t.com</email>
+    </contributor>
+    <contributor>
+      <name>David Hay</name>
+    </contributor>
+
+    <contributor>
+
+    </contributor>
+  </contributors>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/portals/pluto/trunk</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/portals/pluto/trunk</developerConnection>
+    <url>http://svn.apache.org/viewcvs.cgi/portals/pluto/trunk</url>
+  </scm>
+
+  <!-- Dependency Version Properties ======================================= -->
+
+  <!--
+  NOTE:
+
+  Modification of these properties affects:
+  1)  maven-pluto-plugin/src/main/resources/versions.properties as well!
+  -->
+  <properties>
+    <pluto.container.name>Pluto</pluto.container.name>
+    <javax.portlet.version.major>2</javax.portlet.version.major>
+    <javax.portlet.version.minor>0</javax.portlet.version.minor>
+    <portals.portlet2-api-spec.version>1.0</portals.portlet2-api-spec.version>
+    <servlet-api.version>2.4</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>
+    <jaxb.version>2.1</jaxb.version>
+    <jaxb-impl.version>2.1.9</jaxb-impl.version>
+    <stax.impl.version>1.2.0</stax.impl.version>
+    <commons-digester.version>1.8</commons-digester.version>
+    <commons-cli.version>1.0</commons-cli.version>
+    <slf4j.version>1.7.5</slf4j.version>
+    <springframework.version>2.0.2</springframework.version>
+    <maven.version>2.0.5</maven.version>
+    <ant.version>1.6.5</ant.version>
+    <commons-io.version>1.3.1</commons-io.version>
+    <ccpp-api.version>1.0</ccpp-api.version>
+    <junit.version>4.0</junit.version>
+    <jmock.version>1.2.0</jmock.version>
+    <xmlunit.version>1.1</xmlunit.version>
+
+    <!-- The following properties are not directly used as maven
+dependencies, they're used by the maven pluto plugin for
+handling installation dependencies
+TODO: Check if we need all of them. -->
+    <xerces.version>2.6.2</xerces.version>
+    <xalan.version>2.7.0</xalan.version>
+    <castor.version>1.1.1</castor.version>
+    <commons-collections.version>3.2</commons-collections.version>
+    <commons-httpclient.version>3.0</commons-httpclient.version>
+    <commons-beanutils.version>1.7.0</commons-beanutils.version>
+    <log4j.version>1.2.14</log4j.version>
+    <activation.version>1.1</activation.version>
+    <ccpp-ri.version>1.0</ccpp-ri.version>
+    <rdffilter.version>1.0</rdffilter.version>
+    <jena.version>1.4.0</jena.version>
+
+    <!-- scope of certain dependencies is "compile" for deployment on tomcat, 
+         but "provided" for deployment on tomee. See tomee profile. -->
+    <dependency.scope>compile</dependency.scope>
+  </properties>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- Logging =========================================== -->
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-api</artifactId>
+        <version>${slf4j.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-jdk14</artifactId>
+        <version>${slf4j.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>jcl-over-slf4j</artifactId>
+        <version>${slf4j.version}</version>
+      </dependency>
+
+      <!-- Specification Libraries =========================================== -->
+      <dependency>
+        <groupId>org.apache.portals</groupId>
+        <artifactId>portlet-api_2.0_spec</artifactId>
+        <version>${portals.portlet2-api-spec.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>servlet-api</artifactId>
+        <version>${servlet-api.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>javax.xml.bind</groupId>
+        <artifactId>jaxb-api</artifactId>
+        <version>${jaxb.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.sun.xml.bind</groupId>
+        <artifactId>jaxb-impl</artifactId>
+        <version>${jaxb-impl.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>stax</groupId>
+        <artifactId>stax</artifactId>
+        <version>${stax.impl.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>stax</groupId>
+            <artifactId>stax-api</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+
+      <!--  CCPP Libraries -->
+      <dependency>
+        <groupId>javax.ccpp</groupId>
+        <artifactId>ccpp</artifactId>
+        <version>${ccpp-api.version}</version>
+      </dependency>
+
+      <!-- Testing Libraries ================================================= -->
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>${junit.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>jmock</groupId>
+        <artifactId>jmock</artifactId>
+        <version>${jmock.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>jmock</groupId>
+        <artifactId>jmock-cglib</artifactId>
+        <version>${jmock.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>xmlunit</groupId>
+        <artifactId>xmlunit</artifactId>
+        <version>${xmlunit.version}</version>
+        <scope>test</scope>
+      </dependency>
+      <!-- Misc ================================================= -->
+      <dependency>
+        <groupId>ant</groupId>
+        <artifactId>ant</artifactId>
+        <version>${ant.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-core</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-artifact</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-model</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-project</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven-plugin-api</artifactId>
+        <version>${maven.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>jsp-api</artifactId>
+        <version>${jsp-api.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>jstl</artifactId>
+        <version>${jstl.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>taglibs</groupId>
+        <artifactId>standard</artifactId>
+        <version>${taglibs.standard.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-core</artifactId>
+        <version>${springframework.version}</version>
+        <scope>compile</scope>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-beans</artifactId>
+        <version>${springframework.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-web</artifactId>
+        <version>${springframework.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>${commons-io.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-digester</groupId>
+        <artifactId>commons-digester</artifactId>
+        <version>${commons-digester.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>commons-cli</groupId>
+        <artifactId>commons-cli</artifactId>
+        <version>${commons-cli.version}</version>
+        <exclusions>
+          <exclusion>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.portals.pluto</groupId>
+          <artifactId>maven-pluto-plugin</artifactId>
+          <version>${project.version}</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+          <version>2.4</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <version>0.10</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-antrun-plugin</artifactId>
+          <version>1.7</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <configuration>
+            <source>1.5</source>
+            <target>1.5</target>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.felix</groupId>
+          <artifactId>maven-bundle-plugin</artifactId>
+          <version>2.0.1</version>
+          <extensions>true</extensions>
+          <configuration>
+            <instructions>
+              <Implementation-Title>${project.name}</Implementation-Title>
+              <Specification-Version>${project.version}</Specification-Version>
+              <Implementation-Version>${project.version}</Implementation-Version>
+              <Bundle-DocURL>${project.url}</Bundle-DocURL>
+            </instructions>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-release-plugin</artifactId>
+          <configuration>
+            <!-- During release (prepare) the org.apache.felix maven-bundle-plugin needs classpath access to just build dependent artifacts
+                 like the pluto-container-api to determine the needed OSGi imports.
+                 However, the default maven-release-plugin goals (clean verify) somehow don't provide those.
+                 To fix that, the default release plugin set of preparationGoals is changed to do an "install" instead of just "verify".
+            -->
+            <preparationGoals>clean install</preparationGoals>
+            <mavenExecutorId>forked-path</mavenExecutorId>
+            <autoVersionSubmodules>true</autoVersionSubmodules>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>all</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+        <!-- profile must also be activated when building for tomee -->
+        <property>
+          <name>tomee</name>
+        </property>
+      </activation>
+      
+      <!-- Pluto Modules ======================================================= -->
+      <modules>
+        <!-- Pluto Container API -->
+        <module>pluto-container-api</module>
+
+        <!-- Pluto Core Modules -->
+        <module>pluto-container</module>
+        <module>pluto-taglib</module>
+
+        <!-- Pluto Portal and Testsuite Modules -->
+        <module>pluto-container-driver-api</module>
+        <module>pluto-portal-driver</module>
+        <module>pluto-portal-driver-impl</module>
+        <module>pluto-portal</module>
+        <module>pluto-testsuite</module>
+        
+        <!-- PortletHub demo portlets -->
+        <module>pluto-PortletHubDemo</module>
+
+        <!-- Pluto Utilities, Maven Plugins and Ant Tasks -->
+        <module>pluto-util</module>
+        <module>maven-pluto-plugin</module>
+        <module>pluto-ant-tasks</module>
+        <module>pluto-site-skin</module>
+      </modules>
+    </profile>
+    
+    <profile>
+      <id>website</id>
+      <!-- For building website documentation, there's no need to include modules. -->
+      <modules />
+    </profile>
+    
+    <!-- To build Pluto for deployment on tomee, activate this profile -->
+    <!-- Activate using the tomee property: mvn clean install -Dtomee -->
+    <profile>
+      <id>tomee</id>
+      <activation>
+        <property>
+          <name>tomee</name>
+        </property>
+      </activation>
+      <properties>
+         <!-- scope of certain dependencies is "compile" for deployment on tomcat, 
+              but "provided" for deployment on tomee. See tomee profile. -->
+		  <dependency.scope>provided</dependency.scope>
+      </properties>
+    </profile>
+
+  </profiles>
+
+</project>