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 2016/01/18 13:41:03 UTC

[01/35] portals-pluto git commit: Added configuration validation code; updted tests accordingly

Repository: portals-pluto
Updated Branches:
  refs/heads/V3Prototype 875769b8d -> 84f8d9f39


Added configuration validation code; updted tests accordingly


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

Branch: refs/heads/V3Prototype
Commit: fef12ee195f966b5eca71682337bda0e74b56808
Parents: 875769b
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Dec 1 07:51:57 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Dec 1 07:51:57 2015 +0100

----------------------------------------------------------------------
 .../portlet/PortletApplicationDefinition.java   |   7 +
 .../driver/PortletContainerInitializer.java     |   2 +
 .../om/portlet/impl/ConfigurationHolder.java    |   9 +
 .../om/portlet/impl/ConfigurationProcessor.java |  66 +++++-
 .../impl/JSR168ConfigurationProcessor.java      |   5 +-
 .../impl/JSR286ConfigurationProcessor.java      | 226 +++++++++++++------
 .../impl/JSR362ConfigurationProcessor.java      | 129 ++++-------
 .../impl/PortletApplicationDefinitionImpl.java  |  18 ++
 .../container/impl/JaxbReadTest286Gen.java      |   2 +-
 .../container/impl/JaxbReadTest362Gen.java      |   2 +-
 ...PortletApplicationDefinition286ImplTest.java |  44 ++--
 .../jsr286/PortletDefinition286ImplTest.java    |   2 +-
 ...PortletApplicationDefinition362ImplTest.java |  44 ++--
 .../jsr362/PortletDefinition362ImplTest.java    |   2 +-
 .../container/om/portlet/GoodBundle.properties  |   6 +
 .../om/portlet/portlet286Generated.xml          |   4 +-
 .../om/portlet/portlet362Generated.xml          |   4 +-
 17 files changed, 369 insertions(+), 203 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
index 80b3d76..b4698a7 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
@@ -39,6 +39,13 @@ public interface PortletApplicationDefinition {
     
    PortletDefinition getPortlet(String portletName);
    List<PortletDefinition> getPortlets();
+   /**
+    * The portlet name can end with the wildcard character '*'. The wildcard 
+    * matches any suffix. For filter mapping.
+    * 
+    * @return     The list of matching portlets
+    */
+   public List<PortletDefinition> getMatchingPortlets(String portletName);
    void addPortlet(PortletDefinition pd);
    
    List<EventDefinition> getEventDefinitions();

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index 300b3af..b9cb00d 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -95,6 +95,8 @@ public class PortletContainerInitializer implements ServletContainerInitializer
                // parse the web app deployment descriptor
                holder.processWebDD(win);
             }
+            
+            holder.validate();
 
             if (holder.getPad().getPortlets().size() > 0) {
                

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
index 1acf42b..8202fba 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
@@ -203,5 +203,14 @@ public class ConfigurationHolder {
       }
       jcp.processWebDD(in, pad);
    }
+   
+   /**
+    * validates the configuration. To be called after the configuration has been completely read.
+    */
+   public void validate() {
+      if (jcp != null) {
+         jcp.validate();
+      }
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 204b5d7..9ae6021 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -3,6 +3,7 @@ package org.apache.pluto.container.om.portlet.impl;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.ResourceBundle;
 
 import javax.xml.bind.JAXBElement;
 import javax.xml.parsers.DocumentBuilder;
@@ -28,6 +29,13 @@ public abstract class ConfigurationProcessor {
          .getLogger(ConfigurationProcessor.class);
    
 
+   protected PortletApplicationDefinition pad;
+   
+
+   public PortletApplicationDefinition getPad() {
+      return pad;
+   }
+
    /**
     * Traverses the portlet deployment descriptor tree and returns the data in
     * the form of a portlet application definition.
@@ -42,6 +50,23 @@ public abstract class ConfigurationProcessor {
          JAXBElement<?> rootElement) throws IllegalArgumentException;
 
    /**
+    * Validates the given portlet application definition. This method should only be called after 
+    * the complete configuration has been read.
+    * <p>
+    * The validation method is designed to be called within the portlet application servlet context.
+    * It throws exceptions when specified classes cannot be loaded or other severe configuration
+    * problem is discovered. It logs warnings for less severe configuration problems.
+    * <p>
+    * The validation code is separate from the 
+    * configuration reading code so that the config reading code won't cause exceptions when it 
+    * is used by the maven-portlet-plugin packaging code. 
+    * 
+    * @throws IllegalArgumentException
+    *             If there is a validation error.
+    */
+   public abstract void validate() throws IllegalArgumentException;
+
+   /**
     * Handle the locale the old-fashioned way (v1 & v2)
     */
    protected Locale deriveLocale(String lang) {
@@ -110,17 +135,50 @@ public abstract class ConfigurationProcessor {
       Class<?> valClass = null;
       try {
          ClassLoader cl = Thread.currentThread().getContextClassLoader();
+         if (cl == null) {
+            cl = this.getClass().getClassLoader();
+         }
          valClass = cl.loadClass(clsName);
          if (assignable != null && !assignable.isAssignableFrom(valClass)) {
             txt.append(". Specified class is not a ");
             txt.append(assignable.getCanonicalName());
             throw new Exception();
          }
-      } catch (ClassNotFoundException e) {
-         txt.append(", Exception: ").append(e.toString());
+//       } catch (ClassNotFoundException e) {
+//          txt.append(", Exception: ").append(e.toString());
+//          LOG.warn(txt.toString());
+//          // can't throw exception if class not found, since the portlet
+//          // application definition is used by the assembly mojo
+      } catch (Exception e) {
          LOG.warn(txt.toString());
-         // can't throw exception if class not found, since the portlet
-         // application definition is used by the assembly mojo
+         throw new IllegalArgumentException(txt.toString(), e);
+      }
+   }
+
+   /**
+    * checks if resource bundle name is valid by trying to load it. 
+    * 
+    * @param bundleName
+    *           Class name string from configuration
+    */
+   protected void checkValidBundle(String bundleName) {
+   
+      StringBuilder txt = new StringBuilder(128);
+      txt.append("Bad resource bundle: ");
+      txt.append(bundleName);
+      if (!isValidIdentifier(bundleName)) {
+         txt.append(". Invalid java identifier.");
+         LOG.warn(txt.toString());
+         throw new IllegalArgumentException(txt.toString());
+      }
+   
+      try {
+         ClassLoader cl = Thread.currentThread().getContextClassLoader();
+         if (cl == null) {
+            cl = this.getClass().getClassLoader();
+         }
+         @SuppressWarnings("unused")
+         ResourceBundle rb = ResourceBundle.getBundle(bundleName, Locale.getDefault(), cl); 
       } catch (Exception e) {
          LOG.warn(txt.toString());
          throw new IllegalArgumentException(txt.toString(), e);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
index 89304a9..cc69cd1 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
@@ -78,7 +78,6 @@ public class JSR168ConfigurationProcessor extends ConfigurationProcessor {
    // private static final boolean         isDebug = LOG.isDebugEnabled();
    private static final boolean         isTrace = LOG.isTraceEnabled();
 
-   private PortletApplicationDefinition pad;
 
    /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.impl.jsr168.ConfigurationProcessor#process(javax.xml.bind.JAXBElement)
@@ -560,5 +559,9 @@ public class JSR168ConfigurationProcessor extends ConfigurationProcessor {
 
       }
    }
+   @Override
+   public void validate() throws IllegalArgumentException {
+      // For version 1.0, do nothing.
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
index 565efed..248633e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Locale;
 
 import javax.portlet.Portlet;
+import javax.portlet.PortletPreferences;
 import javax.portlet.PortletURLGenerationListener;
 import javax.portlet.PreferencesValidator;
 import javax.portlet.filter.PortletFilter;
@@ -89,7 +90,7 @@ import org.slf4j.LoggerFactory;
  * @author Scott Nicklous
  * 
  */
-public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
+public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
 
    /** Logger. */
    private static final Logger          LOG     = LoggerFactory
@@ -97,13 +98,11 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
    // private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean         isTrace = LOG.isTraceEnabled();
 
-   private PortletApplicationDefinition pad;
-
    /*
     * (non-Javadoc)
     * 
     * @see
-    * org.apache.pluto.container.om.portlet.impl.jsr168.ConfigurationProcessor
+    * org.apache.pluto.container.om.portlet.impl.jsr286.ConfigurationProcessor
     * #process(javax.xml.bind.JAXBElement)
     */
    @Override
@@ -251,17 +250,12 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
       for (FilterType item : args) {
 
          // validate data
-         if ((item.getFilterName() == null)
-               || (item.getFilterClass() == null)) {
+         if ((item.getFilterName() == null) || (item.getFilterName().length() == 0)
+               || (item.getFilterClass() == null) || (item.getFilterClass().length() == 0)) {
             String warning = "Bad Filter definition. name or class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getFilterClass();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, PortletFilter.class,
-                  "Bad filter definition. Filter class is invalid: ");
-         }
 
          // set up the custom portlet mode
          Filter newitem = new FilterImpl(item.getFilterName());
@@ -298,22 +292,11 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         if (pad.getFilter(fname) == null) {
-            String warning = "Bad FilterMapping definition. Filter definition not found: " + fname;
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
          
          // set up the filter mapping
          FilterMapping newitem = new FilterMappingImpl(fname);
          for (PortletNameType pnt : item.getPortletName()) {
-            String pname = pnt.getValue();
-            if (pad.getPortlet(pname) == null) {
-               String warning = "Bad FilterMapping definition. Portlet definition not found: " + pname;
-               LOG.warn(warning);
-//               throw new IllegalArgumentException(warning);
-            }
-            newitem.addPortletName(pname);
+            newitem.addPortletName(pnt.getValue());
          }
 
          // add it to the model
@@ -329,18 +312,13 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
       for (ListenerType item : args) {
 
          // validate data
-         if (item.getListenerClass() == null) {
+         if (item.getListenerClass() == null || item.getListenerClass().length() == 0) {
             String warning = "Bad Listener definition. Class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getListenerClass();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, PortletURLGenerationListener.class,
-                  "Bad listener definition. Listener class is invalid: ");
-         }
 
-         // set up the custom portlet mode
+         // set up the listener
          Listener newitem = new ListenerImpl(item.getListenerClass());
          for (Description desc : handleDescriptions(item.getDescription())) {
             newitem.addDescription(desc);
@@ -364,14 +342,14 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
          // validate data
          if ((cpm.getPortletMode() == null)
                || (cpm.getPortletMode().getValue() == null)) {
-            String warning = "Bad custom portlet mode. Mode was null.";
+            String warning = "Custom portlet mode cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          } else {
             String val = cpm.getPortletMode().getValue();
             if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit")
                   || val.equalsIgnoreCase("help")) {
-               String warning = "Bad custom portlet mode. Mode was: " + val;
+               String warning = "Bad custom portlet mode: " + val;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -406,14 +384,14 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
          // validate data
          if ((cws.getWindowState() == null)
                || (cws.getWindowState().getValue() == null)) {
-            String warning = "Bad custom portlet mode. Mode was null.";
+            String warning = "Custom window state cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          } else {
             String val = cws.getWindowState().getValue();
-            if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit")
-                  || val.equalsIgnoreCase("help")) {
-               String warning = "Bad custom portlet mode. Mode was: " + val;
+            if (val.equalsIgnoreCase("normal") || val.equalsIgnoreCase("maximized")
+                  || val.equalsIgnoreCase("minimized")) {
+               String warning = "Bad custom window state: " + val;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -448,8 +426,8 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
             throw new IllegalArgumentException(warning);
          } else {
             for (PortletNameType pnt : pct.getPortletName()) {
-               if (!isValidIdentifier(pnt.getValue())) {
-                  String warning = "Bad portlet name: " + pnt.getValue();
+               if (pnt.getValue().length() == 0) {
+                  String warning = "Portlet name may not be null.";
                   LOG.warn(warning);
                   throw new IllegalArgumentException(warning);
                }
@@ -532,7 +510,8 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
       for (InitParamType parm : parms) {
 
          // validate data
-         if ((parm.getName() == null) || (parm.getName().getValue() == null)) {
+         if ((parm.getName() == null) || (parm.getName().getValue() == null) ||
+               (parm.getName().getValue().length() == 0)) {
             String warning = "Bad init parameter. Parameter name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -559,7 +538,8 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
       for (PreferenceType item : args) {
 
          // validate data
-         if ((item.getName() == null) || (item.getName().getValue() == null)) {
+         if ((item.getName() == null) || (item.getName().getValue() == null) ||
+               (item.getName().getValue().length() == 0)) {
             String warning = "Bad portlet preference. Preference name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -620,8 +600,9 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
       for (SecurityRoleRefType item : args) {
 
          // validate data
-         if ((item.getRoleName() == null) || (item.getRoleLink() == null)
-               || (item.getRoleLink().getValue() == null)) {
+         if ((item.getRoleName() == null) || (item.getRoleName().length() == 0) || 
+               (item.getRoleLink() == null) || (item.getRoleLink().getValue() == null) ||
+               (item.getRoleLink().getValue().length() == 0)) {
             String warning = "Bad security role reference. Name or link was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -664,13 +645,6 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
             qname = new QName(pad.getDefaultNamespace(), name);
          }
 
-         if (pad.getEventDefinition(qname) == null) {
-            String warning = "Bad Event definition reference. No event definition found for qname: "
-                  + qname;
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
-
          // set up the event def ref
          EventDefinitionReference newedr = new EventDefinitionReferenceImpl(
                qname);
@@ -693,11 +667,6 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getValueType();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, null,
-                  "Bad Event definition. Payload type is invalid: ");
-         }
 
          // prepare the qname
          String name = item.getName();
@@ -708,6 +677,7 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
 
          // set up the event definition
          EventDefinition newed = new EventDefinitionImpl(qname);
+         String clsName = item.getValueType();
          if (clsName != null && clsName.length() > 0) {
             newed.setValueType(clsName);
          }
@@ -771,15 +741,20 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
 
          // validate portlet name & class
          String warning;
-         String pn = portlet.getPortletName().getValue();
-         if (!isValidIdentifier(pn)) {
-            warning = "Portlet name not valid Java identifier: " + pn;
+         if (portlet.getPortletName() == null || portlet.getPortletName().getValue() == null ||
+               portlet.getPortletName().getValue().length() == 0) {
+            warning = "Portlet name may not be null";
             LOG.warn(warning);
-            //throw new IllegalArgumentException(warning);
+            throw new IllegalArgumentException(warning);
          }
+         String pn = portlet.getPortletName().getValue();
 
          String clsName = portlet.getPortletClass();
-         checkValidClass(clsName, Portlet.class, "Bad portlet class: ");
+         if (clsName == null || clsName.length() == 0) {
+            warning = "Portlet class may not be null";
+            LOG.warn(warning);
+            throw new IllegalArgumentException(warning);
+         }
 
          // set up portlet definition
 
@@ -813,12 +788,10 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
 
          PortletInfoType pit = portlet.getPortletInfo();
          if (pit != null) {
-            if (pit.getTitle().getValue() == null) {
-               warning = "Portlet info section does not contain title. Ingoring ...";
-               LOG.warn(warning);
-            } else {
-               String title, st = null, kw = null;
+            String title = null, st = null, kw = null;
+            if (pit.getTitle() != null) {
                title = pit.getTitle().getValue();
+            }
                if (pit.getShortTitle() != null) {
                   st = pit.getShortTitle().getValue();
                }
@@ -828,7 +801,6 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
                PortletInfo info = new PortletInfoImpl(title, kw, st);
                pd.setPortletInfo(info);
             }
-         }
 
          for (SupportedLocaleType slt : portlet.getSupportedLocale()) {
             pd.addSupportedLocale(slt.getValue());
@@ -843,8 +815,6 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
             Preferences newprefs = new PreferencesImpl();
 
             clsName = prefs.getPreferencesValidator();
-            checkValidClass(clsName, PreferencesValidator.class,
-                  "Bad portlet preferences validator class: ");
 
             newprefs.setPreferencesValidator(clsName);
             for (Preference p : handlePreferences(prefs.getPreference())) {
@@ -864,14 +834,8 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
          }
 
          for (String prp : portlet.getSupportedPublicRenderParameter()) {
-            boolean ok = false;
-            for (PublicRenderParameter prpdef : pad.getPublicRenderParameters()) {
-               if (prpdef.getIdentifier().equals(prp)) {
-                  ok = true;
-               }
-            }
-            if (!ok) {
-               warning = "Public render parameter definition not found for: " + prp;
+            if ((prp == null) || (prp.length() == 0)) {
+               warning = "Supported public render parameter definition may not be null.";
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -894,5 +858,117 @@ public class JSR286ConfigurationProcessor extends ConfigurationProcessor {
 
       }
    }
+   
+   /**
+    * validate the v2.0 configuration
+    */
+   public void validate () {
+      super.validate();
+      
+      // validate the resource bundle
+      if (pad.getResourceBundle() != null) {
+         checkValidBundle(pad.getResourceBundle());
+      }
+      
+      // validate event definitions by making sure the payload classes, if provided, can be loaded.
+      for (EventDefinition ed : pad.getEventDefinitions()) {
+         String clsName = ed.getValueType();
+         if (clsName != null && !clsName.equals("")) {
+            checkValidClass(clsName, null,
+                  "Bad Event definition. Payload type is invalid: ");
+         }
+      }
+      
+      // validate provided listener classes
+      for (Listener l : pad.getListeners()) {
+         checkValidClass(l.getListenerClass(), PortletURLGenerationListener.class,
+               "Bad listener definition. Listener class is invalid: ");
+      }
+      
+      // Validate the filter classes
+      for (Filter f : pad.getFilters()) {
+         checkValidClass(f.getFilterClass(), PortletFilter.class,
+               "Bad filter definition. Filter class is invalid: ");
+      }
+      
+      // validate the filter mappings by making sure that the specified filters and 
+      // portlets are available
+      for (FilterMapping fm : pad.getFilterMappings()) {
+         String fname = fm.getFilterName();
+         if (pad.getFilter(fname) == null) {
+            String warning = "Bad FilterMapping definition. Filter definition not found: " + fname;
+            LOG.warn(warning);
+            throw new IllegalArgumentException(warning);
+         }
+         for (String pn : fm.getPortletNames()) {
+            if (pad.getMatchingPortlets(pn).isEmpty()) {
+               String warning = "Bad FilterMapping definition. Portlet definition not found: " + pn;
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
+         }
+      }
+      
+      // Now validate the portlets
+      for (PortletDefinition portlet : pad.getPortlets()) {
+         
+         // check the portlet class
+         if (pad.getVersion().equals("2.0") || pad.getVersion().equals("1.0")) {
+            checkValidClass(portlet.getPortletClass(), Portlet.class, "Bad portlet class: ");
+         }
+         
+         // check the resource bundle
+         if (portlet.getResourceBundle() != null) {
+            checkValidBundle(portlet.getResourceBundle());
+         }
+         
+         // check the portlet preferences validator class
+         Preferences prefs = portlet.getPortletPreferences();
+         if (prefs != null && prefs.getPreferencesValidator() != null) {
+            String clsName = prefs.getPreferencesValidator();
+            checkValidClass(clsName, PreferencesValidator.class,
+                  "Bad portlet preferences validator class: ");
+         }
+         
+         // Check the supported public render parameters
+         for (String prp : portlet.getSupportedPublicRenderParameters()) {
+            boolean ok = false;
+            for (PublicRenderParameter prpdef : pad.getPublicRenderParameters()) {
+               if (prpdef.getIdentifier().equals(prp)) {
+                  ok = true;
+               }
+            }
+            if (!ok) {
+               String warning = "Public render parameter definition not found for: " + prp;
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
+         }
+         
+         // Check the publishing events
+         for (EventDefinitionReference edr : portlet.getSupportedPublishingEvents()) {
+            QName qname = edr.getQualifiedName();
+            if (pad.getEventDefinition(qname) == null) {
+               String warning = "Bad publishing event definition reference. No event definition found for qname: "
+                     + qname;
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
+         }
+         
+         // Check the processing events
+         for (EventDefinitionReference edr : portlet.getSupportedProcessingEvents()) {
+            QName qname = edr.getQualifiedName();
+            if (pad.getEventDefinition(qname) == null) {
+               String warning = "Bad processing event definition reference. No event definition found for qname: "
+                     + qname;
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
+         }
+         
+      }
+      
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index e20898d..03d6d50 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -23,9 +23,7 @@ import java.util.List;
 import java.util.Locale;
 
 import javax.portlet.Portlet;
-import javax.portlet.PortletURLGenerationListener;
 import javax.portlet.PreferencesValidator;
-import javax.portlet.filter.PortletFilter;
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
@@ -89,7 +87,7 @@ import org.slf4j.LoggerFactory;
  * @author Scott Nicklous
  * 
  */
-public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
+public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
    /** Logger. */
    private static final Logger          LOG     = LoggerFactory
@@ -97,13 +95,11 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
    // private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean         isTrace = LOG.isTraceEnabled();
 
-   private PortletApplicationDefinition pad;
-
    /*
     * (non-Javadoc)
     * 
     * @see
-    * org.apache.pluto.container.om.portlet.impl.jsr168.ConfigurationProcessor
+    * org.apache.pluto.container.om.portlet.impl.jsr362.ConfigurationProcessor
     * #process(javax.xml.bind.JAXBElement)
     */
    @Override
@@ -251,17 +247,12 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
       for (FilterType item : args) {
 
          // validate data
-         if ((item.getFilterName() == null)
-               || (item.getFilterClass() == null)) {
+         if ((item.getFilterName() == null) || (item.getFilterName().length() == 0)
+               || (item.getFilterClass() == null) || (item.getFilterClass().length() == 0)) {
             String warning = "Bad Filter definition. name or class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getFilterClass();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, PortletFilter.class,
-                  "Bad filter definition. Filter class is invalid: ");
-         }
 
          // set up the custom portlet mode
          Filter newitem = new FilterImpl(item.getFilterName());
@@ -298,22 +289,11 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         if (pad.getFilter(fname) == null) {
-            String warning = "Bad FilterMapping definition. Filter definition not found: " + fname;
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
          
          // set up the filter mapping
          FilterMapping newitem = new FilterMappingImpl(fname);
          for (PortletNameType pnt : item.getPortletName()) {
-            String pname = pnt.getValue();
-            if (pad.getPortlet(pname) == null) {
-               String warning = "Bad FilterMapping definition. Portlet definition not found: " + pname;
-               LOG.warn(warning);
-               throw new IllegalArgumentException(warning);
-            }
-            newitem.addPortletName(pname);
+            newitem.addPortletName(pnt.getValue());
          }
 
          // add it to the model
@@ -329,18 +309,13 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
       for (ListenerType item : args) {
 
          // validate data
-         if (item.getListenerClass() == null) {
+         if (item.getListenerClass() == null || item.getListenerClass().length() == 0) {
             String warning = "Bad Listener definition. Class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getListenerClass();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, PortletURLGenerationListener.class,
-                  "Bad listener definition. Listener class is invalid: ");
-         }
 
-         // set up the custom portlet mode
+         // set up the listener
          Listener newitem = new ListenerImpl(item.getListenerClass());
          for (Description desc : handleDescriptions(item.getDescription())) {
             newitem.addDescription(desc);
@@ -364,14 +339,14 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
          // validate data
          if ((cpm.getPortletMode() == null)
                || (cpm.getPortletMode().getValue() == null)) {
-            String warning = "Bad custom portlet mode. Mode was null.";
+            String warning = "Custom portlet mode cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          } else {
             String val = cpm.getPortletMode().getValue();
             if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit")
                   || val.equalsIgnoreCase("help")) {
-               String warning = "Bad custom portlet mode. Mode was: " + val;
+               String warning = "Bad custom portlet mode: " + val;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -406,14 +381,14 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
          // validate data
          if ((cws.getWindowState() == null)
                || (cws.getWindowState().getValue() == null)) {
-            String warning = "Bad custom portlet mode. Mode was null.";
+            String warning = "Custom window state cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          } else {
             String val = cws.getWindowState().getValue();
-            if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit")
-                  || val.equalsIgnoreCase("help")) {
-               String warning = "Bad custom portlet mode. Mode was: " + val;
+            if (val.equalsIgnoreCase("normal") || val.equalsIgnoreCase("maximized")
+                  || val.equalsIgnoreCase("minimized")) {
+               String warning = "Bad custom window state: " + val;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -448,8 +423,8 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
             throw new IllegalArgumentException(warning);
          } else {
             for (PortletNameType pnt : pct.getPortletName()) {
-               if (!isValidIdentifier(pnt.getValue())) {
-                  String warning = "Bad portlet name: " + pnt.getValue();
+               if (pnt.getValue().length() == 0) {
+                  String warning = "Portlet name may not be null.";
                   LOG.warn(warning);
                   throw new IllegalArgumentException(warning);
                }
@@ -532,7 +507,8 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
       for (InitParamType parm : parms) {
 
          // validate data
-         if ((parm.getName() == null) || (parm.getName().getValue() == null)) {
+         if ((parm.getName() == null) || (parm.getName().getValue() == null) ||
+               (parm.getName().getValue().length() == 0)) {
             String warning = "Bad init parameter. Parameter name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -559,8 +535,9 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
       for (PreferenceType item : args) {
 
          // validate data
-         if ((item.getName() == null) || (item.getName().getValue() == null)) {
-            String warning = "Bad portlet preference. Ppreference name was null.";
+         if ((item.getName() == null) || (item.getName().getValue() == null) ||
+               (item.getName().getValue().length() == 0)) {
+            String warning = "Bad portlet preference. Preference name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
@@ -572,7 +549,10 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
          for (ValueType vt : vals) {
             lines.add(vt.getValue());
          }
-         boolean isRO = (item.getReadOnly().value().equalsIgnoreCase("true"));
+         boolean isRO = false;      // default if not specified
+         if (item.getReadOnly() != null && item.getReadOnly().value() != null) {
+            isRO = (item.getReadOnly().value().equalsIgnoreCase("true"));
+         }
 
          Preference pref = new PreferenceImpl(name, isRO, lines);
          list.add(pref);
@@ -617,8 +597,9 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
       for (SecurityRoleRefType item : args) {
 
          // validate data
-         if ((item.getRoleName() == null) || (item.getRoleLink() == null)
-               || (item.getRoleLink().getValue() == null)) {
+         if ((item.getRoleName() == null) || (item.getRoleName().length() == 0) || 
+               (item.getRoleLink() == null) || (item.getRoleLink().getValue() == null) ||
+               (item.getRoleLink().getValue().length() == 0)) {
             String warning = "Bad security role reference. Name or link was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -661,13 +642,6 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
             qname = new QName(pad.getDefaultNamespace(), name);
          }
 
-         if (pad.getEventDefinition(qname) == null) {
-            String warning = "Bad Event definition reference. No event definition found for qname: "
-                  + qname;
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
-
          // set up the event def ref
          EventDefinitionReference newedr = new EventDefinitionReferenceImpl(
                qname);
@@ -690,11 +664,6 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         String clsName = item.getValueType();
-         if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, null,
-                  "Bad Event definition. Payload type is invalid: ");
-         }
 
          // prepare the qname
          String name = item.getName();
@@ -705,6 +674,7 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
 
          // set up the event definition
          EventDefinition newed = new EventDefinitionImpl(qname);
+         String clsName = item.getValueType();
          if (clsName != null && clsName.length() > 0) {
             newed.setValueType(clsName);
          }
@@ -768,15 +738,20 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
 
          // validate portlet name & class
          String warning;
-         String pn = portlet.getPortletName().getValue();
-         if (!isValidIdentifier(pn)) {
-            warning = "Portlet name not valid Java identifier: " + pn;
+         if (portlet.getPortletName() == null || portlet.getPortletName().getValue() == null ||
+               portlet.getPortletName().getValue().length() == 0) {
+            warning = "Portlet name may not be null";
             LOG.warn(warning);
-            // throw new IllegalArgumentException(warning);
+            throw new IllegalArgumentException(warning);
          }
+         String pn = portlet.getPortletName().getValue();
 
          String clsName = portlet.getPortletClass();
-         checkValidClass(clsName, Portlet.class, "Bad portlet class: ");
+         if (clsName == null || clsName.length() == 0) {
+            warning = "Portlet class may not be null";
+            LOG.warn(warning);
+            throw new IllegalArgumentException(warning);
+         }
 
          // set up portlet definition
 
@@ -810,12 +785,10 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
 
          PortletInfoType pit = portlet.getPortletInfo();
          if (pit != null) {
-            if (pit.getTitle().getValue() == null) {
-               warning = "Portlet info section does not contain title. Ingoring ...";
-               LOG.warn(warning);
-            } else {
-               String title, st = null, kw = null;
+               String title = null, st = null, kw = null;
+            if (pit.getTitle() != null) {
                title = pit.getTitle().getValue();
+            }
                if (pit.getShortTitle() != null) {
                   st = pit.getShortTitle().getValue();
                }
@@ -825,7 +798,6 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
                PortletInfo info = new PortletInfoImpl(title, kw, st);
                pd.setPortletInfo(info);
             }
-         }
 
          for (SupportedLocaleType slt : portlet.getSupportedLocale()) {
             pd.addSupportedLocale(slt.getValue());
@@ -840,8 +812,6 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
             Preferences newprefs = new PreferencesImpl();
 
             clsName = prefs.getPreferencesValidator();
-            checkValidClass(clsName, PreferencesValidator.class,
-                  "Bad portlet preferences validator class: ");
 
             newprefs.setPreferencesValidator(clsName);
             for (Preference p : handlePreferences(prefs.getPreference())) {
@@ -861,14 +831,8 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
          }
 
          for (String prp : portlet.getSupportedPublicRenderParameter()) {
-            boolean ok = false;
-            for (PublicRenderParameter prpdef : pad.getPublicRenderParameters()) {
-               if (prpdef.getIdentifier().equals(prp)) {
-                  ok = true;
-               }
-            }
-            if (!ok) {
-               warning = "Public render parameter definition not found for: " + prp;
+            if ((prp == null) || (prp.length() == 0)) {
+               warning = "Supported public render parameter definition may not be null.";
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -891,5 +855,12 @@ public class JSR362ConfigurationProcessor extends ConfigurationProcessor {
 
       }
    }
+   
+   /**
+    * validate the v3.0 configuration
+    */
+   public void validate () {
+      super.validate();             // reuse the 2.0 validation code
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
index 0adaf53..08cd166 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
@@ -239,6 +239,24 @@ public class PortletApplicationDefinitionImpl implements
       return ret;
    }
 
+   /**
+    * The portlet name can end with the wildcard character '*'. The wildcard 
+    * matches any suffix. For filter mapping.
+    * 
+    * @return     The list of matching portlets
+    */
+   @Override
+   public List<PortletDefinition> getMatchingPortlets(String portletName) {
+      ArrayList<PortletDefinition> ret = new ArrayList<PortletDefinition>();
+      String match = portletName.replaceAll("^(.*)\\*$",  "$1");
+      for (PortletDefinition pd : portlets) {
+         if (pd.getPortletName().startsWith(match)) {
+            ret.add(new PortletDefinitionImpl(pd));
+         }
+      }
+      return ret;
+   }
+
    @Override
    public void addPortlet(PortletDefinition pd) {
       portlets.add( pd);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
index d5201ce..53e6a2b 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
@@ -115,7 +115,7 @@ public class JaxbReadTest286Gen {
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType", portletApp.getEventDefinition().get(0).getValueType());
       assertEquals("lifecycle", portletApp.getFilter().get(0).getLifecycle().get(0));
       assertEquals("portlet286", portletApp.getFilterMapping().get(0).getPortletName().get(0).getValue());
-      assertEquals("org.apache.portal.ResourceBundle", portletApp.getResourceBundle().getValue());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", portletApp.getResourceBundle().getValue());
       assertEquals("2.0", portletApp.getVersion());
       
       // test container runtime options

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
index a9dbc46..286310a 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
@@ -104,7 +104,7 @@ public class JaxbReadTest362Gen {
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType", portletApp.getEventDefinition().get(0).getValueType());
       assertEquals("lifecycle", portletApp.getFilter().get(0).getLifecycle().get(0));
       assertEquals("portlet362", portletApp.getFilterMapping().get(0).getPortletName().get(0).getValue());
-      assertEquals("org.apache.portal.ResourceBundle", portletApp.getResourceBundle().getValue());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", portletApp.getResourceBundle().getValue());
       assertEquals("3.0", portletApp.getVersion());
       
       // test container runtime options

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
index b88f09b..9faab59 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
@@ -111,11 +111,11 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetSetId() {
-      String val = pad.getId();
+      String val = cut.getId();
       assertNotNull(val);
       assertEquals("id1", val);
-      pad.setId("42");
-      val = pad.getId();
+      cut.setId("42");
+      val = cut.getId();
       assertNotNull(val);
       assertEquals("42", val);
    }
@@ -125,8 +125,8 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetSetName() {
-      pad.setName("Bob");
-      String val = pad.getName();
+      cut.setName("Bob");
+      String val = cut.getName();
       assertNotNull(val);
       assertEquals("Bob", val);
    }
@@ -136,8 +136,8 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testSetGetContextPath() {
-      pad.setContextPath("Bob");
-      String val = pad.getContextPath();
+      cut.setContextPath("Bob");
+      String val = cut.getContextPath();
       assertNotNull(val);
       assertEquals("Bob", val);
    }
@@ -147,11 +147,11 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetSetVersion() {
-      String val = pad.getVersion();
+      String val = cut.getVersion();
       assertNotNull(val);
       assertEquals("2.0", val);
-      pad.setVersion("42");
-      val = pad.getVersion();
+      cut.setVersion("42");
+      val = cut.getVersion();
       assertNotNull(val);
       assertEquals("42", val);
    }
@@ -161,12 +161,12 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetSetResourceBundle() {
-      String val = pad.getResourceBundle();
+      String val = cut.getResourceBundle();
       String txt = "com.ibm.portal.ResourceBundle";
       assertNotNull(val);
-      assertEquals("org.apache.portal.ResourceBundle", val);
-      pad.setResourceBundle(txt);
-      val = pad.getResourceBundle();
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", val);
+      cut.setResourceBundle(txt);
+      val = cut.getResourceBundle();
       assertNotNull(val);
       assertEquals(txt, val);
    }
@@ -176,12 +176,12 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetSetDefaultNamespace() {
-      String val = pad.getDefaultNamespace();
+      String val = cut.getDefaultNamespace();
       String txt = "https://www.ibm.com/";
       assertNotNull(val);
       assertEquals("https://www.apache.org/", val);
-      pad.setDefaultNamespace(txt);
-      val = pad.getDefaultNamespace();
+      cut.setDefaultNamespace(txt);
+      val = cut.getDefaultNamespace();
       assertNotNull(val);
       assertEquals(txt, val);
    }
@@ -191,7 +191,7 @@ public class PortletApplicationDefinition286ImplTest {
     */
    @Test
    public void testGetPortlet() {
-      PortletDefinition pd = pad.getPortlet("portlet286");
+      PortletDefinition pd = cut.getPortlet("portlet286");
       assertNotNull(pd);
    }
 
@@ -648,5 +648,13 @@ public class PortletApplicationDefinition286ImplTest {
          assertEquals(testencs[ind], localemap.get(loc));
       }
    }
+   
+   /**
+    * Make sure validate() throws no exceptions
+    */
+   @Test
+   public void testValidate() {
+         cfp.validate();
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
index d8fb572..62e6cd2 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
@@ -294,7 +294,7 @@ public class PortletDefinition286ImplTest {
    @Test
    public void testGetResourceBundle() {
       assertNotNull(cut.getResourceBundle());
-      assertEquals("resource-bundle", cut.getResourceBundle());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", cut.getResourceBundle());
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
index de06e67..d71a219 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
@@ -111,11 +111,11 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetSetId() {
-      String val = pad.getId();
+      String val = cut.getId();
       assertNotNull(val);
       assertEquals("id1", val);
-      pad.setId("42");
-      val = pad.getId();
+      cut.setId("42");
+      val = cut.getId();
       assertNotNull(val);
       assertEquals("42", val);
    }
@@ -125,8 +125,8 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetSetName() {
-      pad.setName("Bob");
-      String val = pad.getName();
+      cut.setName("Bob");
+      String val = cut.getName();
       assertNotNull(val);
       assertEquals("Bob", val);
    }
@@ -136,8 +136,8 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testSetGetContextPath() {
-      pad.setContextPath("Bob");
-      String val = pad.getContextPath();
+      cut.setContextPath("Bob");
+      String val = cut.getContextPath();
       assertNotNull(val);
       assertEquals("Bob", val);
    }
@@ -147,11 +147,11 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetSetVersion() {
-      String val = pad.getVersion();
+      String val = cut.getVersion();
       assertNotNull(val);
       assertEquals("3.0", val);
-      pad.setVersion("42");
-      val = pad.getVersion();
+      cut.setVersion("42");
+      val = cut.getVersion();
       assertNotNull(val);
       assertEquals("42", val);
    }
@@ -161,12 +161,12 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetSetResourceBundle() {
-      String val = pad.getResourceBundle();
+      String val = cut.getResourceBundle();
       String txt = "com.ibm.portal.ResourceBundle";
       assertNotNull(val);
-      assertEquals("org.apache.portal.ResourceBundle", val);
-      pad.setResourceBundle(txt);
-      val = pad.getResourceBundle();
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", val);
+      cut.setResourceBundle(txt);
+      val = cut.getResourceBundle();
       assertNotNull(val);
       assertEquals(txt, val);
    }
@@ -176,12 +176,12 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetSetDefaultNamespace() {
-      String val = pad.getDefaultNamespace();
+      String val = cut.getDefaultNamespace();
       String txt = "https://www.ibm.com/";
       assertNotNull(val);
       assertEquals("https://www.apache.org/", val);
-      pad.setDefaultNamespace(txt);
-      val = pad.getDefaultNamespace();
+      cut.setDefaultNamespace(txt);
+      val = cut.getDefaultNamespace();
       assertNotNull(val);
       assertEquals(txt, val);
    }
@@ -191,7 +191,7 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testGetPortlet() {
-      PortletDefinition pd = pad.getPortlet("portlet362");
+      PortletDefinition pd = cut.getPortlet("portlet362");
       assertNotNull(pd);
    }
 
@@ -648,5 +648,13 @@ public class PortletApplicationDefinition362ImplTest {
          assertEquals(testencs[ind], localemap.get(loc));
       }
    }
+   
+   /**
+    * Make sure validate() throws no exceptions
+    */
+   @Test
+   public void testValidate() {
+         cfp.validate();
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
index e757ecd..902f163 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
@@ -294,7 +294,7 @@ public class PortletDefinition362ImplTest {
    @Test
    public void testGetResourceBundle() {
       assertNotNull(cut.getResourceBundle());
-      assertEquals("resource-bundle", cut.getResourceBundle());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", cut.getResourceBundle());
    }
 
    @Test

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/GoodBundle.properties
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/GoodBundle.properties b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/GoodBundle.properties
new file mode 100644
index 0000000..3ee6a03
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/GoodBundle.properties
@@ -0,0 +1,6 @@
+#
+# filename: clock_en.properties
+# Portlet Info resource bundle example
+javax.portlet.title=World Population Clock
+javax.portlet.short-title=WorldPopClock
+javax.portlet.keywords=World,Population,Clock

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet286Generated.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet286Generated.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet286Generated.xml
index 0a82e9b..530a569 100644
--- a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet286Generated.xml
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet286Generated.xml
@@ -41,7 +41,7 @@ http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
          <portlet:window-state>window-state3</portlet:window-state>
       </supports>
       <supported-locale>supported-locale</supported-locale>
-      <resource-bundle>resource-bundle</resource-bundle>
+      <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
       <portlet-info id="info1">
          <title>title</title>
          <short-title>short-title</short-title>
@@ -102,7 +102,7 @@ http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
          <transport-guarantee>NONE</transport-guarantee>
       </user-data-constraint>
    </security-constraint>
-   <resource-bundle>org.apache.portal.ResourceBundle</resource-bundle>
+   <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
    <filter>
       <description xml:lang="de">description</description>
       <display-name xml:lang="de">display-name</display-name>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/fef12ee1/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
index f3cd5a7..ba572d2 100644
--- a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
@@ -43,7 +43,7 @@
          <portlet:window-state>window-state3</portlet:window-state>
       </supports>
       <supported-locale>supported-locale</supported-locale>
-      <resource-bundle>resource-bundle</resource-bundle>
+      <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
       <portlet-info id="info1">
          <title>title</title>
          <short-title>short-title</short-title>
@@ -104,7 +104,7 @@
          <transport-guarantee>NONE</transport-guarantee>
       </user-data-constraint>
    </security-constraint>
-   <resource-bundle>org.apache.portal.ResourceBundle</resource-bundle>
+   <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
    <filter>
       <description xml:lang="de">description</description>
       <display-name xml:lang="de">display-name</display-name>


[04/35] portals-pluto git commit: Changed PortletConfigurations#configurations to ..#value

Posted by ms...@apache.org.
Changed PortletConfigurations#configurations to ..#value


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

Branch: refs/heads/V3Prototype
Commit: a283cd04ba581c7bbc4e9b207d718a838bdf22e9
Parents: ef7da94
Author: Scott Nicklous <ms...@apache.org>
Authored: Sun Dec 6 19:29:22 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sun Dec 6 19:29:22 2015 +0100

----------------------------------------------------------------------
 .../main/java/javax/portlet/annotations/PortletConfigurations.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a283cd04/portlet-api/src/main/java/javax/portlet/annotations/PortletConfigurations.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfigurations.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfigurations.java
index cf05926..9aa1f62 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfigurations.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfigurations.java
@@ -47,5 +47,5 @@ public @interface PortletConfigurations {
     * 
     * @return     An array of portlet configurations
     */
-   PortletConfiguration[] configurations();
+   PortletConfiguration[] value();
 }


[10/35] portals-pluto git commit: Prepared for annotated portlet demo. Modified the Pluto container initializer to process the required configuration annotations.

Posted by ms...@apache.org.
Prepared for annotated portlet demo. Modified the Pluto container
initializer to process the required configuration annotations.


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

Branch: refs/heads/V3Prototype
Commit: df30f96a796e22820da6dda7d03c6f1c68835302
Parents: ab12285
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Dec 7 09:29:41 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Dec 7 09:29:41 2015 +0100

----------------------------------------------------------------------
 PortletV3AnnotatedDemo/pom.xml                  | 133 +++++++++++++++++++
 .../src/main/resources/logging.properties       |  37 ++++++
 .../driver/PortletContainerInitializer.java     |   8 +-
 pom.xml                                         |   1 +
 4 files changed, 178 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/df30f96a/PortletV3AnnotatedDemo/pom.xml
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/pom.xml b/PortletV3AnnotatedDemo/pom.xml
new file mode 100644
index 0000000..f84c9e4
--- /dev/null
+++ b/PortletV3AnnotatedDemo/pom.xml
@@ -0,0 +1,133 @@
+<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>3.0-SNAPSHOT</version>
+    </parent>
+
+   <artifactId>PortletV3AnnotatedDemo</artifactId>
+   <packaging>war</packaging>
+
+   <dependencies>
+      <dependency>
+        <groupId>org.apache.portals.pluto</groupId>
+        <artifactId>portlet-api</artifactId>
+        <version>${project.version}</version>
+        <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.portals.pluto</groupId>
+         <artifactId>pluto-taglib</artifactId>
+         <version>${project.version}</version>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.tomcat</groupId>
+         <artifactId>tomcat-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>org.apache.taglibs</groupId>
+         <artifactId>taglibs-standard-spec</artifactId>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.taglibs</groupId>
+          <artifactId>taglibs-standard-impl</artifactId>
+          <scope>provided</scope>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.taglibs</groupId>
+          <artifactId>taglibs-standard-jstlel</artifactId>
+          <scope>provided</scope>
+      </dependency>
+   </dependencies>
+
+   <build>
+      <finalName>PortletV3AnnotatedDemo</finalName>
+      <plugins>
+         <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <configuration>
+               <source>1.7</source>
+               <target>1.7</target>
+            </configuration>
+         </plugin>
+         <plugin>
+            <artifactId>maven-war-plugin</artifactId>
+            <configuration>
+               <archiveClasses>false</archiveClasses>
+               <failOnMissingWebXml>false</failOnMissingWebXml>
+            </configuration>
+         </plugin>
+      </plugins>
+   </build>
+
+   <profiles>
+      <profile>
+         <id>pluto</id>
+         <activation>
+           <property>
+             <name>!alwaysActivate</name>
+           </property>
+         </activation>
+    
+         <dependencies>
+            <dependency>
+                <groupId>org.apache.taglibs</groupId>
+                <artifactId>taglibs-standard-spec</artifactId>
+                <scope>compile</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.taglibs</groupId>
+                <artifactId>taglibs-standard-impl</artifactId>
+                <scope>compile</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.taglibs</groupId>
+                <artifactId>taglibs-standard-jstlel</artifactId>
+                <scope>compile</scope>
+            </dependency>
+         </dependencies>
+         
+         <build>
+            <plugins>
+               <plugin>
+                 <artifactId>maven-war-plugin</artifactId>
+                 <configuration>
+                   <archiveClasses>false</archiveClasses>
+                 </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>
+            </plugins>
+         </build>
+      </profile>
+   </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/df30f96a/PortletV3AnnotatedDemo/src/main/resources/logging.properties
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/resources/logging.properties b/PortletV3AnnotatedDemo/src/main/resources/logging.properties
new file mode 100644
index 0000000..0e27358
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/resources/logging.properties
@@ -0,0 +1,37 @@
+# 
+# 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.
+
+handlers = org.apache.juli.FileHandler
+
+############################################################
+#
+# JDK 1.4+ logging handler specific properties for Pluto portal
+# using Tomcat's custom implementation of LogManager.
+# Logging level can be set to any one of:
+# SEVERE, WARN, INFO, CONFIG, FINE, FINEST or ALL. 
+# See the Tomcat documentation for more details.
+# 
+############################################################
+
+org.apache.juli.FileHandler.level = FINE
+org.apache.juli.FileHandler.directory = ${catalina.base}/logs
+#Log file will be named pluto.<yyyy-mm-dd>.log
+org.apache.juli.FileHandler.prefix = PortletV3AnnotatedDemo.
+
+org.apache.pluto.level=FINEST
+basic.portlet.level=FINEST

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/df30f96a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index b9cb00d..ff90207 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -21,10 +21,15 @@ package org.apache.pluto.container.driver;
 import java.io.InputStream;
 import java.util.Set;
 
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.filter.PortletFilter;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRegistration;
+import javax.servlet.annotation.HandlesTypes;
 
 import org.apache.pluto.container.PortletInvokerService;
 import org.apache.pluto.container.om.portlet.PortletDefinition;
@@ -39,7 +44,8 @@ import org.slf4j.LoggerFactory;
  * @author Scott Nicklous
  * 
  */
-// @HandlesTypes({PortletApplication.class, PortletConfiguration.class})
+@HandlesTypes({PortletApplication.class, PortletConfiguration.class,
+               PortletFilter.class, PortletConfigurations.class})
 public class PortletContainerInitializer implements ServletContainerInitializer {
 
    private static final String WEB_XML     = "/WEB-INF/web.xml";

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/df30f96a/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 3b22b0e..8e5d552 100644
--- a/pom.xml
+++ b/pom.xml
@@ -644,6 +644,7 @@ TODO: Check if we need all of them. -->
         <!-- PortletHub demo portlets -->
         <module>PortletHubDemo</module>
         <module>PortletV3Demo</module>
+        <module>PortletV3AnnotatedDemo</module>
 
         <!-- Pluto Utilities, Maven Plugins and Ant Tasks -->
         <module>pluto-util</module>


[20/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ResourceTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ResourceTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ResourceTest.java
new file mode 100644
index 0000000..c409481
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ResourceTest.java
@@ -0,0 +1,375 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.RESOURCE;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.resource.Resource1;
+import org.apache.pluto.container.bean.processor.fixtures.resource.Resource2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Resource1.class)
+public class ResourceTest {
+
+   @Inject
+   AnnotatedConfigBean          acb;
+
+   private AnnotatedMethodStore ams     = null;
+   private ConfigSummary        summary = null;
+
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(6, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("*"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+      assertTrue(names.contains("portlet7"));
+   }
+
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+
+   @Test
+   public void errorBadException() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet8"));
+   }
+
+   @Test
+   public void errorBadAsterisk() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("*"));
+   }
+
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "", "admin" });
+      assertEquals(2, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RESOURCE, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet1", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "help", "edit", "config", "admin" });
+      assertEquals(4, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RESOURCE, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet2", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+      List<String> ids = Arrays.asList(new String[] { "", "admin", "help" });
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RESOURCE, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+
+   @Test
+   public void class1Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource1a", "resource1b", "resource1c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class1aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "admin", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resourceAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   @Test
+   public void class2aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "admin", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resourceAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2hTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "help", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource2a" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2bTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "edit", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource2c", "resource2b", "resource2d" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class2cTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "config", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource2c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class3Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource3c", "resource3a", "resource3b" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class3aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "admin", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resourceAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class6Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource6and7", "resource6andStar" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class6aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "admin", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resourceAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resource6and7" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "admin", RESOURCE);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "resourceAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Resource2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+   @Test
+   public void procEvent1Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/WeldInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/WeldInitializer.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/WeldInitializer.java
new file mode 100644
index 0000000..ea544a3
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/WeldInitializer.java
@@ -0,0 +1,42 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import org.jboss.weld.environment.se.Weld;
+import org.jboss.weld.environment.se.WeldContainer;
+
+/**
+ * Class that doesn't do much except for initializing weld.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class WeldInitializer {
+
+   // for Weld container initialization
+   public static Weld weld;
+   public static WeldContainer beanContainer;
+   static {
+      weld = new Weld();
+      beanContainer = weld.initialize();
+      System.out.println("SUI: static initializer - initialized Weld");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/package-info.java
new file mode 100644
index 0000000..c2cd1a1
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/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.
+ */
+
+/**
+ * Contains bean processor unit tests.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.bean.processor.tests;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
index 8f7ef42..48c6559 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
@@ -52,8 +52,6 @@ public class JaxbReadTest168Gen {
          Unmarshaller um = cntxt.createUnmarshaller();
          JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(in);
          assertNotNull(jel.getValue());
-         System.out.println("===> Object type: "
-               + jel.getValue().getClass().getCanonicalName());
          assertTrue(jel.getValue() instanceof PortletAppType);
          portletApp = (PortletAppType) jel.getValue();
       } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168NC.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168NC.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168NC.java
index 5d0a63e..fdd8cf6 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168NC.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168NC.java
@@ -55,8 +55,6 @@ public class JaxbReadTest168NC {
          Unmarshaller um = cntxt.createUnmarshaller();
          JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(in);
          assertNotNull(jel.getValue());
-         System.out.println("===> Object type: "
-               + jel.getValue().getClass().getCanonicalName());
          assertTrue(jel.getValue() instanceof PortletAppType);
          portletApp = (PortletAppType) jel.getValue();
       } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
index e5f5b9d..d8f8e7b 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
@@ -56,8 +56,6 @@ public class JaxbReadTest286Gen {
          Unmarshaller um = cntxt.createUnmarshaller();
          JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(in);
          assertNotNull(jel.getValue());
-         System.out.println("===> Object type: "
-               + jel.getValue().getClass().getCanonicalName());
          assertTrue(jel.getValue() instanceof PortletAppType);
          portletApp = (PortletAppType) jel.getValue();
       } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
index b509250..182a015 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
@@ -52,8 +52,6 @@ public class JaxbReadTest286NC {
          Unmarshaller um = cntxt.createUnmarshaller();
          JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(in);
          assertNotNull(jel.getValue());
-         System.out.println("===> Object type: "
-               + jel.getValue().getClass().getCanonicalName());
          assertTrue(jel.getValue() instanceof PortletAppType);
          portletApp = (PortletAppType) jel.getValue();
       } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
index eaf09db..627c46e 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
@@ -52,8 +52,6 @@ public class JaxbReadTest362Gen {
          Unmarshaller um = cntxt.createUnmarshaller();
          JAXBElement<?> jel = (JAXBElement<?>) um.unmarshal(in);
          assertNotNull(jel.getValue());
-         System.out.println("===> Object type: "
-               + jel.getValue().getClass().getCanonicalName());
          assertTrue(jel.getValue() instanceof PortletAppType);
          portletApp = (PortletAppType) jel.getValue();
       } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/IncompletePortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/IncompletePortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/IncompletePortlet.java
new file mode 100644
index 0000000..cf95d64
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/IncompletePortlet.java
@@ -0,0 +1,87 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.DestroyMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.InitMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * A bean portlet that contains no render, headers, or resource method. This 
+ * portlet should be purged from the configuration.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@ApplicationScoped
+public class IncompletePortlet {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private PortletConfig config;
+
+   @InitMethod("IncompletePortlet")
+   public void init(PortletConfig config) {
+      this.config = config;
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(config != null);
+   }
+
+   @DestroyMethod("IncompletePortlet")
+   public void destroy() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy");
+      meths.setConfigExists(config != null);
+   }
+   
+   @ActionMethod(portletName="IncompletePortlet", publishingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event1"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   })
+   public void doAction(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doAction");
+      meths.setConfigExists(config != null);
+   }
+   
+   @EventMethod(portletName="IncompletePortlet", 
+         processingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event2"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   },
+         publishingEvents = {
+         @PortletQName(namespaceURI="", localPart="event3"),
+   })
+   public void doEvent(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent");
+      meths.setConfigExists(config != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1.java
new file mode 100644
index 0000000..41c9346
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1.java
@@ -0,0 +1,126 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.EventDefinition;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+@PortletApplication(
+      defaultNamespaceURI="https://www.java.net/",
+      events = {
+            @EventDefinition(qname=@PortletQName(namespaceURI="http://www.apache.org/", localPart="event1")),
+            @EventDefinition(qname=@PortletQName(namespaceURI="", localPart="event4"))
+      }
+)
+@PortletConfigurations( {
+   @PortletConfiguration(portletName="Portlet1", 
+   initParams = {
+         @InitParameter(name="color", value="#cafeba"),
+      },
+      description={
+         @LocaleString("Portlet displaying the time in different time zones"),
+      }, displayName={
+         @LocaleString("Time Zone Clock Portlet"),
+      }, title={
+         @LocaleString("Annotated Portlet"),
+      }, shortTitle={
+         @LocaleString("Anno Portlet"),
+      }, keywords={
+         @LocaleString("One, Two, Three"),
+      }
+   ),
+})
+public class TestPortlet1 extends GenericPortlet {
+   
+   @Inject
+   private InvocationResults meths;
+
+   @Override
+   public void destroy() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy");
+      meths.setConfigExists(getPortletConfig() != null);
+      super.destroy();
+   }
+
+   @Override
+   public void init(PortletConfig config) throws PortletException {
+      super.init(config);
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void processAction(ActionRequest arg0, ActionResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#processAction");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void processEvent(EventRequest arg0, EventResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#processEvent");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void render(RenderRequest arg0, RenderResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#render");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void renderHeaders(HeaderRequest request, HeaderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#renderHeaders");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void serveResource(ResourceRequest arg0, ResourceResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#serveResource");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1AppScoped.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1AppScoped.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1AppScoped.java
new file mode 100644
index 0000000..263196a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1AppScoped.java
@@ -0,0 +1,32 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.portlet.GenericPortlet;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+@ApplicationScoped
+public class TestPortlet1AppScoped extends GenericPortlet {
+   // add portlet methods
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1a.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1a.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1a.java
new file mode 100644
index 0000000..3289ba1
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet1a.java
@@ -0,0 +1,68 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * A bean portlet with configuration values.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class TestPortlet1a {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @ActionMethod(portletName="Portlet1", actionName="Fred", publishingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event2"),
+         @PortletQName(namespaceURI="", localPart="event3"),
+         @PortletQName(namespaceURI="unknown", localPart="anotherBad"),
+   })
+   public void doAction(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doAction");
+      meths.setConfigExists(false);
+   }
+   
+   @EventMethod(portletName="Portlet1", 
+         processingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event1"),
+         @PortletQName(namespaceURI="", localPart="event3"),
+         @PortletQName(namespaceURI="unknown", localPart="eventBad"),
+   },
+         publishingEvents = {
+         @PortletQName(namespaceURI="", localPart="event4"),
+   })
+   public void doEvent(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent");
+      meths.setConfigExists(false);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet2.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet2.java
new file mode 100644
index 0000000..d569680
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet2.java
@@ -0,0 +1,90 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletQName;
+import javax.portlet.annotations.RenderMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * A bean portlet with configuration values.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@PortletConfiguration(portletName="Portlet2", 
+initParams = {
+      @InitParameter(name="color", value="#def"),
+   },
+   description={
+      @LocaleString(locale="de", value="Dieses Portlet zeigt die Zeit in verschiedenen Zeitzonen an")
+   }, displayName={
+      @LocaleString(locale="de", value="ZeitzonenPortlet")
+   }, title={
+      @LocaleString(locale="DE", value="Annotiertes Portlet")
+   }, shortTitle={
+      @LocaleString(locale="DE", value="Ein Portlet")
+   }, keywords={
+      @LocaleString(locale="DE", value="Eins, Zwei, Drei")
+   }
+)
+public class TestPortlet2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @RenderMethod(portletNames="Portlet2")
+   public String myView() {
+      meths.addMethod(this.getClass().getSimpleName() + "#myView");
+      return null;
+   }
+   
+   @ActionMethod(portletName="Portlet2", publishingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event1"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   })
+   public void doAction(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doAction");
+   }
+   
+   @EventMethod(portletName="Portlet2", 
+         processingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event2"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   },
+         publishingEvents = {
+         @PortletQName(namespaceURI="", localPart="event3"),
+   })
+   public void doEvent(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet3.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet3.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet3.java
new file mode 100644
index 0000000..a3a4acc
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet3.java
@@ -0,0 +1,73 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.Portlet;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class TestPortlet3 implements Portlet {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private PortletConfig config;
+
+   @Override
+   public void destroy() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy");
+      meths.setConfigExists(config != null);
+   }
+
+   @Override
+   public void init(PortletConfig config) throws PortletException {
+      this.config = config;
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(config != null);
+   }
+
+   @Override
+   public void processAction(ActionRequest arg0, ActionResponse arg1)
+         throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#processAction");
+      meths.setConfigExists(config != null);
+   }
+
+   @Override
+   public void render(RenderRequest arg0, RenderResponse arg1)
+         throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#render");
+      meths.setConfigExists(config != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet4.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet4.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet4.java
new file mode 100644
index 0000000..ca44cd0
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet4.java
@@ -0,0 +1,103 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.DestroyMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.InitMethod;
+import javax.portlet.annotations.PortletQName;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ServeResourceMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * A bean portlet with no corresponding configuration. 
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@ApplicationScoped
+public class TestPortlet4 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private PortletConfig config;
+
+   @InitMethod("Portlet4")
+   public void init(PortletConfig config) {
+      this.config = config;
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(config != null);
+   }
+
+   @DestroyMethod("Portlet4")
+   public void destroy() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy");
+      meths.setConfigExists(config != null);
+   }
+   
+   @RenderMethod(portletNames="Portlet4", portletMode="")
+   public String myView() {
+      meths.addMethod(this.getClass().getSimpleName() + "#myView");
+      meths.setConfigExists(config != null);
+      return null;
+   }
+   
+   @ActionMethod(portletName="Portlet4", publishingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event1"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   })
+   public void doAction(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doAction");
+      meths.setConfigExists(config != null);
+   }
+   
+   @EventMethod(portletName="Portlet4", 
+         processingEvents = {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event2"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   },
+         publishingEvents = {
+         @PortletQName(namespaceURI="", localPart="event3"),
+   })
+   public void doEvent(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent");
+      meths.setConfigExists(config != null);
+   }
+
+   @ServeResourceMethod(portletNames="Portlet4")
+   public void res(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#res");
+      meths.setConfigExists(config != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet5.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet5.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet5.java
new file mode 100644
index 0000000..6877f72
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet5.java
@@ -0,0 +1,131 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.EventDefinition;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+@PortletApplication(
+      defaultNamespaceURI="https://www.java.net/",
+      events = {
+            @EventDefinition(qname=@PortletQName(namespaceURI="http://www.apache.org/", localPart="event1")),
+            @EventDefinition(qname=@PortletQName(namespaceURI="", localPart="event4"))
+      }
+)
+@PortletConfigurations( {
+   @PortletConfiguration(portletName="Portlet5", 
+   initParams = {
+         @InitParameter(name="color", value="#cafeba"),
+      },
+      description={
+         @LocaleString("Portlet displaying the time in different time zones"),
+      }, displayName={
+         @LocaleString("Time Zone Clock Portlet"),
+      }, title={
+         @LocaleString("Annotated Portlet"),
+      }, shortTitle={
+         @LocaleString("Anno Portlet"),
+      }, keywords={
+         @LocaleString("One, Two, Three"),
+      }
+   ),
+})
+public class TestPortlet5 extends GenericPortlet {
+   
+   @Inject
+   private InvocationResults meths;
+
+   @Override
+   public void destroy() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy");
+      meths.setConfigExists(getPortletConfig() != null);
+      super.destroy();
+   }
+
+   @Override
+   public void init(PortletConfig config) throws PortletException {
+      super.init(config);
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void processAction(ActionRequest arg0, ActionResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#processAction");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   @EventMethod(portletName="Portlet5", processingEvents= {
+         @PortletQName(namespaceURI="http://www.apache.org/", localPart="event1"),
+         @PortletQName(namespaceURI="", localPart="event4"),
+   })
+   public void processEvent(EventRequest arg0, EventResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#processEvent");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void render(RenderRequest arg0, RenderResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#render");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void renderHeaders(HeaderRequest request, HeaderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#renderHeaders");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void serveResource(ResourceRequest arg0, ResourceResponse arg1) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#serveResource");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet6.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet6.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet6.java
new file mode 100644
index 0000000..5eed2bd
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/TestPortlet6.java
@@ -0,0 +1,122 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.fixtures;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletException;
+import javax.portlet.ProcessAction;
+import javax.portlet.ProcessEvent;
+import javax.portlet.RenderMode;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.annotations.EventDefinition;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * Portlet for testing invocation of GenericPortlet method features.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+@PortletApplication(
+      defaultNamespaceURI="https://www.java.net/",
+      events = {
+            @EventDefinition(qname=@PortletQName(namespaceURI="http://www.apache.org/", localPart="event1")),
+            @EventDefinition(qname=@PortletQName(namespaceURI="", localPart="event4"))
+      }
+)
+@PortletConfiguration(portletName="Portlet6")
+public class TestPortlet6 extends GenericPortlet {
+   
+   @Inject
+   private InvocationResults meths;
+
+   @Override
+   public void init() {
+      meths.addMethod(this.getClass().getSimpleName() + "#init");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void doView(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#doView");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void doEdit(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEdit");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void doHeaders(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doHeaders");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @Override
+   public void doHelp(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doHelp");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+ 
+   @RenderMode(name="config")
+   public void doConfig(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doConfig");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+   
+   @RenderMode(name="admin")
+   public void doAdmin(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doAdmin");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+   
+   @ProcessAction(name="Fred")
+   public void doFred(ActionRequest request, ActionResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doFred");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @ProcessEvent(qname="{http://www.apache.org/}event1")
+   public void doEvent1(EventRequest request, EventResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent1");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+   @ProcessEvent(qname="{https://www.java.net/}event4")
+   public void doEvent4(EventRequest request, EventResponse response) throws PortletException, IOException {
+      meths.addMethod(this.getClass().getSimpleName() + "#doEvent4");
+      meths.setConfigExists(getPortletConfig() != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/package-info.java
new file mode 100644
index 0000000..2ba6477
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/fixtures/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.
+ */
+
+/**
+ * Fixtures for config reconciliation tests.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.reconcile.fixtures;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/AnnotatedGenericPortletInvokeTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/AnnotatedGenericPortletInvokeTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/AnnotatedGenericPortletInvokeTest.java
new file mode 100644
index 0000000..fd60857
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/AnnotatedGenericPortletInvokeTest.java
@@ -0,0 +1,170 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet5;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that if a generic portlet event method is annotated to provide the processing
+ * event reference QNames, the methods are part of te same portlet instance.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, InvokeHelper.class, TestPortlet5.class})
+public class AnnotatedGenericPortletInvokeTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   private InvokeHelper helper;
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet5.class;
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   // Classes under test
+   private AnnotatedMethodStore ams = null;
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+      assertNotNull(helper);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+      
+      helper.init("Portlet5", null);
+   }
+  
+   // Begin portlet 1 tests ================================== 
+
+   @Test
+   public void test1init() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#init";
+      helper.init("Portlet5", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1destroy() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#destroy";
+      helper.destroy("Portlet5", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1action() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#processAction";
+      helper.action("Portlet5", null, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1event1() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#processEvent";
+      QName qn = new QName("http://www.apache.org/", "event1");
+      helper.event("Portlet5", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1event2() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#processEvent";
+      QName qn = new QName("https://www.java.net/", "event4");
+      helper.event("Portlet5", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1header() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#renderHeaders";
+      PortletMode pm = PortletMode.VIEW;
+      helper.header("Portlet5", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1render() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#render";
+      PortletMode pm = PortletMode.VIEW;
+      helper.render("Portlet5", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1res() throws Exception {
+      String expectedMeth = TestPortlet5.class.getSimpleName() + "#serveResource";
+      String resid = null;
+      helper.resource("Portlet5", resid, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/CDIPrototyping.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/CDIPrototyping.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/CDIPrototyping.java
new file mode 100644
index 0000000..9d64317
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/CDIPrototyping.java
@@ -0,0 +1,143 @@
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.*;
+
+import java.util.Set;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.inject.Inject;
+import javax.portlet.EventPortlet;
+import javax.portlet.GenericPortlet;
+import javax.portlet.HeaderPortlet;
+import javax.portlet.Portlet;
+import javax.portlet.ResourceServingPortlet;
+
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1AppScoped;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(CdiRunner.class)
+@AdditionalClasses({TestPortlet1.class, TestPortlet1AppScoped.class})
+public class CDIPrototyping {
+
+   @Inject
+   BeanManager bm;
+   
+   @Test
+   public void beanMgrTest() throws Exception {
+      assertNotNull(bm);
+      
+      Set<Bean<?>> beans = bm.getBeans(TestPortlet1.class);
+      Bean<?> bean = bm.resolve(beans);
+      assertNotNull(bean);
+      
+      CreationalContext<?> coco = bm.createCreationalContext(bean);
+      assertNotNull(coco);
+      
+      Object obj = bm.getReference(bean, TestPortlet1.class, coco);
+      assertNotNull(obj);
+      assertTrue(obj instanceof GenericPortlet);
+      assertTrue(obj instanceof Portlet);
+      assertTrue(obj instanceof HeaderPortlet);
+      assertTrue(obj instanceof EventPortlet);
+      assertTrue(obj instanceof ResourceServingPortlet);
+      
+      Object obj2 = bm.getReference(bean, TestPortlet1.class, coco);
+      assertNotNull(obj2);
+      assertFalse(obj.equals(obj2));
+      assertFalse(obj == obj2);
+   }
+   
+   @Test
+   public void appScopedTest() throws Exception {
+      assertNotNull(bm);
+      
+      Set<Bean<?>> beans = bm.getBeans(TestPortlet1AppScoped.class);
+      Bean<?> bean = bm.resolve(beans);
+      assertNotNull(bean);
+      
+      CreationalContext<?> coco = bm.createCreationalContext(bean);
+      assertNotNull(coco);
+      
+      Object obj = bm.getReference(bean, TestPortlet1AppScoped.class, coco);
+      assertNotNull(obj);
+      assertTrue(obj instanceof GenericPortlet);
+      assertTrue(obj instanceof Portlet);
+      assertTrue(obj instanceof HeaderPortlet);
+      assertTrue(obj instanceof EventPortlet);
+      assertTrue(obj instanceof ResourceServingPortlet);
+      
+      Object obj2 = bm.getReference(bean, TestPortlet1AppScoped.class, coco);
+      assertNotNull(obj2);
+      assertTrue(obj.equals(obj2));
+      assertTrue(obj == obj2);
+   }
+   
+   @Test
+   public void appScopedTest2Coco() throws Exception {
+      assertNotNull(bm);
+      
+      Set<Bean<?>> beans = bm.getBeans(TestPortlet1AppScoped.class);
+      Bean<?> bean = bm.resolve(beans);
+      assertNotNull(bean);
+      
+      CreationalContext<?> coco1 = bm.createCreationalContext(bean);
+      assertNotNull(coco1);
+      
+      Object obj = bm.getReference(bean, TestPortlet1AppScoped.class, coco1);
+      assertNotNull(obj);
+      assertTrue(obj instanceof GenericPortlet);
+      assertTrue(obj instanceof Portlet);
+      assertTrue(obj instanceof HeaderPortlet);
+      assertTrue(obj instanceof EventPortlet);
+      assertTrue(obj instanceof ResourceServingPortlet);
+      
+      CreationalContext<?> coco2 = bm.createCreationalContext(bean);
+      assertNotNull(coco2);
+      
+      Object obj2 = bm.getReference(bean, TestPortlet1AppScoped.class, coco2);
+      assertNotNull(obj2);
+      assertTrue(obj.equals(obj2));
+      assertTrue(obj == obj2);
+   }
+   
+   @Test
+   public void appScopedTest2Coco2Bean() throws Exception {
+      assertNotNull(bm);
+      
+      Set<Bean<?>> beans1 = bm.getBeans(TestPortlet1AppScoped.class);
+      Bean<?> bean1 = bm.resolve(beans1);
+      assertNotNull(bean1);
+      
+      CreationalContext<?> coco1 = bm.createCreationalContext(bean1);
+      assertNotNull(coco1);
+      
+      Object obj = bm.getReference(bean1, TestPortlet1AppScoped.class, coco1);
+      assertNotNull(obj);
+      assertTrue(obj instanceof GenericPortlet);
+      assertTrue(obj instanceof Portlet);
+      assertTrue(obj instanceof HeaderPortlet);
+      assertTrue(obj instanceof EventPortlet);
+      assertTrue(obj instanceof ResourceServingPortlet);
+      
+      Set<Bean<?>> beans2 = bm.getBeans(TestPortlet1AppScoped.class);
+      Bean<?> bean2 = bm.resolve(beans2);
+      assertNotNull(bean2);
+      
+      CreationalContext<?> coco2 = bm.createCreationalContext(bean2);
+      assertNotNull(coco2);
+      
+      Object obj2 = bm.getReference(bean2, TestPortlet1AppScoped.class, coco2);
+      assertNotNull(obj2);
+      assertTrue(obj.equals(obj2));
+      assertTrue(obj == obj2);
+      
+      assertEquals(bean1, bean2);
+      assertNotEquals(coco1, coco2);
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/GenericPortletFeaturesInvokeTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/GenericPortletFeaturesInvokeTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/GenericPortletFeaturesInvokeTest.java
new file mode 100644
index 0000000..e211836
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/GenericPortletFeaturesInvokeTest.java
@@ -0,0 +1,196 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet6;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that if a generic portlet event method is annotated to provide the processing
+ * event reference QNames, the methods are part of te same portlet instance.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, InvokeHelper.class, TestPortlet6.class})
+public class GenericPortletFeaturesInvokeTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   private InvokeHelper helper;
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet6.class;
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   // Classes under test
+   private AnnotatedMethodStore ams = null;
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+      assertNotNull(helper);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+      
+      helper.init("Portlet6", null);
+   }
+  
+   // Begin portlet 1 tests ================================== 
+
+   @Test
+   public void test6init() throws Exception {
+      String expectedMeth = TestPortlet6.class.getSimpleName() + "#init";
+      helper.init("Portlet6", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6action() throws Exception {
+      String expectedMeth = TestPortlet6.class.getSimpleName() + "#doFred";
+      helper.action("Portlet6", "Fred", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6event1() throws Exception {
+      String expectedMeth = TestPortlet6.class.getSimpleName() + "#doEvent1";
+      QName qn = new QName("http://www.apache.org/", "event1");
+      helper.event("Portlet6", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6event4() throws Exception {
+      String expectedMeth = TestPortlet6.class.getSimpleName() + "#doEvent4";
+      QName qn = new QName("https://www.java.net/", "event4");
+      helper.event("Portlet6", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6doView() throws Exception {
+      List<String> methNames = Arrays.asList(new String[] {
+            TestPortlet6.class.getSimpleName() + "#doHeaders",
+            TestPortlet6.class.getSimpleName() + "#doView",
+      });
+      PortletMode pm = PortletMode.VIEW;
+      helper.renderWithHeaders("Portlet6", pm, methNames);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6doHelp() throws Exception {
+      List<String> methNames = Arrays.asList(new String[] {
+            TestPortlet6.class.getSimpleName() + "#doHeaders",
+            TestPortlet6.class.getSimpleName() + "#doHelp",
+      });
+      PortletMode pm = PortletMode.HELP;
+      helper.renderWithHeaders("Portlet6", pm, methNames);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6doEdit() throws Exception {
+      List<String> methNames = Arrays.asList(new String[] {
+            TestPortlet6.class.getSimpleName() + "#doHeaders",
+            TestPortlet6.class.getSimpleName() + "#doEdit",
+      });
+      PortletMode pm = PortletMode.EDIT;
+      helper.renderWithHeaders("Portlet6", pm, methNames);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6doConfig() throws Exception {
+      List<String> methNames = Arrays.asList(new String[] {
+            TestPortlet6.class.getSimpleName() + "#doHeaders",
+            TestPortlet6.class.getSimpleName() + "#doConfig",
+      });
+      PortletMode pm = new PortletMode("config");
+      helper.renderWithHeaders("Portlet6", pm, methNames);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test6doAdmin() throws Exception {
+      List<String> methNames = Arrays.asList(new String[] {
+            TestPortlet6.class.getSimpleName() + "#doHeaders",
+            TestPortlet6.class.getSimpleName() + "#doAdmin",
+      });
+      PortletMode pm = new PortletMode("admin");
+      helper.renderWithHeaders("Portlet6", pm, methNames);
+      assertTrue(meths.isConfigExists());
+   }
+   
+}


[27/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedBeanHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedBeanHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedBeanHolder.java
new file mode 100644
index 0000000..04477a1
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedBeanHolder.java
@@ -0,0 +1,241 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.portlet.PortletRequest;
+import javax.portlet.StateAwareResponse;
+import javax.portlet.annotations.PortletSerializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is a container for PortletStateScoped CDI beans.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class PortletStateScopedBeanHolder implements Serializable {
+   
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletStateScopedBeanHolder.class);
+   private static final boolean isTrace = LOG.isTraceEnabled();
+   
+   private static final long serialVersionUID = 6014843414216617217L;
+   
+   // The ThreadLocal manages the holders so that there is one holder per thread.
+   private static final ThreadLocal<PortletStateScopedBeanHolder> holders =
+         new ThreadLocal<PortletStateScopedBeanHolder>();
+
+   private class BeanInstance<T> implements Serializable {
+      private static final long serialVersionUID = -4173708394115905180L;
+      CreationalContext<T>    crco;
+      T                       instance;
+   }
+   
+   // Each instance of the bean holder gets its own map.
+   // Key: Bean Type, Value: Structure containing CreationalContext and the specific
+   // bean instance.
+   private Map<Contextual<?>, BeanInstance<?>> beans = 
+         new ConcurrentHashMap<Contextual<?>, BeanInstance<?>>();
+   
+   private final PortletRequest request;
+   private final PortletStateScopedConfig config;
+   
+   /**
+    * private constructor
+    */
+   private PortletStateScopedBeanHolder(PortletRequest req, PortletStateScopedConfig config) {
+      this.request = req;
+      this.config = config;
+   }
+
+   /**
+    * Sets the portlet session bean holder in a ThreadLocal object for the given 
+    * portlet session. If no bean holder exists in the session, a new one is created.
+    * 
+    * @param  req    The portlet request
+    * @return        The portlet state bean holder
+    */
+   public static void setBeanHolder(PortletRequest req, PortletStateScopedConfig config) {
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Setting portlet state bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         LOG.trace(txt.toString());
+      }
+
+      PortletStateScopedBeanHolder holder = new PortletStateScopedBeanHolder(req, config);
+      holders.set(holder);
+   }
+   
+   /**
+    * Removes the bean holder for the current request. Deletes all beans contained therein.
+    * If response is provided, the beans are deserialized and stored.
+    * 
+    * @param resp    The response for setting the bean values
+    */
+   public static void removeBeanHolder(StateAwareResponse resp) {
+      
+      PortletStateScopedBeanHolder bh = getBeanHolder();
+      bh.removeAll(resp);
+      holders.remove();
+
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removed portlet state bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         LOG.trace(txt.toString());
+      }
+   }
+   
+   /**
+    * Returns the portlet session bean holder that was set for the thread.
+    * 
+    * @return
+    */
+   public static PortletStateScopedBeanHolder getBeanHolder() {
+      return holders.get();
+   }
+
+   /**
+    * Returns existing instance of object, or null if no instance exists.
+    * 
+    * @param bean    The bean type
+    * @return        The bean instance
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getBean(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+      return (bi == null) ? null : (T) bi.instance;
+   }
+   
+   /**
+    * Returns an instance for the contextual type. If no existing bean is available,
+    * a new instance is created.
+    * 
+    * @param bean       Contextual type (Bean) for which an instance is desired
+    * @return           The instance, or null if none exists
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getBean(Contextual<T> bean, CreationalContext<T> crco) {
+      BeanInstance<?> bi = beans.get(bean);
+      
+      if (bi == null) {
+         
+         // No bean available, so create one.
+         
+         BeanInstance<T> newbi = new BeanInstance<T>();
+         newbi.crco = crco;
+         newbi.instance = bean.create(crco);
+         assert newbi.instance instanceof PortletSerializable;
+         bi = newbi;
+         
+         // Determine the parameter name.
+         // initialize the bean with the proper values.
+         
+         assert bean instanceof Bean<?>;
+         String parmName = config.getParamName((Bean<?>) bean);
+         String[] vals = request.getRenderParameters().getValues(parmName);
+         if (vals == null) {
+            vals = new String[] {};
+         }
+
+         PortletSerializable thisBean = (PortletSerializable) newbi.instance;
+         thisBean.deserialize(vals);
+         beans.put(bean, newbi);
+
+         if (isTrace) {
+            StringBuilder txt = new StringBuilder(80);
+            txt.append("Created bean: ");
+            txt.append(((Bean<?>) bean).getBeanClass().getSimpleName());
+            txt.append(", Render parameter name: ").append(parmName);
+            txt.append(", Values: ").append(Arrays.toString(vals));
+            LOG.trace(txt.toString());
+         }
+
+      }
+  
+      return (T) bi.instance;
+   }
+   
+   /**
+    * Removes & destroys the given bean
+    * @param bean
+    */
+   @SuppressWarnings("unchecked")
+   protected <T> void remove(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removing portlet state scoped bean: ");
+         if (bean instanceof Bean<?>) {
+            Bean<?> b = (Bean<?>) bean;
+            txt.append(b.getBeanClass().getSimpleName());
+         }
+         if (bi == null) {
+            txt.append(", instance is null.");
+         }
+         LOG.trace(txt.toString());
+      }
+
+      if (bi != null) {
+         beans.remove(bean);
+         bi.crco.release();
+         bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco);
+      }
+   }
+   
+   /**
+    * Remove & destroy all beans. if a response is provided, store the bean state.
+    * 
+    * @param   resp     The state aware response
+    */
+   protected void removeAll(StateAwareResponse resp) {
+      for (Contextual<?> bean : beans.keySet()) {
+         if (resp != null) {
+            PortletSerializable thisBean = (PortletSerializable) beans.get(bean).instance;
+            String[] vals = thisBean.serialize();
+            String pn = config.getParamName((Bean<?>) bean);
+            resp.getRenderParameters().setValues(pn, vals);
+            
+            if (isTrace) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("Stored parameter for portlet with namespace: ");
+               txt.append(resp.getNamespace());
+               txt.append(", paramName: ").append(pn);
+               txt.append(", Values: ").append(Arrays.toString(vals));
+               LOG.trace(txt.toString());
+            }
+         }
+         remove(bean);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
new file mode 100644
index 0000000..b92b2cf
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
@@ -0,0 +1,207 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.portlet.annotations.PortletStateScoped;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Configuration for PortletStateScoped CDI beans.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class PortletStateScopedConfig  implements Serializable {
+   private static final long serialVersionUID = -5333145344722804837L;
+   private final Logger LOG = LoggerFactory.getLogger(PortletStateScopedConfig.class);
+   private final boolean isDebug = LOG.isDebugEnabled();
+   
+   
+   // Contains a sorted list of PortletStateScoped annotated class names. The sorted list
+   // is used to generate indexes for the assigned render parameter names.
+   private final List<String> sortedAnnotatedClassNames = new ArrayList<String>();
+   
+   // Prefix used when generating render parameter names
+   private static final String   RP_PREFIX = "\uFE34";
+
+   // Description for the PortletStateScoped bean
+   private class PSSDescription implements Serializable {
+      private static final long serialVersionUID = 4089751663717085089L;
+      PortletStateScoped      pssAnno;
+      String                  paramName;
+   }
+   
+   // Maps the bean contextual to the annotation. The bean contextual is obtained
+   // during the activation process after all beans have been discovered.
+   // Note that synchronization is not needed since the map is only changed during the
+   // bean scanning phase.
+   private final Map<Contextual<?>, PSSDescription> context2Anno = 
+         new HashMap<Contextual<?>, PSSDescription>();
+
+   // Maps the bean class to the corresponding annotation. The entries are set
+   // while the extension is processing annotated types.
+   // Note that synchronization is not needed since the map is only changed during the
+   // bean scanning phase.
+   private final Map<Class<?>, PSSDescription> class2Anno = 
+         new HashMap<Class<?>, PSSDescription>();
+   
+   /**
+    * Called by the CDI extension during the scanning phase to add information about 
+    * a <code>{@literal @}PortletStateScoped</code> bean.
+    * 
+    * @param beanClass     The bean class
+    * @param anno          The annotation
+    */
+   public void addAnnotation(Class<?> beanClass, PortletStateScoped anno) {
+      PSSDescription desc = new PSSDescription();
+      desc.pssAnno = anno;
+      class2Anno.put(beanClass, desc);
+   }
+   
+   /** 
+    * Gets the concrete contextual for the bean and puts it into the context map.
+    * Called after bean discovery during the activation process.
+    * Finishes up the configuration process and provides a debug summary.
+    * 
+    * @param bm      The bean manager
+    */
+   public void activate(BeanManager bm) {
+      
+      // The assigned render parameters are based on the alphabetic order of the PSS bean 
+      // class names, so generate such a list.
+      
+      for (Class<?> c : class2Anno.keySet()) {
+         sortedAnnotatedClassNames.add(c.getCanonicalName());
+      }
+      Collections.sort(sortedAnnotatedClassNames);
+      
+      // Now assign the parameter names. If provided through the annotation, use
+      // that one. Otherwise generate a render parameter name. 
+      
+      for (Class<?> c : class2Anno.keySet()) {
+         PSSDescription desc = class2Anno.get(c);
+         if (desc.pssAnno.paramName().length() > 0) {
+            desc.paramName = desc.pssAnno.paramName();
+         } else {
+            desc.paramName = RP_PREFIX + sortedAnnotatedClassNames.indexOf(c.getCanonicalName());
+         }
+         
+         // Fix up the portlet names if specified by the annotation.
+         // prob not needed desc.portletNames.addAll(Arrays.asList(desc.pssAnno.portletNames()));
+      }
+      
+      // Activate the beans
+      
+      for (Class<?> cls : class2Anno.keySet()) {
+         Set<Bean<?>> beans = bm.getBeans(cls);
+         Bean<?> bean = bm.resolve(beans);
+         assert bean != null;
+         context2Anno.put(bean, class2Anno.get(cls));
+      }
+      
+      // dump configuration data to trace
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("PortletStateScopedBeanHolder configuration: \n");
+         txt.append("\nAnnotatedBeans: ");
+         txt.append(getConfigAsString());
+         LOG.debug(txt.toString());
+      }
+   }
+   
+   /**
+    * Returns the portlet state scoped annotated classes. 
+    * <p>
+    * Used for test / validation purposes.
+    * 
+    * @return  Set of annotated classes
+    */
+   public Set<Class<?>> getBeanClasses() {
+      return class2Anno.keySet();
+   }
+   
+   /**
+    * Returns a portlet state scoped bean summary for display
+    * 
+    * @return  The configuration summary string
+    * 
+    */
+   public String getConfigAsString() {
+      StringBuilder txt = new StringBuilder(128);
+      for (Class<?> c : class2Anno.keySet()) {
+         txt.append("\n\tClass: ").append(c.getCanonicalName());
+         PSSDescription desc = class2Anno.get(c);
+         txt.append(", Param name: ").append(desc.paramName);
+      }
+      return txt.toString();
+   }
+   
+   /**
+    * Returns the parameter name for the given bean class.
+    * 
+    * @param beanClass  The bean class
+    * @return           The corresponding parameter name
+    */
+   public String getParamName(Class<?> beanClass) {
+      String name = null;
+      for (Contextual<?> b : context2Anno.keySet()) {
+         if (b instanceof Bean) {
+            Bean<?> bean = (Bean<?>)b;
+            if (beanClass.isAssignableFrom(bean.getBeanClass())) {
+               name = context2Anno.get(b).paramName;
+               break;
+            }
+         }
+      }
+      return name;
+   }
+   
+   /**
+    * Determines the render parameter name for the given bean.
+    * 
+    * @param bean    The bean
+    * @return        The parameter name
+    */
+   public String getParamName(Bean<?> bean) {
+      
+      // retrieve the annotation for the bean. If a parameter name is provided
+      // use it. Otherwise use the class name.
+      
+      PSSDescription desc = context2Anno.get(bean);
+      assert desc != null;
+      assert desc.paramName.length() > 0;
+      return desc.paramName;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedContext.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedContext.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedContext.java
new file mode 100644
index 0000000..251ebb9
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedContext.java
@@ -0,0 +1,87 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.portlet.annotations.PortletStateScoped;
+
+/**
+ * This is the Context implementation for the PortletStateScoped custom CDI scope.
+ * 
+ * @author nick
+ *
+ */
+public class PortletStateScopedContext implements Context {
+
+   public PortletStateScopedContext() {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean) {
+      PortletStateScopedBeanHolder holder = PortletStateScopedBeanHolder.getBeanHolder();
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet state context is not active.");
+      }
+      return holder.getBean(bean);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual, javax.enterprise.context.spi.CreationalContext)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean, CreationalContext<T> crco) {
+      PortletStateScopedBeanHolder holder = PortletStateScopedBeanHolder.getBeanHolder();
+      
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet state context is not active.");
+      }
+      
+      // The bean hoder will return an existing bean instance or create a new one
+      // if no existing instance is available.
+      T inst = holder.getBean(bean, crco);      
+      return inst;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#getScope()
+    */
+   @Override
+   public Class<? extends Annotation> getScope() {
+      return PortletStateScoped.class;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#isActive()
+    */
+   @Override
+   public boolean isActive() {
+      PortletStateScopedBeanHolder holder = PortletStateScopedBeanHolder.getBeanHolder();
+      return (holder != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/SignatureVariant.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/SignatureVariant.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/SignatureVariant.java
new file mode 100644
index 0000000..2a2faa5
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/SignatureVariant.java
@@ -0,0 +1,65 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+/**
+ * Enum to identify the signature variant for annotated methods that alloe
+ * multiple method signatures.
+ * 
+ * @author Scott Nicklous
+ */
+public enum SignatureVariant {
+
+   /**
+    * The default signature for the method.
+    */
+   DEFAULT,
+   
+   /**
+    * Signature variant for HeaderMethod, with return value void and 
+    * taking a HeaderRequest and HeaderResponse as arguments.
+    */
+   VOID_HEADERREQ_HEADERRESP,
+   
+   /**
+    * Signature variant for RenderMethod, with return value void and 
+    * taking a RenderRequest and RenderResponse as arguments.
+    */
+   VOID_RENDERREQ_RENDERRESP,
+   
+   /**
+    * Signature variant for ResourceMethod, with return value void and 
+    * taking a ResourceRequest and ResourceResponse as arguments.
+    */
+   VOID_RESOURCEREQ_RESOURCERESP,
+   
+   /**
+    * Signature variant for render, header, and resource methods, with return 
+    * value String and taking no arguments.
+    */
+   STRING_VOID,
+   
+   /**
+    * Signature variant for render, header, and resource methods, with return 
+    * value void and taking no arguments.
+    */
+   VOID_VOID,
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/URLFactoryImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/URLFactoryImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/URLFactoryImpl.java
new file mode 100644
index 0000000..03a957b
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/URLFactoryImpl.java
@@ -0,0 +1,75 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import javax.portlet.ActionURL;
+import javax.portlet.MimeResponse;
+import javax.portlet.MimeResponse.Copy;
+import javax.portlet.PortletResponse;
+import javax.portlet.RenderURL;
+import javax.portlet.ResourceURL;
+import javax.portlet.annotations.URLFactory;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class URLFactoryImpl implements URLFactory {
+   
+   private final MimeResponse    mimeResp;
+   
+   public URLFactoryImpl(PortletResponse resp) {
+      assert (resp instanceof MimeResponse);
+      mimeResp = (MimeResponse) resp;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.annotations.URLFactory#createActionURL()
+    */
+   @Override
+   public ActionURL createActionURL(Copy copyOpt) {
+      return mimeResp.createActionURL(copyOpt);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.annotations.URLFactory#createRenderURL()
+    */
+   @Override
+   public RenderURL createRenderURL(Copy copyOpt) {
+      return mimeResp.createRenderURL(copyOpt);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.annotations.URLFactory#createResourceURL()
+    */
+   @Override
+   public ResourceURL createResourceURL() {
+      return mimeResp.createResourceURL();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.annotations.URLFactory#encodeURL(java.lang.String)
+    */
+   @Override
+   public String encodeURL(String path) {
+      return mimeResp.encodeURL(path);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/package-info.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/package-info.java
new file mode 100644
index 0000000..ecee105
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/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.
+ */
+
+/**
+ * Contains code for processing annotated portlet methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.bean.processor;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/ActionParametersImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/ActionParametersImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/ActionParametersImpl.java
index ee1844d..11e1c79 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/ActionParametersImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/ActionParametersImpl.java
@@ -23,7 +23,6 @@ import java.util.Map;
 
 import javax.portlet.ActionParameters;
 import javax.portlet.MutableActionParameters;
-import javax.portlet.MutablePortletParameters;
 
 import org.apache.pluto.container.PortletURLProvider;
 import org.apache.pluto.container.PortletURLProvider.ParamType;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
index 81863c4..f459256 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderRequestImpl.java
@@ -23,7 +23,6 @@ import javax.portlet.HeaderRequest;
 import javax.portlet.PortletRequest;
 
 import org.apache.pluto.container.PortletHeaderResponseContext;
-import org.apache.pluto.container.PortletRenderResponseContext;
 import org.apache.pluto.container.PortletRequestContext;
 
 /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
index 37845ed..1c86620 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/HeaderResponseImpl.java
@@ -21,10 +21,8 @@ import java.util.Collection;
 
 import javax.portlet.HeaderResponse;
 import javax.portlet.PortletMode;
-import javax.portlet.RenderResponse;
 
 import org.apache.pluto.container.PortletHeaderResponseContext;
-import org.apache.pluto.container.PortletRenderResponseContext;
 import org.apache.pluto.container.util.ArgumentUtility;
 
 


[21/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeHeaderTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeHeaderTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeHeaderTest.java
new file mode 100644
index 0000000..adac9e4
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeHeaderTest.java
@@ -0,0 +1,394 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.header.Header1;
+import org.apache.pluto.container.bean.processor.fixtures.header.Header2;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockHeaderRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockHeaderResponse;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for invoking the annotated header methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Header1.class)
+public class InvokeHeaderTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static final MockHeaderRequest req = new MockHeaderRequest();
+   private static final MockHeaderResponse resp = new MockHeaderResponse();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   private static String DEFAULT_NS = "http://www.java.net/";
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+      ams.setDefaultNamespace(DEFAULT_NS);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header1a",
+            Header1.class.getSimpleName() + "#header1b",
+            Header1.class.getSimpleName() + "#header1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke1a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header1a",
+            Header1.class.getSimpleName() + "#header1b",
+            Header1.class.getSimpleName() + "#header1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke1b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = new PortletMode("CustomMode");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header1a",
+            Header1.class.getSimpleName() + "#header1b",
+            Header1.class.getSimpleName() + "#header1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke2a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header2a",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = new PortletMode("Config");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header2c",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.EDIT;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#header2c",
+            Header1.class.getSimpleName() + "#header2b",
+            Header2.class.getSimpleName() + "#header2d",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header3e"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header1.class.getSimpleName() + "#header3c",
+            Header1.class.getSimpleName() + "#header3a",
+            Header1.class.getSimpleName() + "#header3b",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(2, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#header6and7", 
+            Header2.class.getSimpleName() + "#header6andStar",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(2, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#header6and7", 
+            Header2.class.getSimpleName() + "#header6andStar",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#header6and7"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#headerAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#headerAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin3() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#headerAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin4() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet4");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin5() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet5");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin8() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet8");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.renderHeaders(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Header2.class.getSimpleName() + "#headerAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeInitTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeInitTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeInitTest.java
new file mode 100644
index 0000000..3f99803
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeInitTest.java
@@ -0,0 +1,117 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.portlet.PortletConfig;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.init.Init1;
+import org.apache.pluto.container.bean.processor.fixtures.init.Init2;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockPortletConfig;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for init method invocation.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Init1.class)
+public class InvokeInitTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static PortletConfig config = new MockPortletConfig();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      i.init(config);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Init1.class.getSimpleName() + "#init1"));
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      i.init(config);
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Init1.class.getSimpleName() + "#init2", Init2.class.getSimpleName() + "#init2",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+   @Test
+   public void invoke3() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      i.init(config);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Init2.class.getSimpleName() + "#init1"));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeRenderTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeRenderTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeRenderTest.java
new file mode 100644
index 0000000..ca91592
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeRenderTest.java
@@ -0,0 +1,385 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.render.Render1;
+import org.apache.pluto.container.bean.processor.fixtures.render.Render2;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockRenderRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockRenderResponse;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for invoking the annotated render methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Render1.class)
+public class InvokeRenderTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static final MockRenderRequest req = new MockRenderRequest();
+   private static final MockRenderResponse resp = new MockRenderResponse();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   private static String DEFAULT_NS = "http://www.java.net/";
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+      ams.setDefaultNamespace(DEFAULT_NS);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render1a",
+            Render1.class.getSimpleName() + "#render1b",
+            Render1.class.getSimpleName() + "#render1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke1a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke1b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = new PortletMode("CustomMode");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke2a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render2a",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = new PortletMode("Config");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render2c",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = PortletMode.EDIT;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#render2c",
+            Render1.class.getSimpleName() + "#render2b",
+            Render2.class.getSimpleName() + "#render2d",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render3e"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render3c",
+            Render1.class.getSimpleName() + "#render3a",
+            Render1.class.getSimpleName() + "#render3b",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = PortletMode.EDIT;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render1.class.getSimpleName() + "#render3d",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      PortletMode mode = PortletMode.VIEW;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(2, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#render6and7", 
+            Render2.class.getSimpleName() + "#render6andStar",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      PortletMode mode = PortletMode.HELP;
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#renderAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#renderAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin3() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#renderAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin4() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet4");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin5() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet5");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin8() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet8");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      PortletMode mode = new PortletMode("admin");
+      req.setMode(mode);
+      i.render(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Render2.class.getSimpleName() + "#renderAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeResourceTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeResourceTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeResourceTest.java
new file mode 100644
index 0000000..4eb6a29
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeResourceTest.java
@@ -0,0 +1,406 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockResourceRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockResourceResponse;
+import org.apache.pluto.container.bean.processor.fixtures.resource.Resource1;
+import org.apache.pluto.container.bean.processor.fixtures.resource.Resource2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for invoking the annotated resource methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Resource1.class)
+public class InvokeResourceTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static final MockResourceRequest req = new MockResourceRequest();
+   private static final MockResourceResponse resp = new MockResourceResponse();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   private static String DEFAULT_NS = "http://www.java.net/";
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+      ams.setDefaultNamespace(DEFAULT_NS);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      String resid = "VIEW";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource1a",
+            Resource1.class.getSimpleName() + "#resource1b",
+            Resource1.class.getSimpleName() + "#resource1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke1a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      String resid = "HELP";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource1a",
+            Resource1.class.getSimpleName() + "#resource1b",
+            Resource1.class.getSimpleName() + "#resource1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke1b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      String resid = "CustomMode";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource1a",
+            Resource1.class.getSimpleName() + "#resource1b",
+            Resource1.class.getSimpleName() + "#resource1c"
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      String resid = "VIEW";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke2a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      String resid = "help";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource2a",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      String resid = "config";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource2c",
+            });
+      for (String name : names) {
+         assertTrue(soll.contains(name));
+      }
+   }
+   
+   @Test
+   public void invoke2c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      String resid = "edit";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resource2c",
+            Resource1.class.getSimpleName() + "#resource2b",
+            Resource2.class.getSimpleName() + "#resource2d",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke2d() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      // resource ID match is case-sensitive
+      String resid = "eDit";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invoke3a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      String resid = "help";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource3e"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke3b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      String resid = "VIEW";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource1.class.getSimpleName() + "#resource3c",
+            Resource1.class.getSimpleName() + "#resource3a",
+            Resource1.class.getSimpleName() + "#resource3b",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      String resid = "VIEW";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(2, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resource6and7", 
+            Resource2.class.getSimpleName() + "#resource6andStar",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke6a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      String resid = "HELP";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertEquals(2, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resource6and7", 
+            Resource2.class.getSimpleName() + "#resource6andStar",
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invoke7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      String resid = "HELP";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resource6and7"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resourceAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resourceAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin3() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resourceAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+   @Test
+   public void invokeAdmin4() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet4");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin5() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet5");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin8() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet8");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(0, names.size());
+   }
+   
+   @Test
+   public void invokeAdmin7() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet7");
+      String resid = "admin";
+      req.setResourceId(resid);
+      i.serveResource(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      List<String> soll = Arrays.asList(new String[] {
+            Resource2.class.getSimpleName() + "#resourceAll"
+            });
+      assertArrayEquals(soll.toArray(), names.toArray());
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionAppScopeTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionAppScopeTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionAppScopeTest.java
new file mode 100644
index 0000000..efdba48
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionAppScopeTest.java
@@ -0,0 +1,174 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Set;
+
+import javax.enterprise.context.SessionScoped;
+import javax.inject.Inject;
+import javax.portlet.annotations.PortletSessionScoped;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletSessionScopedAnnotatedType;
+import org.apache.pluto.container.bean.processor.PortletSessionScopedConfig;
+import org.apache.pluto.container.bean.processor.PortletStateScopedConfig;
+import org.apache.pluto.container.bean.processor.fixtures.PortletStateScopedClass;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedApp1;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(PortletStateScopedClass.class)
+public class PortletSessionAppScopeTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   private PortletStateScopedConfig psconfig = null;
+   private PortletSessionScopedConfig sessConfig = null;
+   
+   private PortletSessionScopedAnnotatedType appScoped = null;
+   
+//    @Inject
+//    private SessionScopedApp1 abean;
+   
+   @Before
+   public void setUp() {
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      psconfig = acb.getStateScopedConfig();
+      sessConfig = acb.getSessionScopedConfig();
+      
+      assertNotNull(acb);
+      assertNotNull(ams);
+      assertNotNull(summary);
+      assertNotNull(psconfig);
+      assertNotNull(sessConfig);
+      
+      appScoped = summary.getAppScopedTypes().get(0);
+   }
+   
+   @Test
+   public void annotatedClassPresent1() {
+      List<PortletSessionScopedAnnotatedType> types = summary.getAppScopedTypes();
+      assertNotNull(types);
+      assertEquals(1, types.size());
+   }
+   
+   @Test
+   public void checkAppScoped() throws Exception {
+      assertNotNull(appScoped);
+   }
+   
+   @Test
+   public void checkNoPortletSessionScoped() throws Exception {
+      Set<Annotation> annos = appScoped.getAnnotations();
+      assertNotEquals(0, annos.size());
+      boolean ok = true;
+      for (Annotation a : annos) {
+         if (a.annotationType().equals(PortletSessionScoped.class)) {
+            ok = false;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+   
+   @Test
+   public void checkSessionScoped() throws Exception {
+      Set<Annotation> annos = appScoped.getAnnotations();
+      assertEquals(1, annos.size());
+      boolean ok = false;
+      for (Annotation a : annos) {
+         if (a.annotationType().equals(SessionScoped.class)) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+   
+   @Test
+   public void doesNotContainPortletSessionScoped() throws Exception {
+      assertFalse(appScoped.isAnnotationPresent(PortletSessionScoped.class));
+   }
+   
+   @Test
+   public void containsPortletSessionScoped() throws Exception {
+      assertTrue(appScoped.isAnnotationPresent(SessionScoped.class));
+   }
+   
+   @Test
+   public void getAnnotation() throws Exception {
+      assertNotNull(appScoped.getAnnotation(SessionScoped.class));
+   }
+   
+   @Test
+   public void getAnnotationBad() throws Exception {
+      assertNull(appScoped.getAnnotation(PortletSessionScoped.class));
+   }
+   
+   @Test
+   public void checkJavaClass() throws Exception {
+      Class<?> cls = appScoped.getJavaClass();
+      assertEquals(SessionScopedApp1.class, cls);
+   }
+   
+   @Test
+   public void checkBaseType() throws Exception {
+      Type type = appScoped.getBaseType();
+      assertEquals(SessionScopedApp1.class, type);
+   }
+   
+//    @Test
+//    @InSessionScope
+//    public void checkInjection() throws Exception {
+//       assertNotNull(abean);
+//       assertNotNull(abean.sayHi());
+//       assertEquals("Hi!", abean.sayHi());
+//    }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionScopedTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionScopedTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionScopedTest.java
new file mode 100644
index 0000000..995d443
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletSessionScopedTest.java
@@ -0,0 +1,155 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletSessionScopedConfig;
+import org.apache.pluto.container.bean.processor.PortletStateScopedConfig;
+import org.apache.pluto.container.bean.processor.fixtures.PortletStateScopedClass;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedPortlet1;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedPortlet2;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedPortletBad1;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedPortletBad2;
+import org.apache.pluto.container.bean.processor.fixtures.SessionScopedPortletBad3;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(PortletStateScopedClass.class)
+public class PortletSessionScopedTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   private PortletStateScopedConfig psconfig = null;
+   private PortletSessionScopedConfig sessConfig = null;
+   
+   @Before
+   public void setUp() {
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      psconfig = acb.getStateScopedConfig();
+      sessConfig = acb.getSessionScopedConfig();
+   }
+
+   @Test
+   public void injectBeanTest() {
+      assertNotNull(acb);
+      assertNotNull(ams);
+      assertNotNull(summary);
+      assertNotNull(psconfig);
+      assertNotNull(sessConfig);
+   }
+   
+   @Test
+   public void annotatedClassPresent1() {
+      Set<Class<?>> classes = sessConfig.getBeanClasses();
+      assertNotNull(classes);
+      assertEquals(2, classes.size());
+   }
+
+   @Test
+   public void annotatedClassPresent2() {
+      Set<Class<?>> classes = sessConfig.getBeanClasses();
+      assertNotNull(classes);
+      assertTrue(classes.contains(SessionScopedPortlet1.class));
+   }
+
+   @Test
+   public void annotatedClassPresent3() {
+      Set<Class<?>> classes = sessConfig.getBeanClasses();
+      assertNotNull(classes);
+      assertTrue(classes.contains(SessionScopedPortlet2.class));
+   }
+
+   @Test
+   public void annotatedClassNotPresent() {
+      Set<Class<?>> classes = sessConfig.getBeanClasses();
+      assertNotNull(classes);
+      assertFalse(classes.contains(SessionScopedPortletBad1.class));
+      assertFalse(classes.contains(SessionScopedPortletBad2.class));
+      assertFalse(classes.contains(SessionScopedPortletBad3.class));
+   }
+
+   @Test
+   public void isPortletScope1() {
+      Boolean isps = sessConfig.isPortletScoped(SessionScopedPortlet1.class);
+      assertNotNull(isps);
+      assertTrue(isps);
+   }
+
+   @Test
+   public void isPortletScope2() {
+      Boolean isps = sessConfig.isPortletScoped(SessionScopedPortlet2.class);
+      assertNotNull(isps);
+      assertTrue(isps);
+   }
+
+   @Test
+   public void isPortletScopeBad() {
+      assertNull(sessConfig.isPortletScoped(SessionScopedPortletBad1.class));
+      assertNull(sessConfig.isPortletScoped(SessionScopedPortletBad2.class));
+      assertNull(sessConfig.isPortletScoped(SessionScopedPortletBad3.class));
+   }
+   
+   @Test
+   public void errorList() {
+      List<Class<?>> list = summary.getSessionBeansWithErrors();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(list.contains(SessionScopedPortletBad1.class));
+      assertTrue(list.contains(SessionScopedPortletBad2.class));
+      assertTrue(list.contains(SessionScopedPortletBad3.class));
+   }
+   
+   @Test
+   public void errorString() {
+      assertNotNull(summary.getSessionBeanErrorString(SessionScopedPortletBad1.class));
+      assertNotNull(summary.getSessionBeanErrorString(SessionScopedPortletBad2.class));
+      assertNotNull(summary.getSessionBeanErrorString(SessionScopedPortletBad3.class));
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletStateScopedTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletStateScopedTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletStateScopedTest.java
new file mode 100644
index 0000000..36ed9a6
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/PortletStateScopedTest.java
@@ -0,0 +1,135 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletStateScopedConfig;
+import org.apache.pluto.container.bean.processor.fixtures.PortletStateScopedBadClass;
+import org.apache.pluto.container.bean.processor.fixtures.PortletStateScopedClass;
+import org.apache.pluto.container.bean.processor.fixtures.PortletStateScopedNoParamNameClass;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(PortletStateScopedClass.class)
+public class PortletStateScopedTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   private PortletStateScopedConfig psconfig = null;
+   
+   @Before
+   public void setUp() {
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      psconfig = acb.getStateScopedConfig();
+   }
+
+   @Test
+   public void injectBeanTest() {
+      assertNotNull(acb);
+      assertNotNull(ams);
+      assertNotNull(summary);
+      assertNotNull(psconfig);
+   }
+   
+   @Test
+   public void annotatedClassPresent1() {
+      Set<Class<?>> classes = psconfig.getBeanClasses();
+      assertNotNull(classes);
+      assertEquals(2, classes.size());
+   }
+
+   @Test
+   public void annotatedClassPresent2() {
+      Set<Class<?>> classes = psconfig.getBeanClasses();
+      assertNotNull(classes);
+      assertTrue(classes.contains(PortletStateScopedClass.class));
+   }
+
+   @Test
+   public void annotatedClassPresent3() {
+      Set<Class<?>> classes = psconfig.getBeanClasses();
+      assertNotNull(classes);
+      assertTrue(classes.contains(PortletStateScopedNoParamNameClass.class));
+   }
+
+   @Test
+   public void annotatedClassNotPresent() {
+      Set<Class<?>> classes = psconfig.getBeanClasses();
+      assertNotNull(classes);
+      assertFalse(classes.contains(PortletStateScopedBadClass.class));
+   }
+
+   @Test
+   public void paramName1() {
+      String name = psconfig.getParamName(PortletStateScopedClass.class);
+      assertNotNull(name);
+      assertEquals("param1", name);
+   }
+
+   @Test
+   public void paramName2() {
+      String name = psconfig.getParamName(PortletStateScopedNoParamNameClass.class);
+      assertNotNull(name);
+      assertTrue(name.endsWith("1"));
+   }
+   
+   @Test
+   public void errorList() {
+      List<Class<?>> list = summary.getStateBeansWithErrors();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertTrue(list.contains(PortletStateScopedBadClass.class));
+   }
+   
+   @Test
+   public void errorString() {
+      String msg = summary.getStateBeanErrorString(PortletStateScopedBadClass.class);
+      assertNotNull(msg);
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/RenderTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/RenderTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/RenderTest.java
new file mode 100644
index 0000000..0d58bbf
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/RenderTest.java
@@ -0,0 +1,375 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.RENDER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.render.Render1;
+import org.apache.pluto.container.bean.processor.fixtures.render.Render2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Render1.class)
+public class RenderTest {
+
+   @Inject
+   AnnotatedConfigBean          acb;
+
+   private AnnotatedMethodStore ams     = null;
+   private ConfigSummary        summary = null;
+
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(6, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("*"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+      assertTrue(names.contains("portlet7"));
+   }
+
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+
+   @Test
+   public void errorBadException() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet8"));
+   }
+
+   @Test
+   public void errorBadAsterisk() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("*"));
+   }
+
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "VIEW", "ADMIN" });
+      assertEquals(2, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RENDER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet1", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "HELP", "EDIT", "CONFIG", "ADMIN" });
+      assertEquals(4, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RENDER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet2", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(4, portlets.size());
+      List<String> ids = Arrays.asList(new String[] { "VIEW", "HELP", "ADMIN", "" });
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(RENDER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+
+   @Test
+   public void class1Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "VIEW", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "render1a", "render1b", "render1c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class1aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "ADMIN", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "renderAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "VIEW", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   @Test
+   public void class2aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "ADMIN", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "renderAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2hTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "HELP", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "render2a" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2bTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "EDIT", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "render2c", "render2b", "render2d" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class2cTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "CONFIG", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "render2c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class3Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "VIEW", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "render3c", "render3a", "render3b" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class3aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "ADMIN", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "renderAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class6Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "VIEW", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      List<String> names = Arrays.asList(new String[] { "render6and7", "render6andStar" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class6aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "ADMIN", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "renderAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "VIEW", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "render6and7" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "ADMIN", RENDER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "renderAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Render2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+   @Test
+   public void procEvent1Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+}


[30/35] portals-pluto git commit: Adapted the portlet container ServletContainerInitializer to integrate the bean configuration before launching the portlet servlets. Added default portlet class instantiation to support portlets that have declared portle

Posted by ms...@apache.org.
Adapted the portlet container ServletContainerInitializer to integrate
the bean configuration before launching the portlet servlets. Added default
portlet class instantiation to support portlets that have declared portlet
classes, but are not in a valid bean archive.


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

Branch: refs/heads/V3Prototype
Commit: afb1a42f791456bcb3794878b41502e144ea6a48
Parents: 2e60a31
Author: Scott Nicklous <ms...@apache.org>
Authored: Thu Jan 14 17:15:05 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Thu Jan 14 17:15:05 2016 +0100

----------------------------------------------------------------------
 .../driver/PortletContainerInitializer.java     | 157 +++++----
 .../bean/processor/AnnotationRecognizer.java    |   3 -
 .../bean/processor/PortletCDIExtension.java     |   6 +-
 .../processor/PortletSessionScopedConfig.java   |   8 +-
 .../processor/PortletStateScopedConfig.java     |   8 +-
 .../om/portlet/impl/ConfigurationProcessor.java | 334 +++++++++++++++++--
 .../impl/JSR286ConfigurationProcessor.java      |   4 +-
 .../impl/JSR362ConfigurationProcessor.java      | 263 ---------------
 .../src/main/resources/META-INF/beans.xml       |   5 +
 9 files changed, 425 insertions(+), 363 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index afc574c..e48566f 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -32,6 +32,8 @@ import javax.servlet.ServletRegistration;
 import javax.servlet.annotation.HandlesTypes;
 
 import org.apache.pluto.container.PortletInvokerService;
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
 import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
 import org.slf4j.Logger;
@@ -66,82 +68,107 @@ public class PortletContainerInitializer implements ServletContainerInitializer
    public void onStartup(Set<Class<?>> classes, ServletContext ctx)
          throws ServletException {
 
-      InputStream win = ctx.getResourceAsStream(WEB_XML);
-      InputStream pin = ctx.getResourceAsStream(PORTLET_XML);
+      try {
 
-      if (isDebug) {
-         StringBuilder txt = new StringBuilder(128);
-         txt.append("§§§ ServletContainerInitializer. ctx path: ").append(
-               ctx.getContextPath());
-         txt.append(", servlet ctx name: ").append(ctx.getServletContextName());
-         txt.append(", # portlet annotations: ").append(
-               (classes != null) ? classes.size() : "null");
-         txt.append(", found web.xml: ").append(win != null);
-         txt.append(", found portlet.xml: ").append(pin != null);
-         LOG.debug(txt.toString());
-      }
+         // Get the bean configuration from the CDI extension
 
-      // If portlet configuration is available, parse it and launch the portlet
-      // servlets
-      if ((classes != null && classes.size() > 0) || pin != null) {
+         AnnotatedConfigBean acb = PortletCDIExtension.getConfig();
+         if (acb == null) {
+            StringBuilder txt = new StringBuilder();
+            txt.append("The managed bean configuration could not be obtained. \n\nMake sure Tomcat is configured correctly.");
+            txt.append("\nVerify that the CDI implementation is available and configured to run before the Pluto portlet container initializer.");
+            txt.append("\nVerify that the file 'weld-servlet-2.3.1.Final.jar' is in the ${catalina.base}/lib directory.");
+            txt.append("\nVerify that the catalina.properties file contains a line similar to:.");
+            txt.append("\n   common.loader=\"${catalina.home}/lib/weld-servlet-2.3.1.Final.jar\",\"${catalina.base}/lib\",\"${catalina.base}/lib/*.jar\",\"${catalina.home}/lib\",\"${catalina.home}/lib/*.jar\"");
+            txt.append("\n");
+            LOG.warn(txt.toString());
+         }
 
-         try {
-            ConfigurationHolder holder = new ConfigurationHolder();
+         // Read the annotated configuration
 
-            if (classes != null) {
-               holder.processConfigAnnotations(classes);
-            }
+         ConfigurationHolder holder = new ConfigurationHolder();
 
-            if (pin != null) {
-               // parse the portlet deployment descriptor
-               holder.processPortletDD(pin);
-            }
+         if (classes != null) {
+            holder.processConfigAnnotations(classes);
+         }
 
-            if (win != null) {
-               // parse the web app deployment descriptor
-               holder.processWebDD(win);
-            }
-            
-            holder.validate();
-
-            if (holder.getPad().getPortlets().size() > 0) {
-
-               ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder);
-               
-               // dynamically deploy the portlet servlets
-               for (PortletDefinition pd : holder.getPad().getPortlets()) {
-                  String pn = pd.getPortletName();
-                  String mapping = PortletInvokerService.URIPREFIX + pn;
-                  String servletName = pn + "_PS3";
-
-                  if (isDebug) {
-                     StringBuilder txt = new StringBuilder();
-                     txt.append("Adding PortletServlet3. Portlet name: ");
-                     txt.append(pn);
-                     txt.append(", servlet name: ").append(servletName);
-                     txt.append(", mapping: ").append(mapping);
-                     LOG.debug(txt.toString());
-                  }
-                  
-                  ServletRegistration.Dynamic sr = ctx.addServlet(servletName, PortletServlet3.class);
-                  sr.addMapping(mapping);
-                  sr.setInitParameter(PortletServlet3.PORTLET_NAME, pn);
-                  sr.setLoadOnStartup(100);
+         // set up for reading the XML files
+
+         InputStream win = ctx.getResourceAsStream(WEB_XML);
+         InputStream pin = ctx.getResourceAsStream(PORTLET_XML);
+
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("§§§ ServletContainerInitializer. ctx path: ").append(
+                  ctx.getContextPath());
+            txt.append(", servlet ctx name: ").append(ctx.getServletContextName());
+            txt.append(", # portlet annotations: ").append(
+                  (classes != null) ? classes.size() : "null");
+            txt.append(", found web.xml: ").append(win != null);
+            txt.append(", found portlet.xml: ").append(pin != null);
+            LOG.debug(txt.toString());
+         }
 
+         // Now read the XML configuration and validate the resulting explicit config
+
+         if (pin != null) {
+            // parse the portlet deployment descriptor
+            holder.processPortletDD(pin);
+         }
+
+         if (win != null) {
+            // parse the web app deployment descriptor
+            holder.processWebDD(win);
+         }
+
+         holder.validate();
+         
+         // If we were able to obtain a bean config, reconcile the bean config with the
+         // explicitly declared portlet configuration.
+         
+         if (acb != null) {
+            holder.reconcileBeanConfig(acb.getMethodStore());
+         }
+         
+         // If portlets have been found in this servlet context, launch the portlet servlets
+
+         if (holder.getPad().getPortlets().size() > 0) {
+
+            ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder);
+
+            // dynamically deploy the portlet servlets
+            for (PortletDefinition pd : holder.getPad().getPortlets()) {
+               String pn = pd.getPortletName();
+               String mapping = PortletInvokerService.URIPREFIX + pn;
+               String servletName = pn + "_PS3";
+
+               if (isDebug) {
+                  StringBuilder txt = new StringBuilder();
+                  txt.append("Adding PortletServlet3. Portlet name: ");
+                  txt.append(pn);
+                  txt.append(", servlet name: ").append(servletName);
+                  txt.append(", mapping: ").append(mapping);
+                  LOG.debug(txt.toString());
                }
-               
-            } else {
-               LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());
+
+               ServletRegistration.Dynamic sr = ctx.addServlet(servletName, PortletServlet3.class);
+               sr.addMapping(mapping);
+               sr.setInitParameter(PortletServlet3.PORTLET_NAME, pn);
+               sr.setLoadOnStartup(100);
+
             }
 
-         } catch (Exception e) {
-            StringBuilder txt = new StringBuilder(128);
-            txt.append("Exception processing portlet application configuration");
-            txt.append(", Servlet ctx name: ").append(
-                  ctx.getServletContextName());
-            txt.append(", Exception: ").append(e.toString());
-            LOG.info(txt.toString());
+         } else {
+            LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());
          }
+
+      } catch (Exception e) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Exception processing portlet application configuration");
+         txt.append(", Servlet ctx name: ").append(
+               ctx.getServletContextName());
+         txt.append(", Exception: ").append(e.toString());
+         LOG.info(txt.toString());
       }
 
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
index 5530f04..83dcee2 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
@@ -95,9 +95,6 @@ public abstract class AnnotationRecognizer {
    public void checkAnnotatedType(ProcessAnnotatedType pat) throws InvalidAnnotationException {
       AnnotatedType<?> aType = pat.getAnnotatedType();
       String typeName = aType.getJavaClass().getCanonicalName();
-      if (isDebug) {
-         LOG.debug("Checking for annotations on: " + typeName);
-      }
       try {
          
          // Process the class annotations

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
index 35d79c0..1bc695e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
@@ -100,16 +100,16 @@ public class PortletCDIExtension implements Extension {
       // Done processing the annotations, so put the resulting configuration in an
       // application scoped bean to pass it to the servlet
       
-      LOG.debug("Now attempting to get the AnnotatedConfigBean ...");
+      LOG.trace("Now attempting to get the AnnotatedConfigBean ...");
       Set<Bean<?>> beans = bm.getBeans(AnnotatedConfigBean.class);
       @SuppressWarnings("unchecked")
       Bean<AnnotatedConfigBean> bean = (Bean<AnnotatedConfigBean>) bm.resolve(beans);
       if (bean != null) {
-         LOG.debug("Got AnnotatedConfigBean bean: " + bean.getBeanClass().getCanonicalName());
+         LOG.trace("Got AnnotatedConfigBean bean: " + bean.getBeanClass().getCanonicalName());
          try {
             CreationalContext<AnnotatedConfigBean> cc = bm.createCreationalContext(bean);
             acb = (AnnotatedConfigBean) bm.getReference(bean, AnnotatedConfigBean.class, cc);
-            LOG.debug("Got AnnotatedConfigBean instance.");
+            LOG.trace("Got AnnotatedConfigBean instance.");
             acb.setMethodStore(ams);
             acb.setSummary(summary);
             acb.setStateScopedConfig(par.getStateScopedConfig());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
index 5295a6d..c4353a5 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
@@ -46,7 +46,7 @@ import org.slf4j.LoggerFactory;
 public class PortletSessionScopedConfig  implements Serializable {
    private static final long serialVersionUID = -5333145344722804837L;
    private final Logger LOG = LoggerFactory.getLogger(PortletSessionScopedConfig.class);
-   private final boolean isDebug = LOG.isDebugEnabled();
+   private final boolean isTrace = LOG.isTraceEnabled();
    
    
    // Maps the bean contextual to the annotation. The bean contextual is obtained
@@ -94,10 +94,10 @@ public class PortletSessionScopedConfig  implements Serializable {
       
       // dump configuration data to trace
       
-      if (isDebug) {
+      if (isTrace) {
          StringBuilder txt = new StringBuilder(128);
-         txt.append("PortletSessionScopedBeanHolder configuration: \n");
-         txt.append("\nAnnotatedBeans: ");
+         txt.append("PortletSessionScopedBeanHolder configuration. ");
+         txt.append(" AnnotatedBeans: ");
          txt.append(getConfigAsString());
          LOG.debug(txt.toString());
       }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
index b92b2cf..735f1a3 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletStateScopedConfig.java
@@ -44,7 +44,7 @@ import org.slf4j.LoggerFactory;
 public class PortletStateScopedConfig  implements Serializable {
    private static final long serialVersionUID = -5333145344722804837L;
    private final Logger LOG = LoggerFactory.getLogger(PortletStateScopedConfig.class);
-   private final boolean isDebug = LOG.isDebugEnabled();
+   private final boolean isTrace = LOG.isTraceEnabled();
    
    
    // Contains a sorted list of PortletStateScoped annotated class names. The sorted list
@@ -131,10 +131,10 @@ public class PortletStateScopedConfig  implements Serializable {
       
       // dump configuration data to trace
       
-      if (isDebug) {
+      if (isTrace) {
          StringBuilder txt = new StringBuilder(128);
-         txt.append("PortletStateScopedBeanHolder configuration: \n");
-         txt.append("\nAnnotatedBeans: ");
+         txt.append("PortletStateScopedBeanHolder configuration.");
+         txt.append(" Annotated Beans: ");
          txt.append(getConfigAsString());
          LOG.debug(txt.toString());
       }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 5460a10..7f368e4 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -1,14 +1,30 @@
 package org.apache.pluto.container.om.portlet.impl;
 
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_ACT;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_DES;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_EVT;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_HDR;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_INI;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_REN;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_RES;
+
 import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Locale;
 import java.util.Random;
 import java.util.ResourceBundle;
+import java.util.Set;
 
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.portlet.Portlet;
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.xpath.XPath;
@@ -16,8 +32,15 @@ import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathFactory;
 
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
 import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.MethodDescription;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.MethodType;
+import org.apache.pluto.container.om.portlet.EventDefinition;
+import org.apache.pluto.container.om.portlet.EventDefinitionReference;
 import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -29,8 +52,8 @@ public abstract class ConfigurationProcessor {
    
    
    /** Logger. */
-   private static final Logger LOG = LoggerFactory
-         .getLogger(ConfigurationProcessor.class);
+   private static final Logger LOG = LoggerFactory.getLogger(ConfigurationProcessor.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
 
 
    protected PortletApplicationDefinition pad;
@@ -72,23 +95,6 @@ public abstract class ConfigurationProcessor {
     */
    public abstract void validate() throws IllegalArgumentException;
    
-   /**
-    * reconciles the given annotated method store containing the bean configuration
-    * with the configuration as read from the portlet deployment descriptor and 
-    * the corresponding type annotations.
-    * <p>
-    * Portlets that are defined in the bean config are added to the portlet application
-    * definition if not already present. Event reference information from the 
-    * annotations is verified and added to the corresponding portlet definition.
-    * <p>
-    * Methods from portlet classes definied in the portlet definitions are
-    * added to the annotated method store.
-    * 
-    * @param ams
-    */
-   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
-      // do nothing for JSR 168 & JSR 286 portlets
-   }
 
    /**
     * Handle the locale the old-fashioned way (v1 & v2)
@@ -340,4 +346,294 @@ public abstract class ConfigurationProcessor {
    public void processValidatorAnnotation(Class<?> cls) {
    }
 
+   /**
+    * reconciles the given annotated method store containing the bean configuration
+    * with the configuration as read from the portlet deployment descriptor and 
+    * the corresponding type annotations.
+    * <p>
+    * Portlets that are defined in the bean config are added to the portlet application
+    * definition if not already present. Event reference information from the 
+    * annotations is verified and added to the corresponding portlet definition.
+    * <p>
+    * Methods from portlet classes definied in the portlet definitions are
+    * added to the annotated method store.
+    * 
+    * @param ams
+    */
+   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder();
+         txt.append("Beginning reconciliation. Annotated portlets: ").append(ams.getPortletNames().toString());
+         LOG.debug(txt.toString());
+      }
+
+      ams.setDefaultNamespace(pad.getDefaultNamespace());
+      
+      for (String pn : ams.getPortletNames()) {
+         
+         PortletDefinition pd = pad.getPortlet(pn);
+         if (pd == null) {
+            pd = new PortletDefinitionImpl(pn, pad);
+         }
+         
+         List<EventDefinitionReference> edrs = pd.getSupportedProcessingEvents();
+         for (QName qn : ams.getProcessingEventRefs(pn)) {
+            EventDefinition ed = pad.getEventDefinition(qn);
+            if (ed == null) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("No event definition found for annotated processing event reference.");
+               txt.append(" Portlet name: ").append(pn);
+               txt.append(", QName: ").append(qn);
+               LOG.warn(txt.toString());
+               
+               // remove the defective method from the store
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), qn, MethodType.EVENT);
+               ams.removeMethod(mi);
+               
+               continue;
+            }
+            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
+            if (!edrs.contains(newedr)) {
+               pd.addSupportedProcessingEvent(newedr);
+            }
+         }
+         
+         edrs = pd.getSupportedPublishingEvents();
+         for (QName qn : ams.getPublishingEventRefs(pn)) {
+            EventDefinition ed = pad.getEventDefinition(qn);
+            if (ed == null) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("No event definition found for annotated publishing event reference.");
+               txt.append(" Portlet name: ").append(pn);
+               txt.append(", QName: ").append(qn);
+               LOG.warn(txt.toString());
+               continue;
+            }
+            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
+            if (!edrs.contains(newedr)) {
+               pd.addSupportedPublishingEvent(newedr);
+            }
+         }
+         
+         pad.addPortlet(pd);
+      }
+      
+      // Now add the declared portlet class methods to the store
+      
+      List<PortletDefinition> badPortlets = new ArrayList<PortletDefinition>();
+      for (PortletDefinition pd : pad.getPortlets()) {
+         Class<?> cls = null;
+
+         String clsName = pd.getPortletClass();
+         if (isValidIdentifier(clsName)) {
+            
+            // Make sure the class can be loaded
+            Class<?> valClass = null;
+            StringBuilder txt = new StringBuilder(128);
+            try {
+               ClassLoader cl = Thread.currentThread().getContextClassLoader();
+               if (cl == null) {
+                  cl = this.getClass().getClassLoader();
+               }
+               valClass = cl.loadClass(clsName);
+               if (Portlet.class.isAssignableFrom(valClass)) {
+                  cls = valClass;
+               } else {
+                  txt.append("Specified portlet class does not implement the Portlet interface.");
+               }
+            } catch (Exception e) {
+               txt.append("Specified portlet class could not be loaded.");
+            } finally {
+               if (cls == null) {
+                  txt.append(" Portlet name: ").append(pd.getPortletName());
+                  txt.append(", Portlet class: ").append(clsName);
+                  LOG.warn(txt.toString());
+               }
+            }
+         }
+         
+         Object instance = null;
+         if (cls != null) {
+            
+            // Let CDI instantiate the portlet to allow for injection. 
+            // Get the single bean instance for the portlet class.
+            
+            StringBuilder txt = new StringBuilder(128);
+            BeanManager bm = ams.getBeanMgr();
+            if (bm == null) {
+               txt.append("Could not instantiate portlet class. Bean manager is null.");
+            } else {
+               Set<Bean<?>> beans = bm.getBeans(cls);
+               if (beans == null || beans.size() == 0) {
+                  txt.append("Could not instantiate portlet class. No beans found.");
+               } else {
+                  Bean<?> bean = bm.resolve(beans);
+                  if (bean == null) {
+                     txt.append("Could not instantiate portlet class. Could not resolve bean.");
+                  } else {
+                     instance = bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
+                     if (instance == null) {
+                        txt.append("Could not instantiate portlet class. Could not get bean instance.");
+                     }
+                  }
+               }
+            }
+            
+            // If the instance is still null, the portlet class might not be in a valid bean 
+            // archive, as a JSR 286 portlet might be. Try to get a regular old instance.
+            
+            if (instance == null) {
+               LOG.debug("Could not create bean (possibly not in a valid bean archive). Now directly instantiating class: " + cls.getCanonicalName());
+               try {
+                  instance = cls.newInstance();
+               } catch(Exception e) {
+                  txt.append(" Exception creating instance of class: ").append(e.toString());
+               }
+            }
+            
+            
+            if ((instance == null) && (txt.length() > 0)) {
+               txt.append(" Portlet name: ").append(pd.getPortletName());
+               txt.append(", portlet class: ").append(cls);
+               LOG.warn(txt.toString());
+            }
+         }
+
+         if (instance != null) {
+            
+            // The annotated method store might contain methods from the configured
+            // portlet class being processed. For example, this may occur when an action
+            // or event method in the portlet class is annotated to specify processing or
+            // publishing event references. Such annotated methods must use the same bean
+            // instance, so fix up the method store.
+            
+            ams.setPortletClassInstance(cls, instance);
+
+            // extract the methods from the portlet class and add them to the method store
+            // as long there is no corresponding annotated method already present.
+            // (annotated methods take precedence over portlet class methods). 
+            
+            AnnotatedMethod am;
+            am = getMethod(instance, "init", METH_INI);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.INIT);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "destroy", METH_DES);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.DESTROY);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "processAction", METH_ACT);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.ACTION);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "processEvent", METH_EVT);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.EVENT);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "render", METH_REN);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RENDER);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "renderHeaders", METH_HDR);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.HEADER);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "serveResource", METH_RES);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RESOURCE);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+
+         }
+         
+         // and finally make sure that the portlet has at least one render, header, or serveResource
+         // method. If not, delete it.
+         
+         boolean methodsOK = false;
+         for (MethodIdentifier mi : ams.getMethodIDsForPortlet(pd.getPortletName())) {
+            if ((mi.getType() == MethodType.RENDER) || (mi.getType() == MethodType.RESOURCE) ||
+                  (mi.getType() == MethodType.HEADER)) {
+               methodsOK = true;
+               break;
+            }
+         }
+         if (!methodsOK) {
+            
+            ams.removeMethodsForPortlet(pd.getPortletName());
+            badPortlets.add(pd);
+            
+            StringBuilder txt = new StringBuilder();
+            txt.append("Portlet does not have a render, resource, or header method, so cannot be taken into service. ");
+            txt.append("Portlet name: ").append(pd.getPortletName());
+            LOG.warn(txt.toString());
+         }
+      }
+      
+      // if there are bad portlets, delete them from the config
+      for (PortletDefinition pd : badPortlets) {
+         pad.removePortlet(pd);
+      }
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder();
+         txt.append("Finished reconciling bean config. ");
+         txt.append("Resulting portlet list: ").append(ams.getPortletNames().toString());
+         LOG.debug(txt.toString());
+      }
+      
+   }
+   
+   /**
+    * helper method for extracting the portlet methods from the portlet class.
+    * @param cls
+    * @param name
+    * @param md
+    * @return
+    */
+   private AnnotatedMethod getMethod(Object instance, String name, MethodDescription md) {
+      AnnotatedMethod am = null;
+      Class<?> cls = instance.getClass();
+      try {
+         Method meth = cls.getMethod(name, md.getArgTypes());
+         am = new AnnotatedMethod(cls, instance, meth, md);
+      } catch (Exception e) {
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder();
+            txt.append("Could not retrieve method from portlet class.");
+            txt.append(" Method name: ").append(name);
+            txt.append(", Class: ").append(cls.getCanonicalName());
+            txt.append(", Argument types: ").append(md.getArgTypes());
+            LOG.debug(txt.toString());
+         }
+      }
+      return am;
+   }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
index c48c429..7cbb18f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
@@ -478,12 +478,12 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          List<PortletModeType> pmlist = st.getPortletMode();
          if (pmlist.size() == 0) {
             String info = "No portlet modes found in Supports block.";
-            LOG.debug(info);
+            LOG.trace(info);
          }
          List<WindowStateType> wslist = st.getWindowState();
          if (wslist.size() == 0) {
             String info = "No window states found in Supports block.";
-            LOG.debug(info);
+            LOG.trace(info);
          }
 
          // set up Supports

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 891259b..9b97417 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -18,17 +18,13 @@
 
 package org.apache.pluto.container.om.portlet.impl;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
-import javax.enterprise.inject.spi.Bean;
-import javax.enterprise.inject.spi.BeanManager;
 import javax.portlet.Portlet;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletURLGenerationListener;
@@ -51,14 +47,6 @@ import javax.portlet.filter.ResourceFilter;
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
 
-import org.apache.pluto.container.bean.processor.AnnotatedMethod;
-import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
-import org.apache.pluto.container.bean.processor.MethodIdentifier;
-import org.apache.pluto.container.bean.processor.MethodType;
-
-import static org.apache.pluto.container.bean.processor.MethodDescription.*;
-
-import org.apache.pluto.container.bean.processor.MethodDescription;
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
 import org.apache.pluto.container.om.portlet.CustomPortletMode;
 import org.apache.pluto.container.om.portlet.CustomWindowState;
@@ -122,7 +110,6 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
    /** Logger. */
    private static final Logger  LOG     = LoggerFactory.getLogger(JSR362ConfigurationProcessor.class);
-   private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean isTrace = LOG.isTraceEnabled();
    
    // For holding the preference validators while the portlet configuration
@@ -1391,254 +1378,4 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       }
    }
 
-   @Override
-   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
-
-      ams.setDefaultNamespace(pad.getDefaultNamespace());
-      
-      for (String pn : ams.getPortletNames()) {
-         
-         PortletDefinition pd = pad.getPortlet(pn);
-         if (pd == null) {
-            pd = new PortletDefinitionImpl(pn, pad);
-         }
-         
-         List<EventDefinitionReference> edrs = pd.getSupportedProcessingEvents();
-         for (QName qn : ams.getProcessingEventRefs(pn)) {
-            EventDefinition ed = pad.getEventDefinition(qn);
-            if (ed == null) {
-               StringBuilder txt = new StringBuilder(128);
-               txt.append("No event definition found for annotated processing event reference.");
-               txt.append(" Portlet name: ").append(pn);
-               txt.append(", QName: ").append(qn);
-               LOG.warn(txt.toString());
-               
-               // remove the defective method from the store
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), qn, MethodType.EVENT);
-               ams.removeMethod(mi);
-               
-               continue;
-            }
-            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
-            if (!edrs.contains(newedr)) {
-               pd.addSupportedProcessingEvent(newedr);
-            }
-         }
-         
-         edrs = pd.getSupportedPublishingEvents();
-         for (QName qn : ams.getPublishingEventRefs(pn)) {
-            EventDefinition ed = pad.getEventDefinition(qn);
-            if (ed == null) {
-               StringBuilder txt = new StringBuilder(128);
-               txt.append("No event definition found for annotated publishing event reference.");
-               txt.append(" Portlet name: ").append(pn);
-               txt.append(", QName: ").append(qn);
-               LOG.warn(txt.toString());
-               continue;
-            }
-            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
-            if (!edrs.contains(newedr)) {
-               pd.addSupportedPublishingEvent(newedr);
-            }
-         }
-         
-         pad.addPortlet(pd);
-      }
-      
-      // Now add the declared portlet class methods to the store
-      
-      List<PortletDefinition> badPortlets = new ArrayList<PortletDefinition>();
-      for (PortletDefinition pd : pad.getPortlets()) {
-         Class<?> cls = null;
-
-         String clsName = pd.getPortletClass();
-         if (isValidIdentifier(clsName)) {
-            
-            // Make sure the class can be loaded
-            Class<?> valClass = null;
-            StringBuilder txt = new StringBuilder(128);
-            try {
-               ClassLoader cl = Thread.currentThread().getContextClassLoader();
-               if (cl == null) {
-                  cl = this.getClass().getClassLoader();
-               }
-               valClass = cl.loadClass(clsName);
-               if (Portlet.class.isAssignableFrom(valClass)) {
-                  cls = valClass;
-               } else {
-                  txt.append("Specified portlet class does not implement the Portlet interface.");
-               }
-            } catch (Exception e) {
-               txt.append("Specified portlet class could not be loaded.");
-            } finally {
-               if (cls == null) {
-                  txt.append(" Portlet name: ").append(pd.getPortletName());
-                  txt.append(", Portlet class: ").append(clsName);
-                  LOG.warn(txt.toString());
-               }
-            }
-         }
-         
-         Object instance = null;
-         if (cls != null) {
-            
-            // Let CDI instantiate the portlet to allow for injection. 
-            // Get the single bean instance for the portlet class.
-            
-            StringBuilder txt = new StringBuilder(128);
-            BeanManager bm = ams.getBeanMgr();
-            if (bm == null) {
-               txt.append("Could not instantiate portlet class. Bean manager is null.");
-            } else {
-               Set<Bean<?>> beans = bm.getBeans(cls);
-               if (beans == null || beans.size() == 0) {
-                  txt.append("Could not instantiate portlet class. No beans found.");
-               } else {
-                  Bean<?> bean = bm.resolve(beans);
-                  if (bean == null) {
-                     txt.append("Could not instantiate portlet class. Could not resolve bean.");
-                  } else {
-                     instance = bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
-                     if (instance == null) {
-                        txt.append("Could not instantiate portlet class. Could not get bean instance.");
-                     }
-                  }
-               }
-            }
-            
-            if (txt.length() > 0) {
-               txt.append(" Portlet name: ").append(pd.getPortletName());
-               txt.append(", portlet class: ").append(cls);
-               LOG.warn(txt.toString());
-            }
-         }
-
-         if (instance != null) {
-            
-            // The annotated method store might contain methods from the configured
-            // portlet class being processed. For example, this may occur when an action
-            // or event method in the portlet class is annotated to specify processing or
-            // publishing event references. Such annotated methods must use the same bean
-            // instance, so fix up the method store.
-            
-            ams.setPortletClassInstance(cls, instance);
-
-            // extract the methods from the portlet class and add them to the method store
-            // as long there is no corresponding annotated method already present.
-            // (annotated methods take precedence over portlet class methods). 
-            
-            AnnotatedMethod am;
-            am = getMethod(instance, "init", METH_INI);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.INIT);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "destroy", METH_DES);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.DESTROY);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "processAction", METH_ACT);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.ACTION);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "processEvent", METH_EVT);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.EVENT);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "render", METH_REN);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RENDER);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "renderHeaders", METH_HDR);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.HEADER);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-            
-            am = getMethod(instance, "serveResource", METH_RES);
-            if (am != null) {
-               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RESOURCE);
-               if (ams.getMethods(mi).size() == 0) {
-                  ams.addMethod(mi, am);
-               }
-            }
-
-         }
-         
-         // and finally make sure that the portlet has at least one render, header, or serveResource
-         // method. If not, delete it.
-         
-         boolean methodsOK = false;
-         for (MethodIdentifier mi : ams.getMethodIDsForPortlet(pd.getPortletName())) {
-            if ((mi.getType() == MethodType.RENDER) || (mi.getType() == MethodType.RESOURCE) ||
-                  (mi.getType() == MethodType.HEADER)) {
-               methodsOK = true;
-               break;
-            }
-         }
-         if (!methodsOK) {
-            
-            ams.removeMethodsForPortlet(pd.getPortletName());
-            badPortlets.add(pd);
-            
-            StringBuilder txt = new StringBuilder();
-            txt.append("Portlet does not have a render, resource, or header method, so cannot be taken into service. ");
-            txt.append("Portlet name: ").append(pd.getPortletName());
-            LOG.warn(txt.toString());
-         }
-      }
-      
-      // if there are bad portlets, delete them from the config
-      for (PortletDefinition pd : badPortlets) {
-         pad.removePortlet(pd);
-      }
-      
-   }
-   
-   /**
-    * helper method for extracting the portlet methods from the portlet class.
-    * @param cls
-    * @param name
-    * @param md
-    * @return
-    */
-   private AnnotatedMethod getMethod(Object instance, String name, MethodDescription md) {
-      AnnotatedMethod am = null;
-      Class<?> cls = instance.getClass();
-      try {
-         Method meth = cls.getMethod(name, md.getArgTypes());
-         am = new AnnotatedMethod(cls, instance, meth, md);
-      } catch (Exception e) {
-         if (isDebug) {
-            StringBuilder txt = new StringBuilder();
-            txt.append("Could not retrieve method from portlet class.");
-            txt.append(" Method name: ").append(name);
-            txt.append(", Class: ").append(cls.getCanonicalName());
-            txt.append(", Argument types: ").append(md.getArgTypes());
-            LOG.debug(txt.toString());
-         }
-      }
-      return am;
-   }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/afb1a42f/pluto-container/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/META-INF/beans.xml b/pluto-container/src/main/resources/META-INF/beans.xml
new file mode 100644
index 0000000..115420e
--- /dev/null
+++ b/pluto-container/src/main/resources/META-INF/beans.xml
@@ -0,0 +1,5 @@
+<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="
+http://java.sun.com/xml/ns/javaee
+http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+</beans>
\ No newline at end of file


[05/35] portals-pluto git commit: Added configuration by annotation for V3 portlets. For v3 portlets, neither the web application deployment descriptor nor the portlet deployment descriptor are necessary. * Annotations provided for all portlet config

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
index d71a219..bbaa992 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
@@ -91,7 +91,7 @@ public class PortletApplicationDefinition362ImplTest {
       InputStream in = PortletApplicationDefinition362ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      cfp = new ConfigurationHolder(pad);
+      cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -228,6 +228,27 @@ public class PortletApplicationDefinition362ImplTest {
   }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addPortlet(org.apache.pluto.container.om.portlet.PortletDefinition)}.
+    */
+   @Test
+   public void testAddDupPortlet() {
+      String newPN = "portlet362";
+      PortletDefinition pd = new PortletDefinitionImpl(newPN, cut);
+      cut.addPortlet(pd);
+      
+      List<PortletDefinition> list = cut.getPortlets();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      for (PortletDefinition item : list) {
+         if (item.getPortletName().equals(newPN)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+  }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getEventDefinitions()}.
     */
    @Test
@@ -277,6 +298,27 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addEventDefinition(org.apache.pluto.container.om.portlet.EventDefinition)}.
+    */
+   @Test
+   public void testAddDupEventDefinition() {
+      QName qn = new QName("https://www.apache.org/", "supported-processing-event");
+      EventDefinition ed = new EventDefinitionImpl(qn);
+      cut.addEventDefinition(ed);
+
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      boolean ok = false;
+      for (EventDefinition item : list) {
+         if (item.getQName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getPublicRenderParameter(java.lang.String)}.
     */
    @Test
@@ -315,6 +357,22 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addPublicRenderParameter(org.apache.pluto.container.om.portlet.PublicRenderParameter)}.
+    */
+   @Test
+   public void testAddDupPublicRenderParameter() {
+      String prpid = "supported-public-render-parameter";
+      QName qn = new QName("https://www.apache.org/", "QName");
+      PublicRenderParameter prp = new PublicRenderParameterImpl(qn, prpid);
+      cut.addPublicRenderParameter(prp);
+      
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(2, prps.size());
+      assertEquals(prpid, prps.get(1).getIdentifier());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomPortletMode(java.lang.String)}.
     */
    @Test
@@ -352,6 +410,21 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addCustomPortletMode(org.apache.pluto.container.om.portlet.CustomPortletMode)}.
+    */
+   @Test
+   public void testAddDuplicateCustomPortletMode() {
+      String newItem = "portlet-mode";
+      CustomPortletMode prp = new CustomPortletModeImpl(newItem);
+      cut.addCustomPortletMode(prp);
+      
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getPortletMode());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomWindowState(java.lang.String)}.
     */
    @Test
@@ -378,7 +451,7 @@ public class PortletApplicationDefinition362ImplTest {
     */
    @Test
    public void testAddCustomWindowState() {
-      String newItem = "newMode";
+      String newItem = "newState";
       CustomWindowState prp = new CustomWindowStateImpl(newItem);
       cut.addCustomWindowState(prp);
       
@@ -389,6 +462,21 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addCustomWindowState(org.apache.pluto.container.om.portlet.CustomWindowState)}.
+    */
+   @Test
+   public void testAddDupCustomWindowState() {
+      String newItem = "window-state";
+      CustomWindowState prp = new CustomWindowStateImpl(newItem);
+      cut.addCustomWindowState(prp);
+      
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getWindowState());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getUserAttribute(java.lang.String)}.
     */
    @Test
@@ -426,18 +514,34 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addUserAttribute(org.apache.pluto.container.om.portlet.UserAttribute)}.
+    */
+   @Test
+   public void testAddDupUserAttribute() {
+      String newItem = "name";
+      UserAttribute prp = new UserAttributeImpl(newItem);
+      cut.addUserAttribute(prp);
+      
+      List<UserAttribute> list = cut.getUserAttributes();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getName());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
     */
    @Test
    public void testGetFilter() {
       String newItem = "filter-name";
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
       Filter item = cut.getFilter(newItem);
       assertNotNull(item);
       Filter filter = cut.getFilters().get(0);
-      assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter", 
+      assertEquals(filterClass, 
             filter.getFilterClass());
-      assertEquals("description", filter.getDescription(new Locale("de")).getDescription());
-      assertEquals("display-name", filter.getDisplayName(new Locale("de")).getDisplayName());
+      assertEquals("description", filter.getDescription(new Locale("de")).getText());
+      assertEquals("display-name", filter.getDisplayName(new Locale("de")).getText());
       assertEquals("lifecycle", filter.getLifecycles().get(0));
       assertEquals("value", filter.getInitParam("name").getParamValue());
    }
@@ -460,8 +564,10 @@ public class PortletApplicationDefinition362ImplTest {
    @Test
    public void testAddFilter() {
       String newItem = "newFilter";
-      Filter prp = new FilterImpl(newItem);
-      cut.addFilter(prp);
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass(filterClass);
+      cut.addFilter(fil);
       
       List<Filter> list = cut.getFilters();
       assertNotNull(list);
@@ -470,6 +576,40 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testRemoveFilter() {
+      // existing filter def is removed if filter class is null (= not set)
+      String newItem = "filter-name";
+      Filter fil = new FilterImpl(newItem);
+      assertNotNull(cut.getFilter(newItem));
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+      assertEquals(null, cut.getFilter(newItem));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddDupFilter() {
+      String newItem = "filter-name";
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass(filterClass);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMapping(java.lang.String)}.
     */
    @Test
@@ -499,8 +639,10 @@ public class PortletApplicationDefinition362ImplTest {
    @Test
    public void testAddFilterMapping() {
       String newItem = "newFilter";
-      FilterMapping prp = new FilterMappingImpl(newItem);
-      cut.addFilterMapping(prp);
+      String portletName = "portlet362";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName(portletName);
+      cut.addFilterMapping(fm);
       
       List<FilterMapping> list = cut.getFilterMappings();
       assertNotNull(list);
@@ -509,6 +651,39 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testRemoveFilterMapping() {
+      String newItem = "filter-name";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      assertNotNull(cut.getFilterMapping(newItem));
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+      assertEquals(null, cut.getFilterMapping(newItem));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testAddDupFilterMapping() {
+      String newItem = "filter-name";
+      String portletName = "portlet362";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName(portletName);
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getContainerRuntimeOption(java.lang.String)}.
     */
    @Test
@@ -548,6 +723,23 @@ public class PortletApplicationDefinition362ImplTest {
    }
 
    /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addContainerRuntimeOption(org.apache.pluto.container.om.portlet.ContainerRuntimeOption)}.
+    */
+   @Test
+   public void testAddDupContainerRuntimeOption() {
+      String newItem = "Runtime-Option-Portlet-App";
+      String[] newvals = {"v1", "v2"}; 
+      ContainerRuntimeOption item = new ContainerRuntimeOptionImpl(newItem, Arrays.asList(newvals));
+      cut.addContainerRuntimeOption(item);
+      
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getName());
+      assertArrayEquals(newvals, list.get(0).getValues().toArray());
+   }
+
+   /**
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getListeners()}.
     */
    @Test
@@ -556,6 +748,7 @@ public class PortletApplicationDefinition362ImplTest {
       assertNotNull(list);
       assertEquals(1, list.size());
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestListener", list.get(0).getListenerClass());
+      assertEquals("test listener", list.get(0).getListenerName());
    }
 
    /**
@@ -564,24 +757,36 @@ public class PortletApplicationDefinition362ImplTest {
    @Test
    public void testAddListener() {
       String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.DifferentListener";
+      String lisName = "Different Listener";
       Listener newitem = new ListenerImpl(clsName);
+      newitem.setListenerName(lisName);
+      
       cut.addListener(newitem);
       
       List<Listener> list = cut.getListeners();
       assertNotNull(list);
       assertEquals(2, list.size());
       assertEquals(clsName, list.get(1).getListenerClass());
+      assertEquals(lisName, list.get(1).getListenerName());
    }
 
    /**
-    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getSecurityConstraints()}.
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
     */
    @Test
-   public void testGetSecurityConstraints() {
-      List<SecurityConstraint> list = cut.getSecurityConstraints();
+   public void testAddDupListener() {
+      String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.TestListener";
+      String lisName = "test listener";
+      Listener newitem = new ListenerImpl(clsName);
+      newitem.setListenerName(lisName);
+      
+      cut.addListener(newitem);
+      
+      List<Listener> list = cut.getListeners();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("NONE", list.get(0).getUserDataConstraint().getTransportGuarantee());
+      assertEquals(clsName, list.get(0).getListenerClass());
+      assertEquals(lisName, list.get(0).getListenerName());
    }
 
    /**
@@ -594,8 +799,22 @@ public class PortletApplicationDefinition362ImplTest {
       
       List<SecurityConstraint> list = cut.getSecurityConstraints();
       assertNotNull(list);
-      assertEquals(2, list.size());
-      assertEquals("CONFIDENTIAL", list.get(1).getUserDataConstraint().getTransportGuarantee());
+      assertEquals(1, list.size());
+      assertEquals("CONFIDENTIAL", list.get(0).getUserDataConstraint().getTransportGuarantee());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addSecurityConstraint(org.apache.pluto.container.om.portlet.SecurityConstraint)}.
+    */
+   @Test
+   public void testAddDupSecurityConstraint() {
+      SecurityConstraint seco = new SecurityConstraintImpl(new UserDataConstraintImpl("NONE"));
+      cut.addSecurityConstraint(seco);
+      
+      List<SecurityConstraint> list = cut.getSecurityConstraints();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals("NONE", list.get(0).getUserDataConstraint().getTransportGuarantee());
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
new file mode 100644
index 0000000..4d206c0
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362AnnotationTest.java
@@ -0,0 +1,815 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.Dependency;
+import org.apache.pluto.container.om.portlet.Description;
+import org.apache.pluto.container.om.portlet.DisplayName;
+import org.apache.pluto.container.om.portlet.InitParam;
+import org.apache.pluto.container.om.portlet.LocaleText;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.PortletInfo;
+import org.apache.pluto.container.om.portlet.Preference;
+import org.apache.pluto.container.om.portlet.Preferences;
+import org.apache.pluto.container.om.portlet.SecurityRoleRef;
+import org.apache.pluto.container.om.portlet.Supports;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ContainerRuntimeOptionImpl;
+import org.apache.pluto.container.om.portlet.impl.DependencyImpl;
+import org.apache.pluto.container.om.portlet.impl.DescriptionImpl;
+import org.apache.pluto.container.om.portlet.impl.DisplayNameImpl;
+import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
+import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletInfoImpl;
+import org.apache.pluto.container.om.portlet.impl.PreferenceImpl;
+import org.apache.pluto.container.om.portlet.impl.PreferencesImpl;
+import org.apache.pluto.container.om.portlet.impl.SecurityRoleRefImpl;
+import org.apache.pluto.container.om.portlet.impl.SupportsImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPortlet;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * Test class for a portlet configuration annotation applied to a class
+ * that does not extend the Portlet interface.
+ * <p>
+ * Test Class: TestAnnotatedPortlet
+ * 
+ * @author Scott Nicklous
+ */
+public class PortletDefinition362AnnotationTest {
+
+   private static final Class<?>               TEST_ANNOTATED_CLASS = TestAnnotatedPortlet.class;
+
+   private static PortletApplicationDefinition pad;
+
+   // Class under test
+   private PortletDefinition                   cut;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertEquals(1, pad.getPortlets().size());
+      cut = new PortletDefinitionImpl(pad.getPortlets().get(0));
+   }
+
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(cut.getPortletName());
+      assertEquals("AnnotatedPortlet", cut.getPortletName());
+   }
+
+   @Test
+   public void testGetApplication() {
+      assertNotNull(cut.getApplication());
+      assertTrue(cut.getApplication() instanceof PortletApplicationDefinition);
+   }
+
+   @Test
+   public void testGetInitParam() {
+      String name = "AnnoName";
+      String val = "value";
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(val, ip.getParamValue());
+      assertEquals(1, ip.getDescriptions().size());
+      Locale loc = new Locale("de");
+      Description d = ip.getDescription(loc);
+      assertNotNull(d);
+      assertEquals("Beschreibung", d.getText());
+   }
+
+   @Test
+   public void testGetInitParamNullValue() {
+      InitParam ip = cut.getInitParam("nullValueParam");
+      assertNotNull(ip);
+      assertEquals("nullValueParam", ip.getParamName());
+      assertEquals("", ip.getParamValue());
+   }
+
+   @Test
+   public void testGetInitParams() {
+      String name = "AnnoName";
+      String name2 = "ipname";
+      String val = "value";
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(3, ips.size());
+      
+      InitParam ip = new InitParamImpl(name, val);
+      assertTrue(ips.contains(ip));
+      ip = new InitParamImpl(name2, val);
+      assertTrue(ips.contains(ip));
+      
+   }
+
+   @Test
+   public void testAddInitParam() {
+      String name = "Fred", value = "bowling";
+      InitParam newip = new InitParamImpl(name, value);
+      cut.addInitParam(newip);
+
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(4, ips.size());
+      assertTrue(ips.contains(newip));
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(value, ip.getParamValue());
+   }
+
+   @Test
+   public void testAddDupInitParam() {
+      String name = "ipname", value = "new value";
+      InitParam newip = new InitParamImpl(name, value);
+      cut.addInitParam(newip);
+
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(3, ips.size());
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(value, ip.getParamValue());
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNull(cut.getPortletClass());
+   }
+
+   @Test
+   public void testSetPortletClass() {
+      String text = "someClass";
+      cut.setPortletClass(text);
+      assertEquals(text, cut.getPortletClass());
+   }
+
+   @Test
+   public void testGetPortletInfoJSR286Compat() {
+      String title = "Annotated Portlet";
+      String sTitle = "Anno Portlet";
+      String keywords = "One, Two, Three";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      assertEquals(title, info.getTitle());
+      assertEquals(sTitle, info.getShortTitle());
+      assertEquals(keywords, info.getKeywords());
+   }
+
+   @Test
+   public void testSetPortletInfo286() {
+      String ti = "t2", st = "st", kw = "kw";
+      PortletInfo i2 = new PortletInfoImpl(ti, kw, st);
+      cut.setPortletInfo(i2);
+
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      assertEquals(ti, info.getTitle());
+      assertEquals(st, info.getShortTitle());
+      assertEquals(kw, info.getKeywords());
+   }
+
+   @Test
+   public void testGetTitle() {
+      String txt1 = "Annotated Portlet";
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddTitle() {
+      String txt1 = "Annotated Portlet";
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(3, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupTitle() {
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetShortTitle() {
+      String txt1 = "Anno Portlet";
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddShortTitle() {
+      String txt1 = "Anno Portlet";
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(3, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupShortTitle() {
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Short Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetKeywords() {
+      String txt1 = "One, Two, Three";
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddKeywords() {
+      String txt1 = "One, Two, Three";
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(3, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupKeywords() {
+      String txt1 = "One, Two, Three";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "andre Schlagwörter";
+      LocaleText lt = new LocaleTextImpl(Locale.GERMAN, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.GERMAN).getText());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+   }
+   
+   private Preference getPref(String name, List<Preference> list) {
+      for (Preference item : list) {
+         if (item.getName().equals(name)) {
+            return item;
+         }
+      }
+      return null;
+   }
+
+   @Test
+   public void testGetPortletPreferences() {
+      Preferences prefs = cut.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(null, prefs.getPreferencesValidator());
+      List<Preference> list = prefs.getPortletPreferences();
+      assertEquals(2, list.size());
+      Preference item = getPref("aPref", list);
+      List<String> vals = item.getValues();
+      assertEquals(1, vals.size());
+      assertEquals("aValue", vals.get(0));
+      item = getPref("bPref", list);
+      assertNotNull(item);
+   }
+
+   @Test
+   public void testSetPortletPreferences() {
+      String validator = "validator";
+      String name = "prefName";
+      String[] vals = { "v1", "v2" };
+      Preferences prefs = new PreferencesImpl(cut.getPortletPreferences());
+      prefs.setPreferencesValidator(validator);
+      prefs.addPreference(new PreferenceImpl(name, true, Arrays.asList(vals)));
+      cut.setPortletPreferences(prefs);
+
+      Preferences prefs2 = cut.getPortletPreferences();
+      assertNotNull(prefs2);
+      assertEquals(validator, prefs2.getPreferencesValidator());
+      List<Preference> list = prefs2.getPortletPreferences();
+      assertEquals(3, list.size());
+      Preference item = prefs2.getPortletPreference(name);
+      assertEquals(name, item.getName());
+      List<String> newvals = item.getValues();
+      assertEquals(2, newvals.size());
+      assertArrayEquals(vals, newvals.toArray());
+   }
+
+   @Test
+   public void testGetSupportedPublicRenderParameters() {
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      String prp = "color";
+      String prp2 = "aPrp";
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertTrue(list.contains(prp));
+      assertTrue(list.contains(prp2));
+   }
+
+   @Test
+   public void testAddSupportedPublicRenderParameter() {
+      String newprp = "some-prp";
+      cut.addSupportedPublicRenderParameter(newprp);
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(list.contains(newprp));
+   }
+
+   @Test
+   public void testAddDupSupportedPublicRenderParameter() {
+      String newprp = "anno-prp";
+      cut.addSupportedPublicRenderParameter(newprp);
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(list.contains(newprp));
+   }
+
+   @Test
+   public void testGetResourceBundle() {
+      assertNotNull(cut.getResourceBundle());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", cut.getResourceBundle());
+   }
+
+   @Test
+   public void testSetResourceBundle() {
+      String text = "newBundle";
+      cut.setResourceBundle(text);
+      assertNotNull(cut.getResourceBundle());
+      assertEquals(text, cut.getResourceBundle());
+   }
+
+   @Test
+   public void testGetSecurityRoleRef() {
+      String name = "aRole";
+      String link = "aLink";
+      SecurityRoleRef srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
+   public void testGetSecurityRoleRefs() {
+      String name = "aRole";
+      String link = "aLink";
+      String desc = "Beschreibung";
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(1, list.size());
+      SecurityRoleRef srr = list.get(0);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+      Description d = srr.getDescription(new Locale("de"));
+      assertNotNull(d);
+      assertEquals(desc, d.getText());
+   }
+
+   @Test
+   public void testAddSecurityRoleRef() {
+      String name = "NewName";
+      String link = "NewLink";
+      SecurityRoleRef srr = new SecurityRoleRefImpl(name);
+      srr.setRoleLink(link);
+      cut.addSecurityRoleRef(srr);
+
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(2, list.size());
+      srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
+   public void testAddDupSecurityRoleRef() {
+      String name = "aRole";
+      String link = "aDifferentLink";
+      SecurityRoleRef srr = new SecurityRoleRefImpl(name);
+      srr.setRoleLink(link);
+      cut.addSecurityRoleRef(srr);
+
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(1, list.size());
+      srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
+   public void testGetSupportsString() {
+      String mt = "aMimeType";
+      String pm = "aMode";
+      Supports s = cut.getSupports(mt);
+      assertNotNull(s);
+      assertTrue(s.getPortletModes().contains(pm));
+   }
+
+   @Test
+   public void testGetSupportsMode() {
+      String mt = "aMimeType2";
+      String pm = "aMode2";
+      Supports s = cut.getSupports(mt);
+      assertNotNull(s);
+      assertTrue(s.getPortletModes().contains(pm));
+   }
+
+   @Test
+   public void testGetSupportsState() {
+      Supports s = cut.getSupports("mime-type3");
+      assertNotNull(s);
+      assertTrue(s.getWindowStates().contains("aWS3"));
+   }
+
+   @Test
+   public void testGetSupports() {
+      List<Supports> list = cut.getSupports();
+      assertEquals(3, list.size());
+   }
+
+   @Test
+   public void testAddSupports() {
+      Supports s = new SupportsImpl("text/html");
+      cut.addSupports(s);
+      List<Supports> list = cut.getSupports();
+      assertEquals(4, list.size());
+      boolean ok = false;
+      for (Supports item : list) {
+         if (item.getMimeType().equals("text/html")) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testAddDupSupports() {
+      String mt = "mime-type3";
+      String ws = "SomeWindowState";
+      Supports s = new SupportsImpl(mt);
+      s.addWindowState(ws);
+      cut.addSupports(s);
+      List<Supports> list = cut.getSupports();
+      assertEquals(3, list.size());
+      boolean ok = false;
+      for (Supports item : list) {
+         if (item.getMimeType().equals(mt) && item.getWindowStates().get(0).equals(ws)) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testGetDescription() {
+      Locale loc = new Locale("DE");
+      Description desc = cut.getDescription(loc);
+      assertNotNull(desc);
+      assertEquals("Dieses Portlet zeigt die Zeit in verschiedenen Zeitzonen an", desc.getText());
+   }
+
+   @Test
+   public void testGetDescriptions() {
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals("Portlet displaying the time in different time zones", list.get(0).getText());
+   }
+
+   @Test
+   public void testAddDescription() {
+      Locale loc = Locale.FRENCH;
+      String text = "Une description";
+      Description d = new DescriptionImpl(loc, text);
+      cut.addDescription(d);
+
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      for (Description desc : list) {
+         if (desc.getLocale().equals(loc)) {
+            assertEquals(text, desc.getText());
+         }
+      }
+   }
+
+   @Test
+   public void testAddDupDescription() {
+      Locale loc = Locale.GERMAN;
+      String text = "multi line description";
+      Description d = new DescriptionImpl(loc, text);
+      cut.addDescription(d);
+
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      Description desc = cut.getDescription(loc);
+      assertEquals(text, desc.getText());
+   }
+
+   @Test
+   public void testGetDisplayName() {
+      Locale loc = new Locale("DE");
+      DisplayName name = cut.getDisplayName(loc);
+      assertNotNull(name);
+      assertEquals("ZeitzonenPortlet", name.getText());
+   }
+
+   @Test
+   public void testGetDisplayNames() {
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals("Time Zone Clock Portlet", list.get(0).getText());
+   }
+
+   @Test
+   public void testAddDisplayName() {
+      Locale loc = Locale.FRENCH;
+      String text = "un nom de annonce";
+      DisplayName d = new DisplayNameImpl(loc, text);
+      cut.addDisplayName(d);
+
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      for (DisplayName desc : list) {
+         if (desc.getLocale().equals(loc)) {
+            assertEquals(text, desc.getText());
+         }
+      }
+   }
+
+   @Test
+   public void testAddDupDisplayName() {
+      Locale loc = Locale.GERMAN;
+      String text = "Anzeigetext";
+      DisplayName d = new DisplayNameImpl(loc, text);
+      cut.addDisplayName(d);
+
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+
+      assertEquals(2, list.size());
+      DisplayName dn = cut.getDisplayName(loc);
+      assertEquals(text, dn.getText());
+   }
+
+   @Test
+   public void testGetSupportedLocales() {
+      String locname = "Locale1";
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(1, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
+   public void testAddSupportedLocale() {
+      String locname = "zh-cmn-Hans-CN";
+      cut.addSupportedLocale(locname);
+
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(2, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
+   public void testAddDupSupportedLocale() {
+      String locname = "Locale1";
+      cut.addSupportedLocale(locname);
+
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(1, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
+   public void testGetExpirationCache() {
+      assertNotNull(cut.getExpirationCache());
+      assertEquals(30, cut.getExpirationCache());
+   }
+
+   @Test
+   public void testSetExpirationCache() {
+      cut.setExpirationCache(100);
+      assertNotNull(cut.getExpirationCache());
+      assertEquals(100, cut.getExpirationCache());
+   }
+
+   @Test
+   public void testGetCacheScope() {
+      assertNotNull(cut.getCacheScope());
+      assertEquals("private", cut.getCacheScope());
+   }
+
+   @Test
+   public void testSetCacheScope() {
+      String cs = "whatever";
+      cut.setCacheScope(cs);
+      assertNotNull(cut.getCacheScope());
+      assertEquals(cs, cut.getCacheScope());
+   }
+
+   @Test
+   public void testGetContainerRuntimeOption() {
+      ContainerRuntimeOption rto = cut.getContainerRuntimeOption("aRTO");
+      assertNotNull(rto);
+      assertEquals(2, rto.getValues().size());
+      assertArrayEquals(new String[] {"true", "false"}, rto.getValues().toArray());
+   }
+
+   @Test
+   public void testGetContainerRuntimeOptions() {
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      boolean ok = false;
+      for (ContainerRuntimeOption item : list) {
+         if (item.getName().equalsIgnoreCase("Runtime-Option2") && item.getValues().size() == 1
+               && item.getValues().get(0).equalsIgnoreCase("value2")) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testAddContainerRuntimeOption() {
+      String name = "NewRTO";
+      String[] vals = { "v1", "v2", "v3" };
+      ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(name, Arrays.asList(vals));
+      cut.addContainerRuntimeOption(cro);
+
+      ContainerRuntimeOption newcro = cut.getContainerRuntimeOption(name);
+      assertNotNull(newcro);
+      assertArrayEquals(vals, newcro.getValues().toArray());
+   }
+
+   @Test
+   public void testAddDupContainerRuntimeOption() {
+      String name = "aRTO";
+      String[] vals = { "maybe" };
+      ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(name, Arrays.asList(vals));
+      cut.addContainerRuntimeOption(cro);
+
+      ContainerRuntimeOption newcro = cut.getContainerRuntimeOption(name);
+      assertNotNull(newcro);
+      assertArrayEquals(vals, newcro.getValues().toArray());
+   }
+
+   @Test
+   public void testGetDependency() {
+      String depName = "Dojo";
+      String depVers = "3.1.4";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+
+   @Test
+   public void testGetDependency2() {
+      String depName = "AngularJS";
+      String depVers = "1.4.8";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+
+   @Test
+   public void testGetDependencies() {
+      String depName = "Dojo";
+      String depVers = "3.1.4";
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(2, deps.size());
+      Dependency dep = new DependencyImpl(depName, depVers);
+      assertTrue(deps.contains(dep));
+   }
+
+   @Test
+   public void testAddDependency() {
+      String depName = "Bozo";
+      String depVers = "1.4";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(3, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+
+   @Test
+   public void testAddDupDependency() {
+      String depName = "Dojo";
+      String depVers = "2.2.2";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(2, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
index 902f163..401036a 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletDefinition362ImplTest.java
@@ -1,3 +1,22 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
 package org.apache.pluto.container.om.portlet.impl.jsr362;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -13,10 +32,12 @@ import java.util.Locale;
 import javax.xml.namespace.QName;
 
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.Dependency;
 import org.apache.pluto.container.om.portlet.Description;
 import org.apache.pluto.container.om.portlet.DisplayName;
 import org.apache.pluto.container.om.portlet.EventDefinitionReference;
 import org.apache.pluto.container.om.portlet.InitParam;
+import org.apache.pluto.container.om.portlet.LocaleText;
 import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
 import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.apache.pluto.container.om.portlet.PortletInfo;
@@ -26,10 +47,12 @@ import org.apache.pluto.container.om.portlet.SecurityRoleRef;
 import org.apache.pluto.container.om.portlet.Supports;
 import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
 import org.apache.pluto.container.om.portlet.impl.ContainerRuntimeOptionImpl;
+import org.apache.pluto.container.om.portlet.impl.DependencyImpl;
 import org.apache.pluto.container.om.portlet.impl.DescriptionImpl;
 import org.apache.pluto.container.om.portlet.impl.DisplayNameImpl;
 import org.apache.pluto.container.om.portlet.impl.EventDefinitionReferenceImpl;
 import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
+import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
 import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
 import org.apache.pluto.container.om.portlet.impl.PortletInfoImpl;
 import org.apache.pluto.container.om.portlet.impl.PreferenceImpl;
@@ -42,6 +65,12 @@ import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+
+/**
+ * Test class for reading the portlet deployment descriptor.
+ * 
+ * @author Scott Nicklous
+ */
 public class PortletDefinition362ImplTest {
 
    private static final String XML_FILE = 
@@ -58,7 +87,7 @@ public class PortletDefinition362ImplTest {
       InputStream in = PortletDefinition362ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -96,7 +125,7 @@ public class PortletDefinition362ImplTest {
       Locale loc = new Locale("de");
       Description d = ip.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    @Test
@@ -135,6 +164,20 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
+   public void testAddDupInitParam() {
+      String name = "name", value = "value";
+      InitParam newip = new InitParamImpl(name, value);
+      cut.addInitParam(newip);
+      
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(2, ips.size());
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(value, ip.getParamValue());
+   }
+
+   @Test
    public void testGetPortletClass() {
       assertNotNull(cut.getPortletClass());
       assertEquals(TestPortlet.class.getCanonicalName(), cut.getPortletClass());
@@ -148,7 +191,7 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
-   public void testGetPortletInfo() {
+   public void testGetPortletInfoJSR286Compat() {
       PortletInfo info = cut.getPortletInfo();
       assertNotNull(info);
       assertEquals("title", info.getTitle());
@@ -170,6 +213,116 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
+   public void testGetTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals("title", info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(3, list.size());
+      assertEquals("title", info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals("short-title", info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(3, list.size());
+      assertEquals("short-title", info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Short Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals("keywords", info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals("Schlagwörter", info.getKeywords(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(3, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals("keywords", info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals("Schlagwörter", info.getKeywords(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "andre Schlagwörter";
+      LocaleText lt = new LocaleTextImpl(Locale.GERMAN, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.GERMAN).getText());
+      assertEquals("keywords", info.getKeywords(Locale.ENGLISH).getText());
+   }
+
+   @Test
    public void testGetPortletPreferences() {
       Preferences prefs = cut.getPortletPreferences();
       assertNotNull(prefs);
@@ -239,6 +392,24 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test  // JSR 286
+   public void testAddDupSupportedProcessingEvent() {
+      QName qn = new QName("https://www.apache.org/", "supported-processing-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedProcessingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedProcessingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
    public void testGetSupportedPublishingEvents() {
       List<EventDefinitionReference> list = cut.getSupportedPublishingEvents();
       assertNotNull(list);
@@ -273,6 +444,24 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test  // JSR 286
+   public void testAddDupSupportedPublishingEvent() {
+      QName qn = new QName("http://test.com", "supported-publishing-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedPublishingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedPublishingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
    public void testGetSupportedPublicRenderParameters() {
       List<String> list = cut.getSupportedPublicRenderParameters();
       String prp = "supported-public-render-parameter";
@@ -291,6 +480,16 @@ public class PortletDefinition362ImplTest {
       assertTrue(list.contains(newprp));
    }
 
+   @Test  // JSR 286
+   public void testAddDupSupportedPublicRenderParameter() {
+      String newprp = "supported-public-render-parameter";
+      cut.addSupportedPublicRenderParameter(newprp);
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertTrue(list.contains(newprp));
+   }
+
    @Test
    public void testGetResourceBundle() {
       assertNotNull(cut.getResourceBundle());
@@ -323,7 +522,7 @@ public class PortletDefinition362ImplTest {
       assertEquals("role-link", srr.getRoleLink());
       Description d = srr.getDescription(new Locale("de"));
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
       
    }
 
@@ -344,6 +543,22 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
+   public void testAddDupSecurityRoleRef() {
+      String name = "NMTOKEN";
+      String link = "role-link";
+      SecurityRoleRef srr = new SecurityRoleRefImpl(name);
+      srr.setRoleLink(link);
+      cut.addSecurityRoleRef(srr);
+
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(1, list.size());
+      srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
    public void testGetSupportsString() {
       Supports s = cut.getSupports("mime-type2");
       assertNotNull(s);
@@ -387,11 +602,27 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
+   public void testAddDupSupports() {
+      Supports s = new SupportsImpl("mime-type2");
+      cut.addSupports(s);
+      List<Supports> list = cut.getSupports();
+      assertEquals(3, list.size());
+      boolean ok = false;
+      for (Supports item : list) {
+         if (item.getMimeType().equals("mime-type2")) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
    public void testGetDescription() {
       Locale loc = new Locale("DE");
       Description desc = cut.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("multi line description", desc.getDescription());
+      assertEquals("multi line description", desc.getText());
    }
 
    @Test
@@ -399,7 +630,7 @@ public class PortletDefinition362ImplTest {
       List<Description> list = cut.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("multi line description", list.get(0).getDescription());
+      assertEquals("multi line description", list.get(0).getText());
    }
 
    @Test
@@ -414,19 +645,34 @@ public class PortletDefinition362ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("multi line description", desc.getDescription());
+            assertEquals("multi line description", desc.getText());
          }
       }
    }
 
    @Test
+   public void testAddDupDescription() {
+      Locale loc = Locale.GERMAN;
+      String text = "multi line description";
+      Description d = new DescriptionImpl(loc, text);
+      cut.addDescription(d);
+
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      Description desc = list.get(0);
+      assertEquals(text, desc.getText());
+      assertEquals("multi line description", desc.getText());
+   }
+
+   @Test
    public void testGetDisplayName() {
       Locale loc = new Locale("DE");
       DisplayName name = cut.getDisplayName(loc);
       assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
+      assertEquals("display-name", name.getText());
    }
 
    @Test
@@ -434,7 +680,7 @@ public class PortletDefinition362ImplTest {
       List<DisplayName> list = cut.getDisplayNames();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
+      assertEquals("display-name", list.get(0).getText());
    }
 
    @Test
@@ -449,14 +695,29 @@ public class PortletDefinition362ImplTest {
       assertEquals(2, list.size());
       for (DisplayName desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("display-name", desc.getDisplayName());
+            assertEquals("display-name", desc.getText());
          }
       }
    }
 
    @Test
+   public void testAddDupDisplayName() {
+      Locale loc = Locale.GERMAN;
+      String text = "display-name";
+      DisplayName d = new DisplayNameImpl(loc, text);
+      cut.addDisplayName(d);
+
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+
+      assertEquals(1, list.size());
+      DisplayName dn = list.get(0);
+      assertEquals(text, dn.getText());
+   }
+
+   @Test
    public void testGetSupportedLocales() {
       List<String> list = cut.getSupportedLocales();
       assertEquals(1, list.size());
@@ -474,6 +735,16 @@ public class PortletDefinition362ImplTest {
    }
 
    @Test
+   public void testAddDupSupportedLocale() {
+      String locname = "supported-locale";
+      cut.addSupportedLocale(locname);
+      
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(1, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
    public void testGetExpirationCache() {
       assertNotNull(cut.getExpirationCache());
       assertEquals(50, cut.getExpirationCache());
@@ -535,4 +806,73 @@ public class PortletDefinition362ImplTest {
       assertArrayEquals(vals, newcro.getValues().toArray());
    }
 
+   @Test  // JSR 286
+   public void testAddDupContainerRuntimeOption() {
+      String name = "Runtime-Option1";
+      String[] vals = {"true"};
+      ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(name, Arrays.asList(vals));
+      cut.addContainerRuntimeOption(cro);
+      
+      ContainerRuntimeOption newcro = cut.getContainerRuntimeOption(name);
+      assertNotNull(newcro);
+      assertArrayEquals(vals, newcro.getValues().toArray());
+   }
+   
+   @Test
+   public void testGetDependency() {
+      String depName = "JQuery";
+      String depVers = "2.1.4";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+   
+   @Test
+   public void testGetDependency2() {
+      String depName = "AngularJS";
+      String depVers = "1.4.8";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+   
+   @Test
+   public void testGetDependencies() {
+      String depName = "JQuery";
+      String depVers = "2.1.4";
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(2, deps.size());
+      Dependency dep = new DependencyImpl(depName, depVers);
+      assertTrue(deps.contains(dep));
+   }
+   
+   @Test
+   public void testAddDependency() {
+      String depName = "Bozo";
+      String depVers = "1.4";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+      
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(3, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+   
+   @Test
+   public void testAddDupDependency() {
+      String depName = "JQuery";
+      String depVers = "2.2.2";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+      
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(2, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/SecurityConstraint362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/SecurityConstraint362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/SecurityConstraint362ImplTest.java
deleted file mode 100644
index 33eca76..0000000
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/SecurityConstraint362ImplTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.apache.pluto.container.om.portlet.impl.jsr362;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.pluto.container.om.portlet.DisplayName;
-import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
-import org.apache.pluto.container.om.portlet.SecurityConstraint;
-import org.apache.pluto.container.om.portlet.UserDataConstraint;
-import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
-import org.apache.pluto.container.om.portlet.impl.DisplayNameImpl;
-import org.apache.pluto.container.om.portlet.impl.SecurityConstraintImpl;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class SecurityConstraint362ImplTest {
-
-   private static final String XML_FILE = 
-         "org/apache/pluto/container/om/portlet/portlet362Generated.xml";
-   
-   private static PortletApplicationDefinition pad;
-   
-   private ArrayList<SecurityConstraint> constraints;
-   private SecurityConstraint constraint;
-
-   @BeforeClass
-   public static void setUpBeforeClass() throws Exception {
-      
-      InputStream in = SecurityConstraint362ImplTest.class
-            .getClassLoader().getResourceAsStream(XML_FILE);
-      
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
-      try {
-         cfp.processPortletDD(in);
-         pad = cfp.getPad();
-      } catch (Exception e) {
-         e.printStackTrace();
-         throw e;
-      }
-   }
-   
-   @Before
-   public void setUpBefore() throws Exception {
-      constraints = new ArrayList<SecurityConstraint>();
-      for (SecurityConstraint sc : pad.getSecurityConstraints()) {
-         // test the copy constructor
-         constraints.add(new SecurityConstraintImpl(sc));
-      }
-      assertEquals(1, constraints.size());
-      constraint = constraints.get(0);
-   }
-
-   @Test
-   // tests the UserDataConstraint as well
-   public void testGetUserDataConstraint() {
-      UserDataConstraint udc = constraint.getUserDataConstraint();
-      assertNotNull(udc);
-      
-   }
-
-   @Test
-   public void testGetDisplayName() {
-      Locale loc = new Locale("DE");
-      DisplayName name = constraint.getDisplayName(loc);
-      assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
-   }
-
-   @Test
-   public void testGetDisplayNames() {
-      List<DisplayName> list = constraint.getDisplayNames();
-      assertNotNull(list);
-      assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
-   }
-
-   @Test
-   public void testAddDisplayName() {
-      Locale loc = Locale.FRENCH;
-      String text = "Some display name";
-      DisplayName d = new DisplayNameImpl(loc, text);
-      constraint.addDisplayName(d);
-
-      List<DisplayName> list = constraint.getDisplayNames();
-      assertNotNull(list);
-      assertEquals(2, list.size());
-      for (DisplayName desc : list) {
-         if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
-         } else {
-            assertEquals("display-name", desc.getDisplayName());
-         }
-      }
-   }
-
-   @Test
-   public void testGetPortletNames() {
-      List<String> list = constraint.getPortletNames();
-      assertNotNull(list);
-      assertEquals(1, list.size());
-   }
-
-   @Test
-   public void testAddPortletName() {
-      String text = "SomeName";
-      constraint.addPortletName(text);;
-
-      List<String> list = constraint.getPortletNames();
-      assertNotNull(list);
-      assertEquals(2, list.size());
-      assertTrue(list.contains(text));
-      assertTrue(list.contains("portlet362"));
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserAttribute362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserAttribute362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserAttribute362ImplTest.java
index 33fc80f..2ab66c2 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserAttribute362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserAttribute362ImplTest.java
@@ -58,7 +58,7 @@ public class UserAttribute362ImplTest {
       InputStream in = UserAttribute362ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -94,7 +94,7 @@ public class UserAttribute362ImplTest {
       Locale loc = new Locale("DE");
       Description desc = ua.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
+      assertEquals("description", desc.getText());
    }
 
    /**
@@ -105,7 +105,7 @@ public class UserAttribute362ImplTest {
       List<Description> list = ua.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
+      assertEquals("description", list.get(0).getText());
    }
 
    /**
@@ -123,9 +123,9 @@ public class UserAttribute362ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserDataConstraint362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserDataConstraint362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserDataConstraint362ImplTest.java
deleted file mode 100644
index 8b46d1f..0000000
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/UserDataConstraint362ImplTest.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.apache.pluto.container.om.portlet.impl.jsr362;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.InputStream;
-import java.util.List;
-import java.util.Locale;
-
-import org.apache.pluto.container.om.portlet.Description;
-import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
-import org.apache.pluto.container.om.portlet.SecurityConstraint;
-import org.apache.pluto.container.om.portlet.UserDataConstraint;
-import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
-import org.apache.pluto.container.om.portlet.impl.DescriptionImpl;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class UserDataConstraint362ImplTest {
-
-   private static final String XML_FILE = 
-         "org/apache/pluto/container/om/portlet/portlet362Generated.xml";
-   
-   private static PortletApplicationDefinition pad;
-   private        UserDataConstraint udc;
-
-   /**
-    * @throws java.lang.Exception
-    */
-   @BeforeClass
-   public static void setUpBeforeClass() throws Exception {
-      
-      InputStream in = UserDataConstraint362ImplTest.class
-            .getClassLoader().getResourceAsStream(XML_FILE);
-      
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
-      try {
-         cfp.processPortletDD(in);
-         pad = cfp.getPad();
-      } catch (Exception e) {
-         e.printStackTrace();
-         throw e;
-      }
-   }
-   
-   @Before
-   public void setUpBefore() throws Exception {
-      assertEquals(1, pad.getSecurityConstraints().size());
-      SecurityConstraint sc = pad.getSecurityConstraints().get(0);
-      assertNotNull(sc);
-      assertNotNull(sc.getUserDataConstraint());
-      udc = sc.getUserDataConstraint();
-   }
-
-   @Test
-   public void testGetTransportGuarantee() {
-      assertEquals("NONE", udc.getTransportGuarantee());
-   }
-
-   /**
-    * Test method for {@link org.apache.pluto.container.om.portlet.impl.jsr362.UserDataConstraintImpl#getDescription(java.util.Locale)}.
-    */
-   @Test
-   public void testGetDescription() {
-      Locale loc = new Locale("DE");
-      Description desc = udc.getDescription(loc);
-      assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
-   }
-
-   /**
-    * Test method for {@link org.apache.pluto.container.om.portlet.impl.jsr362.UserDataConstraintImpl#getDescriptions()}.
-    */
-   @Test
-   public void testGetDescriptions() {
-      List<Description> list = udc.getDescriptions();
-      assertNotNull(list);
-      assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
-   }
-
-   /**
-    * Test method for {@link org.apache.pluto.container.om.portlet.impl.jsr362.UserDataConstraintImpl#addDescription(org.apache.pluto.container.om.portlet.Description)}.
-    */
-   @Test
-   public void testAddDescription() {
-      Locale loc = Locale.FRENCH;
-      String text = "Some description";
-      Description d = new DescriptionImpl(loc, text);
-      udc.addDescription(d);
-
-      List<Description> list = udc.getDescriptions();
-      assertNotNull(list);
-      assertEquals(2, list.size());
-      for (Description desc : list) {
-         if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
-         } else {
-            assertEquals("description", desc.getDescription());
-         }
-      }
-   }
-
-}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/AnotherBundle.properties
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/AnotherBundle.properties b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/AnotherBundle.properties
new file mode 100644
index 0000000..3ee6a03
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/AnotherBundle.properties
@@ -0,0 +1,6 @@
+#
+# filename: clock_en.properties
+# Portlet Info resource bundle example
+javax.portlet.title=World Population Clock
+javax.portlet.short-title=WorldPopClock
+javax.portlet.keywords=World,Population,Clock

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
index ba572d2..f20bfc4 100644
--- a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
@@ -6,7 +6,7 @@
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
 
-   <!-- generated test file -->
+   <!-- JSR 362 portlet DD test file -->
 
    <portlet id="id2">
       <description xml:lang="de">multi 
@@ -30,24 +30,27 @@
       <supports id="sup1">
          <mime-type>mime-type</mime-type>
          <portlet-mode>portlet-mode</portlet-mode>
-         <portlet:window-state>window-state</portlet:window-state>
+         <window-state>window-state</window-state>
       </supports>
       <supports id="sup2">
          <mime-type>mime-type2</mime-type>
          <portlet-mode>portlet-mode2</portlet-mode>
-         <portlet:window-state>window-state2</portlet:window-state>
+         <window-state>window-state2</window-state>
       </supports>
       <supports id="sup3">
          <mime-type>mime-type3</mime-type>
          <portlet-mode>portlet-mode3</portlet-mode>
-         <portlet:window-state>window-state3</portlet:window-state>
+         <window-state>window-state3</window-state>
       </supports>
       <supported-locale>supported-locale</supported-locale>
       <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
       <portlet-info id="info1">
          <title>title</title>
+         <title xml:lang="de">Titel</title>
          <short-title>short-title</short-title>
+         <short-title xml:lang="de">Kurztitel</short-title>
          <keywords>keywords</keywords>
+         <keywords xml:lang="de">Schlagwörter</keywords>
       </portlet-info>
       <portlet-preferences id="prefs">
          <preference id="pref1">
@@ -80,6 +83,14 @@
          <name>Runtime-Option2</name>
          <value>value2</value>
       </container-runtime-option>
+      <dependency>
+         <name>JQuery</name>
+         <min-version>2.1.4</min-version>
+      </dependency>
+      <dependency>
+         <name>AngularJS</name>
+         <min-version>1.4.8</min-version>
+      </dependency>
    </portlet>
    <custom-portlet-mode id="mode1">
       <description xml:lang="de">description</description>
@@ -145,6 +156,7 @@
       <name>Name</name>
    </public-render-parameter>
    <listener>
+      <listener-name>test listener</listener-name>
       <description xml:lang="de">description</description>
       <display-name xml:lang="de">display-name</display-name>
       <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener</listener-class>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
new file mode 100644
index 0000000..b078403
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Merge.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app id="id1" version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet id="id2">
+      <description xml:lang="de">multi 
+      line 
+      description</description>
+      <portlet-name>AnnotatedPortlet</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet</portlet-class>
+      <init-param id="init1">
+         <description xml:lang="de">description</description>
+         <name>name</name>
+         <value>value</value>
+      </init-param>
+      <init-param id="init2">
+         <description xml:lang="de">description</description>
+         <name>nullValueParam</name>
+         <value></value>
+      </init-param>
+      <expiration-cache>50</expiration-cache>
+      <cache-scope>private</cache-scope>
+      <supports id="sup1">
+         <mime-type>mime-type</mime-type>
+         <portlet-mode>portlet-mode</portlet-mode>
+         <window-state>window-state</window-state>
+      </supports>
+      <supports id="sup2">
+         <mime-type>mime-type2</mime-type>
+         <portlet-mode>portlet-mode2</portlet-mode>
+         <window-state>window-state2</window-state>
+      </supports>
+      <supports id="sup3">
+         <mime-type>mime-type3</mime-type>
+         <portlet-mode>portlet-mode3</portlet-mode>
+         <window-state>window-state3</window-state>
+      </supports>
+      <supported-locale>supported-locale</supported-locale>
+      <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
+      <portlet-info id="info1">
+         <title xml:lang="de">Titel</title>
+         <short-title xml:lang="de">Kurztitel</short-title>
+         <keywords xml:lang="de">Schlagwörter</keywords>
+      </portlet-info>
+      <portlet-preferences id="prefs">
+         <preference id="pref1">
+            <name>name</name>
+            <value>value</value>
+            <read-only>true</read-only>
+         </preference>
+         <preference id="bPref">
+            <name>bPref</name>
+            <value>some value</value>
+            <read-only>true</read-only>
+         </preference>
+         <preferences-validator>
+            org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator
+         </preferences-validator>
+      </portlet-preferences>
+      <security-role-ref id="sec1">
+         <description xml:lang="de">description</description>
+         <role-name>NMTOKEN</role-name>
+         <role-link>role-link</role-link>
+      </security-role-ref>
+      <supported-processing-event>
+         <name>supported-event</name>
+      </supported-processing-event>
+      <supported-publishing-event>
+         <qname xmlns:x="http://test.com">x:supported-event</qname>
+      </supported-publishing-event>
+      <supported-public-render-parameter>color
+      </supported-public-render-parameter>
+      <container-runtime-option>
+         <name>Runtime-Option1</name>
+         <value>true</value>
+      </container-runtime-option>
+      <container-runtime-option>
+         <name>Runtime-Option2</name>
+         <value>value2</value>
+      </container-runtime-option>
+      <dependency>
+         <name>JQuery</name>
+         <min-version>2.1.4</min-version>
+      </dependency>
+      <dependency>
+         <name>AngularJS</name>
+         <min-version>1.4.8</min-version>
+      </dependency>
+   </portlet>
+   <custom-portlet-mode id="mode1">
+      <description xml:lang="de">description</description>
+      <portlet-mode>portlet-mode</portlet-mode>
+      <portal-managed>false</portal-managed>
+   </custom-portlet-mode>
+    <custom-portlet-mode id="mode1">
+      <description xml:lang="de">description</description>
+      <portlet-mode>aMode</portlet-mode>
+      <portal-managed>false</portal-managed>
+   </custom-portlet-mode>
+   <custom-window-state id="state1">
+      <description xml:lang="de">description</description>
+      <window-state>window-state</window-state>
+   </custom-window-state>
+   <custom-window-state id="state1">
+      <description xml:lang="de">description</description>
+      <window-state>half_page</window-state>
+   </custom-window-state>
+   <user-attribute id="att1">
+      <description xml:lang="de">description</description>
+      <name>user.name.family</name>
+   </user-attribute>
+   <user-attribute id="att1">
+      <description xml:lang="de">description</description>
+      <name>dogs.name</name>
+   </user-attribute>
+   <security-constraint id="cons1">
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-collection>
+         <portlet-name>portlet362</portlet-name>
+      </portlet-collection>
+      <user-data-constraint id="data1">
+         <description xml:lang="de">description</description>
+         <transport-guarantee>NONE</transport-guarantee>
+      </user-data-constraint>
+   </security-constraint>
+   <resource-bundle>org.apache.pluto.container.om.portlet.GoodBundle</resource-bundle>
+   <filter>
+      <description xml:lang="de">description</description>
+      <display-name xml:lang="de">display-name</display-name>
+      <filter-name>filter-name</filter-name>
+      <filter-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter</filter-class>
+      <lifecycle>lifecycle</lifecycle>
+      <init-param id="init2">
+         <description xml:lang="de">description</description>
+         <name>name</name>
+         <value>value</value>
+      </init-param>
+   </filter>
+   <filter-mapping>
+      <filter-name>filter-name</filter-name>
+      <portlet-name>AnnotatedPortlet</portlet-name>
+   </filter-mapping>
+   <portlet:default-namespace>https://www.some.org/</portlet:default-namespace>
+   <event-definition id="event1">
+      <description xml:lang="de">description</description>
+      <name>another-event</name>
+      <value-type>org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType</value-type>
+   </event-definition>
+   <event-definition id="event2">
+      <description xml:lang="de">description</description>
+      <qname xmlns:x="http://test.com">x:supported-event</qname>
+      <value-type>java.lang.String</value-type>
+   </event-definition>
+   <public-render-parameter id="color">
+      <description xml:lang="de">description</description>
+      <identifier>color</identifier>
+      <qname>QName</qname>
+   </public-render-parameter>
+   <public-render-parameter id="link">
+      <description xml:lang="de">description2</description>
+      <identifier>link</identifier>
+      <name>Name</name>
+   </public-render-parameter>
+   <listener>
+      <listener-name>test listener</listener-name>
+      <description xml:lang="de">description</description>
+      <display-name xml:lang="de">display-name</display-name>
+      <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener</listener-class>
+   </listener>
+   <container-runtime-option>
+      <name>Runtime-Option-Portlet-App</name>
+      <value>false</value>
+   </container-runtime-option>
+   <container-runtime-option>
+      <name>javax.portlet.renderHeaders</name>
+      <value>false</value>
+   </container-runtime-option>
+</portlet-app>


[02/35] portals-pluto git commit: Some updates to the the portlet API to correct inconsistencies

Posted by ms...@apache.org.
Some updates to the the portlet API to correct inconsistencies


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

Branch: refs/heads/V3Prototype
Commit: 2d563b6cb1a77bfebfd796441eca5dcb582782d4
Parents: fef12ee
Author: Scott Nicklous <ms...@apache.org>
Authored: Thu Dec 3 16:05:13 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Thu Dec 3 16:05:13 2015 +0100

----------------------------------------------------------------------
 .../portlet/annotations/ContentTypeSupport.java | 87 --------------------
 .../portlet/annotations/InitParameter.java      |  9 ++
 .../annotations/PortletConfiguration.java       | 14 +---
 .../annotations/PortletRequestFilter.java       | 13 +++
 .../portlet/annotations/RuntimeOption.java      |  8 +-
 .../portlet/annotations/SecurityRoleRef.java    | 10 +++
 .../javax/portlet/annotations/Supports.java     | 24 ++++--
 .../PortletTests_PortletConfig_ApiRender.java   | 12 ++-
 8 files changed, 65 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/ContentTypeSupport.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/ContentTypeSupport.java b/portlet-api/src/main/java/javax/portlet/annotations/ContentTypeSupport.java
deleted file mode 100644
index 51f1d93..0000000
--- a/portlet-api/src/main/java/javax/portlet/annotations/ContentTypeSupport.java
+++ /dev/null
@@ -1,87 +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 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!
- */
-
-package javax.portlet.annotations;
-
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-
-/**
- * <div class='changed_added_3_0'>
- * This annotation is used within composite portlet configuration annotations to
- * represent the portlet modes and window states supported for a given content type.
- * <p>
- * It cannot be used as a stand-alone portlet annotation.
- * </div>
- */
-@Retention(RUNTIME) @Target({ANNOTATION_TYPE})
-public @interface ContentTypeSupport {
-   
-   /**
-    * <div class='container-change'>
-    * The MIME type for which support is being defined.
-    * MIME type name, e.g. "text/html".
-    * The MIME type may also contain the wildcard
-    * character '*' as in 'text&#x2F;*' or '*&#x2F;*'.
-    * </div>
-    * 
-    * @return     The MIME type
-    */
-   String   mimeType() default "text/html";
-   
-   /**
-    * <div class='container-change'>
-    * Defines the portlet modes supported by this portlet.
-    * <p>
-    * The following names represent the standard portlet modes: 
-    * "edit", "help", "view".
-    * Custom portlet modes may also be defined.
-    * <p>
-    * Portlet mode names are not case sensitive.
-    * </div>
-    * 
-    * @return     The portlet modes
-    */
-   String[] supportedPortletModes() default {"view"};
-   
-   /**
-    * <div class='container-change'>
-    * Defines the window states supported by this portlet.
-    * <p>
-    * The following names represent the standard window states: 
-    * "normal", "minimized", "maximized".
-    * Custom window states may also be defined.
-    * <p>
-    * Window state names are not case sensitive.
-    * </div>
-    * 
-    * @return     The window states
-    */
-   String[] supportedWindowStates() default {"normal", "minimized", "maximized"};
-}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java b/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
index d726577..40880d4 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
@@ -55,4 +55,13 @@ public @interface InitParameter {
     * @return     The parameter value
     */
    String   value();
+   
+   /**
+    * <div class='container-change'>
+    * Provides locale-specific text describing the initialization parameter for use by the portal application or by tools.
+    * </div>
+    * 
+    * @return  The event description
+    */
+   LocaleString[]      description() default {};
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
index 58bc397..7508094 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletConfiguration.java
@@ -151,16 +151,6 @@ public @interface PortletConfiguration {
     * @return     The array of public render parameters.
     */
    String[]  publicParams() default {};
-
-   /**
-    * <div class='container-change'>
-    * Defines the content types supported by the portlet along with
-    * the associated portlet modes and window states.
-    * </div>
-    * 
-    * @return     An array of content type support items
-    */
-   ContentTypeSupport[] contentTypes() default {@ContentTypeSupport};
    
    /**
     * <div class='container-change'>
@@ -178,12 +168,12 @@ public @interface PortletConfiguration {
    
    /**
     * <div class='container-change'>
-    * The supported portlet modes and window states.
+    * The supported portlet modes and window states for a given <code>MIME</code> type.
     * </div>
     * 
     * @return     The supported portlet modes and window states
     */
-   Supports[] supports() default {};
+   Supports[] supports() default {@Supports(mimeType="text/html")};
    
    /**
     * <div class='not-supported'>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
index 258aaed..908d0de 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
@@ -69,6 +69,19 @@ import static java.lang.annotation.RetentionPolicy.*;
 public @interface PortletRequestFilter {
    
    /**
+    * The filter name. 
+    * <p>
+    * The filter name is not required. If a filter name is provided, the filter configuration
+    * may be addressed through the filter name in the portlet deployment descriptor to modify 
+    * the filter or filter mapping.
+    * <p>
+    *  
+    * 
+    * @return  The filter name
+    */
+   String   filterName() default "";
+   
+   /**
     * <div class='not-supported'>
     * The portlet names for which the request filter applies.
     * <p>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/RuntimeOption.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/RuntimeOption.java b/portlet-api/src/main/java/javax/portlet/annotations/RuntimeOption.java
index 98a8da0..766eba5 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/RuntimeOption.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/RuntimeOption.java
@@ -35,7 +35,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 /**
  * <div class='changed_added_3_0'>
  * This annotation is used within composite portlet configuration annotations to
- * represent portlet container runtime option name-value pairs.
+ * represent portlet container runtime option name-value pairs.  
  * It cannot be used as a stand-alone portlet annotation.
  * </div>
  */
@@ -50,9 +50,9 @@ public @interface RuntimeOption {
    String   name();
    
    /**
-    * The container runtime options value
+    * The container runtime options values.
     * 
-    * @return     The parameter value
+    * @return     The parameter values
     */
-   String   value();
+   String[]   values();
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java b/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
index a371110..30e6833 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
@@ -58,4 +58,14 @@ public @interface SecurityRoleRef {
     * @return  The role link
     */
    String      roleLink() default "";
+   
+   /**
+    * <div class='container-change'>
+    * The security role ref description.
+    * It provides locale-specific text describing the security role ref for use by the portal application or by tools.
+    * </div>
+    * 
+    * @return  The portlet description
+    */
+   LocaleString[]   description() default {};
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-api/src/main/java/javax/portlet/annotations/Supports.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/Supports.java b/portlet-api/src/main/java/javax/portlet/annotations/Supports.java
index c9c0e37..75c3a04 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/Supports.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/Supports.java
@@ -34,7 +34,7 @@ import static java.lang.annotation.RetentionPolicy.*;
 /**
  * <div class='changed_added_3_0'>
  * This annotation is used within composite portlet configuration annotations to
- * specify the supported portlet modes and window states for a given locale.
+ * specify the supported portlet modes and window states for a given content type.
  * It cannot be used as a stand-alone portlet annotation.
  * </div>
  */
@@ -50,25 +50,37 @@ public @interface Supports {
     * for example <code>"text{@literal /}*"</code> or <code>"*{@literal /}*"</code>.
     * </div>
     * 
-    * @return  The mime type
+    * @return     The MIME type
     */
    String   mimeType() default "text/html";
    
    /**
     * <div class='container-change'>
-    * The names of the supported portlet modes.
+    * Defines the portlet modes supported by this portlet.
+    * <p>
+    * The following names represent the standard portlet modes: 
+    * "edit", "help", "view".
+    * Custom portlet modes may also be defined.
+    * <p>
+    * Portlet mode names are not case sensitive.
     * </div>
     * 
     * @return  The supported portlet modes
     */
-   String[]      portletModes() default "";
+   String[] portletModes() default {"view"};
    
    /**
     * <div class='container-change'>
-    * The names of the supported window states.
+    * Defines the window states supported by this portlet.
+    * <p>
+    * The following names represent the standard window states: 
+    * "normal", "minimized", "maximized".
+    * Custom window states may also be defined.
+    * <p>
+    * Window state names are not case sensitive.
     * </div>
     * 
     * @return  The supported window states
     */
-   String[]      windowStates() default "";
+   String[] windowStates() default {"normal", "minimized", "maximized"};
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2d563b6c/portlet-tck_3.0/V2PortletTests/src/main/java/javax/portlet/tck/portlets/PortletTests_PortletConfig_ApiRender.java
----------------------------------------------------------------------
diff --git a/portlet-tck_3.0/V2PortletTests/src/main/java/javax/portlet/tck/portlets/PortletTests_PortletConfig_ApiRender.java b/portlet-tck_3.0/V2PortletTests/src/main/java/javax/portlet/tck/portlets/PortletTests_PortletConfig_ApiRender.java
index 3543eb9..3373772 100644
--- a/portlet-tck_3.0/V2PortletTests/src/main/java/javax/portlet/tck/portlets/PortletTests_PortletConfig_ApiRender.java
+++ b/portlet-tck_3.0/V2PortletTests/src/main/java/javax/portlet/tck/portlets/PortletTests_PortletConfig_ApiRender.java
@@ -105,9 +105,15 @@ public class PortletTests_PortletConfig_ApiRender implements Portlet, ResourceSe
       /* TestCase: V2PortletTests_PortletConfig_ApiRender_getPortletName      */
       /* Details: "Method getPortletName(): Returns a String containing the   */
       /* portlet name"                                                        */
-      TestResult tr0 = tcd.getTestResultFailed(V2PORTLETTESTS_PORTLETCONFIG_APIRENDER_GETPORTLETNAME);
-      /* TODO: implement test */
-      tr0.appendTcDetail("Not implemented.");
+      TestResult tr0 = tcd.getTestResultSucceeded(V2PORTLETTESTS_PORTLETCONFIG_APIRENDER_GETPORTLETNAME);
+      String portletName = portletConfig.getPortletName();
+      if (!portletName.equals(this.getClass().getSimpleName())) {
+         tr0.setTcSuccess(false);
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Portlet name did not match class name. Portlet name: ").append(portletName);
+         txt.append(", Class name: ").append(this.getClass().getSimpleName());
+         tr0.appendTcDetail(txt.toString());
+      }
       tr0.writeTo(writer);
 
       /* TestCase: V2PortletTests_PortletConfig_ApiRender_getPortletContext   */


[03/35] portals-pluto git commit: some consistency updates to the schema

Posted by ms...@apache.org.
some consistency updates to the schema


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

Branch: refs/heads/V3Prototype
Commit: ef7da9451e27c15eaff4aefb6c203d25524167bf
Parents: 2d563b6
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Dec 4 17:24:17 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Dec 4 17:24:17 2015 +0100

----------------------------------------------------------------------
 .../pluto/container/impl/portlet-app_3_0.xsd    | 143 +++++++++----------
 1 file changed, 65 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ef7da945/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
index a2f1f16..9aebdea 100644
--- a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
+++ b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
@@ -136,7 +136,6 @@
 			<element name="custom-portlet-mode" type="portlet:custom-portlet-modeType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="custom-window-state" type="portlet:custom-window-stateType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="user-attribute" type="portlet:user-attributeType" minOccurs="0" maxOccurs="unbounded"/>
-			<element name="security-constraint" type="portlet:security-constraintType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="resource-bundle" type="portlet:resource-bundleType" minOccurs="0"/>
 			<element name="filter" type="portlet:filterType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="filter-mapping" type="portlet:filter-mappingType" minOccurs="0" maxOccurs="unbounded"/>
@@ -144,6 +143,7 @@
 			<element name="event-definition" type="portlet:event-definitionType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="public-render-parameter" type="portlet:public-render-parameterType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="listener" type="portlet:listenerType" minOccurs="0" maxOccurs="unbounded"/>
+			<element name="conditional-dispatcher" type="portlet:conditionalDispatcherType" minOccurs="0" maxOccurs="1"/>
 			<element name="container-runtime-option" type="portlet:container-runtime-optionType" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
 		<attribute name="version" type="portlet:string" use="required"/>
@@ -230,7 +230,9 @@
 			</documentation>
 		</annotation>
 		<simpleContent>
-			<extension base="portlet:string"/>
+			<extension base="portlet:string">
+            <attribute ref="xml:lang"/>
+         </extension>
 		</simpleContent>
 	</complexType>
 	<complexType name="mime-typeType">
@@ -257,6 +259,28 @@
 			<extension base="portlet:string"/>
 		</simpleContent>
 	</complexType>
+   <complexType name="resourceNameType">
+      <annotation>
+         <documentation>
+         The resource name element. 
+         Used in the dependency element.
+         </documentation>
+      </annotation>
+      <simpleContent>
+         <extension base="portlet:string"/>
+      </simpleContent>
+   </complexType>
+   <complexType name="resourceVersionType">
+      <annotation>
+         <documentation>
+         The resource version element. 
+         Used in the dependency element.
+         </documentation>
+      </annotation>
+      <simpleContent>
+         <extension base="portlet:string"/>
+      </simpleContent>
+   </complexType>
 	<complexType name="portletType">
 		<annotation>
 			<documentation>
@@ -282,6 +306,8 @@
 			<element name="supported-publishing-event" type="portlet:event-definition-referenceType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="supported-public-render-parameter" type="portlet:string" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="container-runtime-option" type="portlet:container-runtime-optionType" minOccurs="0" maxOccurs="unbounded"/>
+			<element name="dependency" type="portlet:dependencyType" minOccurs="0" maxOccurs="unbounded"/>
+         <element name="conditional-dispatcher" type="portlet:conditionalDispatcherType" minOccurs="0" maxOccurs="1"/>
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
@@ -359,19 +385,6 @@
 			<element name="init-param" type="portlet:init-paramType" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
 	</complexType>
-	<complexType name="portlet-collectionType">
-		<annotation>
-			<documentation>
-			The portlet-collectionType is used to identify a subset
-			of portlets within a portlet application to which a 
-			security constraint applies.
-			Used in: security-constraint
-			</documentation>
-		</annotation>
-		<sequence>
-			<element name="portlet-name" type="portlet:portlet-nameType" maxOccurs="unbounded"/>
-		</sequence>
-	</complexType>
 	<complexType name="event-definitionType">
 		<annotation>
 			<documentation>
@@ -384,6 +397,7 @@
 		</annotation>
 		<sequence>
 			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
+         <element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
 			<choice>
 				<element name="qname" type="xs:QName"/>
 				<element name="name" type="xs:NCName"/>
@@ -407,6 +421,20 @@
 		</choice>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
+   <complexType name="conditionalDispatcherType">
+      <annotation>
+         <documentation>
+         The conditionalDispatcherType is used to declare conditional dispatchers for this portlet or portlet application.
+         Used in: portlet, portlet-app
+         </documentation>
+      </annotation>
+      <sequence>
+         <element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
+         <element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
+         <element name="dispatcher-class" type="portlet:fully-qualified-classType"/>
+      </sequence>
+      <attribute name="id" type="portlet:string" use="optional"/>
+   </complexType>
 	<complexType name="listenerType">
 		<annotation>
 			<documentation>
@@ -415,6 +443,7 @@
 			</documentation>
 		</annotation>
 		<sequence>
+         <element name="listener-name" type="portlet:string" minOccurs="0" maxOccurs="1"/>
 			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="listener-class" type="portlet:fully-qualified-classType"/>
@@ -423,9 +452,9 @@
 	</complexType>
 	<complexType name="portlet-infoType">
 		<sequence>
-			<element name="title" type="portlet:titleType" minOccurs="0"/>
-			<element name="short-title" type="portlet:short-titleType" minOccurs="0"/>
-			<element name="keywords" type="portlet:keywordsType" minOccurs="0"/>
+			<element name="title" type="portlet:titleType" minOccurs="0" maxOccurs="unbounded"/>
+			<element name="short-title" type="portlet:short-titleType" minOccurs="0" maxOccurs="unbounded"/>
+			<element name="keywords" type="portlet:keywordsType" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
@@ -556,21 +585,6 @@
 			<extension base="portlet:string"/>
 		</simpleContent>
 	</complexType>
-	<complexType name="security-constraintType">
-		<annotation>
-			<documentation>
-			The security-constraintType is used to associate
-			intended security constraints with one or more portlets.
-			Used in: portlet-app
-			</documentation>
-		</annotation>
-		<sequence>
-			<element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
-			<element name="portlet-collection" type="portlet:portlet-collectionType"/>
-			<element name="user-data-constraint" type="portlet:user-data-constraintType"/>
-		</sequence>
-		<attribute name="id" type="portlet:string" use="optional"/>
-	</complexType>
 	<complexType name="security-role-refType">
 		<annotation>
 			<documentation>
@@ -605,12 +619,12 @@
 		</annotation>
 		<sequence>
 			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
+         <element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="identifier" type="portlet:string"/>
 			<choice>
 				<element name="qname" type="xs:QName"/>
 				<element name="name" type="xs:NCName"/>
 			</choice>
-			<element name="alias" type="xs:QName" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
@@ -622,7 +636,9 @@
 			</documentation>
 		</annotation>
 		<simpleContent>
-			<extension base="portlet:string"/>
+			<extension base="portlet:string">
+            <attribute ref="xml:lang"/>
+         </extension>
 		</simpleContent>
 	</complexType>
 	<complexType name="supportsType">
@@ -641,6 +657,17 @@
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
+   <complexType name="dependencyType">
+      <annotation>
+         <documentation>
+         Dependency specifies a resource on which the portlet depends.
+         </documentation>
+      </annotation>
+      <sequence>
+         <element name="name" type="portlet:resourceNameType"/>
+         <element name="min-version" type="portlet:resourceVersionType"/>
+      </sequence>
+   </complexType>
 	<complexType name="supported-localeType">
 		<annotation>
 			<documentation>
@@ -660,36 +687,11 @@
 			</documentation>
 		</annotation>
 		<simpleContent>
-			<extension base="portlet:string"/>
+			<extension base="portlet:string">
+            <attribute ref="xml:lang"/>
+         </extension>
 		</simpleContent>
 	</complexType>
-	<simpleType name="transport-guaranteeType">
-		<annotation>
-			<documentation>
-			The transport-guaranteeType specifies that 
-			the communication between client and portlet should 
-			be NONE, INTEGRAL, or CONFIDENTIAL. 
-			NONE means that the portlet does not
-			require any transport guarantees. A value of 
-			INTEGRAL means that the portlet requires that the 
-			data sent between the client and portlet be sent in 
-			such a way that it can't be changed in transit. 
-			CONFIDENTIAL means that the portlet requires 
-			that the data be transmitted in a fashion that
-			prevents other entities from observing the contents 
-			of the transmission. 
-			In most cases, the presence of the INTEGRAL or
-			CONFIDENTIAL flag will indicate that the use 
-			of SSL is required.
- 			Used in: user-data-constraint
-			</documentation>
-		</annotation>
-		<restriction base="portlet:string">
-			<enumeration value="NONE"/>
-			<enumeration value="INTEGRAL"/>
-			<enumeration value="CONFIDENTIAL"/>
-		</restriction>
-	</simpleType>
 	<complexType name="user-attributeType">
 		<annotation>
 			<documentation>
@@ -706,21 +708,6 @@
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>
-	<complexType name="user-data-constraintType">
-		<annotation>
-			<documentation>
-			The user-data-constraintType is used to indicate how
-			data communicated between the client and portlet should be
-			protected.
-			Used in: security-constraint
-			</documentation>
-		</annotation>
-		<sequence>
-			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
-			<element name="transport-guarantee" type="portlet:transport-guaranteeType"/>
-		</sequence>
-		<attribute name="id" type="portlet:string" use="optional"/>
-	</complexType>
 	<complexType name="valueType">
 		<annotation>
 			<documentation>


[13/35] portals-pluto git commit: Renamed PreferencesValidator annotation to PortletPreferencesValidator in order to avoid name clash with PreferencesValidator interface.

Posted by ms...@apache.org.
Renamed PreferencesValidator annotation to PortletPreferencesValidator in
order to avoid name clash with PreferencesValidator interface.


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

Branch: refs/heads/V3Prototype
Commit: d542738fb3595df8dab50adda86539aec8e314f3
Parents: 58a39c3
Author: Scott Nicklous <ms...@apache.org>
Authored: Tue Dec 22 12:50:57 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Tue Dec 22 12:50:57 2015 +0100

----------------------------------------------------------------------
 .../PortletPreferencesValidator.java            | 66 ++++++++++++++++++++
 .../annotations/PreferencesValidator.java       | 66 --------------------
 .../javax/portlet/annotations/package-info.java |  2 +-
 3 files changed, 67 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/d542738f/portlet-api/src/main/java/javax/portlet/annotations/PortletPreferencesValidator.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletPreferencesValidator.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletPreferencesValidator.java
new file mode 100644
index 0000000..372dd2f
--- /dev/null
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletPreferencesValidator.java
@@ -0,0 +1,66 @@
+/*  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!
+ */
+package javax.portlet.annotations;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * <div class='changed_added_3_0'>
+ * Designates a preferences validator class.
+ * The PortletPreferencesValidator allows validation of the set of portlet preferences 
+ * before they are stored in the persistent store.
+ * The validator method is invoked during execution of the 
+ * store method of the PortletPreferences. 
+ * <p>
+ * The annotated class must implement the <code>PortletPreferencesValidator</code> interface.
+ * </div>
+ *    
+ * @see javax.portlet.PreferencesValidator
+ *
+ */
+
+@Retention(RUNTIME) @Target({TYPE})
+public @interface PortletPreferencesValidator {
+   
+   /**
+    * The portlet names for which the validator applies.
+    * <p>
+    * The annotated validator method can apply to multiple portlets within the portlet
+    * application. The names of the portlets to which the validator applies must be 
+    * specified in this field.
+    * <p>
+    * A wildcard character '*' can be specified in the first portletName array element 
+    * to indicate that the validator is to apply to all portlets in the portlet application.
+    * If specified, the wildcard character must appear alone in the first array element.
+    * 
+    * @return     The portlet names
+    */
+   String[]   portletNames() default "*";
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/d542738f/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java b/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
deleted file mode 100644
index fafc46e..0000000
--- a/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
+++ /dev/null
@@ -1,66 +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 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!
- */
-package javax.portlet.annotations;
-
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-
-/**
- * <div class='changed_added_3_0'>
- * Designates a preferences validator class.
- * The PreferencesValidator allows validation of the set of portlet preferences 
- * before they are stored in the persistent store.
- * The validator method is invoked during execution of the 
- * store method of the PortletPreferences. 
- * <p>
- * The annotated class must implement the <code>PreferencesValidator</code> interface.
- * </div>
- *    
- * @see javax.portlet.PreferencesValidator
- *
- */
-
-@Retention(RUNTIME) @Target({TYPE})
-public @interface PreferencesValidator {
-   
-   /**
-    * The portlet names for which the validator applies.
-    * <p>
-    * The annotated validator method can apply to multiple portlets within the portlet
-    * application. The names of the portlets to which the validator applies must be 
-    * specified in this field.
-    * <p>
-    * A wildcard character '*' can be specified in the first portletName array element 
-    * to indicate that the validator is to apply to all portlets in the portlet application.
-    * If specified, the wildcard character must appear alone in the first array element.
-    * 
-    * @return     The portlet names
-    */
-   String[]   portletNames() default "*";
-}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/d542738f/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/package-info.java b/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
index 9e17489..aa02ac5 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
@@ -81,7 +81,7 @@
  * Please see the following annotation descriptions:
  * {@link javax.portlet.annotations.PortletRequestFilter},
  * {@link javax.portlet.annotations.PortletListener}, and
- * {@link javax.portlet.annotations.PreferencesValidator}.
+ * {@link javax.portlet.annotations.PortletPreferencesValidator}.
  * </ul>
  * <h4>Injectable Portlet Artifacts</h4>
  * <p>


[12/35] portals-pluto git commit: Preliminary updates to make the portlet url generation listener and preferences validator annotations type annotations rather than method annotations.

Posted by ms...@apache.org.
Preliminary updates to make the portlet url generation listener and preferences validator annotations type annotations rather than method annotations.


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

Branch: refs/heads/V3Prototype
Commit: 58a39c39190555d1c75fef6e639693655aac8f65
Parents: 0ceee24
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Dec 9 19:01:08 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Dec 9 19:01:08 2015 +0100

----------------------------------------------------------------------
 .../driver/PortletContainerInitializer.java     |   1 -
 .../pluto/container/impl/portlet-app_3_0.xsd    |  19 ++-
 .../portlet/annotations/InitParameter.java      |   2 +-
 .../portlet/annotations/PortletListener.java    |  93 +++++++++++++
 .../annotations/PortletRequestFilter.java       |   2 +-
 .../PortletURLGenerationListener.java           | 129 -------------------
 .../annotations/PreferencesValidator.java       |  27 +---
 .../portlet/annotations/SecurityRoleRef.java    |   2 +-
 .../javax/portlet/annotations/package-info.java |   2 +-
 9 files changed, 118 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index 9fb036b..f53c045 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -25,7 +25,6 @@ import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.portlet.annotations.PortletConfigurations;
 import javax.portlet.annotations.PortletRequestFilter;
-import javax.portlet.filter.PortletFilter;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
index 9aebdea..4cd1a8a 100644
--- a/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
+++ b/pluto-container/src/main/resources/org/apache/pluto/container/impl/portlet-app_3_0.xsd
@@ -372,15 +372,22 @@
 				A filter can be restricted to one or more lifecycle phases
 				of the portlet. Valid entries for lifecycle are:
 				ACTION_PHASE, EVENT_PHASE, RENDER_PHASE,
-				RESOURCE_PHASE
+				RESOURCE_PHASE.
+            The filter-name element allows an annotated filter to be addressed
+            and replaced through a corresponding portlet deployment descriptor 
+            filter and / or filter mapping configuration.
+            If the filter class is null, the annotated filter with matching filter name will
+            be removed from the configuration. The ordinal element determines the order of execution
+            should there be multiple filters configured. The default ordinal number is 0.
 				Used in: portlet-app
 				</documentation>
 		</annotation>
 		<sequence>
 			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
-			<element name="filter-name" type="portlet:filter-nameType"/>
+			<element name="filter-name" type="portlet:filter-nameType" minOccurs="0" maxOccurs="1"/>
 			<element name="filter-class" type="portlet:fully-qualified-classType"/>
+         <element name="ordinal" type="xs:int" minOccurs="0" maxOccurs="1"/>
 			<element name="lifecycle" type="portlet:string" maxOccurs="unbounded"/>
 			<element name="init-param" type="portlet:init-paramType" minOccurs="0" maxOccurs="unbounded"/>
 		</sequence>
@@ -439,14 +446,20 @@
 		<annotation>
 			<documentation>
 			The listenerType is used to declare listeners for this portlet application.
+         The optional listener-name element allows an annotated listener to be addressed
+         and replaced through a corresponding portlet deployment descriptor configuration.
+         If a listener name is provided and the listener class is null, the annotated listener will
+         be removed from the configuration. The ordinal element determines the order of execution
+         should there be multiple listeners configured. The default ordinal number is 0.
 			Used in: portlet-app
 			</documentation>
 		</annotation>
 		<sequence>
          <element name="listener-name" type="portlet:string" minOccurs="0" maxOccurs="1"/>
+         <element name="ordinal" type="xs:int" minOccurs="0" maxOccurs="1"/>
 			<element name="description" type="portlet:descriptionType" minOccurs="0" maxOccurs="unbounded"/>
 			<element name="display-name" type="portlet:display-nameType" minOccurs="0" maxOccurs="unbounded"/>
-			<element name="listener-class" type="portlet:fully-qualified-classType"/>
+			<element name="listener-class" type="portlet:fully-qualified-classType" minOccurs="0" maxOccurs="1"/>
 		</sequence>
 		<attribute name="id" type="portlet:string" use="optional"/>
 	</complexType>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java b/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
index 40880d4..721a91e 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/InitParameter.java
@@ -61,7 +61,7 @@ public @interface InitParameter {
     * Provides locale-specific text describing the initialization parameter for use by the portal application or by tools.
     * </div>
     * 
-    * @return  The event description
+    * @return  The parameter description
     */
    LocaleString[]      description() default {};
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/PortletListener.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletListener.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletListener.java
new file mode 100644
index 0000000..77ead30
--- /dev/null
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletListener.java
@@ -0,0 +1,93 @@
+/*  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!
+ */
+package javax.portlet.annotations;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.*;
+import static java.lang.annotation.RetentionPolicy.*;
+
+
+/**
+ * <div class='changed_added_3_0'>
+ * Designates a portlet URL generation listener class.
+ * The listener method will be invoked before a URL of the corresponding type is
+ * generated.
+ * <p>
+ * The annotated method must implement the <code>PortletListener</code> interface.
+ * </div>
+ *    
+ * @see javax.portlet.PortletURLGenerationListener
+ *
+ */
+
+@Retention(RUNTIME) @Target({TYPE})
+public @interface PortletListener {
+   
+   /**
+    * The listener name. 
+    * <p>
+    * The listener name is not required. If a listener name is provided, the listener configuration
+    * may be addressed through the listener name in the portlet deployment descriptor to modify 
+    * or remove the listener.
+    * <p>
+    *  
+    * 
+    * @return  The listener name
+    */
+   String   listenerName() default "";
+   
+   /**
+    * The ordinal number for this annotated method.
+    * <p>
+    * The ordinal number determines the order of execution if multiple methods
+    * are annotated for a given URL type.
+    * Annotated methods with a lower ordinal number are executed before methods with
+    * a higher ordinal number.
+    * 
+    * @return     The ordinal number
+    */
+   int         ordinal() default 0;
+   
+   /**
+    * <div class='not-supported'>
+    * The display-name type contains a language-specific short name that is intended to be displayed by tools. 
+    * </div>
+    * 
+    * @return  The display name
+    */
+   LocaleString[]   displayName() default {};
+   
+   /**
+    * <div class='not-supported'>
+    * The portlet listener description
+    * providing locale-specific text describing the portlet listener for use by the portal application or by tools.
+    * </div>
+    * 
+    * @return  The portlet description
+    */
+   LocaleString[]   description() default {};
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
index 908d0de..d48127e 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestFilter.java
@@ -96,7 +96,7 @@ public @interface PortletRequestFilter {
     * 
     * @return     The portlet names
     */
-   String[]   portletNames();
+   String[]   portletNames() default "*";
    
    /**
     * <div class='not-supported'>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/PortletURLGenerationListener.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletURLGenerationListener.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletURLGenerationListener.java
deleted file mode 100644
index 1ad3af0..0000000
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletURLGenerationListener.java
+++ /dev/null
@@ -1,129 +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 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!
- */
-package javax.portlet.annotations;
-
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-
-/**
- * <div class='changed_added_3_0'>
- * Designates a portlet URL generation listener method.
- * The listener method will be invoked before a URL of the corresponding type is
- * generated.
- * <p>
- * The annotated method must have one of the following signatures:
- * <p>
- *    <code>public void &lt;methodName&gt;(ActionURL actionURL)</code>
- * <p>   
- * <p>
- *    <code>public void &lt;methodName&gt;(RenderURL renderURL)</code>
- * <p>   
- * <p>
- *    <code>public void &lt;methodName&gt;(ResourceURL resourceURL)</code>
- * <p>   
- * where the method name can be freely selected.
- * </div>
- *    
- * @see javax.portlet.PortletURLGenerationListener
- *
- */
-
-@Retention(RUNTIME) @Target({METHOD})
-public @interface PortletURLGenerationListener {
-   
-   /**
-    * <div class='changed_added_3_0'>
-    * Needed for V2.0 portlets to discern between a Render URL and an Action URL
-    * since both are represented by the interface PortletURL.
-    * 
-    * Not needed for v3.0 portlets.
-    * </div>
-    */
-   public enum URLType {RENDER, ACTION, RESOURCE}
-   
-   /**
-    * The portlet names for which the listener applies.
-    * <p>
-    * The annotated listener method can apply to multiple portlets within the portlet
-    * application. The names of the portlets to which the listener applies must be 
-    * specified in this field.
-    * <p>
-    * A wildcard character '*' can be specified in the first portletName array element 
-    * to indicate that the listener is to apply to all portlets in the portlet application.
-    * If specified, the wildcard character must appear alone in the first array element.
-    * 
-    * @return     The portlet names
-    */
-   String[]    portletNames();
-   
-   /**
-    * The ordinal number for this annotated method.
-    * <p>
-    * The ordinal number determines the order of execution if multiple methods
-    * are annotated for a given URL type.
-    * Annotated methods with a lower ordinal number are executed before methods with
-    * a higher ordinal number.
-    * 
-    * @return     The ordinal number
-    */
-   int         ordinal() default 0;
-   
-   /**
-    * <div class='not-supported'>
-    * The display-name type contains a language-specific short name that is intended to be displayed by tools. 
-    * </div>
-    * 
-    * @return  The display name
-    */
-   LocaleString[]   displayName() default {};
-   
-   /**
-    * <div class='not-supported'>
-    * The portlet filter description
-    * providing locale-specific text describing the portlet filter for use by the portal application or by tools.
-    * </div>
-    * 
-    * @return  The portlet description
-    */
-   LocaleString[]   description() default {};
-   
-   /**
-    * The URL Type. 
-    * This field is needed for v2.0 portlets to discern between render URLs and 
-    * action URLs, since both are represented by the interface PortletURL.
-    * 
-    * Needs not be specified for ResourceURLs, as they are identified by the
-    * ResourceURL interface.
-    * 
-    * Not needed for v3.0 portlets
-    * 
-    * @return  The URL type
-    */
-   URLType     type() default URLType.RENDER;
-}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java b/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
index 2fe4751..fafc46e 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PreferencesValidator.java
@@ -33,25 +33,20 @@ import static java.lang.annotation.RetentionPolicy.*;
 
 /**
  * <div class='changed_added_3_0'>
- * Designates a preferences validator method.
+ * Designates a preferences validator class.
  * The PreferencesValidator allows validation of the set of portlet preferences 
  * before they are stored in the persistent store.
  * The validator method is invoked during execution of the 
  * store method of the PortletPreferences. 
  * <p>
- * The annotated method must have the following signature:
- * <p>
- *    <code>public void &lt;methodName&gt;(PortletPreferences preferences) throws ValidatorException</code>
- * <p>   
- * where the method name can be freely selected.
- * <p>
+ * The annotated class must implement the <code>PreferencesValidator</code> interface.
  * </div>
  *    
- * @see javax.portlet.PreferencesValidator#validate(javax.portlet.PortletPreferences) PreferencesValidator#validate
+ * @see javax.portlet.PreferencesValidator
  *
  */
 
-@Retention(RUNTIME) @Target({METHOD})
+@Retention(RUNTIME) @Target({TYPE})
 public @interface PreferencesValidator {
    
    /**
@@ -67,17 +62,5 @@ public @interface PreferencesValidator {
     * 
     * @return     The portlet names
     */
-   String[]   portletNames();
-   
-   /**
-    * The ordinal number for this annotated method.
-    * <p>
-    * The ordinal number determines the order of execution if multiple methods
-    * are annotated.
-    * Annotated methods with a lower ordinal number are executed before methods with
-    * a higher ordinal number.
-    * 
-    * @return     The ordinal number
-    */
-   int        ordinal() default 0;
+   String[]   portletNames() default "*";
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java b/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
index 30e6833..e143057 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/SecurityRoleRef.java
@@ -65,7 +65,7 @@ public @interface SecurityRoleRef {
     * It provides locale-specific text describing the security role ref for use by the portal application or by tools.
     * </div>
     * 
-    * @return  The portlet description
+    * @return  The security role reference description
     */
    LocaleString[]   description() default {};
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/58a39c39/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/package-info.java b/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
index aa7cb4c..9e17489 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/package-info.java
@@ -80,7 +80,7 @@
  * <p>
  * Please see the following annotation descriptions:
  * {@link javax.portlet.annotations.PortletRequestFilter},
- * {@link javax.portlet.annotations.PortletURLGenerationListener}, and
+ * {@link javax.portlet.annotations.PortletListener}, and
  * {@link javax.portlet.annotations.PreferencesValidator}.
  * </ul>
  * <h4>Injectable Portlet Artifacts</h4>


[32/35] portals-pluto git commit: Bug fix in annotated method store

Posted by ms...@apache.org.
Bug fix in annotated method store


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

Branch: refs/heads/V3Prototype
Commit: abee3790538a428718330419572c21e4b9502f6a
Parents: 92f8e87
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Jan 15 13:08:18 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Jan 15 13:08:18 2016 +0100

----------------------------------------------------------------------
 .../bean/processor/AnnotatedMethodStore.java         | 15 +++++++++------
 .../om/portlet/impl/ConfigurationProcessor.java      |  2 +-
 2 files changed, 10 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/abee3790/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
index 652ef86..50287d2 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
@@ -538,14 +538,17 @@ public class AnnotatedMethodStore {
    }
    
    /**
-    * Sets the bean instance for all annotated methods that are members of a configured portlet
-    * class to ensure that all annotated methods of the portlet class use the same bean instance.
+    * Sets the bean instance for all annotated methods for a given portlet that are members of 
+    * a configured portlet class to ensure that all annotated methods of the portlet class use 
+    * the same bean instance.
     * 
-    * @param cls
-    * @param beanInstance
+    * @param portletName      The portlet name
+    * @param cls              The class
+    * @param beanInstance     The instance to use
     */
-   public void setPortletClassInstance(Class<?> cls, Object beanInstance) {
-      for (List<AnnotatedMethod> list : methods.values()) {
+   public void setPortletClassInstance(String portletName, Class<?> cls, Object beanInstance) {
+      for (MethodIdentifier mi : getMethodIDsForPortlet(portletName)) {
+         List<AnnotatedMethod> list =  methods.get(mi);
          for (AnnotatedMethod am : list) {
             if (am.getJavaMethod().getDeclaringClass().equals(cls)) {
                am.setPortletClassInstance(beanInstance);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/abee3790/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 7f368e4..5c42c06 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -508,7 +508,7 @@ public abstract class ConfigurationProcessor {
             // publishing event references. Such annotated methods must use the same bean
             // instance, so fix up the method store.
             
-            ams.setPortletClassInstance(cls, instance);
+            ams.setPortletClassInstance(pd.getPortletName(), cls, instance);
 
             // extract the methods from the portlet class and add them to the method store
             // as long there is no corresponding annotated method already present.


[34/35] portals-pluto git commit: Added bean portlet demo. Fixed null pointer exception in PortletParametersImpl. Fixed problem where two portlets using the same class were also using the same class instance.

Posted by ms...@apache.org.
Added bean portlet demo. Fixed null pointer exception in
PortletParametersImpl. Fixed problem where two portlets using the same
class were also using the same class instance.


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

Branch: refs/heads/V3Prototype
Commit: a0c6f1c90c34feb8a6fbe7858739c03986ec4b54
Parents: 43d2208
Author: Scott Nicklous <ms...@apache.org>
Authored: Sun Jan 17 19:52:40 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sun Jan 17 19:52:40 2016 +0100

----------------------------------------------------------------------
 .../java/basic/portlet/ColorSelPortlet.java     |   4 +-
 .../samples/CSSIncludingHeaderMethod.java       |  51 +++++++
 .../apache/portals/samples/HelloWorldImage.java | 119 ++++++++++++++++
 .../portals/samples/HelloWorldRender.java       |  60 ++++++++
 .../java/org/apache/portals/samples/Log.java    |  37 +++++
 .../portals/samples/LoggingInterceptor.java     |  70 ++++++++++
 .../org/apache/portals/samples/NameBean.java    | 138 +++++++++++++++++++
 .../src/main/webapp/WEB-INF/jsp/res-simple.jsp  |   9 ++
 .../src/main/webapp/resources/css/bluebold.css  |   4 +
 .../src/main/webapp/resources/css/infobox.css   |  19 +++
 .../main/webapp/resources/images/BabyChimp.gif  | Bin 0 -> 13652 bytes
 .../resources/images/ChimpEatingDollar.gif      | Bin 0 -> 10565 bytes
 .../images/Chimpanzee_thinking-small.gif        | Bin 0 -> 11055 bytes
 .../webapp/resources/images/bonoboMomKid.gif    | Bin 0 -> 28930 bytes
 .../driver/PortletContainerInitializer.java     |  16 +++
 .../container/impl/PortletParametersImpl.java   |   2 +-
 .../om/portlet/impl/ConfigurationProcessor.java |  19 ++-
 17 files changed, 538 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
index 4e3445b..80ac367 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
@@ -52,7 +52,7 @@ import javax.xml.namespace.QName;
 /**
  * An example color selection portlet that uses the portlet hub.
  */
-@PortletConfiguration(portletName = "ColorSelPortlet", publicParams = "color", 
+@PortletConfiguration(portletName = "PH-ColorSelPortlet", publicParams = "color", 
                       title = @LocaleString("PH Color Selection Portlet"))
 public class ColorSelPortlet extends GenericPortlet {
 
@@ -84,7 +84,7 @@ public class ColorSelPortlet extends GenericPortlet {
          throws PortletException, IOException {
    }
 
-   @ActionMethod(portletName="ColorSelPortlet", publishingEvents= {
+   @ActionMethod(portletName="PH-ColorSelPortlet", publishingEvents= {
          @PortletQName(namespaceURI="http://www.apache.org/portals/pluto/ResourcePortlet", localPart="Message")
    })
    public void processAction(ActionRequest req, ActionResponse resp)

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
new file mode 100644
index 0000000..f5f56b6
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/CSSIncludingHeaderMethod.java
@@ -0,0 +1,51 @@
+/*  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.portals.samples;
+
+import java.io.IOException;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.annotations.HeaderMethod;
+
+/**
+ * Header method to include a css file.
+ */
+@ApplicationScoped
+public class CSSIncludingHeaderMethod {
+   
+   // The header method can apply to a list of portlets. If the asterisk is specified 
+   // as first portlet name, the header method is executed for all portlets in
+   // the portlet application.
+   @HeaderMethod(portletNames="*")
+   public void header(HeaderRequest req, HeaderResponse resp) throws IOException {
+
+      // Add link tag to head section to include the style sheet
+
+      String contextRoot = req.getContextPath();
+      StringBuilder txt = new StringBuilder(128);
+      txt.append("<link href='").append(contextRoot);
+      txt.append("/resources/css/styles.css' rel='stylesheet' type='text/css'>");
+      
+      resp.getWriter().write(txt.toString());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
new file mode 100644
index 0000000..870b46f
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldImage.java
@@ -0,0 +1,119 @@
+/*  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.portals.samples;
+
+import javax.inject.Inject;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceURL;
+
+import javax.portlet.annotations.ContextPath;
+import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ResourceParam;
+import javax.portlet.annotations.ServeResourceMethod;
+import javax.portlet.annotations.URLFactory;
+
+/**
+ * Contains a resource method and associated markup generator to insert 
+ * an image.
+ */
+public class HelloWorldImage {
+
+   public static final String RESPARAM_DISPLAY = "display";
+   
+   // Injecting the namespace & URLFactory
+   @Inject @Namespace private String pid;
+   @Inject private            URLFactory uf;
+   
+   @Inject @ContextPath
+   String ctxPath;
+   
+   @Inject
+   PortletRequest req;
+
+   @Inject
+   NameBean nameBean;
+   
+   // Some chimp pictures to associate with a name
+   private final static String[] chimps = new String[] {
+      "/resources/images/BabyChimp.gif",
+      "/resources/images/bonoboMomKid.gif",
+      "/resources/images/Chimpanzee_thinking-small.gif",
+      "/resources/images/ChimpEatingDollar.gif"
+   };
+
+   @RenderMethod(portletNames = {"BeanPortlet"}, ordinal=100)
+   public String getImageInclude() {
+      
+      StringBuilder txt = new StringBuilder(128);
+      ResourceURL resurl = uf.createResourceURL();
+      if (nameBean.getName() != null) {
+         resurl.getResourceParameters().setValue(RESPARAM_DISPLAY, "true");
+      }
+      
+      txt.append("<div class='infobox' id='").append(pid).append("-putResourceHere'></div>\n");
+      txt.append("<script>\n");
+      txt.append("(function () {\n");
+      txt.append("   var xhr = new XMLHttpRequest();\n");
+      txt.append("   xhr.onreadystatechange=function() {\n");
+      txt.append("      if (xhr.readyState==4 && xhr.status==200) {\n");
+      txt.append("         document.getElementById('").append(pid).append("-putResourceHere').innerHTML=xhr.responseText;\n");
+      txt.append("      }\n");
+      txt.append("   };\n");
+      txt.append("   xhr.open(\"GET\",\"").append(resurl.toString()).append("\",true);\n");
+      txt.append("   xhr.send();\n");
+      txt.append("})();\n");
+      txt.append("</script>\n");
+
+      return txt.toString();
+   }
+
+   // Inject the resource parameter to see if image should be displayed.
+   @Inject @ResourceParam(RESPARAM_DISPLAY)
+   String   display;
+   
+   /**
+    *  This resource method generates some output directly, then includes output
+    *  from a JSP as specified in the annotation.
+    *  
+    * @return  The string for inclusion in the output.
+    */
+   @ServeResourceMethod(portletNames={"BeanPortlet"}, include="/WEB-INF/jsp/res-simple.jsp")
+   public String getImage() {
+      String result = "";
+      
+      // illustrate use of the injected display resource parameter
+      if (display != null) {
+         
+         // pick a chimp
+         
+         int ind = (int) (Math.random() * chimps.length);
+         String imgSrc = ctxPath + chimps[ind];
+         imgSrc = uf.encodeURL(imgSrc);
+         req.setAttribute("imgSrc", imgSrc);
+         
+         // set the output
+         
+         result = "<p>Your image appears here:</p>";
+      }
+      return result;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
new file mode 100644
index 0000000..b835d00
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/HelloWorldRender.java
@@ -0,0 +1,60 @@
+/*  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.portals.samples;
+
+import javax.inject.Inject;
+
+import javax.portlet.annotations.RenderMethod;
+
+/**
+ * Simple hello world bean portlet
+ */
+public class HelloWorldRender {
+   
+   // This is an @PortletStateScoped bean containing the name 
+   // entered through the form.
+   @Inject
+   private NameBean nameBean;
+
+   /**
+    * Bean portlet render method for "BeanHelloWorld" portlet.
+    */
+   @RenderMethod(portletNames = {"BeanPortlet"})
+   public String methodName() {
+      
+      // In it's simplest form, the render method just returns text.
+      // The content type is set through the annotation.
+      
+      StringBuilder txt = new StringBuilder(128);
+      
+      txt.append("<h3>Hello ");
+      
+      // Get the name from the bean. If it hasn't been set, just greet the world.
+      if (nameBean.getName() != null) {
+         txt.append(nameBean.getName());
+      } else {
+         txt.append("World");
+      }
+      txt.append("!!</h3>");
+      
+      return txt.toString();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
new file mode 100644
index 0000000..5242c98
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/Log.java
@@ -0,0 +1,37 @@
+/*  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.portals.samples;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.interceptor.InterceptorBinding;
+
+/**
+ * Annotation defining an interceptor binding for logging
+ * 
+ * @author nick
+ */
+@Inherited
+@InterceptorBinding
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface Log {}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
new file mode 100644
index 0000000..13905a3
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/LoggingInterceptor.java
@@ -0,0 +1,70 @@
+/*  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.portals.samples;
+
+import java.io.Serializable;
+import java.util.logging.Logger;
+
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InvocationContext;
+
+/**
+ * Interceptor to provide logging for our project
+ * 
+ * @author Scott Nicklous
+ */
+@Interceptor
+@Log
+public class LoggingInterceptor implements Serializable {
+
+   private static final long serialVersionUID = -73481963162413796L;
+
+   private static final Logger logger = Logger.getLogger(LoggingInterceptor.class.getCanonicalName());
+
+   /**
+    * Method called for use as an interceptor. Called before the intercepted method is 
+    * called. 
+    * 
+    * @param ic
+    * @return
+    * @throws Exception
+    */
+   @AroundInvoke
+   public Object log(InvocationContext ic) throws Exception {
+
+      String cls = ic.getMethod().getDeclaringClass().getCanonicalName();
+      String meth = ic.getMethod().getName();
+      
+      // Log method entry
+      Logger mlogger = Logger.getLogger(cls);
+      mlogger.entering(cls, meth);
+      
+      // Continue through chain until actual bean method is executed
+      Object obj = ic.proceed(); 
+   
+      // this logging statement is only for debugging.
+      logger.fine("Method " + meth + " has been called.");
+      
+      // Now log the exit
+      mlogger.exiting(cls, meth);
+
+      return obj;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
new file mode 100644
index 0000000..25dd88e
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/java/org/apache/portals/samples/NameBean.java
@@ -0,0 +1,138 @@
+/*  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.portals.samples;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.PortletURL;
+
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.ActionParam;
+import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.PortletSerializable;
+import javax.portlet.annotations.PortletStateScoped;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.URLFactory;
+import javax.portlet.MimeResponse.Copy;
+
+/**
+ * Portlet state scoped bean. The bean is stored as a render parameter,
+ * so it needs to be portlet serializable.
+ */
+@PortletStateScoped
+public class NameBean implements PortletSerializable {
+   
+   // Inject the portlet namespace 
+   @Inject @Namespace private String pid;
+   
+   // Inject the URLFactory to allow URL creation
+   @Inject private            URLFactory uf;
+   
+   private final static String PARAM_NAME = "name";
+
+   //========== bean state in this block =======================
+   private String name;
+   //===========================================================
+
+   @Inject @ActionParam(PARAM_NAME)
+   private String apName;
+
+   // getters & setters
+   //================
+   public String getName() {
+      return name;
+   }
+
+   public void setName(String name) {
+      this.name = name;
+   }
+   //================
+   
+   
+   /**
+    * writes the action form as string. This method is placed within the bean 
+    * to allow easier access to form state data, which might be part of the bean
+    * state, but not part of the bean public API.  
+    * 
+    * @return the action form as string
+    */
+   @RenderMethod(portletNames = {"BeanPortlet"}, ordinal=200)
+   public String getActionForm() {
+      StringBuilder txt = new StringBuilder(128);
+      
+      PortletURL aurl = uf.createActionURL(Copy.ALL);
+      txt.append("<FORM id='").append(pid).append("-setParams' METHOD='POST' ACTION='").append(aurl);
+      txt.append("' enctype='application/x-www-form-urlencoded' accept-charset='UTF-8'>");
+      txt.append("   <table><tr><td align='left'>");
+      txt.append("   Enter your name:");
+      txt.append("   </td><td>");
+      txt.append("   <input name='").append(PARAM_NAME);
+      txt.append("' type='text' value='").append((name == null) ? "" : name);
+      txt.append("' size='50' maxlength='50'>");
+      txt.append("   <input type='hidden' name='").append(ActionRequest.ACTION_NAME);
+      txt.append("' value='setName'>");
+      txt.append("   </td></tr><tr><td>");
+      txt.append("   <INPUT VALUE='send' TYPE='submit'>");
+      txt.append("   </td></tr></table>");
+      txt.append("</FORM>");
+
+      return txt.toString();
+   }
+   
+   /**
+    * Bean portlet action method for the "BeanHelloWorld" portlet.
+    * Since the submitted form contains a hidden field with the action 
+    * name set to "setName", the portlet container routes the request
+    * to exactly this method.
+    */
+   @ActionMethod(portletName = "BeanPortlet", actionName="setName")
+   public void setName(ActionRequest req, ActionResponse resp)
+         throws PortletException, IOException {
+      // The action parameter is injected, so just need to check it or
+      // in this case, copy it to the state. Note that you can't inject directly 
+      // into the state, since the injection is performed before the deserialization.
+      name = apName;
+   }
+
+   /**
+    * This method is called by the portlet container to 
+    * initialize the bean at the beginning of a request.
+    */
+   @Override
+   public void deserialize(String[] state) {
+      if (state.length == 1) {
+         name = state[0];
+      }
+   }
+
+   /**
+    * Called by the portlet container at the end of an action or event request
+    * to store the serialized data as a portlet render parameter.
+    */
+   @Override
+   public String[] serialize() {
+      return new String[] {name};
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
new file mode 100644
index 0000000..e182a58
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/jsp/res-simple.jsp
@@ -0,0 +1,9 @@
+<%@ 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 />
+
+<c:if test="${imgSrc != null}">
+   <img src="${imgSrc}" style='border:1px solid blue;' >
+</c:if>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
new file mode 100644
index 0000000..847c8d6
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/bluebold.css
@@ -0,0 +1,4 @@
+.bluebold {
+	color:#00A; 
+	font: bold;
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
new file mode 100644
index 0000000..e38c4e9
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/resources/css/infobox.css
@@ -0,0 +1,19 @@
+.infobox {
+   border-style:solid; 
+   border-width:2px; 
+   padding:4px; 
+   margin-bottom:10px;
+   overflow:auto;
+   border-color:#000088; 
+   background:#E0E0FF;
+}
+
+.parmbox {
+   border-style:solid; 
+   border-width:2px; 
+   padding:4px; 
+   margin:3px;
+   overflow:auto;
+   border-color:#008800; 
+   background:#E0FFE0;
+}

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

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

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif
new file mode 100644
index 0000000..5a11b72
Binary files /dev/null and b/PortletV3AnnotatedDemo/src/main/webapp/resources/images/Chimpanzee_thinking-small.gif differ

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

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index e48566f..5861889 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -19,12 +19,15 @@
 package org.apache.pluto.container.driver;
 
 import java.io.InputStream;
+import java.util.EnumSet;
 import java.util.Set;
 
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.portlet.annotations.PortletConfigurations;
 import javax.portlet.annotations.PortletRequestFilter;
+import javax.servlet.DispatcherType;
+import javax.servlet.FilterRegistration;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -157,6 +160,19 @@ public class PortletContainerInitializer implements ServletContainerInitializer
                sr.setLoadOnStartup(100);
 
             }
+            
+            // Add the cross-context filter & terminal listener
+            
+            FilterRegistration.Dynamic fr = ctx.addFilter("WeldCrossContextFilter", "org.jboss.weld.servlet.WeldCrossContextFilter");
+            EnumSet<DispatcherType> dt = EnumSet.noneOf(DispatcherType.class);
+            dt.add(DispatcherType.FORWARD);
+            dt.add(DispatcherType.INCLUDE);
+            dt.add(DispatcherType.ERROR);
+            fr.addMappingForUrlPatterns(dt, false, "/*");
+            
+            ctx.addListener("org.jboss.weld.servlet.WeldTerminalListener");
+
+            LOG.debug("Completed deployment of servlets & filters for context: " + ctx.getContextPath());
 
          } else {
             LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
index 938a4a5..cd0d27d 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
@@ -126,7 +126,7 @@ public abstract class PortletParametersImpl implements PortletParameters {
     */
    public String[] getValues(String name) {
       checkNull("name", name);
-      String[] vals = params.get(name).clone();
+      String[] vals = (params.get(name) == null) ? null : params.get(name).clone();
       if (isTrace) {
          LOGGER.debug("Name: " + name + ", Values: " + Arrays.toString(vals));
       }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a0c6f1c9/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 92c2803..40e16f4 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -378,15 +378,18 @@ public abstract class ConfigurationProcessor {
     */
    public void reconcileBeanConfig(AnnotatedMethodStore ams) {
       
+      Set<String> portletNames = ams.getPortletNames();
+      // the wildcard is only in the store for display / debug purposes. don't reconcile.
+      portletNames.remove("*");     
       if (isDebug) {
          StringBuilder txt = new StringBuilder();
-         txt.append("Beginning reconciliation. Annotated portlets: ").append(ams.getPortletNames().toString());
+         txt.append("Beginning reconciliation. Annotated portlets: ").append(portletNames.toString());
          LOG.debug(txt.toString());
       }
 
       ams.setDefaultNamespace(pad.getDefaultNamespace());
       
-      for (String pn : ams.getPortletNames()) {
+      for (String pn : portletNames) {
          
          PortletDefinition pd = pad.getPortlet(pn);
          if (pd == null) {
@@ -478,19 +481,19 @@ public abstract class ConfigurationProcessor {
             StringBuilder txt = new StringBuilder(128);
             BeanManager bm = ams.getBeanMgr();
             if (bm == null) {
-               txt.append("Could not instantiate portlet class. Bean manager is null.");
+               txt.append("Could not get portlet bean. Bean manager is null.");
             } else {
                Set<Bean<?>> beans = bm.getBeans(cls);
                if (beans == null || beans.size() == 0) {
-                  txt.append("Could not instantiate portlet class. No beans found.");
+                  txt.append("Could not get portlet bean. No beans found.");
                } else {
                   Bean<?> bean = bm.resolve(beans);
                   if (bean == null) {
-                     txt.append("Could not instantiate portlet class. Could not resolve bean.");
+                     txt.append("Could not get portlet bean. Could not resolve bean.");
                   } else {
                      instance = bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
                      if (instance == null) {
-                        txt.append("Could not instantiate portlet class. Could not get bean instance.");
+                        txt.append("Could not get portlet bean. Could not get bean instance.");
                      }
                   }
                }
@@ -620,7 +623,9 @@ public abstract class ConfigurationProcessor {
       if (isDebug) {
          StringBuilder txt = new StringBuilder();
          txt.append("Finished reconciling bean config. ");
-         txt.append("Resulting portlet list: ").append(ams.getPortletNames().toString());
+         Set<String> finalNames = ams.getPortletNames();
+         finalNames.remove("*");    // don't display wildcard
+         txt.append("Resulting portlet list: ").append(finalNames.toString());
          LOG.debug(txt.toString());
       }
       


[15/35] portals-pluto git commit: Implemented type annotations for portlet request filters, portlet URL generation listeners, and portlet preference validators. The corresponding definitions in the portlet.xml file are merged into the annotated configura

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedListenerTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedListenerTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedListenerTest.java
new file mode 100644
index 0000000..af49bef
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedListenerTest.java
@@ -0,0 +1,222 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Listener;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ListenerImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedListeners1;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedListeners2;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestListener;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class AlterMultipleAnnotatedListenerTest {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = MultipleAnnotatedListeners1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = MultipleAnnotatedListeners2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362AlterListener.xml";
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);
+         try {
+            cfp.validate();         // validate to expand the Listener mapping portlet names
+         } catch (Exception e) {}   // ignore any validation problems.
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Tests that bListener has been removed and aListener modified 
+    */
+   @Test
+   public void testGetListener() {
+      String fn1 = "bListener";
+      String fn2 = "aListener";
+      Listener lis1 = cut.getListener(fn1);
+      assertNull(lis1);
+      Listener lis2 = cut.getListener(fn2);
+      assertNotNull(lis2);
+      assertEquals(-40, lis2.getOrdinal());
+      assertEquals(TestListener.class.getCanonicalName(), lis2.getListenerClass());
+   }
+   
+   /**
+    * make sure we have the right number
+    */
+   @Test
+   public void testGetListeners() {
+      String fn2 = "aListener";
+      List<Listener> list = cut.getListeners();
+      assertEquals(1, list.size());
+      assertEquals(fn2, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test that additional listener can be added
+    */
+   @Test
+   public void testAddListener() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(-101);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getListenerName());
+      assertEquals(oldItem1, list.get(1).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder1() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getListenerName());
+      assertEquals(oldItem1, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder2() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(0);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getListenerName());
+      assertEquals(oldItem1, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void deleteListener1() {
+      String oldItem = "aListener";
+      Listener lis = new ListenerImpl((String)null);
+      lis.setListenerName(oldItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void deleteListener2() {
+      String oldItem = "aListener";
+      Listener lis = new ListenerImpl("");
+      lis.setListenerName(oldItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   @Test
+   public void testAddDupListener() {
+      String fn = "aListener";
+      String fc = "SomeClass";
+      Listener lis = new ListenerImpl(fc);
+      lis.setListenerName(fn);
+      lis.setOrdinal(200);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(fn, list.get(0).getListenerName());
+      assertEquals(fc, list.get(0).getListenerClass());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/FilterMultiplePortletsTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/FilterMultiplePortletsTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/FilterMultiplePortletsTest.java
new file mode 100644
index 0000000..13eddd3
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/FilterMultiplePortletsTest.java
@@ -0,0 +1,125 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.portlet.PortletRequest;
+
+import org.apache.pluto.container.om.portlet.Filter;
+import org.apache.pluto.container.om.portlet.FilterMapping;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedFilterMultiple;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class FilterMultiplePortletsTest {
+   
+   // defines both some portlets and a filter
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestAnnotatedFilterMultiple.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         try {
+            cfp.validate();         // validate to expand the filter mapping portlet names
+         } catch (Exception e) {}   // ignore any validation problems.
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilter() {
+      String newItem = "aFilter";
+      Filter item = cut.getFilter(newItem);
+      assertNotNull(item);
+      Filter filter = cut.getFilters().get(0);
+      assertEquals(TEST_ANNOTATED_CLASS.getCanonicalName(), 
+            filter.getFilterClass());
+      assertEquals("true", filter.getInitParam("execute").getParamValue());
+   }
+   
+   @Test
+   public void testFilterLifecycle() {
+      String newItem = "aFilter";
+      Filter filter = cut.getFilter(newItem);
+      assertNotNull(filter);
+      List<String> lifecycles =  Arrays.asList(new String[] {PortletRequest.RENDER_PHASE, PortletRequest.RESOURCE_PHASE, PortletRequest.HEADER_PHASE});
+      for (String lc : filter.getLifecycles()) {
+         assertTrue(lifecycles.contains(lc));
+      }
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMapping(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilterMapping() {
+      String newItem = "aFilter";
+      FilterMapping item = cut.getFilterMapping(newItem);
+      assertNotNull(item);
+      List<String> names = item.getPortletNames();
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
index 5412191..132adab 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
@@ -146,6 +146,7 @@ public class JSR362PortletFilterAnnotationTest {
       String newItem = "newFilter";
       Filter fil = new FilterImpl(newItem);
       fil.setFilterClass("SomeClass");
+      fil.setOrdinal(100);
       cut.addFilter(fil);
       
       List<Filter> list = cut.getFilters();
@@ -158,6 +159,76 @@ public class JSR362PortletFilterAnnotationTest {
     * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
     */
    @Test
+   public void checkFilterOrder1() {
+      String newItem = "newFilter";
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(10);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+      assertEquals(oldItem, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void checkFilterOrder2() {
+      String newItem = "newFilter";
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+      assertEquals(oldItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter1() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass(null);
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter2() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass("");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
    public void testAddDupFilter() {
       String newItem = "aFilter";
       Filter fil = new FilterImpl(newItem);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
index d949ca0..dcb8d99 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
@@ -56,14 +56,12 @@ import org.apache.pluto.container.om.portlet.impl.EventDefinitionReferenceImpl;
 import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
 import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
 import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
-import org.apache.pluto.container.om.portlet.impl.PortletInfoImpl;
 import org.apache.pluto.container.om.portlet.impl.PreferenceImpl;
 import org.apache.pluto.container.om.portlet.impl.PreferencesImpl;
 import org.apache.pluto.container.om.portlet.impl.SecurityRoleRefImpl;
 import org.apache.pluto.container.om.portlet.impl.SupportsImpl;
 import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPortlet;
 import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet;
-import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortletAppAnnotatedClass;
 import org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -210,9 +208,6 @@ public class MergePortletDefinitionTest {
       PortletInfo info = cut.getPortletInfo();
       assertNotNull(info);
       List<LocaleText> list = info.getTitles();
-      for (LocaleText lt : list) {
-         System.out.println("title: " + lt.getText());
-      }
       assertEquals(2, list.size());
       assertEquals("Annotated Portlet", info.getTitle(Locale.ENGLISH).getText());
       assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs1Test.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs1Test.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs1Test.java
new file mode 100644
index 0000000..1255474
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs1Test.java
@@ -0,0 +1,245 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.Preference;
+import org.apache.pluto.container.om.portlet.Preferences;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPrefs1;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MergePrefs1Test {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestAnnotatedPrefs1.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362AlterValidator1.xml";
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            cfp.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Tests that the validator is properly applied to portlets 1 & 3 only
+    */
+   @Test
+   public void testPrefs() {
+      List<PortletDefinition> list = cut.getPortlets();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+   }
+   
+   @Test
+   public void testGetPreferences1() {
+      String name = "bPref";
+      String[] testVals = {"dValue", "eValue", "fValue"};
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(testVals.length, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+      
+      name = "aPref";
+      testVals = new String[] {"aValue"}; 
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(testVals.length, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+   }
+   
+   @Test
+   public void testGetPreferences2() {
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(0, prefs.getPortletPreferences().size());
+   }
+   
+   @Test
+   public void testGetPreferences3() {
+      String name = "cPref";
+      String val = "cValue";
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+   }
+   
+   @Test
+   public void testGetPreferences4() {
+      String name = "dPref";
+      String val = "dValue";
+      PortletDefinition pd = cut.getPortlet("portlet4");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+   }
+   
+   @Test
+   public void testGetPreferenceList() {
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      for (Preference p : prefs.getPortletPreferences()) {
+         assertTrue(p.isReadOnly());
+      }
+   }
+   
+   @Test
+   public void testReadOnly3() {
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("cPref");
+      assertNotNull(pref);
+      assertFalse(pref.isReadOnly());
+   }
+   
+   @Test
+   public void testReadOnly4() {
+      PortletDefinition pd = cut.getPortlet("portlet4");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("dPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+   }
+
+   @Test
+   public void testValidatorApplied() {
+      PortletDefinition pd1 = cut.getPortlet("portlet1");
+      PortletDefinition pd4 = cut.getPortlet("portlet4");
+      
+      assertNotNull(pd1);
+      assertNotNull(pd4);
+      
+      Preferences prefs1 = pd1.getPortletPreferences();
+      Preferences prefs4 = pd4.getPortletPreferences();
+      
+      assertNotNull(prefs1);
+      assertNotNull(prefs4);
+      
+      assertNotNull(prefs1.getPreferencesValidator());
+      assertNotNull(prefs4.getPreferencesValidator());
+      
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs1.getPreferencesValidator());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs4.getPreferencesValidator());
+   }
+
+   @Test
+   public void testValidatorNotApplied() {
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertNull(prefs.getPreferencesValidator());
+      
+      pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertNull(prefs.getPreferencesValidator());
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs2Test.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs2Test.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs2Test.java
new file mode 100644
index 0000000..f206c31
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePrefs2Test.java
@@ -0,0 +1,306 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.Preference;
+import org.apache.pluto.container.om.portlet.Preferences;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPrefs2;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MergePrefs2Test {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestAnnotatedPrefs2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362AlterValidator2.xml";
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            cfp.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Tests that the validator is properly applied to portlets 1 & 5 only
+    */
+   @Test
+   public void testPrefs() {
+      List<PortletDefinition> list = cut.getPortlets();
+      assertNotNull(list);
+      assertEquals(5, list.size());
+   }
+   
+   @Test
+   public void testGetPreferences1() {
+      String name = "bPref";
+      String[] testVals = {"dValue", "eValue", "fValue"};
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(testVals.length, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+      
+      name = "aPref";
+      testVals = new String[] {"aValue"}; 
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(testVals.length, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+   }
+   
+   @Test
+   public void testGetPreferences2() {
+      String name = "aPref";
+      String val = "aValue";
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+      
+      name = "bPref";
+      String[] testVals = {"bValue", "cValue"};
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(2, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+   }
+   
+   @Test
+   public void testGetPreferences3() {
+      String name = "cPref";
+      String val = "cValue";
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+      
+      name = "aPref";
+      val = "aValue";
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+   }
+   
+   @Test
+   public void testGetPreferences4() {
+      String name = "dPref";
+      String val = "dValue";
+      PortletDefinition pd = cut.getPortlet("portlet4");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+   }
+   
+   @Test
+   public void testGetPreferenceList() {
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      for (Preference p : prefs.getPortletPreferences()) {
+         assertTrue(p.isReadOnly());
+      }
+   }
+   
+   @Test
+   public void testReadOnly1() {
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("aPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+      
+      pref = prefs.getPortletPreference("bPref");
+      assertNotNull(pref);
+      assertFalse(pref.isReadOnly());
+   }
+   
+   @Test
+   public void testReadOnly2() {
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("aPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+      
+      pref = prefs.getPortletPreference("cPref");
+      assertNotNull(pref);
+      assertFalse(pref.isReadOnly());
+   }
+   
+   @Test
+   public void testReadOnly4() {
+      PortletDefinition pd = cut.getPortlet("portlet4");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("dPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+   }
+
+   /**
+    * Annotated Validator is applied to portlets 3 & 4. Portlet 1 gets
+    * a validator specified in the portlet DD. 
+    */
+   @Test
+   public void testValidatorApplied() {
+      PortletDefinition pd1 = cut.getPortlet("portlet1");
+      PortletDefinition pd3 = cut.getPortlet("portlet3");
+      PortletDefinition pd4 = cut.getPortlet("portlet4");
+      
+      assertNotNull(pd1);
+      assertNotNull(pd3);
+      assertNotNull(pd4);
+      
+      Preferences prefs1 = pd1.getPortletPreferences();
+      Preferences prefs3 = pd3.getPortletPreferences();
+      Preferences prefs4 = pd4.getPortletPreferences();
+      
+      assertNotNull(prefs1);
+      assertNotNull(prefs3);
+      assertNotNull(prefs4);
+      
+      assertNotNull(prefs1.getPreferencesValidator());
+      assertNotNull(prefs3.getPreferencesValidator());
+      assertNotNull(prefs4.getPreferencesValidator());
+      
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs1.getPreferencesValidator());
+      assertEquals(TestPreferencesValidator.class.getCanonicalName(), prefs3.getPreferencesValidator());
+      assertEquals(TestPreferencesValidator.class.getCanonicalName(), prefs4.getPreferencesValidator());
+   }
+
+   /**
+    * The annotated validator is not applied to portlet 2. The validator would normally
+    * be applied to portlet 5, but is explicitly set to null in the portlet DD, so
+    * portlet 5 doesn't get a validator.
+    */
+   @Test
+   public void testValidatorNotApplied() {
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertNull(prefs.getPreferencesValidator());
+      
+      pd = cut.getPortlet("portlet5");
+      assertNotNull(pd);
+      prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertNull(prefs.getPreferencesValidator());
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedFilterTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedFilterTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedFilterTest.java
new file mode 100644
index 0000000..77c1e5b
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedFilterTest.java
@@ -0,0 +1,212 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Filter;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.FilterImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedFilters1;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedFilters2;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MultipleAnnotatedFilterTest {
+   
+   // defines both some portlets and a filter
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = MultipleAnnotatedFilters1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = MultipleAnnotatedFilters2.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         try {
+            cfp.validate();         // validate to expand the filter mapping portlet names
+         } catch (Exception e) {}   // ignore any validation problems.
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilter() {
+      String fn1 = "aFilter";
+      String fn2 = "bFilter";
+      Filter fil1 = cut.getFilter(fn1);
+      assertNotNull(fil1);
+      assertEquals(100, fil1.getOrdinal());
+      Filter fil2 = cut.getFilter(fn2);
+      assertNotNull(fil2);
+      assertEquals(-100, fil2.getOrdinal());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), fil1.getFilterClass());
+      assertEquals(TEST_ANNOTATED_CLASS2.getCanonicalName(), fil2.getFilterClass());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddFilter() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      String oldItem2 = "bFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(-101);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+      assertEquals(oldItem1, list.get(2).getFilterName());
+      assertEquals(oldItem2, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void checkFilterOrder1() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      String oldItem2 = "bFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(2).getFilterName());
+      assertEquals(oldItem1, list.get(1).getFilterName());
+      assertEquals(oldItem2, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void checkFilterOrder2() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      String oldItem2 = "bFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(0);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+      assertEquals(oldItem1, list.get(2).getFilterName());
+      assertEquals(oldItem2, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter1() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass(null);
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter2() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass("");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+   }
+
+   @Test
+   public void testAddDupFilter() {
+      String fn = "aFilter";
+      String fc = "SomeClass";
+      Filter fil = new FilterImpl(fn);
+      fil.setFilterClass(fc);
+      fil.setOrdinal(200);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(fn, list.get(1).getFilterName());
+      assertEquals(fc, list.get(1).getFilterClass());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedListenerTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedListenerTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedListenerTest.java
new file mode 100644
index 0000000..5011ab7
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedListenerTest.java
@@ -0,0 +1,212 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Listener;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ListenerImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedListeners1;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedListeners2;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MultipleAnnotatedListenerTest {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = MultipleAnnotatedListeners1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = MultipleAnnotatedListeners2.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         try {
+            cfp.validate();         // validate to expand the Listener mapping portlet names
+         } catch (Exception e) {}   // ignore any validation problems.
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getListener(java.lang.String)}.
+    */
+   @Test
+   public void testGetListener() {
+      String fn1 = "aListener";
+      String fn2 = "bListener";
+      Listener lis1 = cut.getListener(fn1);
+      assertNotNull(lis1);
+      assertEquals(100, lis1.getOrdinal());
+      Listener lis2 = cut.getListener(fn2);
+      assertNotNull(lis2);
+      assertEquals(-100, lis2.getOrdinal());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), lis1.getListenerClass());
+      assertEquals(TEST_ANNOTATED_CLASS2.getCanonicalName(), lis2.getListenerClass());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void testAddListener() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      String oldItem2 = "bListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(-101);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(0).getListenerName());
+      assertEquals(oldItem1, list.get(2).getListenerName());
+      assertEquals(oldItem2, list.get(1).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder1() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      String oldItem2 = "bListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(2).getListenerName());
+      assertEquals(oldItem1, list.get(1).getListenerName());
+      assertEquals(oldItem2, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder2() {
+      String newItem = "newListener";
+      String oldItem1 = "aListener";
+      String oldItem2 = "bListener";
+      Listener lis = new ListenerImpl("SomeClass");
+      lis.setListenerName(newItem);
+      lis.setOrdinal(0);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(1).getListenerName());
+      assertEquals(oldItem1, list.get(2).getListenerName());
+      assertEquals(oldItem2, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void deleteListener1() {
+      String oldItem = "aListener";
+      Listener lis = new ListenerImpl((String)null);
+      lis.setListenerName(oldItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void deleteListener2() {
+      String oldItem = "aListener";
+      Listener lis = new ListenerImpl("");
+      lis.setListenerName(oldItem);
+      lis.setOrdinal(1000);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+   }
+
+   @Test
+   public void testAddDupListener() {
+      String fn = "aListener";
+      String fc = "SomeClass";
+      Listener lis = new ListenerImpl(fc);
+      lis.setListenerName(fn);
+      lis.setOrdinal(200);
+      cut.addListener(lis);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(fn, list.get(1).getListenerName());
+      assertEquals(fc, list.get(1).getListenerClass());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs1Test.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs1Test.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs1Test.java
new file mode 100644
index 0000000..49364c1
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs1Test.java
@@ -0,0 +1,99 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPrefs1;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MultipleAnnotatedPrefs1Test {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestAnnotatedPrefs1.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         try {
+            cfp.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Tests that the default portletNames='*' value in the portlet
+    * preferences validator annotation applies the validator to all
+    * portlets in the portlet app.  
+    */
+   @Test
+   public void testPrefs() {
+      List<PortletDefinition> list = cut.getPortlets();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      
+      for (PortletDefinition item : list) {
+         assertNotNull(item.getPortletPreferences());
+         assertNotNull(item.getPortletPreferences().getPreferencesValidator());
+         assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), 
+               item.getPortletPreferences().getPreferencesValidator());
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs2Test.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs2Test.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs2Test.java
new file mode 100644
index 0000000..371d429
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultipleAnnotatedPrefs2Test.java
@@ -0,0 +1,243 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.Preference;
+import org.apache.pluto.container.om.portlet.Preferences;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPrefs2;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class MultipleAnnotatedPrefs2Test {
+   
+   // defines both some portlets and a Listener
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestAnnotatedPrefs2.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         try {
+            cfp.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Tests that the validator is properly applied to portlets 1, 3, & 5 only
+    */
+   @Test
+   public void testPrefs() {
+      List<PortletDefinition> list = cut.getPortlets();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+   }
+   
+   @Test
+   public void testGetPreferences1() {
+      String name = "aPref";
+      String val = "aValue";
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+      
+      name = "bPref";
+      val = "bValue";
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+   }
+   
+   @Test
+   public void testGetPreferences2() {
+      String name = "aPref";
+      String val = "aValue";
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+      
+      name = "bPref";
+      String[] testVals = {"bValue", "cValue"};
+      pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      vals = pref.getValues();
+      assertEquals(2, vals.size());
+      assertArrayEquals(testVals, vals.toArray());
+   }
+   
+   @Test
+   public void testGetPreferences3() {
+      String name = "aPref";
+      String val = "aValue";
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference(name);
+      assertNotNull(pref);
+      List<String> vals = pref.getValues();
+      assertEquals(1, vals.size());
+      assertEquals(val, vals.get(0));
+      
+      name = "bPref";
+      pref = prefs.getPortletPreference(name);
+      assertNull(pref);
+   }
+   
+   @Test
+   public void testGetPreferences() {
+      PortletDefinition pd = cut.getPortlet("portlet1");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      for (Preference p : prefs.getPortletPreferences()) {
+         assertFalse(p.isReadOnly());
+      }
+   }
+   
+   @Test
+   public void testReadOnly1() {
+      PortletDefinition pd = cut.getPortlet("portlet2");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(2, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("aPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+      
+      pref = prefs.getPortletPreference("bPref");
+      assertNotNull(pref);
+      assertFalse(pref.isReadOnly());
+   }
+   
+   @Test
+   public void testReadOnly2() {
+      PortletDefinition pd = cut.getPortlet("portlet3");
+      assertNotNull(pd);
+      Preferences prefs = pd.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(1, prefs.getPortletPreferences().size());
+      
+      Preference pref = prefs.getPortletPreference("aPref");
+      assertNotNull(pref);
+      assertTrue(pref.isReadOnly());
+   }
+
+   @Test
+   public void testValidatorApplied() {
+      PortletDefinition pd1 = cut.getPortlet("portlet1");
+      PortletDefinition pd3 = cut.getPortlet("portlet3");
+      PortletDefinition pd5 = cut.getPortlet("portlet5");
+      
+      assertNotNull(pd1);
+      assertNotNull(pd3);
+      assertNotNull(pd5);
+      
+      Preferences prefs1 = pd1.getPortletPreferences();
+      Preferences prefs3 = pd3.getPortletPreferences();
+      Preferences prefs5 = pd5.getPortletPreferences();
+      
+      assertNotNull(prefs1);
+      assertNotNull(prefs3);
+      assertNotNull(prefs5);
+      assertNotNull(prefs1.getPreferencesValidator());
+      assertNotNull(prefs3.getPreferencesValidator());
+      assertNotNull(prefs5.getPreferencesValidator());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs1.getPreferencesValidator());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs3.getPreferencesValidator());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), prefs5.getPreferencesValidator());
+   }
+
+   @Test
+   public void testValidatorNotApplied() {
+      PortletDefinition pd2 = cut.getPortlet("portlet2");
+      assertNotNull(pd2);
+      Preferences prefs2 = pd2.getPortletPreferences();
+      assertNotNull(prefs2);
+      assertNull(prefs2.getPreferencesValidator());
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
index bbaa992..13ccd87 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletApplicationDefinition362ImplTest.java
@@ -749,6 +749,7 @@ public class PortletApplicationDefinition362ImplTest {
       assertEquals(1, list.size());
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestListener", list.get(0).getListenerClass());
       assertEquals("test listener", list.get(0).getListenerName());
+      assertEquals(100, list.get(0).getOrdinal());
    }
 
    /**
@@ -758,16 +759,20 @@ public class PortletApplicationDefinition362ImplTest {
    public void testAddListener() {
       String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.DifferentListener";
       String lisName = "Different Listener";
+      int ord = 200;
       Listener newitem = new ListenerImpl(clsName);
       newitem.setListenerName(lisName);
+      newitem.setOrdinal(ord);
       
       cut.addListener(newitem);
       
       List<Listener> list = cut.getListeners();
       assertNotNull(list);
       assertEquals(2, list.size());
-      assertEquals(clsName, list.get(1).getListenerClass());
-      assertEquals(lisName, list.get(1).getListenerName());
+      Listener testItem = list.get(1);
+      assertEquals(clsName, testItem.getListenerClass());
+      assertEquals(lisName, testItem.getListenerName());
+      assertEquals(ord, testItem.getOrdinal());
    }
 
    /**
@@ -777,16 +782,43 @@ public class PortletApplicationDefinition362ImplTest {
    public void testAddDupListener() {
       String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.TestListener";
       String lisName = "test listener";
+      int ord = 100;
       Listener newitem = new ListenerImpl(clsName);
       newitem.setListenerName(lisName);
+      newitem.setOrdinal(ord);
       
       cut.addListener(newitem);
       
       List<Listener> list = cut.getListeners();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals(clsName, list.get(0).getListenerClass());
-      assertEquals(lisName, list.get(0).getListenerName());
+      Listener testItem = list.get(0);
+
+      assertEquals(clsName, testItem.getListenerClass());
+      assertEquals(lisName, testItem.getListenerName());
+      assertEquals(ord, testItem.getOrdinal());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void testReplaceListenerClass() {
+      String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.DifferentListener";
+      String lisName = "test listener";
+      Listener newitem = new ListenerImpl(clsName);
+      newitem.setListenerName(lisName);
+      
+      cut.addListener(newitem);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      Listener testItem = list.get(0);
+
+      assertEquals(clsName, testItem.getListenerClass());
+      assertEquals(lisName, testItem.getListenerName());
+      assertEquals(0, testItem.getOrdinal());
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletListenerAnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletListenerAnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletListenerAnnotationTest.java
new file mode 100644
index 0000000..4f7459c
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/PortletListenerAnnotationTest.java
@@ -0,0 +1,237 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Listener;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ListenerImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedListener;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class PortletListenerAnnotationTest {
+   
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestAnnotatedListener.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getListener(java.lang.String)}.
+    */
+   @Test
+   public void testGetListener() {
+      String newItem = "aListener";
+      Listener item = cut.getListener(newItem);
+      assertNotNull(item);
+      Listener listener = cut.getListeners().get(0);
+      assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedListener", 
+            listener.getListenerClass());
+   }
+   
+   @Test
+   public void testListenerDescription() {
+      String newItem = "aListener";
+      Listener listener = cut.getListener(newItem);
+      assertNotNull(listener);
+      assertEquals(2, listener.getDescriptions().size());
+      assertEquals("Ein ordentlicher Listener", listener.getDescription(new Locale("de")).getText());
+      assertEquals("Quite the listener", listener.getDescription(Locale.ENGLISH).getText());
+   }
+
+   @Test
+   public void testListenerDisplayName() {
+      String newItem = "aListener";
+      Listener listener = cut.getListener(newItem);
+      assertNotNull(listener);
+      assertEquals(2, listener.getDisplayNames().size());
+      assertEquals("Ein Listener", listener.getDisplayName(Locale.GERMAN).getText());
+      assertEquals("A Listener", listener.getDisplayName(new Locale("en")).getText());
+   }
+
+   @Test
+   public void testListenerOrdinal() {
+      String newItem = "aListener";
+      Listener listener = cut.getListener(newItem);
+      assertNotNull(listener);
+      assertEquals(100, listener.getOrdinal());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getListeners()}.
+    */
+   @Test
+   public void testGetListeners() {
+      String newItem = "aListener";
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getListenerName());
+      assertEquals(100, list.get(0).getOrdinal());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void testAddListener() {
+      String newItem = "newListener";
+      Listener l = new ListenerImpl("SomeClass");
+      l.setListenerName(newItem);
+      l.setOrdinal(200);
+      cut.addListener(l);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder1() {
+      String newItem = "newListener";
+      String oldItem = "aListener";
+      Listener l = new ListenerImpl("SomeClass");
+      l.setListenerName(newItem);
+      l.setOrdinal(10);
+      cut.addListener(l);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getListenerName());
+      assertEquals(oldItem, list.get(1).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void checkListenerOrder2() {
+      String newItem = "newListener";
+      String oldItem = "aListener";
+      Listener l = new ListenerImpl("SomeClass");
+      l.setListenerName(newItem);
+      l.setOrdinal(1000);
+      cut.addListener(l);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getListenerName());
+      assertEquals(oldItem, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method to delete listener when class is null
+    */
+   @Test
+   public void deleteListener1() {
+      String oldItem = "aListener";
+      Listener l = new ListenerImpl((String)null);
+      l.setListenerName(oldItem);
+      l.setOrdinal(1000);
+      cut.addListener(l);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method to delete listener when class is empty
+    */
+   @Test
+   public void deleteListener2() {
+      String oldItem = "aListener";
+      Listener l = new ListenerImpl("");
+      l.setListenerName(oldItem);
+      l.setOrdinal(1000);
+      cut.addListener(l);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method for replacing a listener definition
+    */
+   @Test
+   public void testAddDupListener() {
+      String newItem = "aListener";
+      String clsName = "SomeClass";
+      Listener fil = new ListenerImpl(clsName);
+      fil.setListenerName(newItem);
+      cut.addListener(fil);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getListenerName());
+      assertEquals(clsName, list.get(0).getListenerClass());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterFilter.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterFilter.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterFilter.xml
new file mode 100644
index 0000000..6670706
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterFilter.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app id="id1" version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet id="id2">
+      <portlet-name>portlet1</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+   </portlet>
+   <filter>
+      <!-- delete bFilter from configuration (no filter class) -->
+      <filter-name>bFilter</filter-name>
+   </filter>
+   <filter>
+      <!-- change aFilter to use different class -->
+      <filter-name>aFilter</filter-name>
+      <filter-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter</filter-class>
+      <ordinal>-40</ordinal>
+   </filter>
+</portlet-app>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterListener.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterListener.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterListener.xml
new file mode 100644
index 0000000..e00cd2e
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterListener.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app id="id1" version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet id="id2">
+      <portlet-name>portlet1</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+   </portlet>
+   <listener>
+      <!-- delete bListener from configuration (no listener class) -->
+      <listener-name>bListener</listener-name>
+   </listener>
+   <listener>
+      <!-- change aListener to use different class -->
+      <listener-name>aListener</listener-name>
+      <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener</listener-class>
+      <ordinal>-40</ordinal>
+   </listener>
+</portlet-app>


[16/35] portals-pluto git commit: Implemented type annotations for portlet request filters, portlet URL generation listeners, and portlet preference validators. The corresponding definitions in the portlet.xml file are merged into the annotated configura

Posted by ms...@apache.org.
Implemented type annotations for portlet request filters, portlet URL
generation listeners, and portlet preference validators. The corresponding
definitions in the portlet.xml file are merged into the annotated
configuration, with values from the portlet.xml file taking precedence
over values specified in the annotations. Annotated filters, listeners and
validators can be deactivated or replaced through appropriate entries in
the portlet deployment descriptor. Added unit tests to verify the
functionality.


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

Branch: refs/heads/V3Prototype
Commit: a05e1563b0271ea58da19adb7d5a0fde9c747477
Parents: d542738
Author: Scott Nicklous <ms...@apache.org>
Authored: Wed Dec 23 15:48:04 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Wed Dec 23 15:48:04 2015 +0100

----------------------------------------------------------------------
 .../container/om/portlet/FilterMapping.java     |  53 ++--
 .../pluto/container/om/portlet/Listener.java    |   3 +
 .../portlet/PortletApplicationDefinition.java   |   1 +
 .../pluto/container/om/portlet/Preferences.java |   3 +
 .../driver/PortletContainerInitializer.java     |  10 +-
 .../om/portlet/impl/ConfigurationHolder.java    |  16 +-
 .../om/portlet/impl/ConfigurationProcessor.java |  47 +++
 .../om/portlet/impl/FilterComparator.java       |  42 +++
 .../om/portlet/impl/FilterMappingImpl.java      |   5 +
 .../impl/JSR286ConfigurationProcessor.java      |   5 +-
 .../impl/JSR362ConfigurationProcessor.java      | 239 +++++++++++++--
 .../om/portlet/impl/ListenerComparator.java     |  42 +++
 .../container/om/portlet/impl/ListenerImpl.java |  18 ++
 .../impl/PortletApplicationDefinitionImpl.java  |  56 +++-
 .../om/portlet/impl/PortletDefinitionImpl.java  |   4 +-
 .../om/portlet/impl/PreferencesImpl.java        |  18 ++
 .../fixtures/MultipleAnnotatedFilters1.java     |  83 +++++
 .../fixtures/MultipleAnnotatedFilters2.java     |  75 +++++
 .../fixtures/MultipleAnnotatedListeners1.java   |  54 ++++
 .../fixtures/MultipleAnnotatedListeners2.java   |  47 +++
 .../fixtures/TestAnnotatedFilterMultiple.java   |  94 ++++++
 .../impl/fixtures/TestAnnotatedListener.java    |  66 ++++
 .../impl/fixtures/TestAnnotatedPrefs1.java      |  46 +++
 .../impl/fixtures/TestAnnotatedPrefs2.java      |  58 ++++
 .../AlterMultipleAnnotatedFiltersTest.java      | 213 +++++++++++++
 .../AlterMultipleAnnotatedListenerTest.java     | 222 ++++++++++++++
 .../impl/jsr362/FilterMultiplePortletsTest.java | 125 ++++++++
 .../JSR362PortletFilterAnnotationTest.java      |  71 +++++
 .../impl/jsr362/MergePortletDefinitionTest.java |   5 -
 .../om/portlet/impl/jsr362/MergePrefs1Test.java | 245 +++++++++++++++
 .../om/portlet/impl/jsr362/MergePrefs2Test.java | 306 +++++++++++++++++++
 .../jsr362/MultipleAnnotatedFilterTest.java     | 212 +++++++++++++
 .../jsr362/MultipleAnnotatedListenerTest.java   | 212 +++++++++++++
 .../jsr362/MultipleAnnotatedPrefs1Test.java     |  99 ++++++
 .../jsr362/MultipleAnnotatedPrefs2Test.java     | 243 +++++++++++++++
 ...PortletApplicationDefinition362ImplTest.java |  40 ++-
 .../jsr362/PortletListenerAnnotationTest.java   | 237 ++++++++++++++
 .../om/portlet/portlet362AlterFilter.xml        |  25 ++
 .../om/portlet/portlet362AlterListener.xml      |  25 ++
 .../om/portlet/portlet362AlterValidator1.xml    |  61 ++++
 .../om/portlet/portlet362AlterValidator2.xml    |  67 ++++
 .../om/portlet/portlet362Generated.xml          |   1 +
 .../javax/portlet/annotations/Preference.java   |   9 -
 43 files changed, 3415 insertions(+), 88 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/FilterMapping.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/FilterMapping.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/FilterMapping.java
index 2c47517..705c3d6 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/FilterMapping.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/FilterMapping.java
@@ -1,27 +1,28 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.om.portlet;
-
-import java.util.List;
-
-public interface FilterMapping {
-
-	String getFilterName();
-
-	List<String> getPortletNames();
-	void addPortletName(String portletName);
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.om.portlet;
+
+import java.util.List;
+
+public interface FilterMapping {
+
+	String getFilterName();
+
+	List<String> getPortletNames();
+	void addPortletName(String portletName);
+   boolean removePortletName(String pn);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
index f507377..1d62ac0 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
@@ -34,4 +34,7 @@ public interface Listener {
    
    String getListenerName();
    void setListenerName(String listenerName);
+   
+   int getOrdinal();
+   void setOrdinal(int ordinal);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
index 6a76d15..6245850 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
@@ -94,6 +94,7 @@ public interface PortletApplicationDefinition {
    void addFilterMapping(FilterMapping fm);
    boolean removeFilterMapping(FilterMapping fm);
 
+   Listener getListener(String name);
    List<Listener> getListeners();
    void addListener(Listener listener);
    boolean removeListener(Listener listener);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Preferences.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Preferences.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Preferences.java
index 25e8393..3f1d973 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Preferences.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Preferences.java
@@ -26,4 +26,7 @@ public interface Preferences {
 
    String getPreferencesValidator();
    void setPreferencesValidator(String preferencesValidator);
+
+   boolean isNullValidator();
+   void setNullValidator(boolean isNullValidator);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index f53c045..afc574c 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -105,28 +105,30 @@ public class PortletContainerInitializer implements ServletContainerInitializer
             holder.validate();
 
             if (holder.getPad().getPortlets().size() > 0) {
+
+               ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder);
                
                // dynamically deploy the portlet servlets
                for (PortletDefinition pd : holder.getPad().getPortlets()) {
                   String pn = pd.getPortletName();
                   String mapping = PortletInvokerService.URIPREFIX + pn;
+                  String servletName = pn + "_PS3";
 
                   if (isDebug) {
                      StringBuilder txt = new StringBuilder();
-                     txt.append("Adding PortletServlet3, name: ");
+                     txt.append("Adding PortletServlet3. Portlet name: ");
                      txt.append(pn);
+                     txt.append(", servlet name: ").append(servletName);
                      txt.append(", mapping: ").append(mapping);
                      LOG.debug(txt.toString());
                   }
                   
-                  ServletRegistration.Dynamic sr = ctx.addServlet(pn + "_PS3", PortletServlet3.class);
+                  ServletRegistration.Dynamic sr = ctx.addServlet(servletName, PortletServlet3.class);
                   sr.addMapping(mapping);
                   sr.setInitParameter(PortletServlet3.PORTLET_NAME, pn);
                   sr.setLoadOnStartup(100);
 
                }
-
-               ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder);
                
             } else {
                LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
index 2595a95..9e3a18e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
@@ -25,6 +25,8 @@ import java.util.Set;
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletListener;
+import javax.portlet.annotations.PortletPreferencesValidator;
 import javax.portlet.annotations.PortletRequestFilter;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
@@ -136,7 +138,8 @@ public class ConfigurationHolder {
 
       } else if (jel.getValue() instanceof org.apache.pluto.container.om.portlet30.impl.PortletAppType) {
 
-         jcp = new JSR362ConfigurationProcessor(pad);
+         // if config processor already present, there were annotations. don't overwrite
+         jcp = (jcp == null) ? new JSR362ConfigurationProcessor(pad) : jcp;
 
       } else {
          String warning = "Unknown application type: " + jel.getValue().getClass().getCanonicalName();
@@ -212,11 +215,18 @@ public class ConfigurationHolder {
                }
             }
             
-            PortletRequestFilter prf = cls.getAnnotation(PortletRequestFilter.class);
-            if (prf != null) {
+            if (cls.getAnnotation(PortletRequestFilter.class) != null) {
                jcp.processPortletFilterAnnotation(cls);
             }
             
+            if (cls.getAnnotation(PortletListener.class) != null) {
+               jcp.processListenerAnnotation(cls);
+            }
+            
+            if (cls.getAnnotation(PortletPreferencesValidator.class) != null) {
+               jcp.processValidatorAnnotation(cls);
+            }
+            
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 6ae4208..e3932d3 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -3,6 +3,7 @@ package org.apache.pluto.container.om.portlet.impl;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.Locale;
+import java.util.Random;
 import java.util.ResourceBundle;
 
 import javax.portlet.annotations.PortletApplication;
@@ -185,6 +186,28 @@ public abstract class ConfigurationProcessor {
    }
    
    /**
+    * Generates a unique name for use in cases where the item is ordered by name, but the name 
+    * is optional to from the point of view of the portlet developer. For example, the filter name
+    * need not be specified in the filter annotation, but if it is, the filter config can be
+    * modified through a corresponding specification in the portlet deployment descriptor.
+    * 
+    * @return
+    */
+   protected String genUniqueName() {
+     
+      // create random name
+      final String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZüÜäÄöÖß";
+      StringBuilder txt = new StringBuilder(128);
+      txt.append("Generated:");
+      Random rand = new Random();
+      for (int ii = 0; ii < 32; ii++) {
+         txt.append(chars.charAt(rand.nextInt(chars.length())));
+      }
+      return txt.toString();
+
+   }
+   
+   /**
     * Reads web app deployment descriptor to extract the locale - encoding mappings 
     * 
     * @param in            Input stream for DD
@@ -271,4 +294,28 @@ public abstract class ConfigurationProcessor {
       // default impl = do nothing
    }
 
+   /**
+    * Extracts the data from the portlet annotation and adds it to a 
+    * portlet listener definition structure. The portlet listener definition will be created if it does not
+    * already exist.
+    * <p>
+    * The default method implementation does nothing. The V3 implementation will
+    * override this method to provide function.  
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor
+    * is read so that data from the portlet DD can override that provided through annotations.
+    * 
+    * @param cls
+    */
+   public void processListenerAnnotation(Class<?> cls) {
+   }
+
+   /**
+    * Processes PortletPreferencesValidator annotated classes.
+    * 
+    * @param cls
+    */
+   public void processValidatorAnnotation(Class<?> cls) {
+   }
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterComparator.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterComparator.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterComparator.java
new file mode 100644
index 0000000..1f9e89f
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterComparator.java
@@ -0,0 +1,42 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional infooation
+ *  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 peoissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl;
+
+import java.util.Comparator;
+
+import org.apache.pluto.container.om.portlet.Filter;
+
+
+/**
+ * Simple comparator based on the filter ordinal number. used for ordering
+ * filter execution properly.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+public class FilterComparator implements Comparator<Filter> {
+
+   @Override
+   public int compare(Filter o1, Filter o2) {
+      assert (o1 != null) && (o2 != null);
+      return Integer.compare(o1.getOrdinal(), o2.getOrdinal());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
index c727ebc..445aa3c 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
@@ -74,6 +74,11 @@ public class FilterMappingImpl implements FilterMapping {
    public void addPortletName(String portletName) {
       portletNames.add(portletName);
    }
+   
+   @Override
+   public boolean removePortletName(String pn) {
+      return portletNames.remove(pn);
+   }
 
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
index b466e3d..c48c429 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
@@ -958,13 +958,14 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          
          // check the portlet preferences validator class
          Preferences prefs = portlet.getPortletPreferences();
-         if (prefs != null && prefs.getPreferencesValidator() != null) {
             String clsName = prefs.getPreferencesValidator();
+         if (prefs != null && clsName != null) {
             try {
             checkValidClass(clsName, PreferencesValidator.class,
                   "Bad portlet preferences validator class: ");
             } catch (Exception e) {
-               portlet.setPortletPreferences(null);
+               prefs.setPreferencesValidator(null);
+               portlet.setPortletPreferences(prefs);
             }
          }
          

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index a60a6f0..4ee9954 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -20,16 +20,21 @@ package org.apache.pluto.container.om.portlet.impl;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
-import java.util.Random;
+import java.util.Map;
 
 import javax.portlet.Portlet;
 import javax.portlet.PortletRequest;
+import javax.portlet.PortletURLGenerationListener;
+import javax.portlet.PreferencesValidator;
 import javax.portlet.annotations.InitParameter;
 import javax.portlet.annotations.LocaleString;
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletListener;
+import javax.portlet.annotations.PortletPreferencesValidator;
 import javax.portlet.annotations.PortletRequestFilter;
 import javax.portlet.annotations.PublicRenderParameterDefinition;
 import javax.portlet.annotations.RuntimeOption;
@@ -46,9 +51,9 @@ import javax.xml.namespace.QName;
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
 import org.apache.pluto.container.om.portlet.CustomPortletMode;
 import org.apache.pluto.container.om.portlet.CustomWindowState;
+import org.apache.pluto.container.om.portlet.Dependency;
 import org.apache.pluto.container.om.portlet.Description;
 import org.apache.pluto.container.om.portlet.DisplayName;
-import org.apache.pluto.container.om.portlet.Dependency;
 import org.apache.pluto.container.om.portlet.EventDefinition;
 import org.apache.pluto.container.om.portlet.EventDefinitionReference;
 import org.apache.pluto.container.om.portlet.Filter;
@@ -109,6 +114,11 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
    // private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean isTrace = LOG.isTraceEnabled();
 
+   // For holding the preference validators while the portlet configuration
+   // annotations are being processed.
+   private Map<PortletPreferencesValidator, String> prefValidators =
+         new HashMap<PortletPreferencesValidator, String>();
+
    public JSR362ConfigurationProcessor(PortletApplicationDefinition pad) {
       super(pad);
    }
@@ -254,15 +264,32 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
    private void handleFilters(List<FilterType> args) {
       for (FilterType item : args) {
 
-         // validate data
-         if ((item.getFilterName() == null) || (item.getFilterName().length() == 0) || (item.getFilterClass() == null)
-               || (item.getFilterClass().length() == 0)) {
-            String warning = "Bad Filter definition. name or class was null.";
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
+         // Filter name may not be empty
+         String fn = item.getFilterName();
+         if (fn == null || fn.length() == 0) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Bad Filter definition.");
+            txt.append(" Filter name is empty. ");
+            txt.append(", Filter class: ").append(item.getFilterClass());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+         
+         // Filter class may only be empty if an annotated filter of that name
+         // is already present
+         String fc = item.getFilterClass();
+         if (pad.getFilter(fn) == null) {
+            if ((fc == null) || (fc.length() == 0)) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("Bad Filter definition.");
+               txt.append(" Filter name: ").append(item.getFilterName());
+               txt.append(", Filter class is empty.");
+               LOG.warn(txt.toString());
+               throw new IllegalArgumentException(txt.toString());
+            }
          }
 
-         // set up the custom portlet mode
+         // set up the filter config
          Filter newitem = new FilterImpl(item.getFilterName());
          newitem.setFilterClass(item.getFilterClass());
          for (InitParam ip : handleInitParam(item.getInitParam())) {
@@ -277,6 +304,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          for (DisplayName dispName : handleDisplayNames(item.getDisplayName())) {
             newitem.addDisplayName(dispName);
          }
+         newitem.setOrdinal((item.getOrdinal() == null) ? 0 : item.getOrdinal());
 
          // add it to the model
          pad.addFilter(newitem);
@@ -316,19 +344,24 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
    private void handleListeners(List<ListenerType> args) {
       for (ListenerType item : args) {
 
-         // validate data
+         String name = item.getListenerName();
+
+         // validate data. Empty class allowed if annotated config present
+         if ((name == null) || (name.length() == 0) || (pad.getListener(name) == null)) {
          if (item.getListenerClass() == null || item.getListenerClass().length() == 0) {
             String warning = "Bad Listener definition. Class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
+         }
          
+         if (name == null || name.length() == 0) {
+            name = genUniqueName();
+         }
 
          // set up the listener
          Listener newitem = new ListenerImpl(item.getListenerClass());
-         if (item.getListenerName() != null) {
-            newitem.setListenerName(item.getListenerName());
-         }
+         
          for (Description desc : handleDescriptions(item.getDescription())) {
             newitem.addDescription(desc);
          }
@@ -336,6 +369,10 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             newitem.addDisplayName(dispName);
          }
 
+         newitem.setOrdinal((item.getOrdinal() == null) ? 0 : item.getOrdinal());
+
+         newitem.setListenerName(name);
+
          // add it to the model
          pad.addListener(newitem);
 
@@ -695,7 +732,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          if (pd == null) {
             // If no annotated definition, the class name must be present
             if (clsName == null || clsName.length() == 0) {
-               warning = "Portlet class may not be null";
+               warning = "Portlet class may not be null. Portlet name: " + pn;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
             }
@@ -768,16 +805,22 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
             // merge the new prefs with the old
             Preferences newprefs = pd.getPortletPreferences();
-            if (newprefs == null) {
-               newprefs = new PreferencesImpl();
-            }
 
             clsName = prefs.getPreferencesValidator();
+            if (clsName != null && clsName.length() > 0) {
+               if (clsName.equals("null")) {
+                  // marks that an annotated preferences validator should not be 
+                  // applied to this portlet
+                  newprefs.setNullValidator(true);
+               } else {
+                  newprefs.setPreferencesValidator(clsName);
+               }
+            }
 
-            newprefs.setPreferencesValidator(clsName);
             for (Preference p : handlePreferences(prefs.getPreference())) {
                newprefs.addPreference(p);
             }
+            
             pd.setPortletPreferences(newprefs);
          }
 
@@ -833,6 +876,81 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
     * validate the v3.0 configuration
     */
    public void validate() {
+      
+      // If the filter mapping portlet names element contains a single '*', expand
+      // the portlet names into a list of all portlet names in the application.
+      for (FilterMapping fm : pad.getFilterMappings()) {
+         if (fm.getPortletNames().size() == 1) {
+            if (fm.getPortletNames().get(0).equals("*")) {
+               fm.removePortletName("*");
+               for (PortletDefinition pd : pad.getPortlets()) {
+                  fm.addPortletName(pd.getPortletName());
+               }
+               pad.addFilterMapping(fm);
+            }
+         }
+      }
+      
+      // Apply the stored annotated preference validators to the
+      // portlet definitions
+      
+      for (PortletPreferencesValidator vali : prefValidators.keySet()) {
+         String[] pns = vali.portletNames();
+         String clsName = prefValidators.get(vali);
+
+         if ((pns.length > 0) && pns[0].equals("*")) {
+            
+            for (PortletDefinition pd : pad.getPortlets()) {
+               
+               // If a preferences validator is already configured, it had to have
+               // come from the portlet DD, so don't overwrite.
+               
+               Preferences prefs = pd.getPortletPreferences();
+               String oldVali = prefs.getPreferencesValidator();
+               if (oldVali == null || oldVali.length() == 0) {
+                  // If the validator was explicitly set to null in the
+                  // deployment descriptor, don't apply annotated validator
+                  if (!prefs.isNullValidator()) {
+                     prefs.setPreferencesValidator(clsName);
+                     pd.setPortletPreferences(prefs);
+                     pad.addPortlet(pd);
+                  }
+               }
+               
+            }
+            
+         } else {
+            for (String pn : pns) {
+               PortletDefinition pd = pad.getPortlet(pn);
+               
+               if (pd == null) {
+                  StringBuilder txt = new StringBuilder(128);
+                  txt.append("Portlet name defined in preferences validator annotation could not be found in configuration.");
+                  txt.append(" Portlet name: ").append(pn);
+                  txt.append(" Preferences validator class: ").append(clsName);
+                  LOG.warn(txt.toString());
+                  continue;
+               }
+               
+               // If a preferences validator is already configured, it had to have
+               // come from the portlet DD, so don't overwrite.
+               
+               Preferences prefs = pd.getPortletPreferences();
+               String oldVali = prefs.getPreferencesValidator();
+               if (oldVali == null || oldVali.length() == 0) {
+                  // If the validator was explicitly set to null in the
+                  // deployment descriptor, don't apply annotated validator
+                  if (!prefs.isNullValidator()) {
+                     prefs.setPreferencesValidator(clsName);
+                     pd.setPortletPreferences(prefs);
+                     pad.addPortlet(pd);
+                  }
+               }
+               
+            }
+         }
+      }
+      
       super.validate(); // reuse the 2.0 validation code
    }
 
@@ -977,14 +1095,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          String clsName = cls.getCanonicalName();
          String fn = prf.filterName();
          if (fn.length() == 0) {
-            // create random name
-            final String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZüÜäÄöÖß";
-            StringBuilder txt = new StringBuilder(128);
-            Random rand = new Random();
-            for (int ii = 0; ii < 32; ii++) {
-               txt.append(chars.charAt(rand.nextInt(chars.length())));
-            }
-            fn = "Generated " + txt.toString();
+            fn = genUniqueName();
          }
          if (isTrace) {
             LOG.trace("Adding filter named: " + fn);
@@ -993,7 +1104,8 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          if (pad.getFilter(fn) != null) {
             StringBuilder txt = new StringBuilder(128);
             txt.append("Duplicate filter annotation. FilterName: ").append(fn);
-            txt.append(", class: ").append(cls.getCanonicalName());
+            txt.append(", class 1: ").append(cls.getCanonicalName());
+            txt.append(", class 2: ").append(pad.getFilter(fn).getFilterClass());
             LOG.warn(txt.toString());
             throw new IllegalArgumentException(txt.toString());
          }
@@ -1035,6 +1147,79 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
       }
    }
+   
+   @Override
+   public void processListenerAnnotation(Class<?> cls) {
+      
+      PortletListener listener = cls.getAnnotation(PortletListener.class);
+      if (listener != null) {
+
+         if (!PortletURLGenerationListener.class.isAssignableFrom(cls)) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("@PortletListener annotated class must implement PortletURLGenerationListener interface. ");
+            txt.append(", class: ").append(cls.getCanonicalName());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+ 
+         String clsName = cls.getCanonicalName();
+         String name = listener.listenerName();
+         if (name.length() == 0) {
+            name = genUniqueName();
+         }
+
+         if (pad.getListener(name) != null) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Duplicate listener annotation. Listener name: ").append(name);
+            txt.append(", class 1: ").append(clsName);
+            txt.append(", class 2: ").append(pad.getListener(name).getListenerClass());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+         
+         Listener newItem = new ListenerImpl(clsName);
+         newItem.setListenerName(name);
+         newItem.setOrdinal(listener.ordinal());
+
+         for (LocaleString ls : listener.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            newItem.addDescription(d);
+         }
+         for (LocaleString ls : listener.displayName()) {
+            DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            newItem.addDisplayName(d);
+         }
+         
+         pad.addListener(newItem);
+
+      }
+   }
+   
+   /**
+    * Processes PortletPreferencesValidator annotated classes. The preferences 
+    * validators are temorarily stored while the portlet configuration annotations
+    * are being processed. 
+    * 
+    * @param cls  The annotated class
+    */
+   @Override 
+   public void processValidatorAnnotation(Class<?> cls) {
+      
+      PortletPreferencesValidator vali = cls.getAnnotation(PortletPreferencesValidator.class);
+      if (vali != null) {
+
+         if (!PreferencesValidator.class.isAssignableFrom(cls)) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("@PortletPreferencesValidator annotated class must implement PreferencesValidator interface. ");
+            txt.append(", class: ").append(cls.getCanonicalName());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+ 
+         String clsName = cls.getCanonicalName();
+         prefValidators.put(vali, clsName);
+      }
+   }
 
    /**
     * Extracts the data from the portlet annotation and adds it to a portlet definition structure. The portlet

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerComparator.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerComparator.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerComparator.java
new file mode 100644
index 0000000..7df62f5
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerComparator.java
@@ -0,0 +1,42 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional infooation
+ *  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 peoissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl;
+
+import java.util.Comparator;
+
+import org.apache.pluto.container.om.portlet.Listener;
+
+
+/**
+ * Simple comparator based on the Listener ordinal number. used for ordering
+ * Listener execution properly.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+public class ListenerComparator implements Comparator<Listener> {
+
+   @Override
+   public int compare(Listener o1, Listener o2) {
+      assert (o1 != null) && (o2 != null);
+      return Integer.compare(o1.getOrdinal(), o2.getOrdinal());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
index 335fb1e..0790323 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
@@ -38,6 +38,7 @@ public class ListenerImpl implements Listener {
    private final List<DisplayName> dispNames = new ArrayList<DisplayName>();
    private String listenerClass = "";
    private String listenerName = "";
+   private int ordinal = 0;
 
    
    /**
@@ -54,6 +55,7 @@ public class ListenerImpl implements Listener {
       }
       listenerClass = lis.getListenerClass();
       listenerName = lis.getListenerName();
+      ordinal = lis.getOrdinal();
    }
    
    /**
@@ -156,6 +158,22 @@ public class ListenerImpl implements Listener {
       this.listenerName = listenerName;
    }
 
+   /**
+    * @return the ordinal
+    */
+   @Override
+   public int getOrdinal() {
+      return ordinal;
+   }
+
+   /**
+    * @param ordinal the ordinal to set
+    */
+   @Override
+   public void setOrdinal(int ordinal) {
+      this.ordinal = ordinal;
+   }
+
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
index 48fdb99..722d5c2 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
@@ -20,6 +20,7 @@
 package org.apache.pluto.container.om.portlet.impl;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -56,7 +57,7 @@ public class PortletApplicationDefinitionImpl implements
    private String id;
    private String name;
    private String contextPath;
-   private String version;
+   private String version = "3.0";
    private String resourceBundle;
    private String defaultNamespace;
    
@@ -73,8 +74,8 @@ public class PortletApplicationDefinitionImpl implements
    // for the locale - encoding mappings from the web.xml
    private final Map<Locale, String> localemap = new HashMap<Locale, String>();
    
-   private final ArrayList<Listener> listeners = new ArrayList<Listener>();
-   private final ArrayList<SecurityConstraint> constraints = new ArrayList<SecurityConstraint>();
+   private final List<Listener> listeners = new ArrayList<Listener>();
+   private final List<SecurityConstraint> constraints = new ArrayList<SecurityConstraint>();
 
    /**
     * Default constructor
@@ -472,13 +473,22 @@ public class PortletApplicationDefinitionImpl implements
    @Override
    public void addFilter(Filter filter) {
       // If the filter class is null, remove the filter definition, otherwise replace it
-      if (filters.remove(filter)) {
+      boolean removed = filters.remove(filter);
+      
+      if (removed) {
          LOG.debug("Removed duplicate filter definition: " + filter.getFilterName());
       } 
+      
+      // If a filter class is present, add the new one. Otherwise, if the filter was
+      // removed, get rid of the filter mapping as well.
       if (filter.getFilterClass() != null && filter.getFilterClass().length() > 0) {
          filters.add(filter);
+         // sort by ordinal. for JSR286 portlets, the ordinal will always be 0, so
+         // the list will remain in the original order.
+         Collections.sort(filters, new FilterComparator());
       } else {
-         LOG.debug("No filter class for filter: " + filter.getFilterName());
+         LOG.debug("No filter class for filter. Deleting filter mapping. filter name: " + filter.getFilterName());
+         removeFilterMapping(getFilterMapping(filter.getFilterName()));
       }
    }
    
@@ -559,6 +569,16 @@ public class PortletApplicationDefinitionImpl implements
    }
 
    @Override
+   public Listener getListener(String name) {
+      for (Listener l : listeners) {
+         if (l.getListenerName().equals(name)) {
+            return new ListenerImpl(l);
+         }
+      }
+      return null;
+   }
+
+   @Override
    public List<Listener> getListeners() {
       ArrayList<Listener> list = new ArrayList<Listener>();
       for (Listener l : listeners) {
@@ -569,10 +589,34 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addListener(Listener listener) {
+      
+      // Remove the listener if already present. This is based on the listener class
+      // for JSR 286 portlets and on the listener name for JSR 362 portlets
+
+      if (version.equals("3.0")) {
+         for (int ii = 0; ii < listeners.size(); ii++) {
+            if (listeners.get(ii).getListenerName().equals(listener.getListenerName())) {
+               listeners.remove(ii);
+               LOG.debug("Removed duplicate listener with name: " + listener.getListenerName());
+               break;
+            }
+         }
+      } else {
+
+         // If the listener class is null, remove the listener definition, otherwise replace it
       if (listeners.remove(listener)) {
-         LOG.debug("Removed duplicate listener: " + listener.getListenerClass());
+            LOG.debug("Removed duplicate listener for class: " + listener.getListenerClass());
       }
+      } 
+      
+      if (listener.getListenerClass() != null && listener.getListenerClass().length() > 0) {
       listeners.add(listener);
+         // sort by ordinal. for JSR286 portlets, the ordinal will always be 0, so
+         // the list will remain in the original order.
+         Collections.sort(listeners, new ListenerComparator());
+      } else {
+         LOG.debug("No listener class for listener: " + listener.getListenerName());
+      }
    }
    
    @Override

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
index 7708180..c69f48f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
@@ -57,7 +57,7 @@ public class PortletDefinitionImpl implements PortletDefinition {
    private int expirationCache;
    
    private PortletInfo info;
-   private Preferences prefs;
+   private Preferences prefs = new PreferencesImpl();
    
    private final List<String> supportedLocales = new ArrayList<String>();
    private final List<String> pubParms = new ArrayList<String>();
@@ -233,7 +233,7 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public Preferences getPortletPreferences() {
-      return (prefs != null) ? new PreferencesImpl(prefs) : null;
+      return new PreferencesImpl(prefs);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PreferencesImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PreferencesImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PreferencesImpl.java
index 9ad60f1..3216996 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PreferencesImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PreferencesImpl.java
@@ -35,6 +35,7 @@ public class PreferencesImpl implements Preferences {
    
    private final Map<String, Preference> prefs = new HashMap<String, Preference>();
    private String prefVal;
+   private boolean isNullValidator = false;
 
    /**
     * Default constructor
@@ -51,6 +52,7 @@ public class PreferencesImpl implements Preferences {
          prefs.put(pref.getName(), new PreferenceImpl(pref));
       }
       prefVal = pr.getPreferencesValidator();
+      isNullValidator = pr.isNullValidator();
    }
 
    /* (non-Javadoc)
@@ -99,4 +101,20 @@ public class PreferencesImpl implements Preferences {
       prefVal = preferencesValidator;
    }
 
+   /**
+    * @return the isNullValidator
+    */
+   @Override
+   public boolean isNullValidator() {
+      return isNullValidator;
+   }
+
+   /**
+    * @param isNullValidator the isNullValidator to set
+    */
+   @Override
+   public void setNullValidator(boolean isNullValidator) {
+      this.isNullValidator = isNullValidator;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters1.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters1.java
new file mode 100644
index 0000000..caefb6f
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters1.java
@@ -0,0 +1,83 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import java.io.IOException;
+
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletRequestFilter;
+import javax.portlet.filter.FilterChain;
+import javax.portlet.filter.FilterConfig;
+import javax.portlet.filter.HeaderFilter;
+import javax.portlet.filter.HeaderFilterChain;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
+
+/**
+ * Test filter annotation with portletNames = '*', meaning that it applies
+ * to all portlets in the portlet app. 
+ *
+ */
+@PortletConfigurations({
+   @PortletConfiguration(portletName = "portlet1"),
+   @PortletConfiguration(portletName = "portlet2"),
+   @PortletConfiguration(portletName = "portlet3")
+})
+@PortletRequestFilter(portletNames = {"*"}, 
+                      ordinal = 100,
+                      filterName = "aFilter")
+public class MultipleAnnotatedFilters1 implements RenderFilter,
+      ResourceFilter, HeaderFilter {
+
+   @Override
+   public void init(FilterConfig filterConfig) throws PortletException {
+   }
+
+   @Override
+   public void destroy() {
+   }
+
+   @Override
+   public void doFilter(ResourceRequest request, ResourceResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(RenderRequest request, RenderResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(HeaderRequest request, HeaderResponse response, HeaderFilterChain chain) throws IOException,
+         PortletException {
+      
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters2.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters2.java
new file mode 100644
index 0000000..6f58876
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedFilters2.java
@@ -0,0 +1,75 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import java.io.IOException;
+
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.PortletRequestFilter;
+import javax.portlet.filter.FilterChain;
+import javax.portlet.filter.FilterConfig;
+import javax.portlet.filter.HeaderFilter;
+import javax.portlet.filter.HeaderFilterChain;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
+
+/**
+ * Test filter annotation with portletNames = '*', meaning that it applies
+ * to all portlets in the portlet app. 
+ *
+ */
+@PortletRequestFilter(ordinal = -100,
+                      filterName = "bFilter")
+public class MultipleAnnotatedFilters2 implements RenderFilter,
+      ResourceFilter, HeaderFilter {
+
+   @Override
+   public void init(FilterConfig filterConfig) throws PortletException {
+   }
+
+   @Override
+   public void destroy() {
+   }
+
+   @Override
+   public void doFilter(ResourceRequest request, ResourceResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(RenderRequest request, RenderResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(HeaderRequest request, HeaderResponse response, HeaderFilterChain chain) throws IOException,
+         PortletException {
+      
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners1.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners1.java
new file mode 100644
index 0000000..a9a473a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners1.java
@@ -0,0 +1,54 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.ActionURL;
+import javax.portlet.PortletURLGenerationListener;
+import javax.portlet.RenderURL;
+import javax.portlet.ResourceURL;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletListener;
+
+/**
+ * Test Listener annotation  
+ *
+ */
+@PortletConfigurations({
+   @PortletConfiguration(portletName = "portlet1"),
+   @PortletConfiguration(portletName = "portlet2"),
+   @PortletConfiguration(portletName = "portlet3")
+})
+@PortletListener(ordinal = 100, listenerName = "aListener")
+public class MultipleAnnotatedListeners1 implements PortletURLGenerationListener<RenderURL, ActionURL> {
+
+   @Override
+   public void filterActionURL(ActionURL arg0) {
+   }
+
+   @Override
+   public void filterRenderURL(RenderURL arg0) {
+   }
+
+   @Override
+   public void filterResourceURL(ResourceURL arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners2.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners2.java
new file mode 100644
index 0000000..278be92
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/MultipleAnnotatedListeners2.java
@@ -0,0 +1,47 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.ActionURL;
+import javax.portlet.PortletURLGenerationListener;
+import javax.portlet.RenderURL;
+import javax.portlet.ResourceURL;
+import javax.portlet.annotations.PortletListener;
+
+/**
+ * Test Listener annotation 
+ *
+ */
+@PortletListener(ordinal = -100, listenerName = "bListener")
+public class MultipleAnnotatedListeners2 implements PortletURLGenerationListener<RenderURL, ActionURL> {
+
+   @Override
+   public void filterActionURL(ActionURL arg0) {
+   }
+
+   @Override
+   public void filterRenderURL(RenderURL arg0) {
+   }
+
+   @Override
+   public void filterResourceURL(ResourceURL arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilterMultiple.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilterMultiple.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilterMultiple.java
new file mode 100644
index 0000000..46d9fe3
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilterMultiple.java
@@ -0,0 +1,94 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import java.io.IOException;
+
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletRequestFilter;
+import javax.portlet.filter.FilterChain;
+import javax.portlet.filter.FilterConfig;
+import javax.portlet.filter.HeaderFilter;
+import javax.portlet.filter.HeaderFilterChain;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
+
+/**
+ * Test filter annotation with portletNames = '*', meaning that it applies
+ * to all portlets in the portlet app. 
+ *
+ */
+@PortletConfigurations({
+   @PortletConfiguration(portletName = "portlet1"),
+   @PortletConfiguration(portletName = "portlet2"),
+   @PortletConfiguration(portletName = "portlet3")
+})
+@PortletRequestFilter(portletNames = {"*"}, 
+                      ordinal = 100,
+                      filterName = "aFilter",
+                      initParams = {
+                         @InitParameter(name = "execute", value = "true"),
+                         @InitParameter(name = "id", value = "ego")},
+                      description = {
+                         @LocaleString("Quite the filter"),
+                         @LocaleString(locale="DE", value = "Ein ordentlicher Filter")},
+                      displayName = {
+                         @LocaleString("A Filter"),
+                         @LocaleString(locale="DE", value = "Ein Filter")})
+public class TestAnnotatedFilterMultiple implements RenderFilter,
+      ResourceFilter, HeaderFilter {
+
+   @Override
+   public void init(FilterConfig filterConfig) throws PortletException {
+   }
+
+   @Override
+   public void destroy() {
+   }
+
+   @Override
+   public void doFilter(ResourceRequest request, ResourceResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(RenderRequest request, RenderResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(HeaderRequest request, HeaderResponse response, HeaderFilterChain chain) throws IOException,
+         PortletException {
+      
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedListener.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedListener.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedListener.java
new file mode 100644
index 0000000..043e0dc
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedListener.java
@@ -0,0 +1,66 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.ActionURL;
+import javax.portlet.PortletURLGenerationListener;
+import javax.portlet.RenderURL;
+import javax.portlet.ResourceURL;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletListener;
+
+/**
+ * Annotated listener for unit testing.
+ * @author Scott Nicklous
+ */
+
+@PortletListener(ordinal = 100,
+listenerName = "aListener",
+description = {
+   @LocaleString("Quite the listener"),
+   @LocaleString(locale="DE", value = "Ein ordentlicher Listener")},
+displayName = {
+   @LocaleString("A Listener"),
+   @LocaleString(locale="DE", value = "Ein Listener")})
+public class  TestAnnotatedListener implements
+      PortletURLGenerationListener<RenderURL, ActionURL> {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletURLGenerationListener#filterActionURL(javax.portlet.PortletURL)
+    */
+   @Override
+   public void filterActionURL(ActionURL arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletURLGenerationListener#filterRenderURL(javax.portlet.PortletURL)
+    */
+   @Override
+   public void filterRenderURL(RenderURL arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletURLGenerationListener#filterResourceURL(javax.portlet.ResourceURL)
+    */
+   @Override
+   public void filterResourceURL(ResourceURL arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs1.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs1.java
new file mode 100644
index 0000000..eb04c63
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs1.java
@@ -0,0 +1,46 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ValidatorException;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletPreferencesValidator;
+
+/**
+ * Test for Portlet Preferences Validator annotation  
+ *
+ */
+@PortletConfigurations({
+   @PortletConfiguration(portletName = "portlet1"),
+   @PortletConfiguration(portletName = "portlet2"),
+   @PortletConfiguration(portletName = "portlet3")
+})
+
+// No portlet names specified, so validator should apply to all portlets in the app
+@PortletPreferencesValidator
+public class TestAnnotatedPrefs1 implements PreferencesValidator {
+
+   @Override
+   public void validate(PortletPreferences arg0) throws ValidatorException {
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs2.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs2.java
new file mode 100644
index 0000000..9ffc524
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPrefs2.java
@@ -0,0 +1,58 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ValidatorException;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletPreferencesValidator;
+import javax.portlet.annotations.Preference;
+
+/**
+ * Test for Portlet Preferences Validator annotation  
+ *
+ */
+@PortletConfigurations({
+   @PortletConfiguration(portletName = "portlet1", prefs= {
+         @Preference(name="aPref", values="aValue"),
+         @Preference(name="bPref", values="bValue")
+   }),
+   @PortletConfiguration(portletName = "portlet2", prefs = {
+         @Preference(name="aPref", values="aValue", isReadOnly = true),
+         @Preference(name="bPref", values= {"bValue", "cValue"}, isReadOnly = false)
+   }),
+   @PortletConfiguration(portletName = "portlet3", prefs = {
+         @Preference(name="aPref", values="aValue", isReadOnly = true),
+   }),
+   @PortletConfiguration(portletName = "portlet5", prefs = {
+         @Preference(name="aPref", values="aValue", isReadOnly = true),
+   })
+})
+
+// validator applies to portlets 1, 3, & 5 only
+@PortletPreferencesValidator(portletNames= {"portlet1", "portlet3", "portlet5"})
+public class TestAnnotatedPrefs2 implements PreferencesValidator {
+
+   @Override
+   public void validate(PortletPreferences arg0) throws ValidatorException {
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedFiltersTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedFiltersTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedFiltersTest.java
new file mode 100644
index 0000000..3f7335f
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/AlterMultipleAnnotatedFiltersTest.java
@@ -0,0 +1,213 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Filter;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.FilterImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedFilters1;
+import org.apache.pluto.container.om.portlet.impl.fixtures.MultipleAnnotatedFilters2;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class AlterMultipleAnnotatedFiltersTest {
+   
+   // defines both some portlets and a filter
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = MultipleAnnotatedFilters1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = MultipleAnnotatedFilters2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362AlterFilter.xml";
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);
+         try {
+            cfp.validate();         // validate to expand the filter mapping portlet names
+         } catch (Exception e) {}   // ignore any validation problems.
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilter() {
+      String fn1 = "aFilter";
+      String fn2 = "bFilter";
+      Filter fil1 = cut.getFilter(fn1);
+      assertNotNull(fil1);
+      assertEquals(-40, fil1.getOrdinal());
+      Filter fil2 = cut.getFilter(fn2);
+      assertNull(fil2);
+      assertEquals(TestFilter.class.getCanonicalName(), fil1.getFilterClass());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddFilter() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(-101);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+      assertEquals(oldItem1, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void checkFilterOrder1() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+      assertEquals(oldItem1, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void checkFilterOrder2() {
+      String newItem = "newFilter";
+      String oldItem1 = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      fil.setOrdinal(0);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+      assertEquals(oldItem1, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter1() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass(null);
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void deleteFilter2() {
+      String oldItem = "aFilter";
+      Filter fil = new FilterImpl(oldItem);
+      fil.setFilterClass("");
+      fil.setOrdinal(1000);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   @Test
+   public void testAddDupFilter() {
+      String fn = "aFilter";
+      String fc = "SomeClass";
+      Filter fil = new FilterImpl(fn);
+      fil.setFilterClass(fc);
+      fil.setOrdinal(200);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(fn, list.get(0).getFilterName());
+      assertEquals(fc, list.get(0).getFilterClass());
+   }
+
+}


[33/35] portals-pluto git commit: Adapted V3 demo portlets to use annotated config. Fix a bug reading web DD

Posted by ms...@apache.org.
Adapted V3 demo portlets to use annotated config. Fix a bug reading web DD


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

Branch: refs/heads/V3Prototype
Commit: 43d2208eed1733f70484016a3879701bdf960064
Parents: abee379
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Jan 15 17:57:17 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Jan 15 17:57:17 2016 +0100

----------------------------------------------------------------------
 .../java/basic/portlet/ColorSelPortlet.java     | 48 +++++++++++------
 .../java/basic/portlet/ImageSelPortlet.java     |  4 +-
 .../java/basic/portlet/MessageBoxPortlet.java   | 26 ++++++---
 .../java/basic/portlet/ResourcePortlet.java     |  6 +--
 .../src/main/webapp/WEB-INF/portlet.xml         | 55 --------------------
 .../main/java/basic/portlet/AuthSCPortlet.java  |  2 +-
 .../java/basic/portlet/ColorSelPortlet.java     | 15 +++---
 .../main/java/basic/portlet/HeaderPortlet.java  |  4 ++
 .../java/basic/portlet/ImageSelPortlet.java     |  2 +-
 .../java/basic/portlet/MessageBoxPortlet.java   |  2 +-
 .../basic/portlet/PortletConfigPortlet.java     |  2 +-
 .../java/basic/portlet/RedirectPortlet.java     |  2 +
 .../java/basic/portlet/ResourcePortlet.java     |  2 +-
 .../main/java/basic/portlet/UrlTestPortlet.java |  2 +-
 .../src/main/webapp/WEB-INF/portlet.xml         | 29 -----------
 .../org/apache/pluto/container/HeaderData.java  |  5 +-
 .../container/impl/PortletRequestImpl.java      |  2 +-
 .../om/portlet/impl/ConfigurationProcessor.java | 16 ++++++
 .../impl/JSR362ConfigurationProcessor.java      |  7 ++-
 .../driver/url/PortletParameterFactory.java     |  5 +-
 20 files changed, 102 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
index e66e1cc..4e3445b 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ColorSelPortlet.java
@@ -18,12 +18,17 @@
 
 package basic.portlet;
 
-import static basic.portlet.Constants.*;
+import static basic.portlet.Constants.DELIM;
+import static basic.portlet.Constants.PARAM_FG_BLUE;
+import static basic.portlet.Constants.PARAM_FG_COLOR;
+import static basic.portlet.Constants.PARAM_FG_GREEN;
+import static basic.portlet.Constants.PARAM_FG_RED;
+import static basic.portlet.Constants.PARAM_MSG_INPUT;
+import static basic.portlet.Constants.PARAM_SUBTYPE;
 
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Enumeration;
-import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -31,18 +36,24 @@ import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
 import javax.portlet.GenericPortlet;
 import javax.portlet.PortletException;
-import javax.portlet.PortletRequest;
+import javax.portlet.PortletParameters;
 import javax.portlet.PortletRequestDispatcher;
 import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletQName;
 import javax.xml.namespace.QName;
 
 
 /**
- * A management portlet that displays the current deep link configuration
+ * An example color selection portlet that uses the portlet hub.
  */
+@PortletConfiguration(portletName = "ColorSelPortlet", publicParams = "color", 
+                      title = @LocaleString("PH Color Selection Portlet"))
 public class ColorSelPortlet extends GenericPortlet {
 
    // Set up logging
@@ -73,12 +84,16 @@ public class ColorSelPortlet extends GenericPortlet {
          throws PortletException, IOException {
    }
 
+   @ActionMethod(portletName="ColorSelPortlet", publishingEvents= {
+         @PortletQName(namespaceURI="http://www.apache.org/portals/pluto/ResourcePortlet", localPart="Message")
+   })
    public void processAction(ActionRequest req, ActionResponse resp)
          throws PortletException, IOException {
             
-      dumpParameters(req);
+      dumpParameters("Action", req.getActionParameters());
+      dumpParameters("Render", req.getRenderParameters());
       
-      String[] vals = req.getParameterValues(PARAM_FG_COLOR);
+      String[] vals = req.getActionParameters().getValues(PARAM_FG_COLOR);
       String r = "0";
       String g = "0";
       String b = "0";
@@ -94,17 +109,17 @@ public class ColorSelPortlet extends GenericPortlet {
       // make sure the private parameter are all on the URL for 
       // potential back button support
       if (vals != null) {
-         resp.setRenderParameter(PARAM_FG_COLOR, vals);
+         resp.getRenderParameters().setValues(PARAM_FG_COLOR, vals);
       }
       
-      String subType = req.getParameter(PARAM_SUBTYPE);
+      String subType = req.getActionParameters().getValue(PARAM_SUBTYPE);
       if (subType != null) {
-         resp.setRenderParameter(PARAM_SUBTYPE, subType);
+         resp.getRenderParameters().setValue(PARAM_SUBTYPE, subType);
       }
       
-      String text = req.getParameter(PARAM_MSG_INPUT);
+      String text = req.getActionParameters().getValue(PARAM_MSG_INPUT);
       if (text != null) {
-         resp.setRenderParameter(PARAM_MSG_INPUT, text);
+         resp.getRenderParameters().setValue(PARAM_MSG_INPUT, text);
       }
       
       String msg = text + DELIM + clr;
@@ -116,7 +131,7 @@ public class ColorSelPortlet extends GenericPortlet {
          resp.setEvent(qn, msg);
          logger.fine("Firing event with QName: " + qn.toString());
       } else {
-         logger.warning("No publishing event QName available. Check portlet deployment descriptor.");
+         logger.warning("No publishing event QName available. Check portlet configuration.");
       }
       
       StringBuilder sb = new StringBuilder("Color: ").append(Arrays.toString(vals));
@@ -125,14 +140,13 @@ public class ColorSelPortlet extends GenericPortlet {
       logger.fine(sb.toString());
    }
    
-   private void dumpParameters(PortletRequest req) {
+   private void dumpParameters(String type, PortletParameters parms) {
       if (logger.isLoggable(Level.FINEST)) {
          StringBuilder sb = new StringBuilder();
-         sb.append("Portlet request parameters:");
-         Map<String, String[]> parms = req.getParameterMap();
-         for (String name : parms.keySet()) {
+         sb.append("Portlet ").append(type).append(" parameters:");
+         for (String name : parms.getNames()) {
             sb.append("\nName: ").append(name);
-            sb.append(", Values: ").append(Arrays.toString(parms.get(name)));
+            sb.append(", Values: ").append(Arrays.toString(parms.getValues(name)));
          }
          logger.finest(sb.toString());
       }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
index 2221e84..7256b41 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
@@ -80,9 +80,9 @@ public class ImageSelPortlet extends GenericPortlet {
 
 	      String pid = resp.getNamespace();
 	      Set<String> names = imgMap.keySet();
-	      String selType = req.getParameter(PARAM_SELTYPE);
+	      String selType = req.getRenderParameters().getValue(PARAM_SELTYPE);
 	      selType = (selType == null) ? PARAM_SELTYPE_RADIO : selType;
-	      String imgName = req.getParameter(PARAM_IMGNAME);
+	      String imgName = req.getRenderParameters().getValue(PARAM_IMGNAME);
 	      imgName = (imgName == null) ? "default" : imgName;
 
 	      if (selType.equals(PARAM_SELTYPE_RADIO)) {

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
index 13cb517..0eff878 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
@@ -18,7 +18,10 @@
 
 package basic.portlet;
 
-import static basic.portlet.Constants.*;
+import static basic.portlet.Constants.ATTRIB_MSGS;
+import static basic.portlet.Constants.DELIM;
+import static basic.portlet.Constants.PARAM_COLOR;
+import static basic.portlet.Constants.PARAM_NUM_MSGS;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -37,10 +40,16 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletQName;
 
 /**
  * A demo portlet that displays messages sent via event
  */
+@PortletConfiguration(portletName = "MessageBoxPortlet", publicParams = "color", 
+                      title = @LocaleString("PH Message Box Portlet"))
 public class MessageBoxPortlet extends GenericPortlet {
 
    // Set up logging
@@ -68,7 +77,7 @@ public class MessageBoxPortlet extends GenericPortlet {
 
       // the only action for this portlet is to reset the stored messages
       
-      String actionName = req.getParameter("action");
+      String actionName = req.getActionParameters().getValue(ActionRequest.ACTION_NAME);
       logger.fine("MBP: Resetting messages. numMsgs = 0,  actionName = " + actionName);
 
       ArrayList<String> msgs = new ArrayList<String>();
@@ -79,15 +88,18 @@ public class MessageBoxPortlet extends GenericPortlet {
       sb.append("</p>");
       msgs.add(sb.toString());
 
-      resp.setRenderParameter(PARAM_NUM_MSGS, "0");
+      resp.getRenderParameters().setValue(PARAM_NUM_MSGS, "0");
       req.getPortletSession().setAttribute(ATTRIB_MSGS, msgs);
    }
    
-   @SuppressWarnings("unchecked")
+   @EventMethod(portletName="MessageBoxPortlet", processingEvents= {
+         @PortletQName(namespaceURI="http://www.apache.org/portals/pluto/ResourcePortlet", localPart="Message")
+   })
    @Override
    public void processEvent(EventRequest req, EventResponse resp) 
          throws PortletException ,IOException {
       
+      @SuppressWarnings("unchecked")
       ArrayList<String> msgs = (ArrayList<String>) req.getPortletSession().getAttribute(ATTRIB_MSGS);
       if (msgs == null) {
          msgs = new ArrayList<String>();
@@ -96,7 +108,7 @@ public class MessageBoxPortlet extends GenericPortlet {
       String[] msg;
       int numMsgs = 0;
       try {
-         numMsgs = Integer.parseInt(req.getParameter(PARAM_NUM_MSGS));
+         numMsgs = Integer.parseInt(req.getRenderParameters().getValue(PARAM_NUM_MSGS));
       } catch (Exception e) {}
       
       if (numMsgs == 0) {
@@ -117,7 +129,7 @@ public class MessageBoxPortlet extends GenericPortlet {
          msg[1] = "#D00";
       }
       
-      String clr = req.getParameter(PARAM_COLOR);
+      String clr = req.getRenderParameters().getValue(PARAM_COLOR);
       clr = (clr == null) ? "#FFFFFF" : clr;
       
       StringBuffer sb = new StringBuffer();
@@ -130,7 +142,7 @@ public class MessageBoxPortlet extends GenericPortlet {
       
       logger.fine("Adding message: " + sb.toString());
 
-      resp.setRenderParameter(PARAM_NUM_MSGS, Integer.toString(msgs.size()));
+      resp.getRenderParameters().setValue(PARAM_NUM_MSGS, Integer.toString(msgs.size()));
       req.getPortletSession().setAttribute(ATTRIB_MSGS, msgs);
    };
    

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
index eec1af5..52f8d78 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
@@ -107,13 +107,13 @@ public class ResourcePortlet extends GenericPortlet {
    public void serveResource(ResourceRequest req, ResourceResponse resp)
          throws PortletException, IOException {
 
-      String key = req.getParameter(PARAM_IMGNAME);
+      String key = req.getRenderParameters().getValue(PARAM_IMGNAME);
       String imgDir = DEFAULT_IMAGE;
       if ((key != null) && imgMap.containsKey(key)) {
          imgDir = imgMap.get(key);
       }
       
-      String bc = req.getParameter(PARAM_BORDER_COLOR);
+      String bc = req.getResourceParameters().getValue(PARAM_BORDER_COLOR);
       String imgStyle = "";
       if (bc != null) {
          imgStyle = " style='border:1px solid " + bc + ";' ";
@@ -125,7 +125,7 @@ public class ResourcePortlet extends GenericPortlet {
       resp.setContentType("text/html");
       PrintWriter writer = resp.getWriter();
       
-      String clr = req.getParameter(PARAM_COLOR);
+      String clr = req.getRenderParameters().getValue(PARAM_COLOR);
       clr = (clr == null) ? "#FFFFFF" : clr;
       
       // add action button if cacheability allows -

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
deleted file mode 100644
index a79f959..0000000
--- a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<portlet-app xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
-             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-             xmlns:rp="http://www.apache.org/portals/pluto/ResourcePortlet"
-             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet http://xmlns.jcp.org/xml/ns/portlet/portlet-app_3_0.xsd" 
-             version="3.0"
-    		id="ph.resource.portlet">
-
-   <portlet>
-      <portlet-name>MessageBoxPortlet</portlet-name>
-      <display-name>Message Box Portlet</display-name>
-      
-      <portlet-class>basic.portlet.MessageBoxPortlet</portlet-class>
-
-      <supports>
-         <mime-type>text/html</mime-type>
-         <portlet-mode>VIEW</portlet-mode>
-      </supports>
-
-      <supported-locale>en</supported-locale>        
-
-      <portlet-info>
-         <title>PH Message Box Portlet</title>
-      </portlet-info>
-
-      <supported-processing-event>
-         <qname>rp:Message</qname>
-      </supported-processing-event>
-
-      <supported-public-render-parameter>color</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-publishing-event>
-         <qname>rp:Message</qname>
-      </supported-publishing-event>
-      <supported-public-render-parameter>color</supported-public-render-parameter>
-   </portlet>
- </portlet-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/AuthSCPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/AuthSCPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/AuthSCPortlet.java
index 71fe067..744a867 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/AuthSCPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/AuthSCPortlet.java
@@ -40,7 +40,7 @@ import javax.portlet.ResourceResponse;
 
 
 /**
- * A portlet that allows render parameter names & values to be entered and set.
+ * A portlet that causes the resource request status code to be set.
  * 
  * @author Scott Nicklous
  */

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/ColorSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/ColorSelPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/ColorSelPortlet.java
index 5f657bf..acf1a98 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/ColorSelPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/ColorSelPortlet.java
@@ -35,7 +35,7 @@ import javax.xml.namespace.QName;
 
 
 /**
- * A management portlet that displays the current deep link configuration
+ * A demo portlet for color selection.
  */
 public class ColorSelPortlet extends GenericPortlet {
 
@@ -63,11 +63,10 @@ public class ColorSelPortlet extends GenericPortlet {
          throws PortletException, IOException {
    }
 
-   @SuppressWarnings("deprecation")
    public void processAction(ActionRequest req, ActionResponse resp)
          throws PortletException, IOException {
             
-      String[] vals = req.getParameterValues(PARAM_FG_COLOR);
+      String[] vals = req.getActionParameters().getValues(PARAM_FG_COLOR);
       String r = "0";
       String g = "0";
       String b = "0";
@@ -83,17 +82,17 @@ public class ColorSelPortlet extends GenericPortlet {
       // make sure the private parameter are all on the URL for 
       // potential back button support
       if (vals != null) {
-         resp.setRenderParameter(PARAM_FG_COLOR, vals);
+         resp.getRenderParameters().setValues(PARAM_FG_COLOR, vals);
       }
       
-      String val = req.getParameter(PARAM_SUBTYPE);
+      String val = req.getActionParameters().getValue(PARAM_SUBTYPE);
       if (val != null) {
-         resp.setRenderParameter(PARAM_SUBTYPE, val);
+         resp.getRenderParameters().setValue(PARAM_SUBTYPE, val);
       }
       
-      val = req.getParameter(PARAM_MSG_INPUT);
+      val = req.getActionParameters().getValue(PARAM_MSG_INPUT);
       if (val != null) {
-         resp.setRenderParameter(PARAM_MSG_INPUT, val);
+         resp.getRenderParameters().setValue(PARAM_MSG_INPUT, val);
       }
       
       String msg = val + DELIM + clr;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/HeaderPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/HeaderPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/HeaderPortlet.java
index 1310b48..98466c0 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/HeaderPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/HeaderPortlet.java
@@ -38,6 +38,8 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.LocaleString;
 import javax.servlet.http.Cookie;
 
 import org.w3c.dom.Element;
@@ -45,6 +47,8 @@ import org.w3c.dom.Element;
 /**
  * Portlet for testing the redirect funtionality, including the new getRedirectURL API.
  */
+@PortletConfiguration(portletName="V3HeaderPortlet", 
+                      title=@LocaleString("Header Phase Test Portlet"))
 public class HeaderPortlet extends GenericPortlet {
 
    private static final Logger  LOGGER  = Logger.getLogger(HeaderPortlet.class.getName());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/ImageSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/ImageSelPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/ImageSelPortlet.java
index 24095f0..3ea0fb7 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/ImageSelPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/ImageSelPortlet.java
@@ -41,7 +41,7 @@ import javax.portlet.ResourceResponse;
 
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A demo portlet for image selection.
  */
 public class ImageSelPortlet extends GenericPortlet {
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/MessageBoxPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/MessageBoxPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/MessageBoxPortlet.java
index f397886..5a4ddd5 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/MessageBoxPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/MessageBoxPortlet.java
@@ -39,7 +39,7 @@ import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A portlet that recieves messages and displays them.
  */
 public class MessageBoxPortlet extends GenericPortlet {
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/PortletConfigPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/PortletConfigPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/PortletConfigPortlet.java
index 4aaf5cd..a1e32e8 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/PortletConfigPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/PortletConfigPortlet.java
@@ -45,7 +45,7 @@ import javax.portlet.WindowState;
 import javax.xml.namespace.QName;
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A portlet for displaying config data
  */
 public class PortletConfigPortlet extends GenericPortlet {
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/RedirectPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/RedirectPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/RedirectPortlet.java
index a983a6e..1b28843 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/RedirectPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/RedirectPortlet.java
@@ -35,6 +35,7 @@ import javax.portlet.RenderResponse;
 import javax.portlet.RenderURL;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.PortletConfiguration;
 
 import static javax.portlet.MimeResponse.Copy.*;
 import static basic.portlet.Constants.*;
@@ -42,6 +43,7 @@ import static basic.portlet.Constants.*;
 /**
  * Portlet for testing the redirect funtionality, including the new getRedirectURL API.
  */
+@PortletConfiguration(portletName="V3RedirectPortlet")
 public class RedirectPortlet extends GenericPortlet {
 
    private static final Logger  LOGGER  = Logger.getLogger(RedirectPortlet.class.getName());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/ResourcePortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/ResourcePortlet.java b/PortletV3Demo/src/main/java/basic/portlet/ResourcePortlet.java
index 64829af..e4e2cd7 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/ResourcePortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/ResourcePortlet.java
@@ -42,7 +42,7 @@ import javax.portlet.ResourceResponse;
 
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A portlet for displaying an image and text using a resource URL.
  */
 public class ResourcePortlet extends GenericPortlet {
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/java/basic/portlet/UrlTestPortlet.java
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/java/basic/portlet/UrlTestPortlet.java b/PortletV3Demo/src/main/java/basic/portlet/UrlTestPortlet.java
index 8e62c51..e3d9901 100644
--- a/PortletV3Demo/src/main/java/basic/portlet/UrlTestPortlet.java
+++ b/PortletV3Demo/src/main/java/basic/portlet/UrlTestPortlet.java
@@ -53,7 +53,7 @@ import static javax.portlet.ResourceURL.*;
 
 
 /**
- * A purtlet hub portlet that allows parameter names & values to be entered and set.
+ * A portlet that creates various types of URL.
  * 
  * @author Scott Nicklous
  */

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/PortletV3Demo/src/main/webapp/WEB-INF/portlet.xml
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/webapp/WEB-INF/portlet.xml b/PortletV3Demo/src/main/webapp/WEB-INF/portlet.xml
index a7aba59..2cce7d0 100644
--- a/PortletV3Demo/src/main/webapp/WEB-INF/portlet.xml
+++ b/PortletV3Demo/src/main/webapp/WEB-INF/portlet.xml
@@ -95,41 +95,12 @@
 
    <portlet>
       <portlet-name>V3RedirectPortlet</portlet-name>
-      <display-name>Redirect Test Portlet</display-name>
-      
-      <portlet-class>basic.portlet.RedirectPortlet</portlet-class>
-
-      <supports>
-         <mime-type>text/html</mime-type>
-         <portlet-mode>VIEW</portlet-mode>
-      </supports>
-
-      <supported-locale>en</supported-locale>        
-
       <portlet-info>
          <title>Redirect Test Portlet</title>
       </portlet-info>
    </portlet>
 
    <portlet>
-      <portlet-name>V3HeaderPortlet</portlet-name>
-      <display-name>Header Phase Test Portlet</display-name>
-      
-      <portlet-class>basic.portlet.HeaderPortlet</portlet-class>
-
-      <supports>
-         <mime-type>text/html</mime-type>
-         <portlet-mode>VIEW</portlet-mode>
-      </supports>
-
-      <supported-locale>en</supported-locale>        
-
-      <portlet-info>
-         <title>Header Phase Test Portlet</title>
-      </portlet-info>
-   </portlet>
-
-   <portlet>
       <portlet-name>PortletConfigPortlet1</portlet-name>
       <display-name>Portlet Config Portlet #1</display-name>
       

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/pluto-container-api/src/main/java/org/apache/pluto/container/HeaderData.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/HeaderData.java b/pluto-container-api/src/main/java/org/apache/pluto/container/HeaderData.java
index 86f08cc..36ea13e 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/HeaderData.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/HeaderData.java
@@ -64,6 +64,7 @@ public class HeaderData {
    /** Logger. */
    private static final Logger       LOG                = LoggerFactory.getLogger(HeaderData.class);
    private static final boolean      isDebug            = LOG.isDebugEnabled();
+   private static final boolean      isTrace            = LOG.isTraceEnabled();
 
    // for document processing
    private DocumentBuilder           docBuilder         = null;
@@ -345,11 +346,11 @@ public class HeaderData {
          }
       }
 
-      if (isDebug) {
+      if (isTrace) {
          StringBuilder sb = new StringBuilder();
          sb.append("returning tags: ");
          sb.append((tags.length() > 0) ? "\n" + tags : "");
-         LOG.debug(sb.toString());
+         LOG.trace(sb.toString());
       }
 
       return tags;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestImpl.java
index fbb9226..ee05621 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletRequestImpl.java
@@ -374,7 +374,7 @@ public abstract class PortletRequestImpl implements PortletRequest
     {
         if (LOG.isDebugEnabled())
         {
-            LOG.debug("Retreiving portlet session (create=" + create + ")");
+            LOG.debug("Retrieving portlet session (create=" + create + ")");
         }
         //
         // It is critical that we don't retrieve the portlet session until the

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 5c42c06..92c2803 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -8,7 +8,9 @@ import static org.apache.pluto.container.bean.processor.MethodDescription.METH_I
 import static org.apache.pluto.container.bean.processor.MethodDescription.METH_REN;
 import static org.apache.pluto.container.bean.processor.MethodDescription.METH_RES;
 
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.StringReader;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -47,6 +49,9 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
 public abstract class ConfigurationProcessor {
    
@@ -245,7 +250,15 @@ public abstract class ConfigurationProcessor {
 
       // set up document
       DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
+      fact.setValidating(false);
+      
       final DocumentBuilder builder = fact.newDocumentBuilder();
+      builder.setEntityResolver(new EntityResolver() {
+         public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException {
+            return new InputSource(new StringReader(""));
+         }
+      });
+
       final Document document = builder.parse(in);
       final Element root = document.getDocumentElement();
 
@@ -261,13 +274,16 @@ public abstract class ConfigurationProcessor {
       NodeList nodes = (NodeList) GET_LIST.evaluate(root,
             XPathConstants.NODESET);
 
+      int mappings = 0;
       for (int jj = 0; jj < nodes.getLength(); jj++) {
          Node node = nodes.item(jj);
          String locstr = (String) GET_LOC.evaluate(node, XPathConstants.STRING);
          String encstr = (String) GET_ENC.evaluate(node, XPathConstants.STRING);
          Locale locale = deriveLocale(locstr);
          pad.addLocaleEncodingMapping(locale, encstr);
+         mappings++;
       }
+      LOG.debug("done parsing web DD, # mappings: " + mappings);
    }
    
    /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 9b97417..321b706 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -733,8 +733,13 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
                throw new IllegalArgumentException(warning);
             }
             pd = new PortletDefinitionImpl(pn, pad);
+            pd.setPortletClass(portlet.getPortletClass());
+         } else {
+            if ((clsName != null) && (clsName.length() > 0)) {
+               // The portlet class set in the portlet DD overrides the annotated class.
+               pd.setPortletClass(portlet.getPortletClass());
+            }
          }
-         pd.setPortletClass(portlet.getPortletClass());
 
          if (portlet.getResourceBundle() != null) {
             pd.setResourceBundle(portlet.getResourceBundle().getValue());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/43d2208e/pluto-portal-driver/src/main/java/org/apache/pluto/driver/url/PortletParameterFactory.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/url/PortletParameterFactory.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/url/PortletParameterFactory.java
index d4deaef..4776d13 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/url/PortletParameterFactory.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/url/PortletParameterFactory.java
@@ -43,7 +43,6 @@ import org.slf4j.LoggerFactory;
  */
 public class PortletParameterFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(PortletParameterFactory.class);
-   private final static boolean isDebug = LOGGER.isDebugEnabled();
    private final static boolean isTrace = LOGGER.isTraceEnabled();
    
    PortalURL url;
@@ -114,7 +113,7 @@ public class PortletParameterFactory {
          }
       }
 
-      if (isDebug) {
+      if (isTrace) {
          StringBuffer sb = new StringBuffer();
          sb.append("Dump private Parameter Map:");
          for (String k : parameters.keySet()) {
@@ -125,7 +124,7 @@ public class PortletParameterFactory {
                sep = ", ";
             }
          }
-         LOGGER.debug(sb.toString());
+         LOGGER.trace(sb.toString());
       }
       return parameters;
    }


[35/35] portals-pluto git commit: Added @PortletRequestScoped annotation, since the lifetime of the portlet request might be different thatn the lifetime of the underlying servlet request for some portal implementations. The injectable portlet artifacts

Posted by ms...@apache.org.
Added @PortletRequestScoped annotation, since the lifetime of the portlet
request might be different thatn the lifetime of the underlying servlet
request for some portal implementations. The injectable portlet artifacts
such as the RenderRequest object are now scoped to the portlet request.


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

Branch: refs/heads/V3Prototype
Commit: 84f8d9f3916578c4588cdee66ec87643c6c6ed07
Parents: a0c6f1c
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Jan 18 10:28:38 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Jan 18 10:28:38 2016 +0100

----------------------------------------------------------------------
 .../bean/processor/PortletArtifactProducer.java |  32 +--
 .../bean/processor/PortletCDIExtension.java     |   5 +-
 .../bean/processor/PortletInvoker.java          |   6 +
 .../PortletRequestScopedBeanHolder.java         | 197 +++++++++++++++++++
 .../processor/PortletRequestScopedContext.java  |  87 ++++++++
 .../annotations/PortletRequestScoped.java       |  53 +++++
 6 files changed, 363 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
index 8b42975..8830f8e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
@@ -24,7 +24,6 @@ import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Locale;
 
-import javax.enterprise.context.RequestScoped;
 import javax.enterprise.inject.Produces;
 import javax.enterprise.inject.Typed;
 import javax.enterprise.inject.spi.InjectionPoint;
@@ -48,6 +47,7 @@ import javax.portlet.annotations.ActionParam;
 import javax.portlet.annotations.BeanPortlet;
 import javax.portlet.annotations.ContextPath;
 import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.PortletRequestScoped;
 import javax.portlet.annotations.RenderParam;
 import javax.portlet.annotations.ResourceParam;
 import javax.portlet.annotations.URLFactory;
@@ -147,7 +147,7 @@ public class PortletArtifactProducer {
     * Producer method for the portlet config. 
     * @return
     */
-   @Produces @RequestScoped @BeanPortlet @Named("portletConfig")
+   @Produces @PortletRequestScoped @BeanPortlet @Named("portletConfig")
    public static PortletConfig producePortletConfig() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -167,7 +167,7 @@ public class PortletArtifactProducer {
     * Producer method for the portlet request. 
     * @return
     */
-   @Produces @RequestScoped @Named("portletRequest")
+   @Produces @PortletRequestScoped @Named("portletRequest")
    public static PortletRequest producePortletRequest() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -178,7 +178,7 @@ public class PortletArtifactProducer {
     * Producer method for the portlet response. 
     * @return
     */
-   @Produces @RequestScoped @Named("portletResponse")
+   @Produces @PortletRequestScoped @Named("portletResponse")
    public static PortletResponse producePortletResponse() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -190,7 +190,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("actionRequest") @Typed(ActionRequest.class)
+   @Produces @PortletRequestScoped @Named("actionRequest") @Typed(ActionRequest.class)
    public static ActionRequest produceActionRequest() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -206,7 +206,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("actionResponse") @Typed(ActionResponse.class)
+   @Produces @PortletRequestScoped @Named("actionResponse") @Typed(ActionResponse.class)
    public static ActionResponse produceActionResponse() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -222,7 +222,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("renderRequest") @Typed(RenderRequest.class)
+   @Produces @PortletRequestScoped @Named("renderRequest") @Typed(RenderRequest.class)
    public static RenderRequest produceRenderRequest() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -238,7 +238,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("renderResponse") @Typed(RenderResponse.class)
+   @Produces @PortletRequestScoped @Named("renderResponse") @Typed(RenderResponse.class)
    public static RenderResponse produceRenderResponse() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -254,7 +254,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("eventRequest") @Typed(EventRequest.class)
+   @Produces @PortletRequestScoped @Named("eventRequest") @Typed(EventRequest.class)
    public static EventRequest produceEventRequest() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -270,7 +270,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("eventResponse") @Typed(EventResponse.class)
+   @Produces @PortletRequestScoped @Named("eventResponse") @Typed(EventResponse.class)
    public static EventResponse produceEventResponse() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -286,7 +286,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("resourceRequest") @Typed(ResourceRequest.class)
+   @Produces @PortletRequestScoped @Named("resourceRequest") @Typed(ResourceRequest.class)
    public static ResourceRequest produceResourceRequest() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -302,7 +302,7 @@ public class PortletArtifactProducer {
     * Dependent scoped because it sometimes returns <code>null</code>. 
     * @return
     */
-   @Produces @RequestScoped @Named("resourceResponse") @Typed(ResourceResponse.class)
+   @Produces @PortletRequestScoped @Named("resourceResponse") @Typed(ResourceResponse.class)
    public static ResourceResponse produceResourceResponse() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -339,7 +339,7 @@ public class PortletArtifactProducer {
     * Producer method for the portlet preferences. 
     * @return
     */
-   @Produces @RequestScoped @Named("portletPreferences")
+   @Produces @PortletRequestScoped @Named("portletPreferences")
    public static PortletPreferences producePortletPreferences() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -361,7 +361,7 @@ public class PortletArtifactProducer {
     * Producer method for the portlet session. 
     * @return
     */
-   @Produces @RequestScoped @Named("portletSession")
+   @Produces @PortletRequestScoped @Named("portletSession")
    public static PortletSession producePortletSession() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -394,7 +394,7 @@ public class PortletArtifactProducer {
     * Producer method for the window ID. 
     * @return
     */
-   @Produces @RequestScoped @Named("locales") 
+   @Produces @PortletRequestScoped @Named("locales") 
    public static Enumeration<Locale> produceLocales() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;
@@ -427,7 +427,7 @@ public class PortletArtifactProducer {
     * Producer method for the URL factory. 
     * @return
     */
-   @Produces @RequestScoped @Named("urlFactory")
+   @Produces @PortletRequestScoped @Named("urlFactory")
    public static URLFactory produceURLFactory() {
       PortletArtifactProducer pap = producers.get();
       assert pap != null;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
index 1bc695e..1cdba18 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
@@ -76,12 +76,15 @@ public class PortletCDIExtension implements Extension {
     * 
     * @param abd
     */
-   void addPortletSessionScopeContext(@Observes AfterBeanDiscovery abd) {
+   void addPortletCustomScopeContexts(@Observes AfterBeanDiscovery abd) {
       PortletSessionScopedContext pssc = new PortletSessionScopedContext();
       abd.addContext(pssc);
       
       PortletStateScopedContext pstsc = new PortletStateScopedContext();
       abd.addContext(pstsc);
+      
+      PortletRequestScopedContext prsc = new PortletRequestScopedContext();
+      abd.addContext(prsc);
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
index f7494cb..2e1a960 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
@@ -114,6 +114,9 @@ public class PortletInvoker implements Portlet, ResourceServingPortlet, EventPor
    private void beforeInvoke(PortletRequest req, PortletResponse resp) {
 
       // Set the portlet session bean holder for the thread & session
+      PortletRequestScopedBeanHolder.setBeanHolder();
+
+      // Set the portlet session bean holder for the thread & session
       PortletSessionBeanHolder.setBeanHolder(req.getPortletSession());
 
       // Set the portlet state scoped bean holder
@@ -130,6 +133,9 @@ public class PortletInvoker implements Portlet, ResourceServingPortlet, EventPor
    private void afterInvoke(PortletResponse resp) {
 
       // Remove the portlet session bean holder for the thread
+      PortletRequestScopedBeanHolder.removeBeanHolder();
+
+      // Remove the portlet session bean holder for the thread
       PortletSessionBeanHolder.removeBeanHolder();
 
       // Remove the portlet state bean holder. pass response if we're

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedBeanHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedBeanHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedBeanHolder.java
new file mode 100644
index 0000000..468e1f0
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedBeanHolder.java
@@ -0,0 +1,197 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is a container for PortletRequestScoped CDI beans.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class PortletRequestScopedBeanHolder implements Serializable {
+   
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletRequestScopedBeanHolder.class);
+   private static final boolean isTrace = LOG.isTraceEnabled();
+   
+   private static final long serialVersionUID = 6014843414216617217L;
+   
+   // The ThreadLocal manages the holders so that there is one holder per thread.
+   private static final ThreadLocal<PortletRequestScopedBeanHolder> holders =
+         new ThreadLocal<PortletRequestScopedBeanHolder>();
+
+   private class BeanInstance<T> implements Serializable {
+      private static final long serialVersionUID = -4173708394115905180L;
+      CreationalContext<T>    crco;
+      T                       instance;
+   }
+   
+   // Each instance of the bean holder gets its own map.
+   // Key: Bean Type, Value: Structure containing CreationalContext and the specific
+   // bean instance.
+   private Map<Contextual<?>, BeanInstance<?>> beans = 
+         new ConcurrentHashMap<Contextual<?>, BeanInstance<?>>();
+   
+   /**
+    * private constructor
+    */
+   private PortletRequestScopedBeanHolder() {
+   }
+
+   /**
+    * Sets the portlet request bean holder in a ThreadLocal object for the given 
+    * portlet session. If no bean holder exists in the session, a new one is created.
+    */
+   public static void setBeanHolder() {
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Setting portlet request bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         LOG.trace(txt.toString());
+      }
+
+      PortletRequestScopedBeanHolder holder = new PortletRequestScopedBeanHolder();
+      holders.set(holder);
+   }
+   
+   /**
+    * Removes the bean holder for the current request. Deletes all beans contained therein.
+    * If response is provided, the beans are deserialized and stored.
+    * 
+    */
+   public static void removeBeanHolder() {
+      
+      PortletRequestScopedBeanHolder bh = getBeanHolder();
+      bh.removeAll();
+      holders.remove();
+
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removed portlet request bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         LOG.trace(txt.toString());
+      }
+   }
+   
+   /**
+    * Returns the portlet session bean holder that was set for the thread.
+    * 
+    * @return
+    */
+   public static PortletRequestScopedBeanHolder getBeanHolder() {
+      return holders.get();
+   }
+
+   /**
+    * Returns existing instance of object, or null if no instance exists.
+    * 
+    * @param bean    The bean type
+    * @return        The bean instance
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getBean(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+      return (bi == null) ? null : (T) bi.instance;
+   }
+   
+   /**
+    * Returns an instance for the contextual type. If no existing bean is available,
+    * a new instance is created.
+    * 
+    * @param bean       Contextual type (Bean) for which an instance is desired
+    * @return           The instance, or null if none exists
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getBean(Contextual<T> bean, CreationalContext<T> crco) {
+      BeanInstance<?> bi = beans.get(bean);
+      
+      if (bi == null) {
+         
+         // No bean available, so create one.
+         
+         BeanInstance<T> newbi = new BeanInstance<T>();
+         newbi.crco = crco;
+         newbi.instance = bean.create(crco);
+         bi = newbi;
+         beans.put(bean, newbi);
+
+         if (isTrace) {
+            StringBuilder txt = new StringBuilder(80);
+            txt.append("Created bean: ");
+            txt.append(((Bean<?>) bean).getBeanClass().getSimpleName());
+            LOG.trace(txt.toString());
+         }
+
+      }
+  
+      return (T) bi.instance;
+   }
+   
+   /**
+    * Removes & destroys the given bean
+    * @param bean
+    */
+   @SuppressWarnings("unchecked")
+   protected <T> void remove(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removing portlet request scoped bean: ");
+         if (bean instanceof Bean<?>) {
+            Bean<?> b = (Bean<?>) bean;
+            txt.append(b.getBeanClass().getSimpleName());
+         }
+         if (bi == null) {
+            txt.append(", instance is null.");
+         }
+         LOG.trace(txt.toString());
+      }
+
+      if (bi != null) {
+         beans.remove(bean);
+         bi.crco.release();
+         bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco);
+      }
+   }
+   
+   /**
+    * Remove & destroy all beans. 
+    * 
+    * @param   resp     The state aware response
+    */
+   protected void removeAll() {
+      for (Contextual<?> bean : beans.keySet()) {
+         remove(bean);
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedContext.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedContext.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedContext.java
new file mode 100644
index 0000000..7f5f43b
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletRequestScopedContext.java
@@ -0,0 +1,87 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.portlet.annotations.PortletRequestScoped;
+
+/**
+ * This is the Context implementation for the PortletRequestScoped custom CDI scope.
+ * 
+ * @author nick
+ *
+ */
+public class PortletRequestScopedContext implements Context {
+
+   public PortletRequestScopedContext() {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean) {
+      PortletRequestScopedBeanHolder holder = PortletRequestScopedBeanHolder.getBeanHolder();
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet request context is not active.");
+      }
+      return holder.getBean(bean);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual, javax.enterprise.context.spi.CreationalContext)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean, CreationalContext<T> crco) {
+      PortletRequestScopedBeanHolder holder = PortletRequestScopedBeanHolder.getBeanHolder();
+      
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet request context is not active.");
+      }
+      
+      // The bean holder will return an existing bean instance or create a new one
+      // if no existing instance is available.
+      T inst = holder.getBean(bean, crco);      
+      return inst;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#getScope()
+    */
+   @Override
+   public Class<? extends Annotation> getScope() {
+      return PortletRequestScoped.class;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#isActive()
+    */
+   @Override
+   public boolean isActive() {
+      PortletRequestScopedBeanHolder holder = PortletRequestScopedBeanHolder.getBeanHolder();
+      return (holder != null);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/84f8d9f3/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestScoped.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestScoped.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestScoped.java
new file mode 100644
index 0000000..17ebf66
--- /dev/null
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletRequestScoped.java
@@ -0,0 +1,53 @@
+/*  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!
+ */
+package javax.portlet.annotations;
+
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import javax.enterprise.context.NormalScope;
+
+
+/**
+ * <div class='changed_added_3_0'>
+ * Provides a CDI custom scope for the portlet request.
+ * </div>
+ *
+ */
+
+@Retention(RUNTIME) 
+@Target({TYPE, METHOD, FIELD})
+@NormalScope
+@Inherited
+@Documented
+public @interface PortletRequestScoped {
+}


[17/35] portals-pluto git commit: Adapted method annotations to match spec draft 1

Posted by ms...@apache.org.
Adapted method annotations to match spec draft 1


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

Branch: refs/heads/V3Prototype
Commit: 9d5855d46bb901d9c2b6ad26dff2537d424871be
Parents: a05e156
Author: Scott Nicklous <ms...@apache.org>
Authored: Sun Dec 27 18:57:04 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sun Dec 27 18:57:04 2015 +0100

----------------------------------------------------------------------
 .../javax/portlet/annotations/EventMethod.java  |  31 +---
 .../javax/portlet/annotations/HeaderMethod.java |   2 +-
 .../portlet/annotations/PortletResources.java   | 153 -------------------
 3 files changed, 2 insertions(+), 184 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9d5855d4/portlet-api/src/main/java/javax/portlet/annotations/EventMethod.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/EventMethod.java b/portlet-api/src/main/java/javax/portlet/annotations/EventMethod.java
index 8790e33..b735580 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/EventMethod.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/EventMethod.java
@@ -63,39 +63,10 @@ public @interface EventMethod {
    String   portletName();
    
    /**
-    * If set to <code>true</code>, render parameters will be automatically copied
-    * from the <code>EventRequest</code> to the <code>EventResponse</code>.
-    * <p>
-    * The copy will take place before the code body of the annotated method
-    * is executed.
-    * 
-    * @return     <code>true</code> if parameters are to be copied.
-    */
-   boolean  copyParameters() default true; 
-   
-   /**
-    * The event name.
-    * <p>
-    * TODO: rework / remove this.
-    * <p>
-    * If an event name is specified, the bean enabler will dispatch portlet events with 
-    * matching event names to this method. 
-    * <p>
-    * An EventMethod with an empty event 
-    * name will receive all event requests not dispatched to other named EventMethods.
-    * 
-    * 
-    * @return  The event name
-    */
-   String   eventName() default "";
-   
-   /**
     * <div class='container-change'>
     * The processing event QName definitions supported by this method.
     * <p>
     * At least one processing event QName must be specified.
-    * <p>
-    * TODO: remove the default clause after rework above.
     * </div>
     * 
     * @see     EventDefinition
@@ -103,7 +74,7 @@ public @interface EventMethod {
     * 
     * @return  The processing event QNames
     */
-   PortletQName[]   processingEvents() default {};
+   PortletQName[]   processingEvents();
    
    /**
     * <div class='container-change'>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9d5855d4/portlet-api/src/main/java/javax/portlet/annotations/HeaderMethod.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/HeaderMethod.java b/portlet-api/src/main/java/javax/portlet/annotations/HeaderMethod.java
index 7c0a05a..42935b1 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/HeaderMethod.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/HeaderMethod.java
@@ -91,7 +91,7 @@ public @interface HeaderMethod {
     * 
     * @return     The portlet mode
     */
-   String   portletMode() default "view";
+   String   portletMode() default "";
    
    /**
     * Sets the content type, or the MIME type, of content generated by the method.

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/9d5855d4/portlet-api/src/main/java/javax/portlet/annotations/PortletResources.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletResources.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletResources.java
deleted file mode 100644
index 232e000..0000000
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletResources.java
+++ /dev/null
@@ -1,153 +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 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!
- */
-
-package javax.portlet.annotations;
-
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.*;
-
-
-/**
- * <div class='changed_added_3_0'>
- * Declares resources needed by one or more portlets in a portlet application. 
- * The resources may be provided by the portlet for inclusion into the header section
- * through the <code>GenericPortlet#doHeaders</code> method 
- * or may represent dependencies on external resources.
- * <p>
- * The annotated method must have one of the following signatures:
- * <ul>
- * <li>
- * <code>public void &lt;methodName&gt;(RenderRequest, RenderResponse)</code>
- * <p>
- * This corresponds to the <code>doHeaders</code> method. Output written through the
- * render response object will be placed in the document <code>&lt;head&gt;</code> section.
- * </li>   
- * <li>
- * <code>String &lt;methodName&gt;()</code>
- * <p>
- * The String returned by the method will be placed 
- * in the document <code>&lt;head&gt;</code> section.
- * </li>   
- * </ul> 
- * <p> 
- * The method name can be freely selected.
- * <p>
- * The method declaration may contain a throws clause. Exceptions declared in the 
- * throws clause should be of type {@link javax.portlet.PortletException} or
- * {@link java.io.IOException}. 
- * Checked exceptions of any other type will be caught, wrapped with a PortletException, 
- * and rethrown.
- * <p>
- * This annotation may be applied to a type or to a method. 
- * If applied to a type, it behaves as though it were applied to an empty 
- * <code>doHeaders</code> method.  
- * </div>
- *    
- * @see javax.portlet.GenericPortlet#doHeaders(javax.portlet.RenderRequest, javax.portlet.RenderResponse) doHeaders
- */
-
-@Retention(RUNTIME) @Target({METHOD})
-public @interface PortletResources {
-   
-   /**
-    * <div class='container-change'>
-    * The portlet names for which the resources apply.
-    * <p>
-    * The annotated method can apply to multiple portlets within the portlet
-    * application. The names of the portlets to which the resources apply must be 
-    * specified in this field.
-    * <p>
-    * A wildcard character '*' can be specified in the first portletName array element 
-    * to indicate that the resource declarations are to apply to all portlets in 
-    * the portlet application.
-    * If specified, the wildcard character must appear alone in the first array element.
-    * </div>
-    * 
-    * @return     The portlet names
-    */
-   String[]   portletNames();
-   
-   /**
-    * <div class='container-change'>
-    * Sets the content type, or the MIME type, of content generated by the method.
-    * The content type will be set before the annotated method body is executed.
-    * <p>
-    * If this field is empty, no content type will be set.
-    * The portlet can then set the content type using the portlet API
-    * <code>RenderResponse#setContentType</code> method.
-    * </div>
-    * 
-    * @see        javax.portlet.RenderResponse#setContentType(String) RenderResponse#setContentType
-    * 
-    * @return     The content type
-    */
-   String   contentType() default "text/html";
-   
-   /**
-    * <div class='container-change'>
-    * Specifies a resource, such as a JSP, an HTML file, or a servlet, to be included.
-    * <p>
-    * The resource will be included using the 
-    * <code>PortletRequestDispatcher#include</code> method after the method body 
-    * has been executed.
-    * <p>
-    * If this field is empty, no resource will be included.
-    * </div>
-    * 
-    * @see        javax.portlet.PortletRequestDispatcher
-    * @see        javax.portlet.PortletRequestDispatcher#include(javax.portlet.PortletRequest, javax.portlet.PortletResponse) PortletRequestDispatcher#include
-    * 
-    * @return     The resource to be included
-    */
-   String   include() default "";
-   
-   /**
-    * <div class='container-change'>
-    * The dependencies the portlet may have on external resources.
-    * The resources can represent client-side prerequisites such as JavaScript libraries
-    * or stylesheet resources that are shared among portlets.
-    * </div>
-    * 
-    * @return     The dependencies
-    */
-   Dependency[]      dependencies() default {};
-   
-   /**
-    * <div class='container-change'>
-    * The ordinal number for this annotated method.
-    * <p>
-    * The ordinal number determines the order of execution if multiple methods
-    * are annotated.
-    * Annotated methods with a lower ordinal number are executed before methods with
-    * a higher ordinal number.
-    * </div>
-    * 
-    * @return     The ordinal number
-    */
-   int        ordinal() default 0;
-}


[22/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource2.java
new file mode 100644
index 0000000..4ff9811
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource2.java
@@ -0,0 +1,86 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.resource;
+
+import javax.activity.InvalidActivityException;
+import javax.inject.Inject;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.ServeResourceMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Resource2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @ServeResourceMethod(portletNames="portlet2", resourceID="edit", ordinal=-100)
+   public void resource2c(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource2c");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet2", resourceID="edit", ordinal=100)
+   public void resource2d(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource2d");
+   }
+   
+   // invalid signature
+   @ServeResourceMethod(portletNames="portlet4")
+   public void resource4(String x, ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource4");
+   }
+   
+   // invalid signature
+   @ServeResourceMethod(portletNames="portlet5")
+   public String resource5(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource5");
+      return null;
+   }
+   
+   // invalid signature, bad exception
+   @ServeResourceMethod(portletNames="portlet8")
+   public String resource8(ResourceRequest req, ResourceResponse resp) throws InvalidActivityException {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource8");
+      return null;
+   }
+   
+   @ServeResourceMethod(portletNames= {"portlet6", "portlet7"})
+   public void resource6and7(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource6and7");
+   }
+   
+   // ignored asterisk
+   @ServeResourceMethod(portletNames= {"portlet6", "*"}, ordinal=100)
+   public void resource6andStar(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource6andStar");
+   }
+   
+   @ServeResourceMethod(portletNames="*", resourceID="admin")
+   public void resourceAll(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resourceAll");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/package-info.java
new file mode 100644
index 0000000..a13a332
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.resource;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ActionTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ActionTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ActionTest.java
new file mode 100644
index 0000000..98d35b5
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/ActionTest.java
@@ -0,0 +1,242 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.ACTION;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.action.Action1;
+import org.apache.pluto.container.bean.processor.fixtures.action.Action2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for action method annotations.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Action1.class)
+public class ActionTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet2"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod2() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+   
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+   
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(ACTION, mi.getType());
+      assertEquals("", mi.getId());
+      assertEquals("portlet1", mi.getName());
+   }
+   
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(ACTION, mi.getType());
+      assertEquals("", mi.getId());
+      assertEquals("portlet2", mi.getName());
+   }
+   
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+      List<String> ids = Arrays.asList(new String[] {"", "Fred", "Barney"});
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(ACTION, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+   
+   @Test
+   public void class1Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action1", m.getName());
+      assertEquals(Action1.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class2Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action2", m.getName());
+      // don't know which one the scanner will find first
+      List<Class<?>> list = Arrays.asList(new Class<?>[] {Action1.class, Action2.class});
+      assertTrue(list.contains(m.getDeclaringClass()));
+   }
+   
+   @Test
+   public void class3Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action1a", m.getName());
+      assertEquals(Action2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class4Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "Fred", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action1b", m.getName());
+      assertEquals(Action2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class5Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "Barney", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action1c", m.getName());
+      assertEquals(Action2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class6Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "Wilma", ACTION);
+      AnnotatedMethod am = ams.getMethod(mi);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("action6", m.getName());
+      assertEquals(Action2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+   }
+   
+   @Test
+   public void pubEvent2Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(4, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub2")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub3")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub4")));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/DestroyTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/DestroyTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/DestroyTest.java
new file mode 100644
index 0000000..10c831a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/DestroyTest.java
@@ -0,0 +1,104 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.destroy.Destroy1;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for destroy method annotations
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Destroy1.class)
+public class DestroyTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet2"));
+   }
+   
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+   
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventFixupTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventFixupTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventFixupTest.java
new file mode 100644
index 0000000..bf8f224
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventFixupTest.java
@@ -0,0 +1,282 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.EVENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event1;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for PortletStateScoped beans
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Event1.class)
+public class EventFixupTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   private static String DEFAULT_NS = "http://www.java.net/";
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+      ams.setDefaultNamespace(DEFAULT_NS);
+   }
+   
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet2"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod2() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+   
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+   
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(EVENT, mi.getType());
+      QName qn = new QName("http://www.apache.org", "proc1");
+      assertEquals(qn, mi.getId());
+      assertEquals("portlet1", mi.getName());
+   }
+   
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(EVENT, mi.getType());
+      QName qn = new QName("http://www.apache.org", "proc2");
+      assertEquals(qn, mi.getId());
+      assertEquals("portlet2", mi.getName());
+   }
+   
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+      List<QName> ids = Arrays.asList(new QName[] {
+            new QName("http://www.apache.org", "proc3a"),
+            new QName(DEFAULT_NS, "proc3b"),
+            new QName("http://www.apache.org", "proc3c"),
+      });
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(EVENT, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+   
+   @Test
+   public void class1Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc1");
+      MethodIdentifier mi = new MethodIdentifier("portlet1", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("event1", m.getName());
+      assertEquals(Event1.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class2Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc2");
+      MethodIdentifier mi = new MethodIdentifier("portlet2", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("event2", m.getName());
+      // don't know which one the scanner will find first
+      List<Class<?>> clslst = Arrays.asList(new Class<?>[] {Event1.class, Event2.class});
+      assertTrue(clslst.contains(m.getDeclaringClass()));
+   }
+   
+   @Test
+   public void class6Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc6");
+      MethodIdentifier mi = new MethodIdentifier("portlet6", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      // order in which method found undefined
+      List<String> names = Arrays.asList(new String[] {"event6", "event7"});
+      assertTrue(names.contains(m.getName()));
+      assertEquals(Event2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class4Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+
+      List<String> methNames = Arrays.asList(new String[] {"event1a", "event1b", "event1c"});
+      for (MethodIdentifier mi : portlets) {
+         AnnotatedMethod am = ams.getMethod(mi);
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(methNames.contains(m.getName()));
+         assertEquals(Event2.class, m.getDeclaringClass());
+      }
+   }
+   
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+   }
+   
+   @Test
+   public void pubEvent2Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(4, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub2")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub3")));
+      assertTrue(qns.contains(new QName(DEFAULT_NS, "pub4")));
+   }
+   
+   @Test
+   public void procEvent1Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc1")));
+   }
+   
+   @Test
+   public void procEvent2Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet2");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc2")));
+   }
+   
+   @Test
+   public void procEvent3Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(3, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc3a")));
+      assertTrue(qns.contains(new QName(DEFAULT_NS, "proc3b")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc3c")));
+   }
+   
+   @Test
+   public void procEvent6Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet6");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc6")));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventTest.java
new file mode 100644
index 0000000..5e516bc
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/EventTest.java
@@ -0,0 +1,280 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.EVENT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event1;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for event method annotations
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Event1.class)
+public class EventTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet2"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod2() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet6"));
+   }
+   
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+   
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+   
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(EVENT, mi.getType());
+      QName qn = new QName("http://www.apache.org", "proc1");
+      assertEquals(qn, mi.getId());
+      assertEquals("portlet1", mi.getName());
+   }
+   
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      assertEquals(1, portlets.size());
+      MethodIdentifier mi = (MethodIdentifier) portlets.toArray()[0];
+      assertEquals(EVENT, mi.getType());
+      QName qn = new QName("http://www.apache.org", "proc2");
+      assertEquals(qn, mi.getId());
+      assertEquals("portlet2", mi.getName());
+   }
+   
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+      List<QName> ids = Arrays.asList(new QName[] {
+            new QName("http://www.apache.org", "proc3a"),
+            new QName(XMLConstants.NULL_NS_URI, "proc3b"),
+            new QName("http://www.apache.org", "proc3c"),
+      });
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(EVENT, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+   
+   @Test
+   public void class1Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc1");
+      MethodIdentifier mi = new MethodIdentifier("portlet1", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("event1", m.getName());
+      assertEquals(Event1.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class2Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc2");
+      MethodIdentifier mi = new MethodIdentifier("portlet2", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      assertEquals("event2", m.getName());
+      // don't know which one the scanner will find first
+      List<Class<?>> clslst = Arrays.asList(new Class<?>[] {Event1.class, Event2.class});
+      assertTrue(clslst.contains(m.getDeclaringClass()));
+   }
+   
+   @Test
+   public void class6Test() throws Exception {
+      QName qn = new QName("http://www.apache.org", "proc6");
+      MethodIdentifier mi = new MethodIdentifier("portlet6", qn, EVENT);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      AnnotatedMethod am = list.get(0);
+      assertNotNull(am);
+      Method m = am.getJavaMethod();
+      assertNotNull(m);
+      // order in which method found undefined
+      List<String> names = Arrays.asList(new String[] {"event6", "event7"});
+      assertTrue(names.contains(m.getName()));
+      assertEquals(Event2.class, m.getDeclaringClass());
+   }
+   
+   @Test
+   public void class4Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+
+      List<String> methNames = Arrays.asList(new String[] {"event1a", "event1b", "event1c"});
+      for (MethodIdentifier mi : portlets) {
+         AnnotatedMethod am = ams.getMethod(mi);
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(methNames.contains(m.getName()));
+         assertEquals(Event2.class, m.getDeclaringClass());
+      }
+   }
+   
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+   }
+   
+   @Test
+   public void pubEvent2Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(4, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub1")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub2")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "pub3")));
+      assertTrue(qns.contains(new QName(XMLConstants.NULL_NS_URI, "pub4")));
+   }
+   
+   @Test
+   public void procEvent1Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc1")));
+   }
+   
+   @Test
+   public void procEvent2Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet2");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc2")));
+   }
+   
+   @Test
+   public void procEvent3Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(3, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc3a")));
+      assertTrue(qns.contains(new QName(XMLConstants.NULL_NS_URI, "proc3b")));
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc3c")));
+   }
+   
+   @Test
+   public void procEvent6Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet6");
+      assertNotNull(qns);
+      assertEquals(1, qns.size());
+      assertTrue(qns.contains(new QName("http://www.apache.org", "proc6")));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/HeaderTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/HeaderTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/HeaderTest.java
new file mode 100644
index 0000000..2368521
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/HeaderTest.java
@@ -0,0 +1,375 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.apache.pluto.container.bean.processor.MethodType.HEADER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.header.Header1;
+import org.apache.pluto.container.bean.processor.fixtures.header.Header2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for header method annotations
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Header1.class)
+public class HeaderTest {
+
+   @Inject
+   AnnotatedConfigBean          acb;
+
+   private AnnotatedMethodStore ams     = null;
+   private ConfigSummary        summary = null;
+
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(6, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("*"));
+      assertTrue(names.contains("portlet3"));
+      assertTrue(names.contains("portlet6"));
+      assertTrue(names.contains("portlet7"));
+   }
+
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+
+   @Test
+   public void errorBadException() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("portlet8"));
+   }
+
+   @Test
+   public void errorBadAsterisk() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(4, names.size());
+      assertTrue(names.contains("*"));
+   }
+
+   @Test
+   public void methods1Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet1");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "", "ADMIN" });
+      assertEquals(2, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(HEADER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet1", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods2Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet2");
+      assertNotNull(portlets);
+      List<String> ids = Arrays.asList(new String[] { "HELP", "EDIT", "CONFIG", "ADMIN" });
+      assertEquals(4, portlets.size());
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(HEADER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet2", mi.getName());
+      }
+   }
+
+   @Test
+   public void methods3Test() throws Exception {
+      Set<MethodIdentifier> portlets = ams.getMethodIDsForPortlet("portlet3");
+      assertNotNull(portlets);
+      assertEquals(3, portlets.size());
+      List<String> ids = Arrays.asList(new String[] { "", "ADMIN", "HELP" });
+      for (MethodIdentifier mi : portlets) {
+         assertEquals(HEADER, mi.getType());
+         assertTrue(ids.contains(mi.getId()));
+         assertEquals("portlet3", mi.getName());
+      }
+   }
+
+   @Test
+   public void class1Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "header1a", "header1b", "header1c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class1aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet1", "ADMIN", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "headerAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(0, list.size());
+   }
+
+   @Test
+   public void class2aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "ADMIN", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "headerAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2hTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "HELP", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "header2a" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class2bTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "EDIT", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "header2c", "header2b", "header2d" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class2cTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet2", "CONFIG", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "header2c" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header1.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class3Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      List<String> names = Arrays.asList(new String[] { "header3c", "header3a", "header3b" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class3aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet3", "ADMIN", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "headerAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class6Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      List<String> names = Arrays.asList(new String[] { "header6and7", "header6andStar" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+      }
+      // verify order
+      assertArrayEquals(names.toArray(), methNames.toArray());
+   }
+
+   @Test
+   public void class6aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet6", "ADMIN", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "headerAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7Test() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "header6and7" });
+      List<String> methNames = new ArrayList<String>();
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         methNames.add(m.getName());
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void class7aTest() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("portlet7", "ADMIN", HEADER);
+      List<AnnotatedMethod> list = ams.getMethods(mi);
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      List<String> names = Arrays.asList(new String[] { "headerAll" });
+      for (AnnotatedMethod am : list) {
+         Method m = am.getJavaMethod();
+         assertNotNull(m);
+         assertTrue(names.contains(m.getName()));
+         assertEquals(Header2.class, m.getDeclaringClass());
+      }
+   }
+
+   @Test
+   public void pubEvent1Test() throws Exception {
+      List<QName> qns = ams.getPublishingEventRefs("portlet1");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+   @Test
+   public void procEvent1Test() throws Exception {
+      List<QName> qns = ams.getProcessingEventRefs("portlet3");
+      assertNotNull(qns);
+      assertEquals(0, qns.size());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InitTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InitTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InitTest.java
new file mode 100644
index 0000000..ff3a6d8
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InitTest.java
@@ -0,0 +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.container.bean.processor.tests;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.init.Init1;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for the InitMethod annotated methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Init1.class)
+public class InitTest {
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void configBeanTest() throws Exception {
+      AnnotatedConfigBean config = PortletCDIExtension.getConfig();
+      assertNotNull(config);
+      assertEquals(acb, config);
+      assertEquals(acb.getSummary(), config.getSummary());
+      assertEquals(acb.getMethodStore(), config.getMethodStore());
+   }
+   
+   @Test
+   public void portletNamesTest() throws Exception {
+      Set<String> names = ams.getPortletNames();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet1"));
+      assertTrue(names.contains("portlet2"));
+      assertTrue(names.contains("portlet3"));
+   }
+   
+   @Test
+   public void errorDuplicateMethod() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet2"));
+   }
+   
+   @Test
+   public void errorBadReturnType() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet5"));
+   }
+   
+   @Test
+   public void errorBadParameters() throws Exception {
+      List<String> names = summary.getPortletsWithErrors();
+      assertNotNull(names);
+      assertEquals(3, names.size());
+      assertTrue(names.contains("portlet4"));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeActionTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeActionTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeActionTest.java
new file mode 100644
index 0000000..66f1c1b
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeActionTest.java
@@ -0,0 +1,163 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.action.Action1;
+import org.apache.pluto.container.bean.processor.fixtures.action.Action2;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockActionRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockActionResponse;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for invoking the annotated action methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Action1.class)
+public class InvokeActionTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static MockActionRequest req = new MockActionRequest();
+   private static MockActionResponse resp = new MockActionResponse();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      req.setActionName(null);
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Action1.class.getSimpleName() + "#action1"));
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      req.setActionName(null);
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Action1.class.getSimpleName() + "#action2", 
+            Action2.class.getSimpleName() + "#action2",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+   @Test
+   public void invoke3a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      req.setActionName("");
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Action2.class.getSimpleName() + "#action1a"));
+   }
+   
+   @Test
+   public void invoke3b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      req.setActionName("Fred");
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Action2.class.getSimpleName() + "#action1b"));
+   }
+   
+   @Test
+   public void invoke3c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      req.setActionName("Barney");
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Action2.class.getSimpleName() + "#action1c"));
+   }
+   
+   @Test
+   public void invoke6() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      req.setActionName("Wilma");
+      i.processAction(req, resp);
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Action2.class.getSimpleName() + "#action6", 
+            Action2.class.getSimpleName() + "#action7",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeDestroyTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeDestroyTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeDestroyTest.java
new file mode 100644
index 0000000..440f9c4
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeDestroyTest.java
@@ -0,0 +1,113 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.destroy.Destroy1;
+import org.apache.pluto.container.bean.processor.fixtures.destroy.Destroy2;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for destroy method invocation.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Destroy1.class)
+public class InvokeDestroyTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      i.destroy();
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Destroy1.class.getSimpleName() + "#destroy1"));
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      i.destroy();
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Destroy1.class.getSimpleName() + "#destroy2", Destroy2.class.getSimpleName() + "#destroy2",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+   @Test
+   public void invoke3() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      i.destroy();
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Destroy2.class.getSimpleName() + "#destroy1"));
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeEventTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeEventTest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeEventTest.java
new file mode 100644
index 0000000..bea9920
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/tests/InvokeEventTest.java
@@ -0,0 +1,173 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.ConfigSummary;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event1;
+import org.apache.pluto.container.bean.processor.fixtures.event.Event2;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockEventRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockEventResponse;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.AdditionalPackages;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for invoking the annotated event methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses(PortletCDIExtension.class)
+@AdditionalPackages(Event1.class)
+public class InvokeEventTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   private static final MockEventRequest req = new MockEventRequest();
+   private static final MockEventResponse resp = new MockEventResponse();
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+   private ConfigSummary summary = null;
+   
+   private static String DEFAULT_NS = "http://www.java.net/";
+   
+   @Before
+   public void setUp() {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      summary = acb.getSummary();
+      
+      assertNotNull(ams);
+      assertNotNull(summary);
+      ams.setDefaultNamespace(DEFAULT_NS);
+   }
+   
+   @Test
+   public void invoke1() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet1");
+      QName qn = new QName("http://www.apache.org", "proc1");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Event1.class.getSimpleName() + "#event1"));
+   }
+   
+   @Test
+   public void invoke2() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet2");
+      QName qn = new QName("http://www.apache.org", "proc2");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Event1.class.getSimpleName() + "#event2", 
+            Event2.class.getSimpleName() + "#event2",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+   @Test
+   public void invoke3a() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      QName qn = new QName("http://www.apache.org", "proc3a");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Event2.class.getSimpleName() + "#event1a"));
+   }
+   
+   @Test
+   public void invoke3b() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      QName qn = new QName(DEFAULT_NS, "proc3b");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Event2.class.getSimpleName() + "#event1b"));
+   }
+   
+   @Test
+   public void invoke3c() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet3");
+      QName qn = new QName("http://www.apache.org", "proc3c");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(names.contains(Event2.class.getSimpleName() + "#event1c"));
+   }
+   
+   @Test
+   public void invoke6() throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, "portlet6");
+      QName qn = new QName("http://www.apache.org", "proc6");
+      req.setQn(qn);
+      i.processEvent(req, resp);
+      List<String> names = meths.getMethods();
+      // there are two valid possibilities
+      List<String> meths = Arrays.asList(new String[] {
+            Event2.class.getSimpleName() + "#event6", 
+            Event2.class.getSimpleName() + "#event7",
+            });
+      assertNotNull(names);
+      assertEquals(1, names.size());
+      assertTrue(meths.contains(names.get(0)));
+   }
+   
+}


[18/35] portals-pluto git commit: updates to portlet annotations

Posted by ms...@apache.org.
updates to portlet annotations


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

Branch: refs/heads/V3Prototype
Commit: 0e1cc3474d45befa4f6f82523974bbacfd339483
Parents: 9d5855d
Author: Scott Nicklous <ms...@apache.org>
Authored: Sat Jan 2 20:20:14 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Sat Jan 2 20:20:14 2016 +0100

----------------------------------------------------------------------
 .../src/main/java/javax/portlet/annotations/DestroyMethod.java     | 2 +-
 .../src/main/java/javax/portlet/annotations/InitMethod.java        | 2 +-
 .../main/java/javax/portlet/annotations/PortletSessionScoped.java  | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0e1cc347/portlet-api/src/main/java/javax/portlet/annotations/DestroyMethod.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/DestroyMethod.java b/portlet-api/src/main/java/javax/portlet/annotations/DestroyMethod.java
index 7b27cfe..52256d9 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/DestroyMethod.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/DestroyMethod.java
@@ -72,5 +72,5 @@ public @interface DestroyMethod {
     * 
     * @return  The portlet name
     */
-   String   portletName();
+   String   value();
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0e1cc347/portlet-api/src/main/java/javax/portlet/annotations/InitMethod.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/InitMethod.java b/portlet-api/src/main/java/javax/portlet/annotations/InitMethod.java
index ed6176b..1684ebc 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/InitMethod.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/InitMethod.java
@@ -70,5 +70,5 @@ public @interface InitMethod {
     * 
     * @return  The portlet name
     */
-   String   portletName();
+   String   value();
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0e1cc347/portlet-api/src/main/java/javax/portlet/annotations/PortletSessionScoped.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/PortletSessionScoped.java b/portlet-api/src/main/java/javax/portlet/annotations/PortletSessionScoped.java
index f10d83a..d35f5b1 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/PortletSessionScoped.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/PortletSessionScoped.java
@@ -62,7 +62,7 @@ public @interface PortletSessionScoped {
     * PortletSession.PORTLET_SCOPE - scopes the bean to the portlet session
     * </li>
     * <li>
-    * PortletSession.APPLICATION_SCOPED - Scopes the bean to the portlet application session.
+    * PortletSession.APPLICATION_SCOPE - Scopes the bean to the portlet application session.
     * The effect of this scope is the same as using the CDI @SessionScoped annotation.
     * </li>
     * </ul>


[25/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
index c4e0354..8f34ce5 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
@@ -19,41 +19,15 @@ package org.apache.pluto.container.impl;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.regex.Pattern;
 
-import javax.xml.XMLConstants;
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
-import javax.xml.bind.Marshaller;
-import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.helpers.DefaultValidationEventHandler;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.events.XMLEvent;
-import javax.xml.stream.util.StreamReaderDelegate;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathFactory;
 
 import org.apache.pluto.container.PortletAppDescriptorService;
 import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
-import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
 
 /**
  * Service that reads the portlet deployment descriptor.
@@ -63,6 +37,7 @@ public class PortletAppDescriptorServiceImpl implements PortletAppDescriptorServ
    
    /** Logger. */
    private static final Logger LOG = LoggerFactory.getLogger(PortletAppDescriptorServiceImpl.class);
+   @SuppressWarnings("unused")
    private static final boolean isDebug = LOG.isDebugEnabled();
    
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContextImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContextImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContextImpl.java
index 43a1539..8548fc3 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContextImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletContextImpl.java
@@ -1,190 +1,187 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Set;
-
-import javax.portlet.PortletContext;
-import javax.portlet.PortletRequestDispatcher;
-import javax.servlet.ServletContext;
-
-import org.apache.pluto.container.ContainerInfo;
-import org.apache.pluto.container.RequestDispatcherService;
-import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
-
-/**
- * Default Portlet Context Implementation.
- * 
- * @version $Id$
- */
-public class PortletContextImpl implements PortletContext
-{
-    // Private Member Variables ------------------------------------------------
-    
-    protected ServletContext servletContext;
-    protected PortletApplicationDefinition portletApp;
-    protected ContainerInfo containerInfo;
-    protected List<String> supportedContainerRuntimeOptions;
-    protected RequestDispatcherService rdService;
-
-    // Constructor -------------------------------------------------------------
-    
-    /**
-     * Constructs an instance.
-     * @param servletContext  the servlet context in which we are contained.
-     * @param portletApp  the portlet application descriptor.
-     */
-    public PortletContextImpl(ServletContext servletContext,
-                              PortletApplicationDefinition portletApp, 
-                              ContainerInfo containerInfo, 
-                              List<String> supportedContainerRuntimeOptions,
-                              RequestDispatcherService rdService)
-    {
-        this.servletContext = servletContext;
-        this.portletApp = portletApp;
-        this.containerInfo = containerInfo;
-        this.supportedContainerRuntimeOptions = supportedContainerRuntimeOptions;
-        this.rdService = rdService;
-    }
-    
-    // PortletContext Impl -----------------------------------------------------
-    
-    /**
-     * Retrieve the PortletContainer's server info.
-     * @return the server info in the form of <i>Server/Version</i>
-     */
-    public String getServerInfo() {
-        return containerInfo.getServerInfo();
-    }
-    
-    public PortletRequestDispatcher getRequestDispatcher(String path)
-    {
-        return rdService.getRequestDispatcher(servletContext, portletApp, path);
-    }
-    
-    public PortletRequestDispatcher getNamedDispatcher(String name)
-    {
-        return rdService.getNamedDispatcher(servletContext, portletApp, name);
-    }
-
-    public InputStream getResourceAsStream(String path) {
-        return servletContext.getResourceAsStream(path);
-    }
-
-    public int getMajorVersion() {
-        return containerInfo.getMajorSpecificationVersion();
-    }
-
-    public int getMinorVersion() {
-        return containerInfo.getMinorSpecificationVersion();
-    }
-
-    public String getMimeType(String file) {
-        return servletContext.getMimeType(file);
-    }
-
-    public String getRealPath(String path) {
-        return servletContext.getRealPath(path);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Set<String> getResourcePaths(String path) {
-        return servletContext.getResourcePaths(path);
-    }
-
-    public URL getResource(String path)
-        throws java.net.MalformedURLException {
-        if (path == null || !path.startsWith("/")) {
-            throw new MalformedURLException("path must start with a '/'");
-        }
-        return servletContext.getResource(path);
-    }
-
-    public Object getAttribute(java.lang.String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Attribute name == null");
-        }
-
-        return servletContext.getAttribute(name);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Enumeration<String> getAttributeNames() {
-        return servletContext.getAttributeNames();
-    }
-
-    public String getInitParameter(java.lang.String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Parameter name == null");
-        }
-
-        return servletContext.getInitParameter(name);
-    }
-
-    @SuppressWarnings("unchecked")
-    public Enumeration<String> getInitParameterNames() {
-        return servletContext.getInitParameterNames();
-    }
-
-    public void log(java.lang.String msg) {
-        servletContext.log(msg);
-    }
-
-    public void log(java.lang.String message, Throwable throwable) {
-        servletContext.log(message, throwable);
-    }
-
-    public void removeAttribute(String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("Attribute name == null");
-        }
-
-        servletContext.removeAttribute(name);
-    }
-
-    public void setAttribute(String name, Object object) {
-        if (name == null) {
-            throw new IllegalArgumentException("Attribute name == null");
-        }
-
-        servletContext.setAttribute(name, object);
-    }
-
-    public String getPortletContextName() {
-        return servletContext.getServletContextName();
-    }
-    
-    
-    public ServletContext getServletContext() {
-        return servletContext;
-    }
-
-    public PortletApplicationDefinition getPortletApplicationDefinition() {
-        return portletApp;
-    }
-
-	public Enumeration<String> getContainerRuntimeOptions() {
-	    return Collections.enumeration(supportedContainerRuntimeOptions);
-	}
-}
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Set;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequestDispatcher;
+import javax.servlet.ServletContext;
+
+import org.apache.pluto.container.ContainerInfo;
+import org.apache.pluto.container.RequestDispatcherService;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+
+/**
+ * Default Portlet Context Implementation.
+ * 
+ * @version $Id$
+ */
+public class PortletContextImpl implements PortletContext
+{
+    // Private Member Variables ------------------------------------------------
+    
+    protected ServletContext servletContext;
+    protected PortletApplicationDefinition portletApp;
+    protected ContainerInfo containerInfo;
+    protected List<String> supportedContainerRuntimeOptions;
+    protected RequestDispatcherService rdService;
+
+    // Constructor -------------------------------------------------------------
+    
+    /**
+     * Constructs an instance.
+     * @param servletContext  the servlet context in which we are contained.
+     * @param portletApp  the portlet application descriptor.
+     */
+    public PortletContextImpl(ServletContext servletContext,
+                              PortletApplicationDefinition portletApp, 
+                              ContainerInfo containerInfo, 
+                              List<String> supportedContainerRuntimeOptions,
+                              RequestDispatcherService rdService)
+    {
+        this.servletContext = servletContext;
+        this.portletApp = portletApp;
+        this.containerInfo = containerInfo;
+        this.supportedContainerRuntimeOptions = supportedContainerRuntimeOptions;
+        this.rdService = rdService;
+    }
+    
+    // PortletContext Impl -----------------------------------------------------
+    
+    /**
+     * Retrieve the PortletContainer's server info.
+     * @return the server info in the form of <i>Server/Version</i>
+     */
+    public String getServerInfo() {
+        return containerInfo.getServerInfo();
+    }
+    
+    public PortletRequestDispatcher getRequestDispatcher(String path)
+    {
+        return rdService.getRequestDispatcher(servletContext, portletApp, path);
+    }
+    
+    public PortletRequestDispatcher getNamedDispatcher(String name)
+    {
+        return rdService.getNamedDispatcher(servletContext, portletApp, name);
+    }
+
+    public InputStream getResourceAsStream(String path) {
+        return servletContext.getResourceAsStream(path);
+    }
+
+    public int getMajorVersion() {
+        return containerInfo.getMajorSpecificationVersion();
+    }
+
+    public int getMinorVersion() {
+        return containerInfo.getMinorSpecificationVersion();
+    }
+
+    public String getMimeType(String file) {
+        return servletContext.getMimeType(file);
+    }
+
+    public String getRealPath(String path) {
+        return servletContext.getRealPath(path);
+    }
+
+    public Set<String> getResourcePaths(String path) {
+        return servletContext.getResourcePaths(path);
+    }
+
+    public URL getResource(String path)
+        throws java.net.MalformedURLException {
+        if (path == null || !path.startsWith("/")) {
+            throw new MalformedURLException("path must start with a '/'");
+        }
+        return servletContext.getResource(path);
+    }
+
+    public Object getAttribute(java.lang.String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Attribute name == null");
+        }
+
+        return servletContext.getAttribute(name);
+    }
+
+    public Enumeration<String> getAttributeNames() {
+        return servletContext.getAttributeNames();
+    }
+
+    public String getInitParameter(java.lang.String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Parameter name == null");
+        }
+
+        return servletContext.getInitParameter(name);
+    }
+
+    public Enumeration<String> getInitParameterNames() {
+        return servletContext.getInitParameterNames();
+    }
+
+    public void log(java.lang.String msg) {
+        servletContext.log(msg);
+    }
+
+    public void log(java.lang.String message, Throwable throwable) {
+        servletContext.log(message, throwable);
+    }
+
+    public void removeAttribute(String name) {
+        if (name == null) {
+            throw new IllegalArgumentException("Attribute name == null");
+        }
+
+        servletContext.removeAttribute(name);
+    }
+
+    public void setAttribute(String name, Object object) {
+        if (name == null) {
+            throw new IllegalArgumentException("Attribute name == null");
+        }
+
+        servletContext.setAttribute(name, object);
+    }
+
+    public String getPortletContextName() {
+        return servletContext.getServletContextName();
+    }
+    
+    
+    public ServletContext getServletContext() {
+        return servletContext;
+    }
+
+    public PortletApplicationDefinition getPortletApplicationDefinition() {
+        return portletApp;
+    }
+
+	public Enumeration<String> getContainerRuntimeOptions() {
+	    return Collections.enumeration(supportedContainerRuntimeOptions);
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
index b50a8cd..938a4a5 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletParametersImpl.java
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class PortletParametersImpl implements PortletParameters {
    private static final Logger   LOGGER     = LoggerFactory.getLogger(PortletParametersImpl.class);
-   private static final boolean  isDebug    = LOGGER.isDebugEnabled();
+   //private static final boolean  isDebug    = LOGGER.isDebugEnabled();
    private static final boolean  isTrace    = LOGGER.isTraceEnabled();
    
    protected final PortletURLProvider  urlProvider;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletPreferencesImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletPreferencesImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletPreferencesImpl.java
index a634b4d..65cf0c9 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletPreferencesImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletPreferencesImpl.java
@@ -1,322 +1,322 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.portlet.PortletPreferences;
-import javax.portlet.PortletRequest;
-import javax.portlet.PreferencesValidator;
-import javax.portlet.ReadOnlyException;
-import javax.portlet.ValidatorException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.pluto.container.PortletPreference;
-import org.apache.pluto.container.PortletContainer;
-import org.apache.pluto.container.PortletContainerException;
-import org.apache.pluto.container.PortletPreferencesService;
-import org.apache.pluto.container.PortletWindow;
-import org.apache.pluto.container.om.portlet.PortletDefinition;
-import org.apache.pluto.container.util.StringManager;
-
-/**
- * Implementation of the <code>javax.portlet.PortletPreferences</code>
- * interface.
- * 
- * @see PortletPreferences
- * @see PortletPreferenceImpl
- */
-public class PortletPreferencesImpl implements PortletPreferences {
-	
-	/** Logger. */
-    private static final Logger LOG = LoggerFactory.getLogger(PortletPreferencesImpl.class);
-    
-    private static final StringManager EXCEPTIONS = StringManager.getManager(
-    		PortletPreferencesImpl.class.getPackage().getName());
-    
-    
-    // Private Member Variables ------------------------------------------------
-    
-    /** The portlet preferences service provided by the portal. */
-    private PortletPreferencesService preferencesService;
-
-    private PortletWindow window;
-
-    private PortletRequest request;
-    
-    /**
-     * Default portlet preferences retrieved from portlet.xml, and used for
-     * resetting portlet preferences.
-     */
-    private Map<String,PortletPreference> defaultPreferences;
-    
-    /**
-     * Current portlet preferences: key is the preference name as a string,
-     * value is the PortletPreference instance.
-     */
-    private final Map<String, PortletPreference> preferences = new HashMap<String, PortletPreference>();
-
-    // Constructor -------------------------------------------------------------
-    
-    /**
-     * Constructs an instance.
-     * @param container  the portlet container.
-     * @param window  the internal portlet window.
-     * @param request  the internal portlet request.
-     */
-    public PortletPreferencesImpl(PortletContainer container,
-                                  PortletWindow window,
-                                  PortletRequest request)
-    {
-        this.window = window;
-        this.request = request;
-        
-        // Get the portlet preferences service from container.
-        preferencesService = container.getContainerServices()
-        		.getPortletPreferencesService();
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Using PortletPreferencesService: "
-            		+ preferencesService.getClass().getName());
-        }
-        
-        try {
-            // Put default portlet preferences into preferences map.
-            defaultPreferences = preferencesService.getDefaultPreferences(window, request);
-            if (defaultPreferences != null) {
-                for (PortletPreference p : defaultPreferences.values()) {
-                    preferences.put(p.getName(), p.clone());
-                }
-            }
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Loaded default preferences: " + toString());
-            }
-            
-            // Merge stored portlet preferences into preferences map.
-            
-            Map<String,PortletPreference> storedPreferences = preferencesService
-            		.getStoredPreferences(window, request);
-            preferences.putAll(storedPreferences);
-        	
-        } catch (PortletContainerException ex) {
-            LOG.error("Error retrieving preferences.", ex);
-            //TODO: Rethrow up the stack????
-        }
-        if (LOG.isDebugEnabled()) {
-        	LOG.debug("Merged stored preferences: " + toString());
-        }
-    }
-    
-    
-    // PortletPreferences Impl -------------------------------------------------
-    
-    public boolean isReadOnly(String key) {
-        if (key == null) {
-            throw new IllegalArgumentException(
-            		EXCEPTIONS.getString("error.null", "Preference key "));
-        }
-        PortletPreference pref = preferences.get(key);
-        return (pref != null && pref.isReadOnly());
-    }
-
-    public String getValue(String key, String defaultValue) {
-        String[] values = getValues(key, new String[] { defaultValue });
-        String value = defaultValue;
-        if (values != null) {
-            if (values.length == 0) {
-                value = null;
-            }
-            else if (values[0] != null) {
-                value = values[0];
-            }
-        }
-        return value;
-    }
-
-    public String[] getValues(String key, String[] defaultValues) {
-        if (key == null) {
-            throw new IllegalArgumentException(
-                    EXCEPTIONS.getString("error.null", "Preference key "));
-        }
-        String[] values = null;
-        PortletPreference pref = preferences.get(key);
-        if (pref != null) {
-            values = pref.getValues();
-        }
-        if (values == null) {
-            values = defaultValues;
-        }
-        return values;
-    }
-
-    public void setValue(String key, String value) throws ReadOnlyException {
-        if (isReadOnly(key)) {
-            throw new ReadOnlyException(EXCEPTIONS.getString(
-                    "error.preference.readonly", key));
-        }
-        PortletPreference pref = preferences.get(key);
-        String[] values = value == null ? new String[0] : new String[] { value };
-        if (pref != null) {
-            pref.setValues(values);
-        } else {
-            pref = new PortletPreferenceImpl(key, values);
-            preferences.put(key, pref);
-        }
-    }
-
-    public void setValues(String key, String[] values) throws ReadOnlyException {
-        if (isReadOnly(key)) {
-            throw new ReadOnlyException(EXCEPTIONS.getString(
-                    "error.preference.readonly", key));
-        }
-        if (values == null) {
-            values = new String[0];
-        }
-        PortletPreference pref = preferences.get(key);
-        if (pref != null) {
-            pref.setValues(values);
-        } else {
-            pref = new PortletPreferenceImpl(key, values);
-            preferences.put(key, pref);
-        }
-    }
-
-    public Enumeration<String> getNames() {
-        return Collections.enumeration(preferences.keySet());
-    }
-
-    public Map<String,String[]> getMap() {
-        Map<String,String[]> map = new HashMap<String,String[]>();
-        for (PortletPreference pref : preferences.values()) {
-            map.put(pref.getName(),
-                    pref.getValues() != null ? pref.getValues().clone() : null);
-        }
-        return Collections.unmodifiableMap(map);
-    }
-    
-    public void reset(String key) throws ReadOnlyException {
-    	// Read-only preferences cannot be reset.
-        if (isReadOnly(key)) {
-            throw new ReadOnlyException(EXCEPTIONS.getString(
-            		"error.preference.readonly", key));
-        }
-        // Try to reset preference to the default values.
-        PortletPreference p = defaultPreferences.get(key);
-        if (p != null) {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Resetting preference for key: " + key);
-            }
-            preferences.put(key,p.clone());
-        }       
-        // Remove preference if default values are not defined (PLT.14.1).
-        else {
-        	if (LOG.isDebugEnabled()) {
-        		LOG.debug("Resetting preference to null for key: " + key);
-        	}
-        	preferences.remove(key);
-        }
-    }
-    
-    /**
-     * Stores the portlet preferences to a persistent storage. This method
-     * should only be invoked within <code>processAction()</code> method.
-     * 
-     * @see #internalStore()
-     * 
-     * @throws IllegalStateException  if this method is not invoked within
-     *         <code>processAction()</code> method.
-     * @throws ValidatorException  if the portlet preferences are not valid.
-     * @throws IOException  if an error occurs with the persistence mechanism.
-     */
-    public void store() throws IOException, ValidatorException {
-        if (PortletRequest.RENDER_PHASE.equals(request.getAttribute(PortletRequest.LIFECYCLE_PHASE))) {
-            throw new IllegalStateException(
-                	"store is not allowed during RENDER phase.");
-        }
-        internalStore();
-    }
-    
-    
-    // Private Methods ---------------------------------------------------------
-    
-    /**
-     * Stores the portlet preferences to a persistent storage. If a preferences
-     * validator is defined for this portlet, this method firstly validates the
-     * portlet preferences.
-     * <p>
-     * This method is invoked internally, thus it does not check the portlet
-     * request method ID (METHOD_RENDER or METHOD_ACTION).
-     * </p>
-     * @throws ValidatorException  if the portlet preferences are not valid.
-     * @throws IOException  if an error occurs with the persistence mechanism.
-     */
-    protected final void internalStore() throws IOException, ValidatorException {
-        // Validate the preferences before storing, if a validator is defined.
-        //   If the preferences cannot pass the validation,
-        //   an ValidatorException will be thrown out.
-        PortletDefinition portletD = window.getPortletDefinition();
-        PreferencesValidator validator = preferencesService.getPreferencesValidator(portletD);
-        if (validator != null)
-        {
-            validator.validate(this);
-        }
-        // Store the portlet preferences.
-        try {
-        	preferencesService.store(window, request, preferences);
-        } catch (PortletContainerException ex) {
-            LOG.error("Error storing preferences.", ex);
-            throw new IOException("Error storing perferences: " + ex.getMessage());
-        }
-    }
-    
-    
-    // Object Methods ----------------------------------------------------------
-    
-    /**
-     * Returns the string representation of this object. Preferences are
-     * separated by ';' character, while values in one preference are separated
-     * by ',' character.
-     * @return the string representation of this object.
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-    	StringBuffer buffer = new StringBuffer();    	
-    	buffer.append(getClass().getName()).append("[");
-    	for (PortletPreference p : preferences.values()) {
-            buffer.append(p.getName());
-            buffer.append("(readOnly:").append(p.isReadOnly()).append(")=");
-            String[] values = p.getValues();
-            if (values != null) {
-                for (int i = 0; i < values.length; i++) {
-                    buffer.append(values[i]);
-                    if (i < values.length - 1) {
-                        buffer.append(",");
-                    }
-                }
-            } else {
-                buffer.append("NULL");
-            }
-            buffer.append(";");
-    	}
-    	buffer.append("]");
-    	return buffer.toString();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ReadOnlyException;
+import javax.portlet.ValidatorException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.pluto.container.PortletPreference;
+import org.apache.pluto.container.PortletContainer;
+import org.apache.pluto.container.PortletContainerException;
+import org.apache.pluto.container.PortletPreferencesService;
+import org.apache.pluto.container.PortletWindow;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.util.StringManager;
+
+/**
+ * Implementation of the <code>javax.portlet.PortletPreferences</code>
+ * interface.
+ * 
+ * @see PortletPreferences
+ * @see PortletPreferenceImpl
+ */
+public class PortletPreferencesImpl implements PortletPreferences {
+	
+	/** Logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(PortletPreferencesImpl.class);
+    
+    private static final StringManager EXCEPTIONS = StringManager.getManager(
+    		PortletPreferencesImpl.class.getPackage().getName());
+    
+    
+    // Private Member Variables ------------------------------------------------
+    
+    /** The portlet preferences service provided by the portal. */
+    private PortletPreferencesService preferencesService;
+
+    private PortletWindow window;
+
+    private PortletRequest request;
+    
+    /**
+     * Default portlet preferences retrieved from portlet.xml, and used for
+     * resetting portlet preferences.
+     */
+    private Map<String,PortletPreference> defaultPreferences;
+    
+    /**
+     * Current portlet preferences: key is the preference name as a string,
+     * value is the PortletPreference instance.
+     */
+    private final Map<String, PortletPreference> preferences = new HashMap<String, PortletPreference>();
+
+    // Constructor -------------------------------------------------------------
+    
+    /**
+     * Constructs an instance.
+     * @param container  the portlet container.
+     * @param window  the internal portlet window.
+     * @param request  the internal portlet request.
+     */
+    public PortletPreferencesImpl(PortletContainer container,
+                                  PortletWindow window,
+                                  PortletRequest request)
+    {
+        this.window = window;
+        this.request = request;
+        
+        // Get the portlet preferences service from container.
+        preferencesService = container.getContainerServices()
+        		.getPortletPreferencesService();
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Using PortletPreferencesService: "
+            		+ preferencesService.getClass().getName());
+        }
+        
+        try {
+            // Put default portlet preferences into preferences map.
+            defaultPreferences = preferencesService.getDefaultPreferences(window, request);
+            if (defaultPreferences != null) {
+                for (PortletPreference p : defaultPreferences.values()) {
+                    preferences.put(p.getName(), p.clone());
+                }
+            }
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Loaded default preferences: " + toString());
+            }
+            
+            // Merge stored portlet preferences into preferences map.
+            
+            Map<String,PortletPreference> storedPreferences = preferencesService
+            		.getStoredPreferences(window, request);
+            preferences.putAll(storedPreferences);
+        	
+        } catch (PortletContainerException ex) {
+            LOG.error("Error retrieving preferences.", ex);
+            //TODO: Rethrow up the stack????
+        }
+        if (LOG.isDebugEnabled()) {
+        	LOG.debug("Merged stored preferences: " + toString());
+        }
+    }
+    
+    
+    // PortletPreferences Impl -------------------------------------------------
+    
+    public boolean isReadOnly(String key) {
+        if (key == null) {
+            throw new IllegalArgumentException(
+            		EXCEPTIONS.getString("error.null", "Preference key "));
+        }
+        PortletPreference pref = preferences.get(key);
+        return (pref != null && pref.isReadOnly());
+    }
+
+    public String getValue(String key, String defaultValue) {
+        String[] values = getValues(key, new String[] { defaultValue });
+        String value = defaultValue;
+        if (values != null) {
+            if (values.length == 0) {
+                value = null;
+            }
+            else if (values[0] != null) {
+                value = values[0];
+            }
+        }
+        return value;
+    }
+
+    public String[] getValues(String key, String[] defaultValues) {
+        if (key == null) {
+            throw new IllegalArgumentException(
+                    EXCEPTIONS.getString("error.null", "Preference key "));
+        }
+        String[] values = null;
+        PortletPreference pref = preferences.get(key);
+        if (pref != null) {
+            values = pref.getValues();
+        }
+        if (values == null) {
+            values = defaultValues;
+        }
+        return values;
+    }
+
+    public void setValue(String key, String value) throws ReadOnlyException {
+        if (isReadOnly(key)) {
+            throw new ReadOnlyException(EXCEPTIONS.getString(
+                    "error.preference.readonly", key));
+        }
+        PortletPreference pref = preferences.get(key);
+        String[] values = value == null ? new String[0] : new String[] { value };
+        if (pref != null) {
+            pref.setValues(values);
+        } else {
+            pref = new PortletPreferenceImpl(key, values);
+            preferences.put(key, pref);
+        }
+    }
+
+    public void setValues(String key, String... values) throws ReadOnlyException {
+        if (isReadOnly(key)) {
+            throw new ReadOnlyException(EXCEPTIONS.getString(
+                    "error.preference.readonly", key));
+        }
+        if (values == null) {
+            values = new String[0];
+        }
+        PortletPreference pref = preferences.get(key);
+        if (pref != null) {
+            pref.setValues(values);
+        } else {
+            pref = new PortletPreferenceImpl(key, values);
+            preferences.put(key, pref);
+        }
+    }
+
+    public Enumeration<String> getNames() {
+        return Collections.enumeration(preferences.keySet());
+    }
+
+    public Map<String,String[]> getMap() {
+        Map<String,String[]> map = new HashMap<String,String[]>();
+        for (PortletPreference pref : preferences.values()) {
+            map.put(pref.getName(),
+                    pref.getValues() != null ? pref.getValues().clone() : null);
+        }
+        return Collections.unmodifiableMap(map);
+    }
+    
+    public void reset(String key) throws ReadOnlyException {
+    	// Read-only preferences cannot be reset.
+        if (isReadOnly(key)) {
+            throw new ReadOnlyException(EXCEPTIONS.getString(
+            		"error.preference.readonly", key));
+        }
+        // Try to reset preference to the default values.
+        PortletPreference p = defaultPreferences.get(key);
+        if (p != null) {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Resetting preference for key: " + key);
+            }
+            preferences.put(key,p.clone());
+        }       
+        // Remove preference if default values are not defined (PLT.14.1).
+        else {
+        	if (LOG.isDebugEnabled()) {
+        		LOG.debug("Resetting preference to null for key: " + key);
+        	}
+        	preferences.remove(key);
+        }
+    }
+    
+    /**
+     * Stores the portlet preferences to a persistent storage. This method
+     * should only be invoked within <code>processAction()</code> method.
+     * 
+     * @see #internalStore()
+     * 
+     * @throws IllegalStateException  if this method is not invoked within
+     *         <code>processAction()</code> method.
+     * @throws ValidatorException  if the portlet preferences are not valid.
+     * @throws IOException  if an error occurs with the persistence mechanism.
+     */
+    public void store() throws IOException, ValidatorException {
+        if (PortletRequest.RENDER_PHASE.equals(request.getAttribute(PortletRequest.LIFECYCLE_PHASE))) {
+            throw new IllegalStateException(
+                	"store is not allowed during RENDER phase.");
+        }
+        internalStore();
+    }
+    
+    
+    // Private Methods ---------------------------------------------------------
+    
+    /**
+     * Stores the portlet preferences to a persistent storage. If a preferences
+     * validator is defined for this portlet, this method firstly validates the
+     * portlet preferences.
+     * <p>
+     * This method is invoked internally, thus it does not check the portlet
+     * request method ID (METHOD_RENDER or METHOD_ACTION).
+     * </p>
+     * @throws ValidatorException  if the portlet preferences are not valid.
+     * @throws IOException  if an error occurs with the persistence mechanism.
+     */
+    protected final void internalStore() throws IOException, ValidatorException {
+        // Validate the preferences before storing, if a validator is defined.
+        //   If the preferences cannot pass the validation,
+        //   an ValidatorException will be thrown out.
+        PortletDefinition portletD = window.getPortletDefinition();
+        PreferencesValidator validator = preferencesService.getPreferencesValidator(portletD);
+        if (validator != null)
+        {
+            validator.validate(this);
+        }
+        // Store the portlet preferences.
+        try {
+        	preferencesService.store(window, request, preferences);
+        } catch (PortletContainerException ex) {
+            LOG.error("Error storing preferences.", ex);
+            throw new IOException("Error storing perferences: " + ex.getMessage());
+        }
+    }
+    
+    
+    // Object Methods ----------------------------------------------------------
+    
+    /**
+     * Returns the string representation of this object. Preferences are
+     * separated by ';' character, while values in one preference are separated
+     * by ',' character.
+     * @return the string representation of this object.
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+    	StringBuffer buffer = new StringBuffer();    	
+    	buffer.append(getClass().getName()).append("[");
+    	for (PortletPreference p : preferences.values()) {
+            buffer.append(p.getName());
+            buffer.append("(readOnly:").append(p.isReadOnly()).append(")=");
+            String[] values = p.getValues();
+            if (values != null) {
+                for (int i = 0; i < values.length; i++) {
+                    buffer.append(values[i]);
+                    if (i < values.length - 1) {
+                        buffer.append(",");
+                    }
+                }
+            } else {
+                buffer.append("NULL");
+            }
+            buffer.append(";");
+    	}
+    	buffer.append("]");
+    	return buffer.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletResponseImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletResponseImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletResponseImpl.java
index a7f7e36..79e9281 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletResponseImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletResponseImpl.java
@@ -18,7 +18,6 @@ package org.apache.pluto.container.impl;
 
 import java.util.Enumeration;
 
-import javax.portlet.MimeResponse;
 import javax.portlet.PortalContext;
 import javax.portlet.PortletMode;
 import javax.portlet.PortletResponse;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletSessionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletSessionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletSessionImpl.java
index 0257dd4..d8fdf60 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletSessionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletSessionImpl.java
@@ -1,329 +1,328 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.portlet.PortletContext;
-import javax.portlet.PortletSession;
-import javax.portlet.PortletSessionUtil;
-import javax.servlet.http.HttpSession;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.pluto.container.PortletWindow;
-import org.apache.pluto.container.util.ArgumentUtility;
-
-/**
- * Implementation of the <code>javax.portlet.PortletSession</code> interface.
- * 
- */
-public class PortletSessionImpl implements PortletSession {
-	
-	/** Logger. */
-    private static final Logger LOG = LoggerFactory.getLogger(PortletSessionImpl.class);
-    
-    /** The default scope (<code>PORTLET_SCOPE</code>) for storing objects. */
-    protected static final int DEFAULT_SCOPE = PortletSession.PORTLET_SCOPE;
-    
-    /** The portlet scope namespace as defined in PLT. 15.3. */
-    protected static final String PORTLET_SCOPE_NAMESPACE = "javax.portlet.p.";
-    
-    /** The portlet window ID / attribute name separator as defined in PLT. 15.3. */
-    protected static final char ID_NAME_SEPARATOR = '?';
-
-    
-    // Private Member Variables ------------------------------------------------
-    
-    /** The wrapped HttpSession object. */
-    private HttpSession httpSession;
-    
-    /** The portlet context. */
-    private PortletContext portletContext;
-    
-    /** The portlet window. */
-    private PortletWindow portletWindow;
-    
-    // Constructor -------------------------------------------------------------
-    
-    /**
-     * Constructs an instance.
-     */
-    public PortletSessionImpl(PortletContext portletContext,
-                              PortletWindow portletWindow,
-                              HttpSession httpSession) {
-        this.portletContext = portletContext;
-        this.portletWindow = portletWindow;
-        this.httpSession = httpSession;
-    }
-    
-    // InternalPortletSession Impl -----------------------------------------
-    
-    public HttpSession getHttpSession()
-    {
-        return httpSession;
-    }
-    
-    // PortletSession Impl: Attributes -----------------------------------------
-    
-    public Object getAttribute(String name) {
-        return getAttribute(name, DEFAULT_SCOPE);
-    }
-    
-    /**
-     * Returns the attribute of the specified name under the given scope.
-     * 
-     * @param name  the attribute name.
-     * @param scope  the scope under which the attribute object is stored.
-     * @return the attribute object.
-     */
-    public Object getAttribute(String name, int scope) {
-    	ArgumentUtility.validateNotNull("attributeName", name);
-    	String key = (scope == PortletSession.APPLICATION_SCOPE)
-    			? name : createPortletScopedId(name);
-    	return httpSession.getAttribute(key);
-    }
-    
-    public Enumeration<String> getAttributeNames() {
-        return getAttributeNames(DEFAULT_SCOPE);
-    }
-    
-    @SuppressWarnings("unchecked")
-    public Enumeration<String> getAttributeNames(int scope) {
-    	// Return all attribute names in the nested HttpSession object.
-        if (scope == PortletSession.APPLICATION_SCOPE) {
-            return httpSession.getAttributeNames();
-        }
-        // Return attribute names with the portlet-scoped prefix.
-        Vector<String> portletScopedNames = new Vector<String>();
-        for (Enumeration<String> en = httpSession.getAttributeNames();
-        en.hasMoreElements(); ) {
-        	String name = en.nextElement();
-        	if (isInCurrentPortletScope(name)) {
-        		portletScopedNames.add(
-        				PortletSessionUtil.decodeAttributeName(name));
-        	}
-        }
-        return portletScopedNames.elements();
-        
-    }
-    
-    public void removeAttribute(String name) {
-        removeAttribute(name, DEFAULT_SCOPE);
-    }
-
-    public void removeAttribute(String name, int scope) {
-    	ArgumentUtility.validateNotNull("attributeName", name);
-    	if (scope == PortletSession.APPLICATION_SCOPE) {
-    		httpSession.removeAttribute(name);
-    	} else {
-    		httpSession.removeAttribute(createPortletScopedId(name));
-    	}
-    }
-    
-    public void setAttribute(String name, Object value) {
-    	setAttribute(name, value, DEFAULT_SCOPE);
-    }
-
-    public void setAttribute(String name, Object value, int scope) {
-    	ArgumentUtility.validateNotNull("attributeName", name);
-    	if (scope == PortletSession.APPLICATION_SCOPE) {
-    		httpSession.setAttribute(name, value);
-    	} else {
-    		httpSession.setAttribute(createPortletScopedId(name),  value);
-    	}
-    }
-
-    
-    // PortletSession Impl: Other Methods --------------------------------------
-    
-    public PortletContext getPortletContext() {
-        return portletContext;
-    }
-
-    public long getCreationTime() {
-        return httpSession.getCreationTime();
-    }
-
-    public String getId() {
-        return httpSession.getId();
-    }
-
-    public long getLastAccessedTime() {
-        return httpSession.getLastAccessedTime();
-    }
-
-    public int getMaxInactiveInterval() {
-        return httpSession.getMaxInactiveInterval();
-    }
-
-    public void invalidate(){
-        httpSession.invalidate();
-    }
-
-    public boolean isNew(){
-        return httpSession.isNew();
-    }
-    
-    /**
-     * Specifies the time, in seconds, between client requests, before the
-     * portlet container invalidates this session. A negative time indicates
-     * the session should never timeout.
-     * <p>
-     * [Portlet Spec. PLT. 15.4.] If the PortletSession object is invalidated
-     * by a portlet, the portlet container must invalidate the associated
-     * HttpSession object.
-     * </p>
-     * @param interval  an integer specifying the number of seconds.
-     */ 
-    public void setMaxInactiveInterval(int interval) {
-        httpSession.setMaxInactiveInterval(interval);
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("Session timeout set to: " + interval);
-        }
-    }
-    
-    
-    // Private Methods ---------------------------------------------------------
-    
-    /**
-     * Creates portlet-scoped ID for the specified attribute name.
-     * Portlet-scoped ID for a given attribute name has the following form:
-     * <code>javax.portlet.p.&lt;ID&gt;?&lt;name&gt;</code>
-     * where <code>ID</code> is a unique identification for the portlet window
-     * (assigned by the portal/portlet-container) that must not contain a '?'
-     * character. <code>name</code> is the attribute name.
-     * <p>
-     * Refer to Portlet Specification PLT. 15.3 for more details.
-     * </p>
-     * @param name  the attribute name.
-     * @return portlet-scoped ID for the attribute name.
-     */
-    protected String createPortletScopedId(String name) {
-    	StringBuffer buffer = new StringBuffer();
-    	buffer.append(PORTLET_SCOPE_NAMESPACE);
-    	buffer.append(portletWindow.getId().getStringId());
-    	buffer.append(ID_NAME_SEPARATOR);
-    	buffer.append(name);
-    	return buffer.toString();
-    }
-    
-    /**
-     * Checks if the attribute name in APPLICATION_SCOPE is in the current
-     * portlet scope. 
-     * @param name  the attribute name to check.
-     * @return true if the attribute name is in the current portlet scope.
-     * @see #createPortletScopedId(String)
-     */
-    protected boolean isInCurrentPortletScope(String name) {
-    	// Portlet-scoped attribute names MUST start with "javax.portlet.p.",
-    	//   and contain the ID-name separator '?'.
-    	if (name.startsWith(PORTLET_SCOPE_NAMESPACE)
-    			&& name.indexOf(ID_NAME_SEPARATOR) > -1) {
-        	String id = name.substring(PORTLET_SCOPE_NAMESPACE.length(),
-        	                           name.indexOf(ID_NAME_SEPARATOR));
-        	return (id.equals(portletWindow.getId().getStringId()));
-        }
-    	// Application-scoped attribute names are not in portlet scope.
-    	return false;
-    }
-    
-    
-    // HttpSession Impl --------------------------------------------------------
-    
-	public Map<String, Object> getMap() {
-		List<String> paramNames = getAttributeNamesAsList(DEFAULT_SCOPE);		
-		return fillMap(paramNames, DEFAULT_SCOPE);	
-	}
-
-	public Map<String, Object> getMap(int scope) {
-		List<String> paramNames = getAttributeNamesAsList(scope);		
-		return fillMap(paramNames, scope);
-	}
-    
-// ***** private methods *****
-
-	/**
-	 * transforms the getAttributeNames enumeration to a list
-	 * @return list of getAttributeNames
-	 */
-	private List<String> getAttributeNamesAsList(int scope) {
-		//transform Enum to List
-		List<String> paramNames = new ArrayList<String>();
-		Enumeration<String> e = getAttributeNames(scope);
-		while (e.hasMoreElements()){
-			paramNames.add(e.nextElement());
-		}
-		return paramNames;
-	}
-	
-	/**
-	 * @param paramNames list of the attribute names to be filled in the map
-	 * @return the filled map
-	 */
-	private Map<String, Object> fillMap(List<String> paramNames, int scope) {
-		Map<String, Object> resultMap = new HashMap<String, Object>();
-		for (String string : paramNames) {
-			resultMap.put(string, getAttribute(string,scope));
-		}
-		return resultMap;
-	}
-
-	/** 
-	   * Returns a <code>Map</code> of the session attributes in
-	   * the portlet session scope.
-	   * <p>
-	   * The keys are of type <code>String</code> and the values in the 
-	   * returned <code>Map</code> are from type <code>Object</code>.
-	   * <p>
-	   * If no session attributes exist this method returns an empty <code>Map</code>.
-	   *
-	   * @return     an immutable <code>Map</code> containing the session attributes in the  
-	   *             portlet session scope as keys and attribute values as map values, or an empty <code>Map</code>
-	   *             if no session attributes exist. The keys in the
-	   *             map are of type String, the values of type
-	   *             Object.
-	   *  @since 2.0
-	   */
-	  public Map<String, Object> getAttributeMap(int scope){
-		  return getMap(scope); 
-	  }
-	  /** 
-	   * Returns a <code>Map</code> of the session attributes in
-	   * the portlet session scope.
-	   * <p>
-	   * The keys are of type <code>String</code> and the values in the 
-	   * returned <code>Map</code> are from type <code>Object</code>.
-	   * <p>
-	   * If no session attributes exist this method returns an empty <code>Map</code>.
-	   *
-	   * @return     an immutable <code>Map</code> containing the session attributes in the  
-	   *             portlet session scope as keys and attribute values as map values, or an empty <code>Map</code>
-	   *             if no session attributes exist. The keys in the
-	   *             map are of type String, the values of type
-	   *             Object.
-	   *  @since 2.0
-	   */
-	  public Map<String, Object> getAttributeMap(){
-		  return getMap();
-	  }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+import javax.portlet.PortletSessionUtil;
+import javax.servlet.http.HttpSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.pluto.container.PortletWindow;
+import org.apache.pluto.container.util.ArgumentUtility;
+
+/**
+ * Implementation of the <code>javax.portlet.PortletSession</code> interface.
+ * 
+ */
+public class PortletSessionImpl implements PortletSession {
+	
+	/** Logger. */
+    private static final Logger LOG = LoggerFactory.getLogger(PortletSessionImpl.class);
+    
+    /** The default scope (<code>PORTLET_SCOPE</code>) for storing objects. */
+    protected static final int DEFAULT_SCOPE = PortletSession.PORTLET_SCOPE;
+    
+    /** The portlet scope namespace as defined in PLT. 15.3. */
+    protected static final String PORTLET_SCOPE_NAMESPACE = "javax.portlet.p.";
+    
+    /** The portlet window ID / attribute name separator as defined in PLT. 15.3. */
+    protected static final char ID_NAME_SEPARATOR = '?';
+
+    
+    // Private Member Variables ------------------------------------------------
+    
+    /** The wrapped HttpSession object. */
+    private HttpSession httpSession;
+    
+    /** The portlet context. */
+    private PortletContext portletContext;
+    
+    /** The portlet window. */
+    private PortletWindow portletWindow;
+    
+    // Constructor -------------------------------------------------------------
+    
+    /**
+     * Constructs an instance.
+     */
+    public PortletSessionImpl(PortletContext portletContext,
+                              PortletWindow portletWindow,
+                              HttpSession httpSession) {
+        this.portletContext = portletContext;
+        this.portletWindow = portletWindow;
+        this.httpSession = httpSession;
+    }
+    
+    // InternalPortletSession Impl -----------------------------------------
+    
+    public HttpSession getHttpSession()
+    {
+        return httpSession;
+    }
+    
+    // PortletSession Impl: Attributes -----------------------------------------
+    
+    public Object getAttribute(String name) {
+        return getAttribute(name, DEFAULT_SCOPE);
+    }
+    
+    /**
+     * Returns the attribute of the specified name under the given scope.
+     * 
+     * @param name  the attribute name.
+     * @param scope  the scope under which the attribute object is stored.
+     * @return the attribute object.
+     */
+    public Object getAttribute(String name, int scope) {
+    	ArgumentUtility.validateNotNull("attributeName", name);
+    	String key = (scope == PortletSession.APPLICATION_SCOPE)
+    			? name : createPortletScopedId(name);
+    	return httpSession.getAttribute(key);
+    }
+    
+    public Enumeration<String> getAttributeNames() {
+        return getAttributeNames(DEFAULT_SCOPE);
+    }
+    
+    public Enumeration<String> getAttributeNames(int scope) {
+    	// Return all attribute names in the nested HttpSession object.
+        if (scope == PortletSession.APPLICATION_SCOPE) {
+            return httpSession.getAttributeNames();
+        }
+        // Return attribute names with the portlet-scoped prefix.
+        Vector<String> portletScopedNames = new Vector<String>();
+        for (Enumeration<String> en = httpSession.getAttributeNames();
+        en.hasMoreElements(); ) {
+        	String name = en.nextElement();
+        	if (isInCurrentPortletScope(name)) {
+        		portletScopedNames.add(
+        				PortletSessionUtil.decodeAttributeName(name));
+        	}
+        }
+        return portletScopedNames.elements();
+        
+    }
+    
+    public void removeAttribute(String name) {
+        removeAttribute(name, DEFAULT_SCOPE);
+    }
+
+    public void removeAttribute(String name, int scope) {
+    	ArgumentUtility.validateNotNull("attributeName", name);
+    	if (scope == PortletSession.APPLICATION_SCOPE) {
+    		httpSession.removeAttribute(name);
+    	} else {
+    		httpSession.removeAttribute(createPortletScopedId(name));
+    	}
+    }
+    
+    public void setAttribute(String name, Object value) {
+    	setAttribute(name, value, DEFAULT_SCOPE);
+    }
+
+    public void setAttribute(String name, Object value, int scope) {
+    	ArgumentUtility.validateNotNull("attributeName", name);
+    	if (scope == PortletSession.APPLICATION_SCOPE) {
+    		httpSession.setAttribute(name, value);
+    	} else {
+    		httpSession.setAttribute(createPortletScopedId(name),  value);
+    	}
+    }
+
+    
+    // PortletSession Impl: Other Methods --------------------------------------
+    
+    public PortletContext getPortletContext() {
+        return portletContext;
+    }
+
+    public long getCreationTime() {
+        return httpSession.getCreationTime();
+    }
+
+    public String getId() {
+        return httpSession.getId();
+    }
+
+    public long getLastAccessedTime() {
+        return httpSession.getLastAccessedTime();
+    }
+
+    public int getMaxInactiveInterval() {
+        return httpSession.getMaxInactiveInterval();
+    }
+
+    public void invalidate(){
+        httpSession.invalidate();
+    }
+
+    public boolean isNew(){
+        return httpSession.isNew();
+    }
+    
+    /**
+     * Specifies the time, in seconds, between client requests, before the
+     * portlet container invalidates this session. A negative time indicates
+     * the session should never timeout.
+     * <p>
+     * [Portlet Spec. PLT. 15.4.] If the PortletSession object is invalidated
+     * by a portlet, the portlet container must invalidate the associated
+     * HttpSession object.
+     * </p>
+     * @param interval  an integer specifying the number of seconds.
+     */ 
+    public void setMaxInactiveInterval(int interval) {
+        httpSession.setMaxInactiveInterval(interval);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Session timeout set to: " + interval);
+        }
+    }
+    
+    
+    // Private Methods ---------------------------------------------------------
+    
+    /**
+     * Creates portlet-scoped ID for the specified attribute name.
+     * Portlet-scoped ID for a given attribute name has the following form:
+     * <code>javax.portlet.p.&lt;ID&gt;?&lt;name&gt;</code>
+     * where <code>ID</code> is a unique identification for the portlet window
+     * (assigned by the portal/portlet-container) that must not contain a '?'
+     * character. <code>name</code> is the attribute name.
+     * <p>
+     * Refer to Portlet Specification PLT. 15.3 for more details.
+     * </p>
+     * @param name  the attribute name.
+     * @return portlet-scoped ID for the attribute name.
+     */
+    protected String createPortletScopedId(String name) {
+    	StringBuffer buffer = new StringBuffer();
+    	buffer.append(PORTLET_SCOPE_NAMESPACE);
+    	buffer.append(portletWindow.getId().getStringId());
+    	buffer.append(ID_NAME_SEPARATOR);
+    	buffer.append(name);
+    	return buffer.toString();
+    }
+    
+    /**
+     * Checks if the attribute name in APPLICATION_SCOPE is in the current
+     * portlet scope. 
+     * @param name  the attribute name to check.
+     * @return true if the attribute name is in the current portlet scope.
+     * @see #createPortletScopedId(String)
+     */
+    protected boolean isInCurrentPortletScope(String name) {
+    	// Portlet-scoped attribute names MUST start with "javax.portlet.p.",
+    	//   and contain the ID-name separator '?'.
+    	if (name.startsWith(PORTLET_SCOPE_NAMESPACE)
+    			&& name.indexOf(ID_NAME_SEPARATOR) > -1) {
+        	String id = name.substring(PORTLET_SCOPE_NAMESPACE.length(),
+        	                           name.indexOf(ID_NAME_SEPARATOR));
+        	return (id.equals(portletWindow.getId().getStringId()));
+        }
+    	// Application-scoped attribute names are not in portlet scope.
+    	return false;
+    }
+    
+    
+    // HttpSession Impl --------------------------------------------------------
+    
+	public Map<String, Object> getMap() {
+		List<String> paramNames = getAttributeNamesAsList(DEFAULT_SCOPE);		
+		return fillMap(paramNames, DEFAULT_SCOPE);	
+	}
+
+	public Map<String, Object> getMap(int scope) {
+		List<String> paramNames = getAttributeNamesAsList(scope);		
+		return fillMap(paramNames, scope);
+	}
+    
+// ***** private methods *****
+
+	/**
+	 * transforms the getAttributeNames enumeration to a list
+	 * @return list of getAttributeNames
+	 */
+	private List<String> getAttributeNamesAsList(int scope) {
+		//transform Enum to List
+		List<String> paramNames = new ArrayList<String>();
+		Enumeration<String> e = getAttributeNames(scope);
+		while (e.hasMoreElements()){
+			paramNames.add(e.nextElement());
+		}
+		return paramNames;
+	}
+	
+	/**
+	 * @param paramNames list of the attribute names to be filled in the map
+	 * @return the filled map
+	 */
+	private Map<String, Object> fillMap(List<String> paramNames, int scope) {
+		Map<String, Object> resultMap = new HashMap<String, Object>();
+		for (String string : paramNames) {
+			resultMap.put(string, getAttribute(string,scope));
+		}
+		return resultMap;
+	}
+
+	/** 
+	   * Returns a <code>Map</code> of the session attributes in
+	   * the portlet session scope.
+	   * <p>
+	   * The keys are of type <code>String</code> and the values in the 
+	   * returned <code>Map</code> are from type <code>Object</code>.
+	   * <p>
+	   * If no session attributes exist this method returns an empty <code>Map</code>.
+	   *
+	   * @return     an immutable <code>Map</code> containing the session attributes in the  
+	   *             portlet session scope as keys and attribute values as map values, or an empty <code>Map</code>
+	   *             if no session attributes exist. The keys in the
+	   *             map are of type String, the values of type
+	   *             Object.
+	   *  @since 2.0
+	   */
+	  public Map<String, Object> getAttributeMap(int scope){
+		  return getMap(scope); 
+	  }
+	  /** 
+	   * Returns a <code>Map</code> of the session attributes in
+	   * the portlet session scope.
+	   * <p>
+	   * The keys are of type <code>String</code> and the values in the 
+	   * returned <code>Map</code> are from type <code>Object</code>.
+	   * <p>
+	   * If no session attributes exist this method returns an empty <code>Map</code>.
+	   *
+	   * @return     an immutable <code>Map</code> containing the session attributes in the  
+	   *             portlet session scope as keys and attribute values as map values, or an empty <code>Map</code>
+	   *             if no session attributes exist. The keys in the
+	   *             map are of type String, the values of type
+	   *             Object.
+	   *  @since 2.0
+	   */
+	  public Map<String, Object> getAttributeMap(){
+		  return getMap();
+	  }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
index a520f24..5470ee5 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/ServletPortletSessionProxy.java
@@ -1,134 +1,132 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS"
- * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.pluto.container.util.NamespacedNamesEnumeration;
-
-/**
- * Proxy for a Servlet HttpSession to attach to a PortletSession, providing only access to PORTLET_SCOPE session attributes
- * and hiding the APPLICATION_SCOPE attributes from the Servlet.
- * <br/>
- * This Proxy can be used to isolate two instances of the same Portlet dispatching to Servlets so they don't overwrite or read
- * each others session attributes.
- * 
- * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
- * @version $Id$
- */
-public class ServletPortletSessionProxy implements InvocationHandler
-{
-    HttpSession servletSession;
-    String portletWindowId;
-    String portletScopeAttrNamePrefix;
-
-    public static HttpSession createProxy(HttpServletRequest request, String portletWindowId)
-    {
-        HttpSession servletSession = request.getSession();
-        HashSet<Class<? extends Object>> interfaces = new HashSet<Class<? extends Object>>();
-        interfaces.add(HttpSession.class);
-        Class<? extends Object> current = servletSession.getClass();
-        while (current != null)
-        {
-            try
-            {
-                @SuppressWarnings("unchecked")
-                Class<? extends Object>[] currentInterfaces = current.getInterfaces();
-                for (int i = 0; i < currentInterfaces.length; i++)
-                {
-                    interfaces.add(currentInterfaces[i]);
-                }
-                current = current.getSuperclass();
-            }
-            catch (Exception e)
-            {
-                current = null;
-            }
-        }
-        Object proxy = Proxy.newProxyInstance(servletSession.getClass().getClassLoader(),
-                interfaces.toArray(new Class[interfaces.size()]),
-                new ServletPortletSessionProxy(request.getSession(), portletWindowId));
-        return (HttpSession)proxy;
-    }
-
-    private ServletPortletSessionProxy(HttpSession servletSession, String portletWindowId)
-    {
-        this.servletSession = servletSession;
-        this.portletWindowId = portletWindowId;
-        this.portletScopeAttrNamePrefix = PortletSessionImpl.PORTLET_SCOPE_NAMESPACE + this.portletWindowId + PortletSessionImpl.ID_NAME_SEPARATOR;
-    }
-
-    /**
-     * (non-Javadoc)
-     * 
-     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
-     *      java.lang.reflect.Method, java.lang.Object[])
-     */
-    @SuppressWarnings("unchecked")
-    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
-    {
-        Object retval = null;
-        if (("getAttribute".equals(m.getName()) || "getValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
-        {
-            retval = servletSession.getAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
-        }
-        else if (("setAttribute".equals(m.getName()) || "putValue".equals(m.getName())) && args.length == 2 && args[0] instanceof String)
-        {
-            servletSession.setAttribute(this.portletScopeAttrNamePrefix + (String) args[0], args[1]);
-        }
-        else if (("removeAttribute".equals(m.getName()) || "removeValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
-        {
-            servletSession.removeAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
-        }
-        else if ("getAttributeNames".equals(m.getName()) && args == null)
-        {
-            retval = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
-        }
-        else if ("getValueNames".equals(m.getName()) && args == null)
-        {
-            final List<String> list = new ArrayList<String>();
-            Enumeration<String> e = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
-            while (e.hasMoreElements())
-            {
-                list.add(e.nextElement());
-            }
-            retval = list.toArray(new String[list.size()]);
-        }
-        else
-        {
-            try
-            {
-                retval = m.invoke(servletSession, args);
-            }
-            catch (InvocationTargetException ite)
-            {
-                throw ite.getTargetException();
-            }
-        }
-        return retval;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS"
+ * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.apache.pluto.container.util.NamespacedNamesEnumeration;
+
+/**
+ * Proxy for a Servlet HttpSession to attach to a PortletSession, providing only access to PORTLET_SCOPE session attributes
+ * and hiding the APPLICATION_SCOPE attributes from the Servlet.
+ * <br/>
+ * This Proxy can be used to isolate two instances of the same Portlet dispatching to Servlets so they don't overwrite or read
+ * each others session attributes.
+ * 
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class ServletPortletSessionProxy implements InvocationHandler
+{
+    HttpSession servletSession;
+    String portletWindowId;
+    String portletScopeAttrNamePrefix;
+
+    public static HttpSession createProxy(HttpServletRequest request, String portletWindowId)
+    {
+        HttpSession servletSession = request.getSession();
+        HashSet<Class<? extends Object>> interfaces = new HashSet<Class<? extends Object>>();
+        interfaces.add(HttpSession.class);
+        Class<? extends Object> current = servletSession.getClass();
+        while (current != null)
+        {
+            try
+            {
+                Class<? extends Object>[] currentInterfaces = current.getInterfaces();
+                for (int i = 0; i < currentInterfaces.length; i++)
+                {
+                    interfaces.add(currentInterfaces[i]);
+                }
+                current = current.getSuperclass();
+            }
+            catch (Exception e)
+            {
+                current = null;
+            }
+        }
+        Object proxy = Proxy.newProxyInstance(servletSession.getClass().getClassLoader(),
+                interfaces.toArray(new Class[interfaces.size()]),
+                new ServletPortletSessionProxy(request.getSession(), portletWindowId));
+        return (HttpSession)proxy;
+    }
+
+    private ServletPortletSessionProxy(HttpSession servletSession, String portletWindowId)
+    {
+        this.servletSession = servletSession;
+        this.portletWindowId = portletWindowId;
+        this.portletScopeAttrNamePrefix = PortletSessionImpl.PORTLET_SCOPE_NAMESPACE + this.portletWindowId + PortletSessionImpl.ID_NAME_SEPARATOR;
+    }
+
+    /**
+     * (non-Javadoc)
+     * 
+     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
+     *      java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
+    {
+        Object retval = null;
+        if (("getAttribute".equals(m.getName()) || "getValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
+        {
+            retval = servletSession.getAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
+        }
+        else if (("setAttribute".equals(m.getName()) || "putValue".equals(m.getName())) && args.length == 2 && args[0] instanceof String)
+        {
+            servletSession.setAttribute(this.portletScopeAttrNamePrefix + (String) args[0], args[1]);
+        }
+        else if (("removeAttribute".equals(m.getName()) || "removeValue".equals(m.getName())) && args.length == 1 && args[0] instanceof String)
+        {
+            servletSession.removeAttribute(this.portletScopeAttrNamePrefix + (String) args[0]);
+        }
+        else if ("getAttributeNames".equals(m.getName()) && args == null)
+        {
+            retval = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
+        }
+        else if ("getValueNames".equals(m.getName()) && args == null)
+        {
+            final List<String> list = new ArrayList<String>();
+            Enumeration<String> e = new NamespacedNamesEnumeration(servletSession.getAttributeNames(), this.portletScopeAttrNamePrefix);
+            while (e.hasMoreElements())
+            {
+                list.add(e.nextElement());
+            }
+            retval = list.toArray(new String[list.size()]);
+        }
+        else
+        {
+            try
+            {
+                retval = m.invoke(servletSession, args);
+            }
+            catch (InvocationTargetException ite)
+            {
+                throw ite.getTargetException();
+            }
+        }
+        return retval;
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
index 9e3a18e..46ba537 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
@@ -36,6 +36,7 @@ import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
 import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
 import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.slf4j.Logger;
@@ -70,6 +71,14 @@ public class ConfigurationHolder {
    }
 
    /**
+    * Constructor taking existing portlet app definition - for testing purposes
+    * @param pad
+    */
+   public ConfigurationHolder(PortletApplicationDefinition pad) {
+      this.pad = pad;
+   }
+
+   /**
     * returns the finished portlet application definition
     * 
     * @return the portlet application definition
@@ -235,9 +244,20 @@ public class ConfigurationHolder {
     * validates the configuration. To be called after the configuration has been completely read.
     */
    public void validate() {
-      if (jcp != null) {
-         jcp.validate();
+      if (jcp == null) {
+         jcp = new JSR362ConfigurationProcessor(pad);
+      }
+      jcp.validate();
+   }
+
+   /**
+    * Reconciles the bean configuration with the config from annotations & portlet DD.
+    */
+   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
+      if (jcp == null) {
+         jcp = new JSR362ConfigurationProcessor(pad);
       }
+      jcp.reconcileBeanConfig(ams);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index e3932d3..5460a10 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -16,6 +16,7 @@ import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathFactory;
 
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
 import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -70,6 +71,24 @@ public abstract class ConfigurationProcessor {
     *             If there is a validation error.
     */
    public abstract void validate() throws IllegalArgumentException;
+   
+   /**
+    * reconciles the given annotated method store containing the bean configuration
+    * with the configuration as read from the portlet deployment descriptor and 
+    * the corresponding type annotations.
+    * <p>
+    * Portlets that are defined in the bean config are added to the portlet application
+    * definition if not already present. Event reference information from the 
+    * annotations is verified and added to the corresponding portlet definition.
+    * <p>
+    * Methods from portlet classes definied in the portlet definitions are
+    * added to the annotated method store.
+    * 
+    * @param ams
+    */
+   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
+      // do nothing for JSR 168 & JSR 286 portlets
+   }
 
    /**
     * Handle the locale the old-fashioned way (v1 & v2)
@@ -101,6 +120,9 @@ public abstract class ConfigurationProcessor {
     * @return
     */
    protected boolean isValidIdentifier(String id) {
+      if (id == null || id.length() == 0) {
+         return false;
+      }
       char[] chars = id.toCharArray();
       if (!Character.isJavaIdentifierStart(chars[0])) {
          return false;

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
index a4a70bd..ad0cc63 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
@@ -40,7 +40,7 @@ public class EventDefinitionImpl implements EventDefinition {
    private final ArrayList<QName> aliases = new ArrayList<QName>();
    private final List<Description> descs = new ArrayList<Description>();
    private final List<DisplayName> dispNames = new ArrayList<DisplayName>();
-   private String valType = "";
+   private String valType;
 
    /**
     * Copy constructor


[23/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init2.java
new file mode 100644
index 0000000..477b695
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init2.java
@@ -0,0 +1,62 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.init;
+
+import javax.inject.Inject;
+import javax.portlet.PortletConfig;
+import javax.portlet.annotations.InitMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Init2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @InitMethod("portlet3")
+   public void init1(PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init1");
+   }
+   
+   // duplicate method
+   @InitMethod("portlet2")
+   public void init2(PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init2");
+   }
+   
+   // invalid signature
+   @InitMethod("portlet4")
+   public void init4(String x, PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init4");
+   }
+   
+   // invalid signature
+   @InitMethod("portlet5")
+   public String init5(PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init5");
+      return null;
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/package-info.java
new file mode 100644
index 0000000..af29142
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.init;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionParameters.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionParameters.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionParameters.java
new file mode 100644
index 0000000..ac4a112
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionParameters.java
@@ -0,0 +1,102 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Collections;
+import java.util.Set;
+
+import javax.portlet.ActionParameters;
+import javax.portlet.ActionRequest;
+import javax.portlet.MutableActionParameters;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockActionParameters implements ActionParameters {
+   
+   private String actionName;
+   
+   /**
+    * Constructor 
+    */
+   public MockActionParameters(String name) {
+      actionName = name;
+   }
+   
+   public void setActionName(String name) {
+      actionName = name;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletParameters#getNames()
+    */
+   @Override
+   public Set<? extends String> getNames() {
+      return Collections.singleton(ActionRequest.ACTION_NAME);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletParameters#getValue(java.lang.String)
+    */
+   @Override
+   public String getValue(String arg0) {
+      if (arg0.equals(ActionRequest.ACTION_NAME)) {
+         return actionName;
+      }
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletParameters#getValues(java.lang.String)
+    */
+   @Override
+   public String[] getValues(String arg0) {
+      if (arg0.equals(ActionRequest.ACTION_NAME)) {
+         return new String[] {actionName};
+      }
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletParameters#isEmpty()
+    */
+   @Override
+   public boolean isEmpty() {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletParameters#size()
+    */
+   @Override
+   public int size() {
+      return 1;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ActionParameters#clone()
+    */
+   @Override
+   public MutableActionParameters clone() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionRequest.java
new file mode 100644
index 0000000..49534d0
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionRequest.java
@@ -0,0 +1,61 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.ActionParameters;
+import javax.portlet.ActionRequest;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockActionRequest extends MockClientDataRequest implements ActionRequest {
+
+   private String actionName;
+   
+
+   
+   /**
+    * @return the actionName
+    */
+   public String getActionName() {
+      return actionName;
+   }
+
+
+
+   /**
+    * @param actionName the actionName to set
+    */
+   public void setActionName(String actionName) {
+      this.actionName = actionName;
+   }
+
+   @Override
+   public ActionParameters getActionParameters() {
+      return new MockActionParameters(actionName);
+   }
+
+   @Override
+   public String getParameter(String name) {
+      return actionName;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionResponse.java
new file mode 100644
index 0000000..7abbafd
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockActionResponse.java
@@ -0,0 +1,56 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.io.IOException;
+
+import javax.portlet.ActionResponse;
+import javax.portlet.MimeResponse.Copy;
+import javax.portlet.RenderURL;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockActionResponse extends MockStateAwareResponse implements ActionResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ActionResponse#getRedirectURL(javax.portlet.MimeResponse.Copy)
+    */
+   @Override
+   public RenderURL getRedirectURL(Copy arg0) throws IllegalStateException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ActionResponse#sendRedirect(java.lang.String)
+    */
+   @Override
+   public void sendRedirect(String arg0) throws IOException {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ActionResponse#sendRedirect(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void sendRedirect(String arg0, String arg1) throws IOException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
new file mode 100644
index 0000000..3a48052
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockClientDataRequest.java
@@ -0,0 +1,90 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import javax.portlet.ClientDataRequest;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockClientDataRequest extends MockPortletRequest implements ClientDataRequest {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getCharacterEncoding()
+    */
+   @Override
+   public String getCharacterEncoding() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getContentLength()
+    */
+   @Override
+   public int getContentLength() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getContentType()
+    */
+   @Override
+   public String getContentType() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getMethod()
+    */
+   @Override
+   public String getMethod() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getPortletInputStream()
+    */
+   @Override
+   public InputStream getPortletInputStream() throws IOException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#getReader()
+    */
+   @Override
+   public BufferedReader getReader() throws UnsupportedEncodingException, IOException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ClientDataRequest#setCharacterEncoding(java.lang.String)
+    */
+   @Override
+   public void setCharacterEncoding(String arg0) throws UnsupportedEncodingException {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEvent.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEvent.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEvent.java
new file mode 100644
index 0000000..828afe6
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEvent.java
@@ -0,0 +1,63 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.io.Serializable;
+
+import javax.portlet.Event;
+import javax.xml.namespace.QName;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockEvent implements Event {
+   
+   private final QName qn;
+   
+   public MockEvent(QName qn) {
+      this.qn = qn;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.Event#getName()
+    */
+   @Override
+   public String getName() {
+      return qn.getLocalPart();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.Event#getQName()
+    */
+   @Override
+   public QName getQName() {
+      return qn;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.Event#getValue()
+    */
+   @Override
+   public Serializable getValue() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventRequest.java
new file mode 100644
index 0000000..10906f7
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventRequest.java
@@ -0,0 +1,57 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.Event;
+import javax.portlet.EventRequest;
+import javax.xml.namespace.QName;
+
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockEventRequest extends MockClientDataRequest implements EventRequest {
+   
+   private QName qn;
+
+   /**
+    * @return the qn
+    */
+   public QName getQn() {
+      return qn;
+   }
+
+   /**
+    * @param qn the qn to set
+    */
+   public void setQn(QName qn) {
+      this.qn = qn;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.EventRequest#getEvent()
+    */
+   @Override
+   public Event getEvent() {
+      return new MockEvent(qn);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventResponse.java
new file mode 100644
index 0000000..c68c4c9
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockEventResponse.java
@@ -0,0 +1,39 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockEventResponse extends MockStateAwareResponse implements EventResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.EventResponse#setRenderParameters(javax.portlet.EventRequest)
+    */
+   @Override
+   public void setRenderParameters(EventRequest arg0) {
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderRequest.java
new file mode 100644
index 0000000..7085fe6
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderRequest.java
@@ -0,0 +1,30 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.HeaderRequest;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockHeaderRequest extends MockRenderRequest implements HeaderRequest {
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderResponse.java
new file mode 100644
index 0000000..e2d1201
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockHeaderResponse.java
@@ -0,0 +1,38 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.HeaderResponse;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockHeaderResponse extends MockMimeResponse implements HeaderResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.HeaderResponse#setTitle(java.lang.String)
+    */
+   @Override
+   public void setTitle(String arg0) {
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockMimeResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockMimeResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockMimeResponse.java
new file mode 100644
index 0000000..e8a060a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockMimeResponse.java
@@ -0,0 +1,184 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import javax.portlet.ActionURL;
+import javax.portlet.CacheControl;
+import javax.portlet.MimeResponse;
+import javax.portlet.PortletURL;
+import javax.portlet.RenderURL;
+import javax.portlet.ResourceURL;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockMimeResponse extends MockPortletResponse implements MimeResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#createActionURL()
+    */
+   @Override
+   public <T extends PortletURL & ActionURL> T createActionURL() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#createActionURL(javax.portlet.MimeResponse.Copy)
+    */
+   @Override
+   public ActionURL createActionURL(Copy arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#createRenderURL()
+    */
+   @Override
+   public <T extends PortletURL & RenderURL> T createRenderURL() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#createRenderURL(javax.portlet.MimeResponse.Copy)
+    */
+   @Override
+   public RenderURL createRenderURL(Copy arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#createResourceURL()
+    */
+   @Override
+   public ResourceURL createResourceURL() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#flushBuffer()
+    */
+   @Override
+   public void flushBuffer() throws IOException {
+
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getBufferSize()
+    */
+   @Override
+   public int getBufferSize() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getCacheControl()
+    */
+   @Override
+   public CacheControl getCacheControl() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getCharacterEncoding()
+    */
+   @Override
+   public String getCharacterEncoding() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getContentType()
+    */
+   @Override
+   public String getContentType() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getLocale()
+    */
+   @Override
+   public Locale getLocale() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getPortletOutputStream()
+    */
+   @Override
+   public OutputStream getPortletOutputStream() throws IOException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#getWriter()
+    */
+   @Override
+   public PrintWriter getWriter() throws IOException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#isCommitted()
+    */
+   @Override
+   public boolean isCommitted() {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#reset()
+    */
+   @Override
+   public void reset() {
+
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#resetBuffer()
+    */
+   @Override
+   public void resetBuffer() {
+
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#setBufferSize(int)
+    */
+   @Override
+   public void setBufferSize(int arg0) {
+
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MimeResponse#setContentType(java.lang.String)
+    */
+   @Override
+   public void setContentType(String arg0) {
+
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletConfig.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletConfig.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletConfig.java
new file mode 100644
index 0000000..9762f16
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletConfig.java
@@ -0,0 +1,160 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Enumeration;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+import javax.xml.namespace.QName;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockPortletConfig implements PortletConfig {
+   
+   private class PortletRes extends ListResourceBundle {
+      protected Object[][] getContents() {
+          return new Object[][] {
+              {"javax.portlet.title", "Some Title"},
+          };
+      }
+  }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getContainerRuntimeOptions()
+    */
+   @Override
+   public Map<String, String[]> getContainerRuntimeOptions() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getDefaultNamespace()
+    */
+   @Override
+   public String getDefaultNamespace() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getInitParameter(java.lang.String)
+    */
+   @Override
+   public String getInitParameter(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getInitParameterNames()
+    */
+   @Override
+   public Enumeration<String> getInitParameterNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPortletContext()
+    */
+   @Override
+   public PortletContext getPortletContext() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPortletModes(java.lang.String)
+    */
+   @Override
+   public Enumeration<PortletMode> getPortletModes(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPortletName()
+    */
+   @Override
+   public String getPortletName() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getProcessingEventQNames()
+    */
+   @Override
+   public Enumeration<QName> getProcessingEventQNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPublicRenderParameterDefinitions()
+    */
+   @Override
+   public Map<String, QName> getPublicRenderParameterDefinitions() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPublicRenderParameterNames()
+    */
+   @Override
+   public Enumeration<String> getPublicRenderParameterNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getPublishingEventQNames()
+    */
+   @Override
+   public Enumeration<QName> getPublishingEventQNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getResourceBundle(java.util.Locale)
+    */
+   @Override
+   public ResourceBundle getResourceBundle(Locale arg0) {
+      return new PortletRes();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getSupportedLocales()
+    */
+   @Override
+   public Enumeration<Locale> getSupportedLocales() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletConfig#getWindowStates(java.lang.String)
+    */
+   @Override
+   public Enumeration<WindowState> getWindowStates(String arg0) {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletRequest.java
new file mode 100644
index 0000000..d8e2d6d
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletRequest.java
@@ -0,0 +1,369 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.security.Principal;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.portlet.RenderParameters;
+import javax.portlet.WindowState;
+import javax.servlet.http.Cookie;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockPortletRequest implements PortletRequest {
+   
+   private PortletSession ps = new MockPortletSession();
+   private PortletMode mode;
+
+   /**
+    * @return the mode
+    */
+   public PortletMode getMode() {
+      return mode;
+   }
+
+   /**
+    * @param mode the mode to set
+    */
+   public void setMode(PortletMode mode) {
+      this.mode = mode;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletState#getPortletMode()
+    */
+   @Override
+   public PortletMode getPortletMode() {
+      return mode;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletState#getRenderParameters()
+    */
+   @Override
+   public RenderParameters getRenderParameters() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletState#getWindowState()
+    */
+   @Override
+   public WindowState getWindowState() {
+      return WindowState.NORMAL;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getAttribute(java.lang.String)
+    */
+   @Override
+   public Object getAttribute(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getAttributeNames()
+    */
+   @Override
+   public Enumeration<String> getAttributeNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getAuthType()
+    */
+   @Override
+   public String getAuthType() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getContextPath()
+    */
+   @Override
+   public String getContextPath() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getCookies()
+    */
+   @Override
+   public Cookie[] getCookies() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getLocale()
+    */
+   @Override
+   public Locale getLocale() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getLocales()
+    */
+   @Override
+   public Enumeration<Locale> getLocales() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getParameter(java.lang.String)
+    */
+   @Override
+   public String getParameter(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getParameterMap()
+    */
+   @Override
+   public Map<String, String[]> getParameterMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getParameterNames()
+    */
+   @Override
+   public Enumeration<String> getParameterNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getParameterValues(java.lang.String)
+    */
+   @Override
+   public String[] getParameterValues(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPortalContext()
+    */
+   @Override
+   public PortalContext getPortalContext() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPortletSession()
+    */
+   @Override
+   public PortletSession getPortletSession() {
+      return ps;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPortletSession(boolean)
+    */
+   @Override
+   public PortletSession getPortletSession(boolean arg0) {
+      return ps;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPreferences()
+    */
+   @Override
+   public PortletPreferences getPreferences() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPrivateParameterMap()
+    */
+   @Override
+   public Map<String, String[]> getPrivateParameterMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getProperties(java.lang.String)
+    */
+   @Override
+   public Enumeration<String> getProperties(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getProperty(java.lang.String)
+    */
+   @Override
+   public String getProperty(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPropertyNames()
+    */
+   @Override
+   public Enumeration<String> getPropertyNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getPublicParameterMap()
+    */
+   @Override
+   public Map<String, String[]> getPublicParameterMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getRemoteUser()
+    */
+   @Override
+   public String getRemoteUser() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getRequestedSessionId()
+    */
+   @Override
+   public String getRequestedSessionId() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getResponseContentType()
+    */
+   @Override
+   public String getResponseContentType() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getResponseContentTypes()
+    */
+   @Override
+   public Enumeration<String> getResponseContentTypes() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getScheme()
+    */
+   @Override
+   public String getScheme() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getServerName()
+    */
+   @Override
+   public String getServerName() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getServerPort()
+    */
+   @Override
+   public int getServerPort() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getUserPrincipal()
+    */
+   @Override
+   public Principal getUserPrincipal() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#getWindowID()
+    */
+   @Override
+   public String getWindowID() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#isPortletModeAllowed(javax.portlet.PortletMode)
+    */
+   @Override
+   public boolean isPortletModeAllowed(PortletMode arg0) {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#isRequestedSessionIdValid()
+    */
+   @Override
+   public boolean isRequestedSessionIdValid() {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#isSecure()
+    */
+   @Override
+   public boolean isSecure() {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#isUserInRole(java.lang.String)
+    */
+   @Override
+   public boolean isUserInRole(String arg0) {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#isWindowStateAllowed(javax.portlet.WindowState)
+    */
+   @Override
+   public boolean isWindowStateAllowed(WindowState arg0) {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#removeAttribute(java.lang.String)
+    */
+   @Override
+   public void removeAttribute(String arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletRequest#setAttribute(java.lang.String, java.lang.Object)
+    */
+   @Override
+   public void setAttribute(String arg0, Object arg1) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletResponse.java
new file mode 100644
index 0000000..ffa0aca
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletResponse.java
@@ -0,0 +1,86 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.PortletResponse;
+import javax.servlet.http.Cookie;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Element;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockPortletResponse implements PortletResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#addProperty(javax.servlet.http.Cookie)
+    */
+   @Override
+   public void addProperty(Cookie arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#addProperty(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void addProperty(String arg0, String arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#addProperty(java.lang.String, org.w3c.dom.Element)
+    */
+   @Override
+   public void addProperty(String arg0, Element arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#createElement(java.lang.String)
+    */
+   @Override
+   public Element createElement(String arg0) throws DOMException {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#encodeURL(java.lang.String)
+    */
+   @Override
+   public String encodeURL(String arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#getNamespace()
+    */
+   @Override
+   public String getNamespace() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletResponse#setProperty(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void setProperty(String arg0, String arg1) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletSession.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletSession.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletSession.java
new file mode 100644
index 0000000..35f58be
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockPortletSession.java
@@ -0,0 +1,177 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockPortletSession implements PortletSession {
+   
+   private Map<String, Object> attrs = new HashMap<String, Object>();
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttribute(java.lang.String)
+    */
+   @Override
+   public Object getAttribute(String arg0) {
+      return attrs.get(arg0);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttribute(java.lang.String, int)
+    */
+   @Override
+   public Object getAttribute(String arg0, int arg1) {
+      return attrs.get(arg0);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttributeMap()
+    */
+   @Override
+   public Map<String, Object> getAttributeMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttributeMap(int)
+    */
+   @Override
+   public Map<String, Object> getAttributeMap(int arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttributeNames()
+    */
+   @Override
+   public Enumeration<String> getAttributeNames() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getAttributeNames(int)
+    */
+   @Override
+   public Enumeration<String> getAttributeNames(int arg0) {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getCreationTime()
+    */
+   @Override
+   public long getCreationTime() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getId()
+    */
+   @Override
+   public String getId() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getLastAccessedTime()
+    */
+   @Override
+   public long getLastAccessedTime() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getMaxInactiveInterval()
+    */
+   @Override
+   public int getMaxInactiveInterval() {
+      return 0;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#getPortletContext()
+    */
+   @Override
+   public PortletContext getPortletContext() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#invalidate()
+    */
+   @Override
+   public void invalidate() {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#isNew()
+    */
+   @Override
+   public boolean isNew() {
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#removeAttribute(java.lang.String)
+    */
+   @Override
+   public void removeAttribute(String arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#removeAttribute(java.lang.String, int)
+    */
+   @Override
+   public void removeAttribute(String arg0, int arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#setAttribute(java.lang.String, java.lang.Object)
+    */
+   @Override
+   public void setAttribute(String arg0, Object arg1) {
+      attrs.put(arg0, arg1);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#setAttribute(java.lang.String, java.lang.Object, int)
+    */
+   @Override
+   public void setAttribute(String arg0, Object arg1, int arg2) {
+      attrs.put(arg0, arg1);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletSession#setMaxInactiveInterval(int)
+    */
+   @Override
+   public void setMaxInactiveInterval(int arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderRequest.java
new file mode 100644
index 0000000..f365fa0
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderRequest.java
@@ -0,0 +1,38 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import javax.portlet.RenderRequest;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockRenderRequest extends MockPortletRequest implements RenderRequest {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.RenderRequest#getETag()
+    */
+   @Override
+   public String getETag() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderResponse.java
new file mode 100644
index 0000000..3ec5812
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockRenderResponse.java
@@ -0,0 +1,47 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Collection;
+
+import javax.portlet.PortletMode;
+import javax.portlet.RenderResponse;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockRenderResponse extends MockMimeResponse implements RenderResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.RenderResponse#setNextPossiblePortletModes(java.util.Collection)
+    */
+   @Override
+   public void setNextPossiblePortletModes(Collection<? extends PortletMode> arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.RenderResponse#setTitle(java.lang.String)
+    */
+   @Override
+   public void setTitle(String arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceRequest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceRequest.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceRequest.java
new file mode 100644
index 0000000..6a36ed5
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceRequest.java
@@ -0,0 +1,89 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Map;
+
+import javax.portlet.ResourceParameters;
+import javax.portlet.ResourceRequest;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockResourceRequest extends MockClientDataRequest implements ResourceRequest {
+   
+   private String resourceId;
+
+   /**
+    * @return the resourceId
+    */
+   public String getResourceId() {
+      return resourceId;
+   }
+
+   /**
+    * @param resourceId the resourceId to set
+    */
+   public void setResourceId(String resourceId) {
+      this.resourceId = resourceId;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceRequest#getCacheability()
+    */
+   @Override
+   public String getCacheability() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceRequest#getETag()
+    */
+   @Override
+   public String getETag() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceRequest#getPrivateRenderParameterMap()
+    */
+   @Override
+   public Map<String, String[]> getPrivateRenderParameterMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceRequest#getResourceID()
+    */
+   @Override
+   public String getResourceID() {
+      return resourceId;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceRequest#getResourceParameters()
+    */
+   @Override
+   public ResourceParameters getResourceParameters() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceResponse.java
new file mode 100644
index 0000000..e0d734a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockResourceResponse.java
@@ -0,0 +1,60 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.util.Locale;
+
+import javax.portlet.ResourceResponse;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class MockResourceResponse extends MockMimeResponse implements ResourceResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceResponse#setCharacterEncoding(java.lang.String)
+    */
+   @Override
+   public void setCharacterEncoding(String arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceResponse#setContentLength(int)
+    */
+   @Override
+   public void setContentLength(int arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceResponse#setLocale(java.util.Locale)
+    */
+   @Override
+   public void setLocale(Locale arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.ResourceResponse#setStatus(int)
+    */
+   @Override
+   public void setStatus(int arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockStateAwareResponse.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockStateAwareResponse.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockStateAwareResponse.java
new file mode 100644
index 0000000..cbfc72d
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/MockStateAwareResponse.java
@@ -0,0 +1,127 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import javax.portlet.MutableRenderParameters;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.StateAwareResponse;
+import javax.portlet.WindowState;
+import javax.portlet.WindowStateException;
+import javax.xml.namespace.QName;
+
+/**
+ * @author Scott
+ *
+ */
+public class MockStateAwareResponse extends MockPortletResponse implements StateAwareResponse {
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MutablePortletState#getRenderParameters()
+    */
+   @Override
+   public MutableRenderParameters getRenderParameters() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MutablePortletState#setPortletMode(javax.portlet.PortletMode)
+    */
+   @Override
+   public void setPortletMode(PortletMode arg0) throws PortletModeException {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.MutablePortletState#setWindowState(javax.portlet.WindowState)
+    */
+   @Override
+   public void setWindowState(WindowState arg0) throws WindowStateException {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletState#getPortletMode()
+    */
+   @Override
+   public PortletMode getPortletMode() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.PortletState#getWindowState()
+    */
+   @Override
+   public WindowState getWindowState() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#getRenderParameterMap()
+    */
+   @Override
+   public Map<String, String[]> getRenderParameterMap() {
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#removePublicRenderParameter(java.lang.String)
+    */
+   @Override
+   public void removePublicRenderParameter(String arg0) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#setEvent(javax.xml.namespace.QName, java.io.Serializable)
+    */
+   @Override
+   public void setEvent(QName arg0, Serializable arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#setEvent(java.lang.String, java.io.Serializable)
+    */
+   @Override
+   public void setEvent(String arg0, Serializable arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#setRenderParameter(java.lang.String, java.lang.String)
+    */
+   @Override
+   public void setRenderParameter(String arg0, String arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#setRenderParameter(java.lang.String, java.lang.String[])
+    */
+   @Override
+   public void setRenderParameter(String arg0, String... arg1) {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.portlet.StateAwareResponse#setRenderParameters(java.util.Map)
+    */
+   @Override
+   public void setRenderParameters(Map<String, String[]> arg0) {
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/package-info.java
new file mode 100644
index 0000000..657b9a4
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/mocks/package-info.java
@@ -0,0 +1,26 @@
+/*  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 containing mock portlet artifacts. Used for testing the 
+ * portlet invoker.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.mocks;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/package-info.java
new file mode 100644
index 0000000..e232510
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/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.
+ */
+
+/**
+ * Contains test fixtures for the bean processor.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render1.java
new file mode 100644
index 0000000..857d3c1
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render1.java
@@ -0,0 +1,97 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.render;
+
+import javax.inject.Inject;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.annotations.RenderMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Render1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @RenderMethod(portletNames="portlet1")
+   public void render1a(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render1a");
+   }
+   
+   @RenderMethod(portletNames="portlet1")
+   public void render1b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render1b");
+   }
+   
+   @RenderMethod(portletNames="portlet1")
+   public String render1c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render1c");
+      return null;
+   }
+   
+   @RenderMethod(portletNames="portlet2", portletMode="help")
+   public void render2a(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render2a");
+   }
+   
+   @RenderMethod(portletNames="portlet2", portletMode="edit")
+   public void render2b(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render2b");
+   }
+   
+   @RenderMethod(portletNames="portlet2", portletMode="config")
+   public void render2c(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render2c");
+   }
+   
+   @RenderMethod(portletNames="portlet3", ordinal=200)
+   public void render3a(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render3a");
+   }
+   
+   @RenderMethod(portletNames="portlet3", ordinal=300)
+   public void render3b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render3b");
+   }
+   
+   @RenderMethod(portletNames="portlet3", ordinal=-42)
+   public String render3c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render3c");
+      return null;
+   }
+   
+   @RenderMethod(portletNames="portlet3", ordinal=-420, portletMode="")
+   public String render3d() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render3d");
+      return null;
+   }
+   
+   @RenderMethod(portletNames="portlet3", ordinal=300, portletMode="help")
+   public void render3e() {
+      meths.addMethod(this.getClass().getSimpleName() + "#render3e");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render2.java
new file mode 100644
index 0000000..031af11
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/Render2.java
@@ -0,0 +1,83 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.render;
+
+import javax.activity.InvalidActivityException;
+import javax.inject.Inject;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.annotations.RenderMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Render2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @RenderMethod(portletNames="portlet2", portletMode="edit", ordinal=-100)
+   public void render2c(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render2c");
+   }
+   
+   @RenderMethod(portletNames="portlet2", portletMode="edit", ordinal=100)
+   public void render2d(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render2d");
+   }
+   
+   // invalid signature
+   @RenderMethod(portletNames="portlet4")
+   public void render4(String x, RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render4");
+   }
+   
+   // invalid signature
+   @RenderMethod(portletNames="portlet5")
+   public String render5(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render5");
+      return null;
+   }
+   
+   // invalid signature, bad exception
+   @RenderMethod(portletNames="portlet8")
+   public String render8(RenderRequest req, RenderResponse resp) throws InvalidActivityException {return null;}
+   
+   @RenderMethod(portletNames= {"portlet6", "portlet7"})
+   public void render6and7(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render6and7");
+   }
+   
+   // ignored asterisk
+   @RenderMethod(portletNames= {"portlet6", "*"}, ordinal=100)
+   public void render6andStar(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#render6andStar");
+   }
+   
+   @RenderMethod(portletNames="*", portletMode="admin")
+   public void renderAll(RenderRequest req, RenderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#renderAll");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/package-info.java
new file mode 100644
index 0000000..492d736
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/render/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.render;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource1.java
new file mode 100644
index 0000000..69486d6
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/resource/Resource1.java
@@ -0,0 +1,92 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.resource;
+
+import javax.inject.Inject;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.ServeResourceMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Resource1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @ServeResourceMethod(portletNames="portlet1")
+   public void resource1a(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource1a");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet1")
+   public void resource1b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource1b");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet1")
+   public String resource1c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource1c");
+      return null;
+   }
+   
+   @ServeResourceMethod(portletNames="portlet2", resourceID="help")
+   public void resource2a(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource2a");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet2", resourceID="edit")
+   public void resource2b(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource2b");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet2", resourceID="config")
+   public void resource2c(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource2c");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet3", ordinal=200)
+   public void resource3a(ResourceRequest req, ResourceResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource3a");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet3", ordinal=300)
+   public void resource3b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource3b");
+   }
+   
+   @ServeResourceMethod(portletNames="portlet3", ordinal=-42)
+   public String resource3c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource3c");
+      return null;
+   }
+   
+   @ServeResourceMethod(portletNames="portlet3", ordinal=200, resourceID="help")
+   public String resource3e() {
+      meths.addMethod(this.getClass().getSimpleName() + "#resource3e");
+      return null;
+   }
+   
+
+}


[14/35] portals-pluto git commit: Implemented type annotations for portlet request filters, portlet URL generation listeners, and portlet preference validators. The corresponding definitions in the portlet.xml file are merged into the annotated configura

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator1.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator1.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator1.xml
new file mode 100644
index 0000000..3ad0f2d
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator1.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE xml>
+<portlet-app id="id1" version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet>
+      <portlet-name>portlet1</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-preferences>
+         <preference>
+            <name>aPref</name>
+            <value>aValue</value>
+            <read-only>true</read-only>
+         </preference>
+         <preference>
+            <name>bPref</name>
+            <value>dValue</value>
+            <value>eValue</value>
+            <value>fValue</value>
+            <read-only>true</read-only>
+         </preference>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet2</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-preferences>
+         <preferences-validator>null</preferences-validator>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet3</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-preferences>
+         <preference>
+            <name>cPref</name>
+            <value>cValue</value>
+            <read-only>false</read-only>
+         </preference>
+         <preferences-validator>null</preferences-validator>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet4</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet</portlet-class>
+      <portlet-preferences>
+         <preference>
+            <name>dPref</name>
+            <value>dValue</value>
+            <read-only>true</read-only>
+         </preference>
+      </portlet-preferences>
+   </portlet>
+</portlet-app>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator2.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator2.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator2.xml
new file mode 100644
index 0000000..a80426b
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362AlterValidator2.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE xml>
+<portlet-app id="id1" version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet>
+      <portlet-name>portlet1</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-preferences>
+         <preference>
+            <name>aPref</name>
+            <value>aValue</value>
+            <read-only>true</read-only>
+         </preference>
+         <preference>
+            <name>bPref</name>
+            <value>dValue</value>
+            <value>eValue</value>
+            <value>fValue</value>
+            <read-only>true</read-only>
+         </preference>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet3</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-preferences>
+         <preference>
+            <name>cPref</name>
+            <value>cValue</value>
+            <read-only>false</read-only>
+         </preference>
+         <preferences-validator>
+            org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator
+         </preferences-validator>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet4</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet</portlet-class>
+      <portlet-preferences>
+         <preference>
+            <name>dPref</name>
+            <value>dValue</value>
+            <read-only>true</read-only>
+         </preference>
+         <preferences-validator>
+            org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator
+         </preferences-validator>
+      </portlet-preferences>
+   </portlet>
+   <portlet>
+      <portlet-name>portlet5</portlet-name>
+      <display-name xml:lang="de">display-name</display-name>
+      <portlet-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet</portlet-class>
+      <portlet-preferences>
+         <preferences-validator>null</preferences-validator>
+      </portlet-preferences>
+   </portlet>
+</portlet-app>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
index f20bfc4..bc2d3d4 100644
--- a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Generated.xml
@@ -157,6 +157,7 @@
    </public-render-parameter>
    <listener>
       <listener-name>test listener</listener-name>
+      <ordinal>100</ordinal>
       <description xml:lang="de">description</description>
       <display-name xml:lang="de">display-name</display-name>
       <listener-class>org.apache.pluto.container.om.portlet.impl.fixtures.TestListener</listener-class>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/a05e1563/portlet-api/src/main/java/javax/portlet/annotations/Preference.java
----------------------------------------------------------------------
diff --git a/portlet-api/src/main/java/javax/portlet/annotations/Preference.java b/portlet-api/src/main/java/javax/portlet/annotations/Preference.java
index 1bfa5ca..8cbd5e0 100644
--- a/portlet-api/src/main/java/javax/portlet/annotations/Preference.java
+++ b/portlet-api/src/main/java/javax/portlet/annotations/Preference.java
@@ -61,13 +61,4 @@ public @interface Preference {
     * @return  The read-only flag
     */
    boolean     isReadOnly() default false;
-   
-   /**
-    * <div class='container-change'>
-    * Provides locale-specific text describing the portlet preference for use by the portal application or by tools.
-    * </div>
-    * 
-    * @return  The portlet preference description
-    */
-   LocaleString[]      description() default {};
 }


[31/35] portals-pluto git commit: Modified the portlet servlet to use the bean-based portlet invoker. added beans.xml file to the V3 demos.

Posted by ms...@apache.org.
Modified the portlet servlet to use the bean-based portlet invoker.
added beans.xml file to the V3 demos.


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

Branch: refs/heads/V3Prototype
Commit: 92f8e874f8ff304e12ab93acb7445b2437bd7d56
Parents: afb1a42
Author: Scott Nicklous <ms...@apache.org>
Authored: Fri Jan 15 09:59:46 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Fri Jan 15 09:59:46 2016 +0100

----------------------------------------------------------------------
 .../src/main/resources/logging.properties       |   4 +-
 .../src/main/webapp/WEB-INF/beans.xml           |   7 +
 .../src/main/resources/logging.properties       |   2 +-
 .../src/main/webapp/WEB-INF/beans.xml           |   7 +
 .../src/main/resources/logging.properties       |   2 +-
 PortletV3Demo/src/main/webapp/WEB-INF/beans.xml |   7 +
 .../pluto/container/driver/PortletServlet3.java | 132 +++++--------------
 .../src/main/resources/META-INF/beans.xml       |  18 ++-
 8 files changed, 75 insertions(+), 104 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletHubDemo/src/main/resources/logging.properties
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/resources/logging.properties b/PortletHubDemo/src/main/resources/logging.properties
index 04c2b66..30b4ec8 100644
--- a/PortletHubDemo/src/main/resources/logging.properties
+++ b/PortletHubDemo/src/main/resources/logging.properties
@@ -28,10 +28,10 @@ handlers = org.apache.juli.FileHandler
 # 
 ############################################################
 
-org.apache.juli.FileHandler.level = FINEST
+org.apache.juli.FileHandler.level = FINE
 org.apache.juli.FileHandler.directory = ${catalina.base}/logs
 #Log file will be named pluto.<yyyy-mm-dd>.log
 org.apache.juli.FileHandler.prefix = PortletHubDemo.
 
-org.apache.pluto.level=FINEST
+org.apache.pluto.level=FINE
 basic.portlet.level=FINEST

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletHubDemo/src/main/webapp/WEB-INF/beans.xml
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/beans.xml b/PortletHubDemo/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..6c3e86c
--- /dev/null
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
+       version="1.1" bean-discovery-mode="all">
+   
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletV3AnnotatedDemo/src/main/resources/logging.properties
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/resources/logging.properties b/PortletV3AnnotatedDemo/src/main/resources/logging.properties
index 0e27358..09bae36 100644
--- a/PortletV3AnnotatedDemo/src/main/resources/logging.properties
+++ b/PortletV3AnnotatedDemo/src/main/resources/logging.properties
@@ -33,5 +33,5 @@ org.apache.juli.FileHandler.directory = ${catalina.base}/logs
 #Log file will be named pluto.<yyyy-mm-dd>.log
 org.apache.juli.FileHandler.prefix = PortletV3AnnotatedDemo.
 
-org.apache.pluto.level=FINEST
+org.apache.pluto.level=FINE
 basic.portlet.level=FINEST

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/beans.xml
----------------------------------------------------------------------
diff --git a/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/beans.xml b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..6c3e86c
--- /dev/null
+++ b/PortletV3AnnotatedDemo/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
+       version="1.1" bean-discovery-mode="all">
+   
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletV3Demo/src/main/resources/logging.properties
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/resources/logging.properties b/PortletV3Demo/src/main/resources/logging.properties
index 42a1f93..a83e946 100644
--- a/PortletV3Demo/src/main/resources/logging.properties
+++ b/PortletV3Demo/src/main/resources/logging.properties
@@ -33,5 +33,5 @@ org.apache.juli.FileHandler.directory = ${catalina.base}/logs
 #Log file will be named pluto.<yyyy-mm-dd>.log
 org.apache.juli.FileHandler.prefix = PortletV3Demo.
 
-org.apache.pluto.level=FINEST
+org.apache.pluto.level=FINE
 basic.portlet.level=FINEST

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/PortletV3Demo/src/main/webapp/WEB-INF/beans.xml
----------------------------------------------------------------------
diff --git a/PortletV3Demo/src/main/webapp/WEB-INF/beans.xml b/PortletV3Demo/src/main/webapp/WEB-INF/beans.xml
new file mode 100644
index 0000000..6c3e86c
--- /dev/null
+++ b/PortletV3Demo/src/main/webapp/WEB-INF/beans.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
+       version="1.1" bean-discovery-mode="all">
+   
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
index d939d24..7155e04 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletServlet3.java
@@ -20,16 +20,13 @@ import java.io.IOException;
 import java.util.Timer;
 import java.util.TimerTask;
 
+import javax.inject.Inject;
 import javax.portlet.ActionRequest;
 import javax.portlet.ActionResponse;
-import javax.portlet.EventPortlet;
 import javax.portlet.EventRequest;
 import javax.portlet.EventResponse;
-import javax.portlet.HeaderPortlet;
 import javax.portlet.HeaderRequest;
 import javax.portlet.HeaderResponse;
-import javax.portlet.Portlet;
-import javax.portlet.PortletConfig;
 import javax.portlet.PortletException;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletResponse;
@@ -37,7 +34,6 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
-import javax.portlet.ResourceServingPortlet;
 import javax.portlet.UnavailableException;
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
@@ -53,12 +49,13 @@ import org.apache.pluto.container.PortletRequestContext;
 import org.apache.pluto.container.PortletResourceRequestContext;
 import org.apache.pluto.container.PortletResponseContext;
 import org.apache.pluto.container.PortletWindow;
-import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Portlet Invocation Servlet. This servlet recieves cross context requests from the the container and services the
+ * Portlet Invocation Servlet. This servlet receives cross context requests from the the container and services the
  * portlet request for the specified method.
  * 
  * @version 1.1
@@ -69,42 +66,16 @@ public class PortletServlet3 extends HttpServlet {
    
    /** Logger. */
    private static final Logger LOG = LoggerFactory.getLogger(PortletServlet3.class);
-   private static final boolean isDebug = LOG.isDebugEnabled();
-   
 
    /**
     * Portlet name constant, needed by portlet container initializer
     */
    public static final String PORTLET_NAME     = "portlet-name";
 
-   private class NullPortlet implements EventPortlet, ResourceServingPortlet, Portlet, HeaderPortlet {
-      public void processEvent(EventRequest arg0, EventResponse arg1) throws PortletException, IOException {
-      }
-
-      public void serveResource(ResourceRequest arg0, ResourceResponse arg1) throws PortletException, IOException {
-      }
-
-      public void destroy() {
-      }
-
-      public void init(PortletConfig arg0) throws PortletException {
-      }
-
-      public void processAction(ActionRequest arg0, ActionResponse arg1) throws PortletException, IOException {
-      }
-
-      public void render(RenderRequest arg0, RenderResponse arg1) throws PortletException, IOException {
-      }
-
-      @Override
-      public void renderHeaders(HeaderRequest request, HeaderResponse response) throws PortletException, IOException {
-         if (isDebug) {
-            LOG.debug("NullPortlet renderHeaders! Portlet name: " + portletName);
-         }
-      }
-   }
-
    // Private Member Variables ------------------------------------------------
+   
+   @Inject
+   private AnnotatedConfigBean acb;
 
    /**
     * The portlet name as defined in the portlet app descriptor.
@@ -114,7 +85,7 @@ public class PortletServlet3 extends HttpServlet {
    /**
     * The portlet instance wrapped by this servlet.
     */
-   private Portlet                portlet;
+   private PortletInvoker invoker = null;
 
    /**
     * The internal portlet context instance.
@@ -126,19 +97,6 @@ public class PortletServlet3 extends HttpServlet {
     */
    private DriverPortletConfig    portletConfig;
 
-   /**
-    * The Event Portlet instance (the same object as portlet) wrapped by this servlet.
-    */
-   private EventPortlet           eventPortlet;
-   
-   /**
-    * Header portlet instance
-    */
-   private HeaderPortlet          headerPortlet;
-
-   /** The resource serving portlet instance wrapped by this servlet. */
-   private ResourceServingPortlet resourceServingPortlet;
-
    private PortletContextService  contextService;
 
    private boolean                started = false;
@@ -163,6 +121,20 @@ public class PortletServlet3 extends HttpServlet {
 
       // Retrieve portlet name as defined as an initialization parameter.
       portletName = getInitParameter(PORTLET_NAME);
+      
+      // Get the config bean and create the invoker
+      try {
+         if (acb == null || acb.getMethodStore() == null) {
+            LOG.error("Could not obtain configuration bean for portlet " + portletName + ". Exiting.");
+            return;
+         } else {
+            invoker = new PortletInvoker(acb, portletName);
+            LOG.debug("Created the portlet invoker for portlet: " + portletName);
+         }
+      } catch(Exception e) {
+         LOG.error("Exception obtaining configuration bean for portlet " + portletName + ". Exiting. Exception: " + e.toString());
+         return;
+      }
 
       started = false;
 
@@ -204,21 +176,14 @@ public class PortletServlet3 extends HttpServlet {
             return true;
          }
 
-         PortletDefinition portletDD = portletConfig.getPortletDefinition();
-
-         // Create and initialize the portlet wrapped in the servlet.
+         // initialize the portlet wrapped in the servlet.
          try {
-            Class<?> clazz = paClassLoader.loadClass((portletDD.getPortletClass()));
-            portlet = (Portlet) clazz.newInstance();
-            portlet.init(portletConfig);
-            initializeEventPortlet();
-            initializeResourceServingPortlet();
-            initializeHeaderPortlet();
+            invoker.init(portletConfig);
             return true;
          } catch (Exception ex) {
             context.log(ex.getMessage(), ex);
             // take out of service
-            portlet = null;
+            invoker = null;
             portletConfig = null;
             return true;
          }
@@ -234,13 +199,13 @@ public class PortletServlet3 extends HttpServlet {
          } else if (started && portletContext != null) {
             started = false;
             contextService.unregister(portletContext);
-            if (portlet != null) {
+            if (invoker != null) {
                try {
-                  portlet.destroy();
+                  invoker.destroy();
                } catch (Exception e) {
                   // ignore
                }
-               portlet = null;
+               invoker = null;
             }
          }
          super.destroy();
@@ -278,7 +243,7 @@ public class PortletServlet3 extends HttpServlet {
     * @throws IOException
     */
    private void dispatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-      if (portlet == null) {
+      if (invoker == null) {
          throw new javax.servlet.UnavailableException("Portlet " + portletName + " unavailable");
       }
 
@@ -325,7 +290,7 @@ public class PortletServlet3 extends HttpServlet {
                renderRequest.setAttribute(PortletRequest.RENDER_PART, rh);
             }
             RenderResponse renderResponse = (RenderResponse) portletResponse;
-            filterManager.processFilter(renderRequest, renderResponse, portlet, portletContext);
+            filterManager.processFilter(renderRequest, renderResponse, invoker, portletContext);
          }
 
          // The requested method is HEADER: call
@@ -333,7 +298,7 @@ public class PortletServlet3 extends HttpServlet {
          else if (methodId == PortletInvokerService.METHOD_HEADER) {
             HeaderRequest headerRequest = (HeaderRequest) portletRequest;
             HeaderResponse headerResponse = (HeaderResponse) portletResponse;
-            filterManager.processFilter(headerRequest, headerResponse, headerPortlet, portletContext);
+            filterManager.processFilter(headerRequest, headerResponse, invoker, portletContext);
          }
 
          // The requested method is RESOURCE: call
@@ -350,21 +315,21 @@ public class PortletServlet3 extends HttpServlet {
             }
 
             ResourceResponse resourceResponse = (ResourceResponse) portletResponse;
-            filterManager.processFilter(resourceRequest, resourceResponse, resourceServingPortlet, portletContext);
+            filterManager.processFilter(resourceRequest, resourceResponse, invoker, portletContext);
          }
 
          // The requested method is ACTION: call Portlet.processAction(..)
          else if (methodId == PortletInvokerService.METHOD_ACTION) {
             ActionRequest actionRequest = (ActionRequest) portletRequest;
             ActionResponse actionResponse = (ActionResponse) portletResponse;
-            filterManager.processFilter(actionRequest, actionResponse, portlet, portletContext);
+            filterManager.processFilter(actionRequest, actionResponse, invoker, portletContext);
          }
 
          // The request methode is Event: call Portlet.processEvent(..)
          else if (methodId == PortletInvokerService.METHOD_EVENT) {
             EventRequest eventRequest = (EventRequest) portletRequest;
             EventResponse eventResponse = (EventResponse) portletResponse;
-            filterManager.processFilter(eventRequest, eventResponse, eventPortlet, portletContext);
+            filterManager.processFilter(eventRequest, eventResponse, invoker, portletContext);
          }
          // The requested method is ADMIN: call handlers.
          else if (methodId == PortletInvokerService.METHOD_ADMIN) {
@@ -392,15 +357,14 @@ public class PortletServlet3 extends HttpServlet {
 
          // Portlet.destroy() isn't called by Tomcat, so we have to fix it.
          try {
-            portlet.destroy();
+            invoker.destroy();
          } catch (Throwable th) {
             // Don't care for Exception
             this.getServletContext().log("Error during portlet destroy.", th);
          }
          // take portlet out of service
-         portlet = null;
+         invoker = null;
 
-         // TODO: Handle everything as permanently for now.
          throw new javax.servlet.UnavailableException(ex.getMessage());
 
       } catch (PortletException ex) {
@@ -423,28 +387,4 @@ public class PortletServlet3 extends HttpServlet {
          }
       }
    }
-
-   private void initializeEventPortlet() {
-      if (portlet instanceof EventPortlet) {
-         eventPortlet = (EventPortlet) portlet;
-      } else {
-         eventPortlet = new NullPortlet();
-      }
-   }
-
-   private void initializeResourceServingPortlet() {
-      if (portlet instanceof ResourceServingPortlet) {
-         resourceServingPortlet = (ResourceServingPortlet) portlet;
-      } else {
-         resourceServingPortlet = new NullPortlet();
-      }
-   }
-
-   private void initializeHeaderPortlet() {
-      if (portlet instanceof HeaderPortlet) {
-         headerPortlet = (HeaderPortlet) portlet;
-      } else {
-         headerPortlet = new NullPortlet();
-      }
-   }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/92f8e874/pluto-container/src/main/resources/META-INF/beans.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/META-INF/beans.xml b/pluto-container/src/main/resources/META-INF/beans.xml
index 115420e..451d465 100644
--- a/pluto-container/src/main/resources/META-INF/beans.xml
+++ b/pluto-container/src/main/resources/META-INF/beans.xml
@@ -1,5 +1,15 @@
-<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="
-http://java.sun.com/xml/ns/javaee
-http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
+       version="1.1" bean-discovery-mode="all">
+   
+   <scan>
+      <exclude name="org.apache.container.impl.*"></exclude>
+      <exclude name="org.apache.container.util.*"></exclude>
+      <exclude name="org.apache.container.om.portlet.impl.*"></exclude>
+      <exclude name="org.apache.container.om.portlet10.impl.*"></exclude>
+      <exclude name="org.apache.container.om.portlet20.impl.*"></exclude>
+      <exclude name="org.apache.container.om.portlet30.impl.*"></exclude>
+   </scan>
 </beans>
\ No newline at end of file


[29/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
Initial integration of bean processor 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/2e60a313
Tree: http://git-wip-us.apache.org/repos/asf/portals-pluto/tree/2e60a313
Diff: http://git-wip-us.apache.org/repos/asf/portals-pluto/diff/2e60a313

Branch: refs/heads/V3Prototype
Commit: 2e60a3135ee9a7b5ff6dd2bc5421964b9468b168
Parents: 0e1cc34
Author: Scott Nicklous <ms...@apache.org>
Authored: Thu Jan 14 13:32:55 2016 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Thu Jan 14 13:32:55 2016 +0100

----------------------------------------------------------------------
 pluto-container/pom.xml                         |   19 +
 .../bean/processor/AnnotatedConfigBean.java     |   95 +
 .../bean/processor/AnnotatedMethod.java         |  176 ++
 .../processor/AnnotatedMethodComparator.java    |   40 +
 .../bean/processor/AnnotatedMethodStore.java    |  557 ++++
 .../bean/processor/AnnotationRecognizer.java    |  271 ++
 .../container/bean/processor/ConfigServlet.java |  159 +
 .../container/bean/processor/ConfigSummary.java |  166 +
 .../processor/InvalidAnnotationException.java   |   73 +
 .../bean/processor/MethodDescription.java       |  297 ++
 .../bean/processor/MethodIdentifier.java        |  129 +
 .../processor/MethodIdentifierComparator.java   |   44 +
 .../container/bean/processor/MethodType.java    |   29 +
 .../processor/PortletAnnotationRecognizer.java  |  432 +++
 .../bean/processor/PortletArtifactProducer.java |  583 ++++
 .../bean/processor/PortletCDIExtension.java     |  129 +
 .../bean/processor/PortletInvoker.java          |  518 ++++
 .../processor/PortletSessionBeanHolder.java     |  234 ++
 .../PortletSessionScopedAnnotatedType.java      |  151 +
 .../processor/PortletSessionScopedConfig.java   |  165 +
 .../processor/PortletSessionScopedContext.java  |   90 +
 .../processor/PortletStateScopedBeanHolder.java |  241 ++
 .../processor/PortletStateScopedConfig.java     |  207 ++
 .../processor/PortletStateScopedContext.java    |   87 +
 .../bean/processor/SignatureVariant.java        |   65 +
 .../bean/processor/URLFactoryImpl.java          |   75 +
 .../container/bean/processor/package-info.java  |   25 +
 .../container/impl/ActionParametersImpl.java    |    1 -
 .../pluto/container/impl/HeaderRequestImpl.java |    1 -
 .../container/impl/HeaderResponseImpl.java      |    2 -
 .../impl/HttpServletPortletRequestWrapper.java  | 2927 +++++++++---------
 .../impl/PortletAppDescriptorServiceImpl.java   |   27 +-
 .../container/impl/PortletContextImpl.java      |  377 ++-
 .../container/impl/PortletParametersImpl.java   |    2 +-
 .../container/impl/PortletPreferencesImpl.java  |  644 ++--
 .../container/impl/PortletResponseImpl.java     |    1 -
 .../container/impl/PortletSessionImpl.java      |  657 ++--
 .../impl/ServletPortletSessionProxy.java        |  266 +-
 .../om/portlet/impl/ConfigurationHolder.java    |   24 +-
 .../om/portlet/impl/ConfigurationProcessor.java |   22 +
 .../om/portlet/impl/EventDefinitionImpl.java    |    2 +-
 .../impl/JSR362ConfigurationProcessor.java      |  303 +-
 .../impl/PortletApplicationDefinitionImpl.java  |   31 +-
 .../pluto/container/util/ClasspathScanner.java  |  231 +-
 .../javax.enterprise.inject.spi.Extension       |    1 +
 .../processor/fixtures/InvocationResults.java   |   74 +
 .../fixtures/PortletStateScopedBadClass.java    |   33 +
 .../fixtures/PortletStateScopedClass.java       |   43 +
 .../PortletStateScopedNoParamNameClass.java     |   42 +
 .../processor/fixtures/SessionScopedApp1.java   |   38 +
 .../fixtures/SessionScopedPortlet1.java         |   35 +
 .../fixtures/SessionScopedPortlet2.java         |   36 +
 .../fixtures/SessionScopedPortletBad1.java      |   35 +
 .../fixtures/SessionScopedPortletBad2.java      |   35 +
 .../fixtures/SessionScopedPortletBad3.java      |   35 +
 .../bean/processor/fixtures/action/Action1.java |   53 +
 .../bean/processor/fixtures/action/Action2.java |   95 +
 .../processor/fixtures/action/package-info.java |   23 +
 .../processor/fixtures/destroy/Destroy1.java    |   47 +
 .../processor/fixtures/destroy/Destroy2.java    |   61 +
 .../fixtures/destroy/package-info.java          |   23 +
 .../bean/processor/fixtures/event/Event1.java   |   59 +
 .../bean/processor/fixtures/event/Event2.java   |  120 +
 .../processor/fixtures/event/package-info.java  |   23 +
 .../bean/processor/fixtures/header/Header1.java |   91 +
 .../bean/processor/fixtures/header/Header2.java |   86 +
 .../processor/fixtures/header/package-info.java |   23 +
 .../bean/processor/fixtures/init/Init1.java     |   48 +
 .../bean/processor/fixtures/init/Init2.java     |   62 +
 .../processor/fixtures/init/package-info.java   |   23 +
 .../fixtures/mocks/MockActionParameters.java    |  102 +
 .../fixtures/mocks/MockActionRequest.java       |   61 +
 .../fixtures/mocks/MockActionResponse.java      |   56 +
 .../fixtures/mocks/MockClientDataRequest.java   |   90 +
 .../processor/fixtures/mocks/MockEvent.java     |   63 +
 .../fixtures/mocks/MockEventRequest.java        |   57 +
 .../fixtures/mocks/MockEventResponse.java       |   39 +
 .../fixtures/mocks/MockHeaderRequest.java       |   30 +
 .../fixtures/mocks/MockHeaderResponse.java      |   38 +
 .../fixtures/mocks/MockMimeResponse.java        |  184 ++
 .../fixtures/mocks/MockPortletConfig.java       |  160 +
 .../fixtures/mocks/MockPortletRequest.java      |  369 +++
 .../fixtures/mocks/MockPortletResponse.java     |   86 +
 .../fixtures/mocks/MockPortletSession.java      |  177 ++
 .../fixtures/mocks/MockRenderRequest.java       |   38 +
 .../fixtures/mocks/MockRenderResponse.java      |   47 +
 .../fixtures/mocks/MockResourceRequest.java     |   89 +
 .../fixtures/mocks/MockResourceResponse.java    |   60 +
 .../fixtures/mocks/MockStateAwareResponse.java  |  127 +
 .../processor/fixtures/mocks/package-info.java  |   26 +
 .../bean/processor/fixtures/package-info.java   |   25 +
 .../bean/processor/fixtures/render/Render1.java |   97 +
 .../bean/processor/fixtures/render/Render2.java |   83 +
 .../processor/fixtures/render/package-info.java |   23 +
 .../processor/fixtures/resource/Resource1.java  |   92 +
 .../processor/fixtures/resource/Resource2.java  |   86 +
 .../fixtures/resource/package-info.java         |   23 +
 .../bean/processor/tests/ActionTest.java        |  242 ++
 .../bean/processor/tests/DestroyTest.java       |  104 +
 .../bean/processor/tests/EventFixupTest.java    |  282 ++
 .../bean/processor/tests/EventTest.java         |  280 ++
 .../bean/processor/tests/HeaderTest.java        |  375 +++
 .../bean/processor/tests/InitTest.java          |  111 +
 .../bean/processor/tests/InvokeActionTest.java  |  163 +
 .../bean/processor/tests/InvokeDestroyTest.java |  113 +
 .../bean/processor/tests/InvokeEventTest.java   |  173 ++
 .../bean/processor/tests/InvokeHeaderTest.java  |  394 +++
 .../bean/processor/tests/InvokeInitTest.java    |  117 +
 .../bean/processor/tests/InvokeRenderTest.java  |  385 +++
 .../processor/tests/InvokeResourceTest.java     |  406 +++
 .../tests/PortletSessionAppScopeTest.java       |  174 ++
 .../tests/PortletSessionScopedTest.java         |  155 +
 .../processor/tests/PortletStateScopedTest.java |  135 +
 .../bean/processor/tests/RenderTest.java        |  375 +++
 .../bean/processor/tests/ResourceTest.java      |  375 +++
 .../bean/processor/tests/WeldInitializer.java   |   42 +
 .../bean/processor/tests/package-info.java      |   25 +
 .../container/impl/JaxbReadTest168Gen.java      |    2 -
 .../pluto/container/impl/JaxbReadTest168NC.java |    2 -
 .../container/impl/JaxbReadTest286Gen.java      |    2 -
 .../pluto/container/impl/JaxbReadTest286NC.java |    2 -
 .../container/impl/JaxbReadTest362Gen.java      |    2 -
 .../reconcile/fixtures/IncompletePortlet.java   |   87 +
 .../reconcile/fixtures/TestPortlet1.java        |  126 +
 .../fixtures/TestPortlet1AppScoped.java         |   32 +
 .../reconcile/fixtures/TestPortlet1a.java       |   68 +
 .../reconcile/fixtures/TestPortlet2.java        |   90 +
 .../reconcile/fixtures/TestPortlet3.java        |   73 +
 .../reconcile/fixtures/TestPortlet4.java        |  103 +
 .../reconcile/fixtures/TestPortlet5.java        |  131 +
 .../reconcile/fixtures/TestPortlet6.java        |  122 +
 .../reconcile/fixtures/package-info.java        |   25 +
 .../AnnotatedGenericPortletInvokeTest.java      |  170 +
 .../reconcile/tests/CDIPrototyping.java         |  143 +
 .../tests/GenericPortletFeaturesInvokeTest.java |  196 ++
 .../reconcile/tests/ImpliedPortletTest.java     |  168 +
 .../container/reconcile/tests/InvokeHelper.java |  163 +
 .../reconcile/tests/MergeEventDefsTest.java     |  210 ++
 .../reconcile/tests/PortletInvokeTest.java      |  323 ++
 .../reconcile/tests/PortletMethodTest.java      |  317 ++
 .../reconcile/tests/ReconcileAnnotatedTest.java |  246 ++
 .../tests/StandAloneBeanPortletInvokeTest.java  |  131 +
 .../container/reconcile/tests/package-info.java |   27 +
 .../om/portlet/portlet362Reconcile.xml          |   31 +
 .../driver/container/PortletContextManager.java |    5 +-
 145 files changed, 18934 insertions(+), 2636 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-container/pom.xml b/pluto-container/pom.xml
index d05a50b..ed41612 100644
--- a/pluto-container/pom.xml
+++ b/pluto-container/pom.xml
@@ -79,6 +79,25 @@
          <groupId>jmock</groupId>
          <artifactId>jmock-cglib</artifactId>
       </dependency>
+      <dependency>
+         <groupId>org.jboss.weld.se</groupId>
+         <artifactId>weld-se-core</artifactId>
+         <version>${cdi.version}</version>
+         <scope>test</scope>
+      </dependency>
+      <dependency>
+         <groupId>org.jglue.cdi-unit</groupId>
+         <artifactId>cdi-unit</artifactId>
+         <version>3.1.3</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.jboss.weld.se</groupId>
+               <artifactId>weld-se-core</artifactId>
+            </exclusion>
+         </exclusions>
+         <scope>test</scope>
+      </dependency>
+
    </dependencies>
 
    <build>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedConfigBean.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedConfigBean.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedConfigBean.java
new file mode 100644
index 0000000..4944dcd
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedConfigBean.java
@@ -0,0 +1,95 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import javax.enterprise.context.ApplicationScoped;
+
+/**
+ * A container for the annotated method configuration.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@ApplicationScoped
+public class AnnotatedConfigBean {
+
+   private AnnotatedMethodStore methodStore = null;
+   private ConfigSummary summary = null;
+   private PortletStateScopedConfig stateScopedConfig = null;
+   private PortletSessionScopedConfig sessionScopedConfig = null;
+   
+   /**
+    * @return the methodStore
+    */
+   public AnnotatedMethodStore getMethodStore() {
+      return methodStore;
+   }
+
+   /**
+    * @param methodStore the methodStore to set
+    */
+   public void setMethodStore(AnnotatedMethodStore methodStore) {
+      this.methodStore = methodStore;
+   }
+
+   /**
+    * @return the summary
+    */
+   public ConfigSummary getSummary() {
+      return summary;
+   }
+
+   /**
+    * @param summary the summary to set
+    */
+   public void setSummary(ConfigSummary summary) {
+      this.summary = summary;
+   }
+
+   /**
+    * @return the stateScopedConfig
+    */
+   public PortletStateScopedConfig getStateScopedConfig() {
+      return stateScopedConfig;
+   }
+
+   /**
+    * @param stateScopedConfig the stateScopedConfig to set
+    */
+   public void setStateScopedConfig(PortletStateScopedConfig stateScopedConfig) {
+      this.stateScopedConfig = stateScopedConfig;
+   }
+
+   /**
+    * @return the sessionScopedConfig
+    */
+   public PortletSessionScopedConfig getSessionScopedConfig() {
+      return sessionScopedConfig;
+   }
+
+   /**
+    * @param sessionScopedConfig the sessionScopedConfig to set
+    */
+   public void setSessionScopedConfig(PortletSessionScopedConfig sessionScopedConfig) {
+      this.sessionScopedConfig = sessionScopedConfig;
+   }
+   
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethod.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethod.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethod.java
new file mode 100644
index 0000000..13cc4d1
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethod.java
@@ -0,0 +1,176 @@
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+
+public class AnnotatedMethod {
+   
+   private final Class<?>           beanClass; 
+   private final Method             meth;
+   private final Annotation         annotation;
+   private final MethodDescription  description;
+   
+   // Proxied methods of the same type and for the same portlet name as indicated
+   // by the method identifier are stored by ordinal number. Methods that can appear more
+   // than once have an ordinal number as annotation element, which lands here.
+   private int                      ordinal = 0;
+   private boolean                  ordinalSet = false;
+   
+   private BeanManager     beanMgr;
+   
+   // The specific bean we are using
+   private Bean<?> bean;
+   private Object beanInstance;
+   private boolean isPortletClass = false;
+
+   /**
+    * Constructor.
+    * 
+    * @param anno          The annotation for this method
+    * @param beanClass     The Class of the bean containing the method
+    * @param meth          The method to be invoked
+    * @param desc          The method description for this method
+    */
+   public AnnotatedMethod(Annotation anno, Class<?> beanClass, Method meth, MethodDescription desc) {
+      this.beanClass = beanClass;
+      this.meth = meth;
+      this.annotation = anno;
+      this.description = desc;
+      
+      try {
+         Method ord = anno.getClass().getMethod("ordinal");
+         ordinal = (Integer) ord.invoke(anno);
+         ordinalSet = true;
+      } catch(Exception e) {}
+   }
+
+   /**
+    * Constructor for portlet class methods that don't have annotations. The classes 
+    * containing these methods may only be instantiated once, so the bean instance is passed
+    * in as well.
+    * 
+    * @param beanClass     The Class of the bean containing the method
+    * @param beanInstance  The instance to be used for invocation
+    * @param meth          The method to be invoked
+    * @param desc          The method description for this method
+    */
+   public AnnotatedMethod(Class<?> beanClass, Object beanInstance, Method meth, MethodDescription desc) {
+      this.beanClass = beanClass;
+      this.beanInstance = beanInstance;
+      this.meth = meth;
+      this.annotation = null;
+      this.description = desc;
+      this.isPortletClass = true;
+   }
+   
+   /**
+    * @return the annotation
+    */
+   public Annotation getAnnotation() {
+      return annotation;
+   }
+
+   /**
+    * @return the description
+    */
+   public MethodDescription getDescription() {
+      return description;
+   }
+
+   /**
+    * The annotated method is activated by using the specified BeanManager to
+    * obtain a reference to a bean that can be used for method invocation.
+    * 
+    * @param bm   The BeanManager
+    */
+   public void activate(BeanManager bm) {
+      beanMgr = bm;
+      Set<Bean<?>> beans = bm.getBeans(beanClass);
+      bean = bm.resolve(beans);
+      assert bean != null;
+   }
+   
+   /**
+    * Sets the bean instance. Used when the annotated method class is a configured portlet
+    * class to ensure that all annotated methods of the portlet class use the same bean instance.
+    * 
+    * @param beanInstance
+    */
+   public void setPortletClassInstance(Object beanInstance) {
+      this.beanInstance = beanInstance;
+      this.isPortletClass = true;
+   }
+   
+   /**
+    * Invoke the method with the arguments provided. It is expected that this method is called 
+    * is called by a proxy or facade for the method / class.
+    * 
+    * @param args    Arguments
+    * @return        Object returned by method
+    * @throws IllegalAccessException
+    * @throws IllegalArgumentException
+    * @throws InvocationTargetException
+    */
+   public Object invoke(Object... args) 
+         throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+      if (!isPortletClass) {
+         // get the reference for beans other than portlet classes in order to respect the 
+         // scope of the bean.
+         beanInstance = beanMgr.getReference(bean, bean.getBeanClass(), beanMgr.createCreationalContext(bean));
+      }
+      return meth.invoke(beanInstance, args);
+   }
+
+   /**
+    * returns string representation of the method.
+    */
+   public String toString() {
+      StringBuilder txt = new StringBuilder(256);
+      txt.append("Bean class=").append(beanClass.getCanonicalName());
+      txt.append(", Method name=").append(meth.getName());
+      if (ordinalSet) {
+         txt.append(", Ordinal=").append(ordinal);
+      }
+      return txt.toString();
+   }
+   
+   /**
+    * Returns the method wrapped by this class.
+    */
+   public Method getJavaMethod() {
+      return meth;
+   }
+
+   /**
+    * @return the ordinal
+    */
+   public int getOrdinal() {
+      return ordinal;
+   }
+   
+   /**
+    * one annotated method is equal to another if both represent 
+    * the same method in the same class.
+    */
+   @Override
+   public boolean equals(Object o) {
+      if ((o != null) && (o instanceof AnnotatedMethod)) {
+         AnnotatedMethod pm = (AnnotatedMethod) o;
+         return meth.equals(pm.meth);
+      }
+      return false;  
+   }
+   
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((meth == null) ? 0 : meth.hashCode());
+      return result;
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodComparator.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodComparator.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodComparator.java
new file mode 100644
index 0000000..703e6d9
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodComparator.java
@@ -0,0 +1,40 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional infooation
+ *  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 peoissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.util.Comparator;
+
+
+/**
+ * Simple comparator based on the filter ordinal number. used for ordering
+ * the annotated method store properly.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+public class AnnotatedMethodComparator implements Comparator<AnnotatedMethod> {
+
+   @Override
+   public int compare(AnnotatedMethod o1, AnnotatedMethod o2) {
+      assert (o1 != null) && (o2 != null);
+      return Integer.compare(o1.getOrdinal(), o2.getOrdinal());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
new file mode 100644
index 0000000..652ef86
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotatedMethodStore.java
@@ -0,0 +1,557 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import static org.apache.pluto.container.bean.processor.MethodType.ACTION;
+import static org.apache.pluto.container.bean.processor.MethodType.EVENT;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.PortletQName;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Makes the configuration data & annotated portlet methods that are read during the
+ * CDI scanning phase available for the portlets.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class AnnotatedMethodStore {
+   private static final Logger LOG = LoggerFactory.getLogger(AnnotatedMethodStore.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
+   private static final boolean isTrace = LOG.isTraceEnabled();
+   
+
+   // Note that the maps do not need to be synchronized, as the writes are only performed
+   // during the single-threaded CDI archive scanning phase.
+   // Also, TreeMap & TreeSet are used here to provide config & debug output ordered by 
+   // portlet name.
+   
+   // Map containing the annotated methods. Key is the MethodIdentifier, which consists
+   // of the portlet name, the method type, and the dispatch ID. There can be more
+   // than one method per method identifier.
+   // Important: In this map, a value can be linked to by more than one key!!
+   private final Map<MethodIdentifier, List<AnnotatedMethod>> methods =
+         new HashMap<MethodIdentifier, List<AnnotatedMethod>>();
+   
+   // Set containing all portlet names appearing in either the configuration map, 
+   // the method map, or both.
+   private final Set<String>  portletNames = new TreeSet<String>();
+   
+   // Holds deployment error descriptions and other information for display.
+   private final ConfigSummary summary;
+
+   // per portlet processing event references
+   private final Map<String, List<QName>> procEvtRefs = new HashMap<String, List<QName>>();
+
+   // Set of processing event method identifiers that have the QName namespace 
+   // equal to XMLConstants.NULL_NS_URI. These may need to be fixed up when the
+   // default namespace becomes known during config reconciliation.
+   private final Set<MethodIdentifier> procEvtRefFixups = new HashSet<MethodIdentifier>();
+   
+   // per portlet publishing event references
+   private final Map<String, List<QName>> pubEvtRefs = new HashMap<String, List<QName>>();
+   
+   // The bean manager for use during config reconciliation
+   private BeanManager beanMgr = null;
+   
+   /**
+    * Constructor
+    * @param consum
+    */
+   public AnnotatedMethodStore(ConfigSummary consum) {
+      this.summary = consum;
+   }
+   
+   /**
+    * Returns the method list for a given method identifier, or null if an entry
+    * already exists, but multiple entries are not allowed.
+    * 
+    * @param mi   the method identifier
+    * @param am   the annotated method
+    * @return     the list, or null if error condition
+    */
+   private List<AnnotatedMethod> getMethodList(MethodIdentifier mi, AnnotatedMethod am) {
+      List<AnnotatedMethod> list = methods.get(mi);
+      if (list != null) {
+         
+         // A method already exists for this ID. 
+         // Verify that multiple methods are allowed. 
+         
+         if (!am.getDescription().isAllowMultiple()) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Duplicate method specification. Method identifier: ");
+            txt.append(mi.toString());
+            txt.append(" / Method 1: ").append(list.get(0).toString());
+            txt.append(" / Method 2: ").append(am.toString());
+            summary.addErrorString(mi.getName(), txt.toString());
+            LOG.warn("Disallowed duplicate entry: " + mi.toString());
+            list = null;
+         }
+      } else {
+         list = new ArrayList<AnnotatedMethod>();
+         methods.put(mi, list);
+      }
+      return list;
+   }
+
+   /**
+    * Adds a annotated method for the given method identifier.
+    * 
+    * @param mi      Method identifier
+    * @param am      Annotated method
+    * @return        <code>true</code> if the AnnotatedMethod was added
+    *                <code>false</code> if there was a disallowed duplicate entry.
+    */
+   public boolean addMethod(MethodIdentifier mi, AnnotatedMethod am) {
+            
+      // First collect the event references, if any
+      
+      List<QName> procqns = new ArrayList<QName>();
+      List<QName> pubqns = new ArrayList<QName>();
+      if (mi.getType() == ACTION && am.getAnnotation() != null) {
+         ActionMethod anno = (ActionMethod) am.getAnnotation();
+         for (PortletQName pqn : anno.publishingEvents()) {
+            String uri = pqn.namespaceURI().trim();
+            uri = (uri.length() == 0) ? XMLConstants.NULL_NS_URI : uri;
+            QName qn = new QName(uri, pqn.localPart());
+            pubqns.add(qn);
+         }
+      } else if (mi.getType() == EVENT && am.getAnnotation() != null) {
+         EventMethod anno = (EventMethod) am.getAnnotation();
+         for (PortletQName pqn : anno.publishingEvents()) {
+            String uri = pqn.namespaceURI().trim();
+            uri = (uri.length() == 0) ? XMLConstants.NULL_NS_URI : uri;
+            QName qn = new QName(uri, pqn.localPart());
+            pubqns.add(qn);
+         }
+         for (PortletQName pqn : anno.processingEvents()) {
+            String uri = pqn.namespaceURI().trim();
+            uri = (uri.length() == 0) ? XMLConstants.NULL_NS_URI : uri;
+            QName qn = new QName(uri, pqn.localPart());
+            procqns.add(qn);
+         }
+      }
+      
+      if (mi.getType() == EVENT && procqns.size() > 0) {
+         
+         // If this is an event method, verify that the processing event QName 
+         // is not a duplicate. Add a separate entry for each processing event.
+
+         List<QName> qns = procEvtRefs.get(mi.getName());
+         if (qns != null) {
+            EventMethod anno = (EventMethod) am.getAnnotation();
+            for (PortletQName pqn : anno.processingEvents()) {
+               QName qn = new QName(pqn.namespaceURI(), pqn.localPart());
+               if (qns.contains(qn)) {
+                  StringBuilder txt = new StringBuilder(128);
+                  txt.append("Duplicate processing event QName. Portlet name: ");
+                  txt.append(mi.getName());
+                  txt.append(", QName: ").append(qn);
+                  txt.append(", Annotation: @EventMethod");
+                  txt.append(", Class: ").append(am.getJavaMethod().getDeclaringClass().getCanonicalName());
+                  summary.addErrorString(mi.getName(), txt.toString());
+                  LOG.warn(txt.toString());
+                  return false;
+               }
+            }
+         } else if (procqns.size() == 0) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Missing processing event QName. Portlet name: ");
+            txt.append(mi.getName());
+            txt.append(", Annotation: @EventMethod");
+            txt.append(", Class: ").append(am.getJavaMethod().getDeclaringClass().getCanonicalName());
+            summary.addErrorString(mi.getName(), txt.toString());
+            LOG.warn(txt.toString());
+            return false;
+         }
+         
+         List<QName> badQns = new ArrayList<QName>();
+         for (QName qn : procqns) {
+            MethodIdentifier newmi = new MethodIdentifier(mi);
+            newmi.setId(qn);
+
+            List<AnnotatedMethod> list = getMethodList(newmi, am);
+            if (list == null) {
+               badQns.add(qn);
+               continue;
+            }
+            
+            if (qn.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) {
+               procEvtRefFixups.add(newmi);
+            }
+            list.add(am);
+         }
+         
+         if (badQns.size() > 0) {
+            procqns.removeAll(badQns);
+            if (procqns.size() == 0) {
+               return false;
+            }
+         }
+         
+      } else {
+         
+         // For all other methods, including the event default method with dispatchId = "",
+         // just get the list and add the method
+         
+         List<AnnotatedMethod> list = getMethodList(mi, am);
+         if (list == null) {
+            return false;
+         }
+         
+         list.add(am);
+         
+      }
+      
+      // Collect additional info about the added method(s)
+      
+      portletNames.add(mi.getName());
+      
+      String portletName = mi.getName();
+      if (procqns.size() > 0) {
+         if (!procEvtRefs.containsKey(portletName)) {
+            procEvtRefs.put(portletName, new ArrayList<QName>());
+         }
+         procEvtRefs.get(portletName).addAll(procqns);
+      }
+      
+      if (pubqns.size() > 0) {
+         if (!pubEvtRefs.containsKey(portletName)) {
+            pubEvtRefs.put(portletName, new ArrayList<QName>());
+         }
+         pubEvtRefs.get(portletName).addAll(pubqns);
+      }
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder();
+         txt.append("Stored annotated method for: ").append(mi.toString());
+         txt.append(", Processing event refs: ").append(procqns);
+         txt.append(", Publishing event refs: ").append(procqns);
+         LOG.debug(txt.toString());
+      }
+      return true;
+   }
+   
+   /**
+    * Removes the annotated method or methods stored for the given method identifier.
+    * 
+    * @param mi   the method identifier
+    * @return     The list of annotated methods removed, or <code>null</code> if no list exists
+    */
+   public List<AnnotatedMethod> removeMethod(MethodIdentifier mi) {
+      return methods.remove(mi);
+   }
+   
+   /**
+    * Returns the annotated method for a given identifier.
+    * 
+    * It's a programming error if this method is used when multiple methods could be expected. 
+    * 
+    * @param mi   The method identifier
+    * @return     The annotated method, or <code>null</code> if none was found.
+    */
+   public AnnotatedMethod getMethod(MethodIdentifier mi) {
+      AnnotatedMethod pm = null;
+      List<AnnotatedMethod> list = methods.get(mi);
+      if (list != null) {
+         assert list.size() == 1;
+         assert !list.get(0).getDescription().isAllowMultiple();
+         pm = list.get(0);
+      }
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Retrieved annotated method for: ").append(mi.toString());
+         txt.append(", Method: ").append(pm == null ? "null" : pm.toString());
+         LOG.trace(txt.toString());
+      }
+      return pm;
+   }
+   
+   /**
+    * Returns all registered methods for the given method identifier.
+    * <p>
+    * This is intended for use with method identifiers such as PortletResources
+    * that can have more than one annotated method for each method identifier.
+    * 
+    * @param mi     The method identifier
+    * @return       A list of annotated methods.
+    */
+   public List<AnnotatedMethod> getMethods(MethodIdentifier mi){
+      List<AnnotatedMethod> aList = new ArrayList<AnnotatedMethod>();
+      if (methods.containsKey(mi)) {
+         aList.addAll(methods.get(mi));
+      }
+      return aList;
+   }
+   
+   /**
+    * Returns a String representation of the stored methods.
+    * 
+    * @return  String
+    */
+   public String getMethodsAsString() {
+      
+      List<MethodIdentifier> meths = new ArrayList<MethodIdentifier>();
+      meths.addAll(methods.keySet());
+      Collections.sort(meths, new MethodIdentifierComparator());
+
+      StringBuilder txt = new StringBuilder(256);
+      txt.append("Stored methods: ");
+      for (MethodIdentifier mi : meths) {
+         txt.append("\n\t").append(mi.toString());
+         for (AnnotatedMethod pm : methods.get(mi)) {
+            txt.append("\n\t\t").append(pm.toString());
+         }
+      }
+      return txt.toString();
+   }
+   
+   /**
+    * returns a String representation of all data stored.
+    */
+   @Override
+   public String toString() {
+      StringBuilder txt = new StringBuilder(256);
+      txt.append("\n");
+      txt.append(getMethodsAsString());
+      return txt.toString();
+   }
+   
+   /**
+    * Returns a Set containing the unique portlet names represented in the store.
+    * @return     The portlet names
+    */
+   public Set<String> getPortletNames() {
+      return new HashSet<String>(portletNames);
+   }
+   
+   /**
+    * Returns the stored methods for the given portlet name.
+    * 
+    * @param   portletName    The portlet name
+    * @return                 Set of method identifiers. The Set is empty if there are no 
+    *                         methods available
+    */
+   public Set<MethodIdentifier> getMethodIDsForPortlet(String portletName) {
+      Set<MethodIdentifier> meths = new HashSet<MethodIdentifier>();
+      for (MethodIdentifier mi : methods.keySet()) {
+         if (mi.getName().equals(portletName)) {
+            meths.add(mi);
+         }
+      }
+      return meths;
+   }
+   
+   /**
+    * Removes the stored methods for the given portlet name.
+    * 
+    * @param   portletName    The portlet name
+    */
+   public void removeMethodsForPortlet(String portletName) {
+      
+      Set<MethodIdentifier> meths = new HashSet<MethodIdentifier>();
+      for (MethodIdentifier mi : methods.keySet()) {
+         if (mi.getName().equals(portletName)) {
+            meths.add(mi);
+         }
+      }
+      
+      for (MethodIdentifier mi : meths) {
+         methods.remove(mi);
+      }
+      
+      portletNames.remove(portletName);
+   }
+   
+   /**
+    * Activate the methods by providing them with a bean manager. 
+    * Sort the method lists for the method types that can have multiple
+    * entries.
+    * 
+    * @param bm
+    */
+   public void activateMethods(BeanManager bm) {
+      beanMgr = bm;
+      Collection<List<AnnotatedMethod>> methlists = methods.values();
+      for (List<AnnotatedMethod> list : methlists) {
+         Collections.sort(list, new AnnotatedMethodComparator());
+         for (AnnotatedMethod meth : list) {
+            meth.activate(bm);
+         }
+      }
+   }
+   
+   /**
+    * Returns the configured processing event references for the given portlet.
+    * <p>
+    * Used during configuration reconciliation.
+    * 
+    * @param   portletName
+    * @return  The event references
+    */
+   public List<QName> getProcessingEventRefs(String portletName) {
+      List<QName> list = new ArrayList<QName>();
+      if (procEvtRefs.containsKey(portletName)) {
+         list.addAll(procEvtRefs.get(portletName));
+      }
+      return list;
+   }
+   
+   /**
+    * Returns the configured publishing event references for the given portlet.
+    * <p>
+    * Used during configuration reconciliation.
+    * 
+    * @param   portletName
+    * @return  The event references
+    */
+   public List<QName> getPublishingEventRefs(String portletName) {
+      List<QName> list = new ArrayList<QName>();
+      if (pubEvtRefs.containsKey(portletName)) {
+         list.addAll(pubEvtRefs.get(portletName));
+      }
+      return list;
+   }
+   
+   /**
+    * Sets the default namespace for method identifiers whose QName NS URIs are
+    * XMLConstants.NULL_NS_URI.
+    * <p>
+    * Used during configuration reconciliation.
+    * This method should be called after the bean configuration has been read, but before
+    * the processing and publishing event references are retrieved. 
+    * 
+    * @param ns      The default namespace
+    */
+   public void setDefaultNamespace(String ns) {
+      if ((ns != null) && !ns.equals(XMLConstants.NULL_NS_URI)) {
+         
+         // fix up the invokable event methods
+         
+         for (MethodIdentifier mi : procEvtRefFixups) {
+            List<AnnotatedMethod> meths = methods.get(mi);
+               
+            assert (meths != null) && (meths.size() > 0);
+            assert (mi.getType() == EVENT) && (mi.getId() instanceof QName);
+            QName oldqn = (QName) mi.getId();
+            assert oldqn.getNamespaceURI().equals(XMLConstants.NULL_NS_URI);
+            QName newqn = new QName(ns, oldqn.getLocalPart());
+            MethodIdentifier newmi = new MethodIdentifier(mi);
+            newmi.setId(newqn);
+
+            methods.remove(mi);
+            methods.put(newmi, meths);
+            
+            if (isDebug) {
+               StringBuilder txt = new StringBuilder();
+               txt.append("Fixing up Method identifier with default namespace: ").append(ns);
+               txt.append(", old MI: ").append(mi);
+               txt.append(", new MI: ").append(newmi);
+               LOG.debug(txt.toString());
+            }
+         }
+         
+         // Fixup the per-portlet processing event references
+         
+         for (String pn : procEvtRefs.keySet()) {
+            List<QName> oldqns = new ArrayList<QName>(procEvtRefs.get(pn));
+            for (QName oldqn : oldqns) {
+               if (oldqn.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) {
+                  QName newqn = new QName(ns, oldqn.getLocalPart());
+                  procEvtRefs.get(pn).remove(oldqn);
+                  procEvtRefs.get(pn).add(newqn);
+                  
+                  if (isDebug) {
+                     StringBuilder txt = new StringBuilder();
+                     txt.append("Fixed up processing event reference for portlet: ").append(pn);
+                     txt.append(", old QN: ").append(oldqn);
+                     txt.append(", new QN: ").append(newqn);
+                     LOG.debug(txt.toString());
+                  }
+               }
+            }
+         }
+         
+         // Fixup the per-portlet publishing event references
+         
+         for (String pn : pubEvtRefs.keySet()) {
+            List<QName> oldqns = new ArrayList<QName>(pubEvtRefs.get(pn));
+            for (QName oldqn : oldqns) {
+               if (oldqn.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) {
+                  QName newqn = new QName(ns, oldqn.getLocalPart());
+                  pubEvtRefs.get(pn).remove(oldqn);
+                  pubEvtRefs.get(pn).add(newqn);
+                  
+                  if (isDebug) {
+                     StringBuilder txt = new StringBuilder();
+                     txt.append("Fixed up publishing event reference for portlet: ").append(pn);
+                     txt.append(", old QN: ").append(oldqn);
+                     txt.append(", new QN: ").append(newqn);
+                     LOG.debug(txt.toString());
+                  }
+               }
+            }
+         }
+      }
+   }
+
+   /**
+    * @return the beanMgr
+    */
+   public BeanManager getBeanMgr() {
+      return beanMgr;
+   }
+   
+   /**
+    * Sets the bean instance for all annotated methods that are members of a configured portlet
+    * class to ensure that all annotated methods of the portlet class use the same bean instance.
+    * 
+    * @param cls
+    * @param beanInstance
+    */
+   public void setPortletClassInstance(Class<?> cls, Object beanInstance) {
+      for (List<AnnotatedMethod> list : methods.values()) {
+         for (AnnotatedMethod am : list) {
+            if (am.getJavaMethod().getDeclaringClass().equals(cls)) {
+               am.setPortletClassInstance(beanInstance);
+            }
+         }
+      }
+   }
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
new file mode 100644
index 0000000..5530f04
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/AnnotationRecognizer.java
@@ -0,0 +1,271 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class recognizes "interesting" classes and methods by their annotations and
+ * verifies the method signatures. 
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public abstract class AnnotationRecognizer {
+   private static final Logger LOG = LoggerFactory.getLogger(AnnotationRecognizer.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
+   private static final boolean isTrace = LOG.isTraceEnabled();
+   
+
+   protected final Set<Class<? extends Annotation>> classAnnotations;
+   protected final Map<Class<? extends Annotation>, List<MethodDescription>> descriptions;
+   
+   // Holds deployment error descriptions and other information for display.
+   protected final ConfigSummary summary;
+
+   
+   protected AnnotationRecognizer(Set<Class<? extends Annotation>> cla, 
+         Map<Class<? extends Annotation>, List<MethodDescription>> descriptions,
+         ConfigSummary summary) {
+      this.classAnnotations = cla;
+      this.descriptions = descriptions;
+      this.summary = summary;
+   }
+   
+   /**
+    * Returns the annotation found if the specified annotation is in the specified Set
+    * and <code>null</code> if not.
+    * 
+    * @param clsSet     Set containing candidate annotations
+    * @param anno       Annotation to be checked
+    * @return           the annotation, if annotation is contained in Set, otherwise null
+    */
+   private Class<? extends Annotation> setContains(Set<Class<? extends Annotation>> clsSet, Annotation anno) {
+      for (Class<? extends Annotation> cls : clsSet) {
+         if (anno.annotationType().isAssignableFrom(cls)) {
+            return cls;
+         }
+      }
+      return null;
+   }
+   
+   /**
+    * Checks annotations on an input AnnotatedType. Any portlet-related annotation
+    * data found is stored as configuration data.
+    * 
+    * The methods on the annotated type are scanned for relevant annotations as well. If a 
+    * portlet-related method annotation is found, the method and bean instance is stored.
+    * 
+    * A class can have multiple portlet annotations, but they all must be for the same portlet.
+    *  
+    * @param   aType    The type to check
+    * @throws  InvalidAnnotationException    If multiple portlet annotations don't have 
+    *                                        the same portlet names.   
+    */
+   @SuppressWarnings({ "unchecked", "rawtypes" })
+   public void checkAnnotatedType(ProcessAnnotatedType pat) throws InvalidAnnotationException {
+      AnnotatedType<?> aType = pat.getAnnotatedType();
+      String typeName = aType.getJavaClass().getCanonicalName();
+      if (isDebug) {
+         LOG.debug("Checking for annotations on: " + typeName);
+      }
+      try {
+         
+         // Process the class annotations
+         
+         Set<Annotation> annos = aType.getAnnotations();
+         for (Annotation anno : annos) {
+            if (setContains(classAnnotations, anno) != null) {
+               if (isDebug) {
+                  StringBuilder txt = new StringBuilder(128);
+                  txt.append("Found Annotation: ").append(anno.toString());
+                  txt.append(", portlet name: ").append(getDisplayNames(anno));
+                  LOG.debug(txt.toString());
+               }
+               AnnotatedType<?> ret = handleClassAnnotation(anno, aType);
+               if (ret != null) {
+                  pat.setAnnotatedType(ret);
+               }
+            }
+         }
+         
+         // Get the annotated methods and handle them
+         
+         for (AnnotatedMethod<?> meth : aType.getMethods()) {
+            annos = meth.getAnnotations();
+            for (Annotation anno : annos) {
+               Class<? extends Annotation> keyAnno = 
+                     setContains(descriptions.keySet(), anno);
+               if (keyAnno != null) {
+                  
+                  // Get the valid method descriptions for this annotation
+                  
+                  List<MethodDescription> descs = descriptions.get(keyAnno);
+                  assert descs != null;
+                  assert descs.size() > 0;
+                  
+                  // try to find the matching method description
+                  
+                  MethodDescription matchingDesc = null;
+                  StringBuilder errtxt = new StringBuilder(128);
+                  String sep = "   ";
+                  for (MethodDescription desc : descs) {
+                     if (desc.isMethodMatched(meth.getJavaMember())) {
+                        matchingDesc = desc;
+                        break;
+                     } else {
+                        errtxt.append(sep).append(desc.getExpectedSignature(true));
+                        sep = "\n   ";
+                     }
+                  }
+  
+                  if (isTrace) {
+                     StringBuilder txt = new StringBuilder(128);
+                     txt.append("For method annotation: ").append(anno.annotationType().getSimpleName());
+                     txt.append(" on class: ").append(typeName);
+                     txt.append(", method: ").append(meth.getJavaMember().getName());
+                     if (matchingDesc != null) {
+                        txt.append(", recognized type: ").append(matchingDesc.getType());
+                        txt.append(", signature variant: ").append(matchingDesc.getVariant());
+                     } else {
+                        txt.append(", No match found. Error string:\n");
+                        txt.append(errtxt);
+                     }
+                     LOG.trace(txt.toString());
+                  }
+
+                  if (matchingDesc != null) {
+                     
+                     // Found a matching method, so handle.
+                     
+                     handleMethod(anno, aType.getJavaClass(), meth.getJavaMember(), matchingDesc);
+                  } else {
+                     
+                     // Method doesn't match any of the descriptions. 
+                     // this might occur when someone makes a mistake with configuration,
+                     // so handle gracefully.
+                     
+                     StringBuilder txt = new StringBuilder(128);
+                     txt.append("Unrecognized method annotation: ")
+                        .append(anno.annotationType().getSimpleName());
+                     txt.append(", Class: ").append(typeName);
+                     txt.append(", Method: ").append(meth.getJavaMember().getName());
+                     txt.append("\n").append(errtxt);
+                     LOG.debug(txt.toString());
+                     
+                     // Store the error for each portlet name in array 
+                     for (String n : getDisplayNames(anno)) {
+                        summary.addErrorString(n, txt.toString());
+                     }
+                  }
+               }
+            }
+         }
+         
+      } catch (Exception e) {
+         
+         // The rest of the possible exceptions are unexpected, so someone will
+         // have to analyze a stack trace.
+         
+         StringBuilder txt = new StringBuilder("Error processing annotations for ");
+         txt.append(aType.toString());
+         throw new InvalidAnnotationException(txt.toString(), e); 
+      }
+   }
+
+   /**
+    * extracts array of portlet names from the annotation
+    * 
+    * @param anno    the annotation
+    * @return        array of names
+    */
+   protected String[] getDisplayNames(Annotation anno) {
+      String[] portletNames = {"unknown"};
+      try {
+         Method getPN = anno.getClass().getMethod("portletName");
+         String[] annoNames = new String[] {(String)getPN.invoke(anno)};
+         if (annoNames[0] != null && annoNames[0].length() > 0) {
+            portletNames = annoNames;
+         }
+      } catch(Exception e) {
+         try {
+            Method getPN = anno.getClass().getMethod("portletNames");
+            String[] names = (String[])getPN.invoke(anno);
+            if (names != null && names.length > 0) {
+               portletNames = names;
+            }
+         } catch(Exception e2) {
+            try {
+               Method getPN = anno.getClass().getMethod("value");
+               String[] annoNames = new String[] {(String)getPN.invoke(anno)};
+               if (annoNames[0] != null && annoNames[0].length() > 0) {
+                  portletNames = annoNames;
+               }
+            } catch (Exception e3) {}
+         }
+      }
+      return portletNames;
+   }
+
+   /**
+    * Extracts data from the class annotation and stores it for later use.
+    * 
+    * @param anno
+    * @throws InvalidAnnotationException
+    */
+   protected abstract AnnotatedType<?> handleClassAnnotation(Annotation anno, AnnotatedType<?> aType) 
+         throws InvalidAnnotationException;
+
+   /**
+    * Extracts and stores relevant information from the specified annotation, bean
+    * class, and Method.
+    *  
+    * @param anno
+    * @param beanClass
+    * @param meth
+    * @throws InvalidAnnotationException  If the specified information is inconsistent
+    *                                     or if a duplicate method has already been stored.
+    */
+   protected abstract void handleMethod(Annotation anno, Class<?> beanClass,
+         Method meth, MethodDescription desc);
+
+   /**
+    * To be called by the CDI extension afterDeploymentValidation method to
+    * verify that the stored methods are consistent and to create the bean referenecs.
+    *  
+    * @param bm      BeanManager needed to activate the beans.
+    * @throws InvalidAnnotationException  If the deployment is inconsistent or if the
+    *                                     beans cannot be instantiated.
+    */
+   protected abstract void activateDeployment(BeanManager bm)
+         throws InvalidAnnotationException;
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigServlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigServlet.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigServlet.java
new file mode 100644
index 0000000..8757441
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigServlet.java
@@ -0,0 +1,159 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Servlet to display the portlet configuration along with any configuration
+ * errors or warnings for this servlet context.
+ * 
+ * @author Scott Nicklous
+ */
+public class ConfigServlet extends HttpServlet {
+   private static final long serialVersionUID = -3842324547802444406L;
+
+   private StringBuilder errorString = new StringBuilder();
+   public static final String ATTRIB_ERROR = "_Error";
+   
+   @Inject
+   private AnnotatedConfigBean acb;
+
+   /**
+    * TODO: complete and make work.
+    */
+   @Override
+   protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+      String portletName = "Fred";
+      
+      ConfigSummary summary = acb.getSummary();
+      AnnotatedMethodStore ams = acb.getMethodStore();
+      PortletStateScopedConfig config = acb.getStateScopedConfig();
+      
+      // Make sure there are beans for this portlet name. If not, build an error
+      // string for later viewing. The error string shows all deployment errors that were
+      // logged along with all annotated portlet artifacts that were found.
+      
+      List<String> errors = summary.getErrorStrings(portletName);
+      if (!ams.getPortletNames().contains(portletName) && errors.size() == 0) {
+
+         errorString.append("<h3>Portlet Name: ").append(portletName).append("</h3>");
+         errorString.append("<p>No portlet annotations could be found for this portlet.</p>");
+         errorString.append("<h4>Deployment errors:</h4>");
+         List<String> portletNames = summary.getPortletsWithErrors();
+         portletNames.remove("*");
+         for (String name: portletNames) {
+            errorString.append("<p style='color: #00F; font: bold;'>Portlet: " + name + "</p>");
+            List<String> errs = summary.getErrorStrings(name);
+            for (String err : errs) {
+               errorString.append("<div style='padding-left: 15px;'>");
+               String[] lines = err.split("\\n");
+               errorString.append(lines[0]);
+               if (lines.length > 1) {
+                  for (String line : Arrays.copyOfRange(lines, 1, lines.length)) {
+                     errorString.append("<div style='padding-left: 15px;'>");
+                     errorString.append(line);
+                     errorString.append("</div>");
+                  }
+               }
+               errorString.append("</div>");
+            }
+         }
+         errorString.append("<h4>Available annotated portlet artifacts:</h4>");
+//         formatToErrorString(ams.getConfigAsString().split("\n"));
+         formatToErrorString(ams.getMethodsAsString().split("\n"));
+         errorString.append("<h4>PortletStateScoped Bean Configuration:</h4>");
+         formatToErrorString(config.getConfigAsString().split("\n"));
+      } else {
+         
+         // If there are deployment errors for this portlet, display them rather 
+         // than trying to dispatch to potentially erroneous bean methods.
+         
+         if (errors.size() > 0) {
+
+            errorString.append("<h3>Portlet Name: ").append(portletName).append("</h3>");
+            errorString.append("<p>There were deployment problems with this portlet.</p>");
+            errorString.append("<h4>Deployment errors:</h4>");
+            for (String err : errors) {
+               errorString.append("<div style='padding-left: 15px;'>");
+               String[] lines = err.split("\\n");
+               errorString.append(lines[0]);
+               if (lines.length > 1) {
+                  for (String line : Arrays.copyOfRange(lines, 1, lines.length)) {
+                     errorString.append("<div style='padding-left: 15px;'>");
+                     errorString.append(line);
+                     errorString.append("</div>");
+                  }
+               }
+               errorString.append(err.replaceAll("\\n", "<br/>"));
+               errorString.append("</div>");
+            }
+         }
+
+      }
+
+      resp.setContentType("text/html");
+      PrintWriter writer = resp.getWriter();
+      writer.write(errorString.toString());
+
+   }
+
+   
+   /**
+    * Formats an array of text lines to the error string. The first line is highlighted.
+    * subsequent lines are indented once for each tab character at the beginning.
+    *   
+    * @param lines   The lines to format
+    */
+   private void formatToErrorString(String[] lines) {
+      if (lines.length > 0) {
+         errorString.append("<p style='color: #00F; font: bold;'>" + lines[0] + "</p>");
+         for (String line : Arrays.copyOfRange(lines, 1, lines.length)) {
+            Stack<String> closingTags = new Stack<String>();
+            
+            errorString.append("<div style='padding-left: 15px;'>");
+            closingTags.push("</div>");
+
+            while (line.length() > 0 && line.startsWith("\t")) {
+               errorString.append("<div style='padding-left: 15px;'>");
+               closingTags.push("</div>");
+               line = line.substring(1);
+            }
+            
+            errorString.append(line);
+            
+            while(!closingTags.empty()) {
+               errorString.append(closingTags.pop());
+            }
+         }
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigSummary.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigSummary.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigSummary.java
new file mode 100644
index 0000000..ebbb309
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/ConfigSummary.java
@@ -0,0 +1,166 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Contains a summary of the configuration along with configuration errors
+ * and warnings for display purposes only.
+ * 
+ * @author Scott
+ *
+ */
+public class ConfigSummary {
+   
+   // List of PortletSessionScoped beans with APPLICATION_SCOPE
+   List<PortletSessionScopedAnnotatedType> appScopedTypes = new ArrayList<PortletSessionScopedAnnotatedType>();
+
+   // Per-class error messages for portlet session scoped bean deployment problems
+   private final Map<Class<?>, String> badSessionBeans = new HashMap<Class<?>, String>();
+
+   // Per-class error messages for portlet state scoped bean deployment problems
+   private final Map<Class<?>, String> badStateBeans = new HashMap<Class<?>, String>();
+   
+   // Per-portlet error messages for deployment problems
+   private final Map<String, List<String>> errors = new TreeMap<String, List<String>>();
+   
+   /**
+    * Stores an error string to document deployment problems.
+    * 
+    * @param portletName
+    * @param msg
+    */
+   public void addErrorString(String portletName, String msg) {
+      assert portletName != null && portletName.length() > 0;
+      if (!errors.containsKey(portletName)) {
+         errors.put(portletName, new ArrayList<String>());
+      }
+      errors.get(portletName).add(msg);
+   }
+   
+   /**
+    * Returns the error strings associated with the given portlet name.
+    * 
+    * @param portletName
+    * @return
+    */
+   public List<String> getErrorStrings(String portletName) {
+      assert portletName != null && portletName.length() > 0;
+      List<String> errs = new ArrayList<String>();
+      List<String> perrs = errors.get(portletName);
+      if (perrs != null) {
+         errs.addAll(perrs);
+      }
+      return errs;
+   }
+   
+   /**
+    * Returns a list of all portlet names with deployment problems.
+    * 
+    * @return
+    */
+   public List<String> getPortletsWithErrors() {
+      return new ArrayList<String>(errors.keySet());
+   }
+   
+   /**
+    * Stores an error string to document portlet state scoped bean deployment problems.
+    * 
+    * @param portletName
+    * @param msg
+    */
+   public void addStateBeanErrorString(Class<?> cls, String msg) {
+      badStateBeans.put(cls, msg);
+   }
+   
+   /**
+    * Returns the error strings associated with the given state scoped bean.
+    * 
+    * @param portletName
+    * @return
+    */
+   public String getStateBeanErrorString(Class<?> bean) {
+      return badStateBeans.get(bean);
+   }
+   
+   /**
+    * Returns a list of all portlet state scoped bean classes with deployment problems.
+    * 
+    * @return
+    */
+   public List<Class<?>> getStateBeansWithErrors() {
+      return new ArrayList<Class<?>>(badStateBeans.keySet());
+   }
+   
+   /**
+    * Stores an error string to document portlet session scoped bean deployment problems.
+    * 
+    * @param portletName
+    * @param msg
+    */
+   public void addSessionBeanErrorString(Class<?> cls, String msg) {
+      badSessionBeans.put(cls, msg);
+   }
+   
+   /**
+    * Returns the error strings associated with the given session scoped bean.
+    * 
+    * @param portletName
+    * @return
+    */
+   public String getSessionBeanErrorString(Class<?> bean) {
+      return badSessionBeans.get(bean);
+   }
+   
+   /**
+    * Returns a list of all portlet session scoped bean classes with deployment problems.
+    * 
+    * @return
+    */
+   public List<Class<?>> getSessionBeansWithErrors() {
+      return new ArrayList<Class<?>>(badSessionBeans.keySet());
+   }
+   
+   /**
+    * Adds a PortletSessionScoped bean with APPLICATION_SCOPE to list
+    * for test / display purposes. These annotated types have been
+    * modified by deleting the PortletSessionScoped annotation and adding 
+    * a SessionScoped annotation. 
+    * 
+    * @param type
+    */
+   public void addAppScopedType(PortletSessionScopedAnnotatedType type) {
+      appScopedTypes.add(type);
+   }
+   
+   /**
+    * Returns list of all portlet session Scoped beans with APPLICATION_SCOPE
+    * @return
+    */
+   public List<PortletSessionScopedAnnotatedType> getAppScopedTypes() {
+      return appScopedTypes;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/InvalidAnnotationException.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/InvalidAnnotationException.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/InvalidAnnotationException.java
new file mode 100644
index 0000000..03dc33a
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/InvalidAnnotationException.java
@@ -0,0 +1,73 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+
+/**
+ * @author Scott
+ *
+ */
+public class InvalidAnnotationException extends Exception {
+   private static final long serialVersionUID = 4387915782102207038L;
+   
+   private String portletName = "";
+
+   /**
+    * @param message
+    */
+   public InvalidAnnotationException(String message) {
+      super(message);
+   }
+
+   /**
+    * @param cause
+    */
+   public InvalidAnnotationException(Throwable cause) {
+      super(cause);
+   }
+
+   /**
+    * @param message
+    * @param cause
+    */
+   public InvalidAnnotationException(String message, Throwable cause) {
+      super(message, cause);
+   }
+
+   /**
+    * @param message
+    * @param cause
+    * @param enableSuppression
+    * @param writableStackTrace
+    */
+   public InvalidAnnotationException(String message, Throwable cause,
+         boolean enableSuppression, boolean writableStackTrace) {
+      super(message, cause, enableSuppression, writableStackTrace);
+   }
+
+   public String getPortletName() {
+      return portletName;
+   }
+
+   public void setPortletName(String portletName) {
+      this.portletName = portletName;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodDescription.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodDescription.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodDescription.java
new file mode 100644
index 0000000..f6c30a6
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodDescription.java
@@ -0,0 +1,297 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+
+/**
+ * Verifies the method signature according to the constructor parameters.
+ * 
+ * @author nick
+ *
+ */
+public class MethodDescription {
+   
+   // Constants for standard portlet class methods
+   //==============================================
+   
+   public static MethodDescription METH_INI = new MethodDescription(void.class, 
+         new Class<?>[] {PortletConfig.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.INIT);
+   
+   public static MethodDescription METH_DES = new MethodDescription(void.class, 
+         new Class<?>[] {},  
+         new Class<?>[] {}, 
+         MethodType.DESTROY);
+   
+   public static MethodDescription METH_ACT = new MethodDescription(void.class, 
+         new Class<?>[] {ActionRequest.class, ActionResponse.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.ACTION);
+   
+   public static MethodDescription METH_EVT = new MethodDescription(void.class, 
+         new Class<?>[] {EventRequest.class, EventResponse.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.EVENT);
+
+   public static MethodDescription METH_REN = new MethodDescription(void.class, 
+         new Class<?>[] {RenderRequest.class, RenderResponse.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.RENDER);
+   static {
+      METH_REN.setAllowMultiple(true);
+      METH_REN.setVariant(SignatureVariant.VOID_RENDERREQ_RENDERRESP);
+   }
+
+   public static MethodDescription METH_RES = new MethodDescription(void.class, 
+         new Class<?>[] {ResourceRequest.class, ResourceResponse.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.RESOURCE);
+   static {
+      METH_RES.setAllowMultiple(true);
+      METH_RES.setVariant(SignatureVariant.VOID_RESOURCEREQ_RESOURCERESP);
+   }
+   
+   public static MethodDescription METH_HDR = new MethodDescription(void.class, 
+         new Class<?>[] {HeaderRequest.class, HeaderResponse.class},  
+         new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+         MethodType.HEADER);
+   static {
+      METH_HDR.setAllowMultiple(true);
+      METH_HDR.setVariant(SignatureVariant.VOID_HEADERREQ_HEADERRESP);
+   }
+
+   //==============================================
+   
+   private final Class<?>     retType;
+   private final Class<?>[]   argTypes;
+   private final Class<?>[]   expTypes;
+   
+   // The lifecycle method type
+   private final MethodType   type;
+
+   // The method signature variant 
+   private SignatureVariant   variant = SignatureVariant.DEFAULT;
+   
+   // If true, the declared exceptions are verified as part of the method signature
+   private boolean            checkExceptions = false;
+   
+   // If true, multiple methods of this type are allowed
+   private boolean            allowMultiple = false;
+   
+   // Message string used during method matching.
+   private final StringBuilder errtxt = new StringBuilder(128);
+
+   public MethodDescription(Class<?> rt, Class<?>[] at, Class<?>[] et, MethodType mt) {
+      retType = rt;
+      argTypes = at;
+      expTypes = et;
+      type = mt;
+   }
+   
+   /**
+    * gets the argument types for extracting a method from a class.
+    * 
+    * @return the argument types
+    */
+   public Class<?>[] getArgTypes() {
+      return argTypes;
+   }
+
+   /**
+    * @return the checkExceptions
+    */
+   public boolean isCheckExceptions() {
+      return checkExceptions;
+   }
+
+   /**
+    * @param checkExceptions the checkExceptions to set
+    */
+   public void setCheckExceptions(boolean checkExceptions) {
+      this.checkExceptions = checkExceptions;
+   }
+   
+   /**
+    * @return the type
+    */
+   public MethodType getType() {
+      return type;
+   }
+
+   public boolean isAllowMultiple() {
+      return allowMultiple;
+   }
+
+   public void setAllowMultiple(boolean allowMultiple) {
+      this.allowMultiple = allowMultiple;
+   }
+
+   public SignatureVariant getVariant() {
+      return variant;
+   }
+
+   public void setVariant(SignatureVariant variant) {
+      this.variant = variant;
+   }
+   
+   /**
+    * Returns <code>true</code> if the given method matches this method definition.
+    * <p>
+    * Sets the error text for potential later retrieval & display.
+    * 
+    * @param meth
+    * @return                 <code>true</code> if the method matches
+    */
+   public boolean isMethodMatched(Method meth) {
+      boolean ok = true;
+      errtxt.setLength(0);
+      
+      if (!retType.isAssignableFrom(meth.getReturnType())) {
+         ok = false;
+         errtxt.append("Unexpected return value. Actual: ")
+               .append(meth.getReturnType().getCanonicalName());
+      }
+      
+      if (ok) {
+
+         // Compare argument type arrays
+
+         Class<?>[] types = meth.getParameterTypes();
+         if (types.length != argTypes.length) {
+            ok = false;
+         } else {
+            for (int ii = 0; ii < types.length; ii++) {
+               if (!types[ii].isAssignableFrom(argTypes[ii])) {
+                  ok = false;
+               }
+            }
+         }
+         
+         if (!ok) {
+            ArrayList<String> tmp = new ArrayList<String>();
+            for (Class<?> c : types) {
+               tmp.add(c.getCanonicalName());
+            }
+            errtxt.append("Parameter type mismatch.  Actual: ").append(tmp.toString());
+         }
+
+         // Compare exception type arrays. The order in which the exceptions are 
+         // specified is not relevant. If exceptions are being checked, the method 
+         // under test must have a subset of the allowed exceptions. 
+
+         if (ok && checkExceptions) {
+            types = meth.getExceptionTypes();
+            if (types.length > expTypes.length) {
+               ok = false;
+            } else {
+               for (int ii = 0; ii < types.length && ok; ii++) {
+                  ok = false;
+                  for (int jj = 0; jj < expTypes.length && !ok; jj++) {
+                     if (expTypes[jj].isAssignableFrom(types[ii])) {
+                        ok = true;
+                     }
+                  }
+               }
+            }
+            if (!ok) {
+               ArrayList<String> tmp = new ArrayList<String>();
+               for (Class<?> c : types) {
+                  tmp.add(c.getCanonicalName());
+               }
+               errtxt.append("Exception type mismatch. Actual: ").append(tmp.toString());
+            }
+         }
+      }
+
+      return ok;
+   }
+   
+
+   /**
+    * Returns the expected method signature in string form, optionally
+    * showing the preceeding error message, if any.
+    * 
+    * @param showErrorString  If true, the error message is shown.
+    * @return                 The method signature
+    */
+   public String getExpectedSignature(boolean showErrorString) {
+      if (!showErrorString) {
+         errtxt.setLength(0);
+      } else {
+         errtxt.append(", Expected signature:\n");
+      }
+      
+      // return value
+      errtxt.append(retType.getCanonicalName());
+
+      // method name ( arguments
+      errtxt.append(" &lt;name&gt;(");
+      String sep = "";
+      for (Class<?> c : argTypes) {
+         errtxt.append(sep).append(c.getCanonicalName());
+         sep = ", ";
+      }
+      errtxt.append(")");
+      
+      // exceptions, if any
+      if (expTypes.length > 0) {
+         errtxt.append(" throws ");
+         sep = "";
+         for (Class<?> c : expTypes) {
+            errtxt.append(sep).append(c.getCanonicalName());
+            sep = ", ";
+         }
+      }
+      
+      return errtxt.toString();
+   }
+   
+   /**
+    * shows all info about this description
+    */
+   public String toString() {
+      StringBuilder txt = new StringBuilder(128);
+      
+      txt.append(getExpectedSignature(false));
+      txt.append("/ type=").append(type);
+      txt.append(", variant=").append(variant);
+      txt.append(", checkExceptions=").append(checkExceptions);
+      txt.append(", allowMultiple=").append(allowMultiple);
+      
+      return txt.toString();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifier.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifier.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifier.java
new file mode 100644
index 0000000..2c6a666
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifier.java
@@ -0,0 +1,129 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+
+/**
+ * Identifies the annotated method type.
+ * <p>
+ * The dispatchId is the action name for action methods, resource ID for resource
+ * methods, the portlet mode as string for header & render methods, and the processing
+ * event reference QName for event methods. 
+ * 
+ * @author Scott
+ *
+ */
+public class MethodIdentifier {
+   
+   private final  String portletName;
+   private        Object dispatchId;
+   private final  MethodType type;
+
+   /**
+    * Constructor
+    */
+   public MethodIdentifier(String name, Object id, MethodType type) {;
+      this.portletName = name;
+      this.dispatchId = id;
+      this.type = type;
+   }
+   
+   /**
+    * Copy constructor
+    */
+   public MethodIdentifier(MethodIdentifier mi) {
+      this.portletName = mi.portletName;
+      this.dispatchId = mi.dispatchId;
+      this.type = mi.type;
+   }
+   
+   public String getName() {
+      return portletName;
+   }
+   
+   public Object getId() {
+      return dispatchId;
+   }
+   
+   public void setId(Object id) {
+      this.dispatchId = id;
+   }
+   
+   public MethodType getType() {
+      return type;
+   }
+
+   @Override
+   public boolean equals(Object o) {
+      boolean eq = false;
+      if (o instanceof MethodIdentifier) {
+         if (o == this) {
+            eq = true; 
+         } else {
+            MethodIdentifier mi = (MethodIdentifier) o;
+            if (equals(portletName, mi.portletName)) {
+               if (equals(type, mi.type)) {
+                  if (equals(dispatchId, mi.dispatchId)) {
+                     eq = true;
+                  }
+               }
+            }
+         }
+      }
+      return eq;
+   }
+
+   @Override
+   public int hashCode() {
+      int hc = 17;
+      if (portletName != null) {
+         hc += 37*hc + portletName.hashCode();
+      }
+      if (dispatchId != null) {
+         hc += 37*hc + dispatchId.hashCode();
+      }
+      if (type != null) {
+         hc += 37*hc + type.hashCode();
+      }
+      return hc;
+   }
+
+   /**
+    * helper function for equality comparison. 
+    */
+   private boolean equals(Object o1, Object o2) {
+      boolean eq = false;
+      if (o1 == o2) {
+         eq = true;
+      } else if (o1 != null && o2 != null) {
+         eq = o1.equals(o2);
+      }
+      return eq;
+   }
+   
+   public String toString() {
+      StringBuilder txt = new StringBuilder(256);
+      txt.append("Portlet name='").append(portletName).append("'");
+      txt.append(", Method type='").append(type).append("'");
+      txt.append(", Dispatch ID='").append(dispatchId).append("'");
+      return txt.toString();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifierComparator.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifierComparator.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifierComparator.java
new file mode 100644
index 0000000..7f44a2b
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodIdentifierComparator.java
@@ -0,0 +1,44 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional infooation
+ *  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 peoissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.util.Comparator;
+
+
+/**
+ * Simple comparator based on the method identifier portlet name and method type fields.
+ * Used for ordering the annotated method store string output for display & debug.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+public class MethodIdentifierComparator implements Comparator<MethodIdentifier> {
+
+   @Override
+   public int compare(MethodIdentifier o1, MethodIdentifier o2) {
+      assert (o1 != null) && (o2 != null);
+      int rc = o1.getName().compareTo(o2.getName());
+      if (rc == 0) {
+         rc = o1.getType().compareTo(o2.getType());
+      }
+      return rc;
+   }
+
+}


[28/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodType.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodType.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodType.java
new file mode 100644
index 0000000..6638471
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/MethodType.java
@@ -0,0 +1,29 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+
+/**
+ * @author Scott
+ *
+ */
+public enum MethodType {
+   HEADER, RENDER, ACTION, EVENT, RESOURCE, INIT, DESTROY,
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletAnnotationRecognizer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletAnnotationRecognizer.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletAnnotationRecognizer.java
new file mode 100644
index 0000000..074aa5f
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletAnnotationRecognizer.java
@@ -0,0 +1,432 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_ACT;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_DES;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_EVT;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_HDR;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_INI;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_REN;
+import static org.apache.pluto.container.bean.processor.MethodDescription.METH_RES;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.portlet.PortletException;
+import javax.portlet.PortletSession;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.DestroyMethod;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.HeaderMethod;
+import javax.portlet.annotations.InitMethod;
+import javax.portlet.annotations.PortletSerializable;
+import javax.portlet.annotations.PortletSessionScoped;
+import javax.portlet.annotations.PortletStateScoped;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ServeResourceMethod;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Scott
+ *
+ */
+public class PortletAnnotationRecognizer extends AnnotationRecognizer {
+   private static final Logger LOG = LoggerFactory.getLogger(PortletAnnotationRecognizer.class);
+   
+   
+   private final static Set<Class<? extends Annotation>> classAnnotations = 
+         new HashSet<Class<? extends Annotation>>();
+   
+   static {
+      classAnnotations.add(PortletStateScoped.class);
+      classAnnotations.add(PortletSessionScoped.class);
+   }
+   
+   // Maps the annotation class to a list of method descriptions. A given annnotation
+   // may support multiple method signatures, each of which has its own method description.
+   private final static Map<Class<? extends Annotation>, List<MethodDescription>> descriptions = 
+         new HashMap<Class<? extends Annotation>, List<MethodDescription>>();
+   
+   static {
+      
+      ArrayList<MethodDescription> list;
+      MethodDescription md;
+      
+      // Add method definitions for init methods
+      
+      list = new ArrayList<MethodDescription>();
+      list.add(METH_INI);
+      descriptions.put(InitMethod.class, list);
+      
+      // Add method definitions for destroy methods
+      
+      list = new ArrayList<MethodDescription>();
+      list.add(METH_DES);
+      descriptions.put(DestroyMethod.class, list);
+      
+      // Add method definitions for action methods
+      
+      list = new ArrayList<MethodDescription>();
+      list.add(METH_ACT);
+      descriptions.put(ActionMethod.class, list);
+      
+      // Add method definitions for event methods
+      
+      list = new ArrayList<MethodDescription>();
+      list.add(METH_EVT);
+      descriptions.put(EventMethod.class, list);
+      
+      // Add method definitions for serve resource
+      
+      list = new ArrayList<MethodDescription>();
+      
+      list.add(METH_RES);
+      
+      md = new MethodDescription(String.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.RESOURCE);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.STRING_VOID);
+      list.add(md);
+      
+      md = new MethodDescription(void.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.RESOURCE);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.VOID_VOID);
+      list.add(md);
+      
+      descriptions.put(ServeResourceMethod.class, list);
+      
+      // Add method definitions for render
+      
+      list = new ArrayList<MethodDescription>();
+      
+      list.add(METH_REN);
+      
+      md = new MethodDescription(String.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.RENDER);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.STRING_VOID);
+      list.add(md);
+      
+      md = new MethodDescription(void.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.RENDER);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.VOID_VOID);
+      list.add(md);
+
+      descriptions.put(RenderMethod.class, list);
+      
+      // Add method definitions for header methods
+      
+      list = new ArrayList<MethodDescription>();
+      list.add(METH_HDR);
+      
+      md = new MethodDescription(String.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.HEADER);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.STRING_VOID);
+      list.add(md);
+      
+      md = new MethodDescription(void.class, 
+            new Class<?>[] {},  
+            new Class<?>[] {PortletException.class, java.io.IOException.class}, 
+            MethodType.HEADER);
+      md.setAllowMultiple(true);
+      md.setVariant(SignatureVariant.VOID_VOID);
+      list.add(md);
+
+      descriptions.put(HeaderMethod.class, list);
+      
+   }
+
+   private final AnnotatedMethodStore ams;
+   private final PortletStateScopedConfig stateScopedConfig = new PortletStateScopedConfig();
+   private final PortletSessionScopedConfig sessionScopedConfig = new PortletSessionScopedConfig();
+   
+   /**
+    * @param cla
+    * @param metha
+    */
+   public PortletAnnotationRecognizer(AnnotatedMethodStore pms, ConfigSummary summary) {
+      super(classAnnotations, descriptions, summary);
+      this.ams = pms;
+      LOG.trace("Created the PortletAnnotationRecognizer.");
+   }
+
+   /**
+    * Extracts data from the class annotation and stores it for later use.
+    * <p>
+    * When reading the PortletConfiguration annotation, data from a later 
+    * annotation will override data from a preceding annotation for a given portlet name.
+    * <p>
+    * 
+    */
+   @SuppressWarnings("unchecked")
+   @Override
+   protected AnnotatedType<?> handleClassAnnotation(Annotation anno, AnnotatedType<?> aType) throws InvalidAnnotationException {
+      String typeName = aType.getJavaClass().getCanonicalName();
+      Class<?> theClass = aType.getJavaClass();
+      
+      if (anno instanceof PortletStateScoped) {
+         
+         // Verify the portlet state scoped class, store the annotation &
+         // bean type with the corresponding bean holder.
+         
+         if (!PortletSerializable.class.isAssignableFrom(theClass)) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Annotation problem: An @PortletStateScoped bean must implement PortletSerializable. ");
+            txt.append("Annotation: ").append(anno.annotationType().getSimpleName());
+            txt.append(", Class: ").append(typeName);
+            LOG.debug(txt.toString());
+            summary.addStateBeanErrorString(theClass, txt.toString());
+         } else {
+            stateScopedConfig.addAnnotation(theClass, (PortletStateScoped) anno);
+         }
+         
+      }  else if (anno instanceof PortletSessionScoped) {
+         
+         // Verify the portlet session scoped class, store the annotation &
+         // bean type with the corresponding bean holder.
+         
+         PortletSessionScoped pss = (PortletSessionScoped) anno;
+         if ((pss.value() != PortletSession.APPLICATION_SCOPE) && (pss.value() != PortletSession.PORTLET_SCOPE)) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Annotation problem: A @PortletSessionScoped bean scope must be APPLICATION_SCOPE or PORTLET_SCOPE. ");
+            txt.append("Annotation: ").append(anno.annotationType().getSimpleName());
+            txt.append(", Scope: ").append(pss.value());
+            txt.append(", Class: ").append(typeName);
+            LOG.debug(txt.toString());
+            summary.addSessionBeanErrorString(theClass, txt.toString());
+         } else {
+            if (pss.value() == PortletSession.APPLICATION_SCOPE) {
+               PortletSessionScopedAnnotatedType at = new PortletSessionScopedAnnotatedType((AnnotatedType<PortletSessionScoped>)aType);
+               summary.addAppScopedType(at);
+               return at;
+            } else {
+               sessionScopedConfig.addAnnotation(theClass, pss);
+            }
+         }
+
+      }  else {
+         
+         // Any other annotation that lands here indicates a programming error
+         
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Unrecognized class annotation: ")
+            .append(anno.annotationType().getSimpleName());
+         txt.append(", Class: ").append(typeName);
+         LOG.warn(txt.toString());
+      }
+      return null;
+   }
+
+   /**
+    * Extracts and stores relevant information from the specified annotation, bean
+    * class, and Method.
+    *  
+    * @param anno
+    * @param beanClass
+    * @param meth
+    */
+   @Override
+   protected void handleMethod(Annotation anno, Class<?> beanClass, Method meth, MethodDescription desc) {
+      ArrayList<String> portletNames = new ArrayList<String>();
+      String dispatchId = "";
+      
+      MethodType type = desc.getType();
+      if (anno instanceof RenderMethod) {
+         RenderMethod tcc = (RenderMethod) anno;
+         portletNames.addAll(Arrays.asList(tcc.portletNames()));
+         dispatchId = tcc.portletMode().toUpperCase();
+      } else if (anno instanceof HeaderMethod) {
+         HeaderMethod tcc = (HeaderMethod) anno;
+         portletNames.addAll(Arrays.asList(tcc.portletNames()));
+         dispatchId = tcc.portletMode().toUpperCase();
+      } else if (anno instanceof ActionMethod) {
+         ActionMethod tcc = (ActionMethod) anno;
+         portletNames.add(tcc.portletName());
+         dispatchId = tcc.actionName();
+      } else if (anno instanceof EventMethod) {
+         EventMethod tcc = (EventMethod) anno;
+         portletNames.add(tcc.portletName());
+      } else if (anno instanceof ServeResourceMethod) {
+         ServeResourceMethod tcc = (ServeResourceMethod) anno;
+         portletNames.addAll(Arrays.asList(tcc.portletNames()));
+         dispatchId = tcc.resourceID();
+      } else if (anno instanceof DestroyMethod) {
+         DestroyMethod tcc = (DestroyMethod) anno;
+         portletNames.add(tcc.value());
+      } else if (anno instanceof InitMethod) {
+         InitMethod tcc = (InitMethod) anno;
+         portletNames.add(tcc.value());
+      } else {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Unrecognized method annotation: ")
+            .append(anno.annotationType().getSimpleName());
+         txt.append(", Method: ").append(meth.getName());
+         txt.append(", Class: ").append(beanClass.getCanonicalName());
+         LOG.debug(txt.toString());
+         
+         // Store the error for each portlet name in array 
+         for (String n : getDisplayNames(anno)) {
+            summary.addErrorString(n, txt.toString());
+         }
+         return;
+      }
+      
+      
+      // some classAnnotations allow arrays of portlet names. To simplify method retrieval, 
+      // add to the method store with each of the specified portlet names.
+      // The proxied method is present once, but it is referred to by multiple 
+      // method identifier aliases.
+      
+      AnnotatedMethod pm = new AnnotatedMethod(anno, beanClass, meth, desc);
+      for (String portletName : portletNames) {
+
+         // The portlet name may not be empty. Note that the annotation itself
+         // will prevent the field from being null.
+
+         if (portletName.length() == 0) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Bad portlet name. Name may not be of length 0.");
+            txt.append(" Annotation: ").append(anno.annotationType().getSimpleName());
+            txt.append(", Method: ").append(meth.getName());
+            txt.append(", Class: ").append(beanClass.getCanonicalName());
+            LOG.debug(txt.toString());
+            summary.addErrorString(portletName, txt.toString());
+            return;
+         }
+
+         // Asterisk is ignored if not first and only array element.
+
+         if (portletName.equals("*") && portletNames.size() > 1) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Wildcard character '*' must be first and only array element. Will be ignored.");
+            txt.append(" Annotation: ").append(anno.annotationType().getSimpleName());
+            txt.append(", Method: ").append(meth.getName());
+            txt.append(", Class: ").append(beanClass.getCanonicalName());
+            LOG.debug(txt.toString());
+            summary.addErrorString(portletName, txt.toString());
+            continue;
+         }
+
+         // we've collected the required info, so store the method.
+
+         MethodIdentifier mi = new MethodIdentifier(portletName, dispatchId, type);
+         ams.addMethod(mi, pm);
+      }
+   }
+
+   
+   /**
+    * To be called by the CDI extension afterDeploymentValidation method to
+    * verify that the stored methods are consistent and to create the bean references.
+    *  
+    * @param bm      BeanManager needed to activate the beans.
+    * @throws InvalidAnnotationException  If the deployment is inconsistent or if the
+    *                                     beans cannot be instantiated.
+    */
+   @Override
+   protected void activateDeployment(BeanManager bm) {
+      
+      // Verify the portlet names in the proxied method store. It is an error if:
+      // 1) There is no method for a given name, but configuration data exists
+      
+      Set<String> names = ams.getPortletNames();
+      names.remove("*");
+      for (String name : names) {
+         StringBuilder txt = new StringBuilder(128);
+         Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet(name);
+         if (meths.isEmpty()) {
+            txt.append("No methods exist for portlet.");
+            txt.append(" Portlet name: ").append(name);
+         }
+         if (txt.length() > 0) {
+            LOG.debug(txt.toString());
+            summary.addErrorString(name, txt.toString());
+         }
+      }
+      
+      // See if there is a portlet with a wild-card character. If so, then:
+      // 1) Create set of names of portlets without errors
+      // 2) replicate the method identifiers to cover all other portlet names
+      
+      Set<MethodIdentifier> mis = ams.getMethodIDsForPortlet("*");
+      if (!mis.isEmpty()) {
+         names = ams.getPortletNames();
+         names.removeAll(summary.getPortletsWithErrors());
+         names.remove("*");
+         for (MethodIdentifier mi : mis) {
+            List<AnnotatedMethod> meths = ams.getMethods(mi);
+            for (String name : names) {
+               MethodIdentifier newMi = new MethodIdentifier(name, mi.getId(), mi.getType());
+               for (AnnotatedMethod meth : meths) {
+                  ams.addMethod(newMi, meth);
+               }
+            }
+         }
+      }
+      
+      // Now activate the methods by providing a BeanManager to the store.
+      
+      ams.activateMethods(bm);
+      
+      // Activate the custom scoped beans
+      stateScopedConfig.activate(bm);
+      sessionScopedConfig.activate(bm);
+   }
+
+   /**
+    * @return the stateScopedConfig
+    */
+   public PortletStateScopedConfig getStateScopedConfig() {
+      return stateScopedConfig;
+   }
+
+   /**
+    * @return the stateScopedConfig
+    */
+   public PortletSessionScopedConfig getSessionScopedConfig() {
+      return sessionScopedConfig;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
new file mode 100644
index 0000000..8b42975
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletArtifactProducer.java
@@ -0,0 +1,583 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Named;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletResponse;
+import javax.portlet.PortletSession;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.WindowState;
+import javax.portlet.annotations.ActionParam;
+import javax.portlet.annotations.BeanPortlet;
+import javax.portlet.annotations.ContextPath;
+import javax.portlet.annotations.Namespace;
+import javax.portlet.annotations.RenderParam;
+import javax.portlet.annotations.ResourceParam;
+import javax.portlet.annotations.URLFactory;
+import javax.portlet.annotations.WindowId;
+import javax.servlet.http.Cookie;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Contains producer methods for portlet artifacts that are dependent on the portlet
+ * request, response, or configuration.
+ *  
+ * @author Scott Nicklous
+ *
+ */
+public class PortletArtifactProducer {
+   private static final Logger LOG = LoggerFactory.getLogger(PortletArtifactProducer.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
+   private static final boolean isTrace = LOG.isTraceEnabled();
+   
+   
+   // There needs to be a single producer instance per thread.
+   private static final ThreadLocal<PortletArtifactProducer> producers = 
+         new ThreadLocal<PortletArtifactProducer>();
+   
+   private PortletRequest    req;
+   private PortletResponse   resp;
+   private PortletConfig     config;   
+   
+   /**
+    * Private constructor. Each instance gets put into the thread local.
+    */
+   private PortletArtifactProducer() { }
+  
+   /**
+    * Producer method to make this into a managed bean, so that CDI can use the other 
+    * producer methods. 
+    * @return
+    */
+   @Produces
+   public static PortletArtifactProducer getPAP() {
+      PortletArtifactProducer pap = producers.get();
+      if (pap == null) {
+         pap = new PortletArtifactProducer();
+         producers.set(pap);
+         
+         if (isTrace) {
+            StringBuilder txt = new StringBuilder(80);
+            txt.append("Created new empty PortletArtifactProducer");
+            txt.append(", ThreadId=").append(Thread.currentThread().getId());
+            LOG.trace(txt.toString());
+         }
+
+      }
+      return producers.get();
+   }
+   
+   /**
+    * Must be called at the end of a request to remove the current instance
+    * from the thread local.
+    */
+   public static void remove() {
+      producers.remove();
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Disposed of the PortletArtifactProducer");
+         txt.append(", ThreadId=").append(Thread.currentThread().getId());
+         LOG.trace(txt.toString());
+      }
+   }
+   
+   /**
+    * Creates a new producer for this thread and stores it in the thread local.
+    * @param req        The portlet request
+    * @param resp       The portlet response
+    * @param config     The portlet config
+    */
+   public static void setPrecursors(PortletRequest req, PortletResponse resp, PortletConfig config) {
+      PortletArtifactProducer pap = getPAP();
+      pap.req = req;
+      pap.resp = resp;
+      pap.config = config;
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Set precursors.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         txt.append(", Portlet name: ").append(config == null ? "null" : config.getPortletName());
+         LOG.trace(txt.toString());
+      }
+
+   }
+
+   /**
+    * Producer method for the portlet config. 
+    * @return
+    */
+   @Produces @RequestScoped @BeanPortlet @Named("portletConfig")
+   public static PortletConfig producePortletConfig() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      
+      if (isTrace) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         txt.append(", Portlet name: ").append(pap.config.getPortletName());
+         txt.append(", Init param names: ").append(Collections.list(pap.config.getInitParameterNames()).toString());
+         LOG.trace(txt.toString());
+      }
+
+      return pap.config;
+   }
+
+   /**
+    * Producer method for the portlet request. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("portletRequest")
+   public static PortletRequest producePortletRequest() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req;
+   }
+
+   /**
+    * Producer method for the portlet response. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("portletResponse")
+   public static PortletResponse producePortletResponse() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.resp;
+   }
+
+   /**
+    * Producer method for the ActionRequest.
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("actionRequest") @Typed(ActionRequest.class)
+   public static ActionRequest produceActionRequest() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      ActionRequest req = null;
+      if (pap.req instanceof ActionRequest) {
+         req = (ActionRequest) pap.req;
+      }
+      return req;
+   }
+
+   /**
+    * Producer method for the ActionResponse. 
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("actionResponse") @Typed(ActionResponse.class)
+   public static ActionResponse produceActionResponse() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      ActionResponse resp = null;
+      if (pap.resp instanceof ActionResponse) {
+         resp = (ActionResponse) pap.resp;
+      }
+      return resp;
+   }
+
+   /**
+    * Producer method for the RenderRequest.
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("renderRequest") @Typed(RenderRequest.class)
+   public static RenderRequest produceRenderRequest() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      RenderRequest req = null;
+      if (pap.req instanceof RenderRequest) {
+         req = (RenderRequest) pap.req;
+      }
+      return req;
+   }
+
+   /**
+    * Producer method for the RenderResponse. 
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("renderResponse") @Typed(RenderResponse.class)
+   public static RenderResponse produceRenderResponse() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      RenderResponse resp = null;
+      if (pap.resp instanceof RenderResponse) {
+         resp = (RenderResponse) pap.resp;
+      }
+      return resp;
+   }
+
+   /**
+    * Producer method for the EventRequest.
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("eventRequest") @Typed(EventRequest.class)
+   public static EventRequest produceEventRequest() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      EventRequest req = null;
+      if (pap.req instanceof EventRequest) {
+         req = (EventRequest) pap.req;
+      }
+      return req;
+   }
+
+   /**
+    * Producer method for the EventResponse. 
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("eventResponse") @Typed(EventResponse.class)
+   public static EventResponse produceEventResponse() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      EventResponse resp = null;
+      if (pap.resp instanceof EventResponse) {
+         resp = (EventResponse) pap.resp;
+      }
+      return resp;
+   }
+
+   /**
+    * Producer method for the ResourceRequest.
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("resourceRequest") @Typed(ResourceRequest.class)
+   public static ResourceRequest produceResourceRequest() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      ResourceRequest req = null;
+      if (pap.req instanceof ResourceRequest) {
+         req = (ResourceRequest) pap.req;
+      }
+      return req;
+   }
+
+   /**
+    * Producer method for the ResourceResponse. 
+    * Dependent scoped because it sometimes returns <code>null</code>. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("resourceResponse") @Typed(ResourceResponse.class)
+   public static ResourceResponse produceResourceResponse() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      ResourceResponse resp = null;
+      if (pap.resp instanceof ResourceResponse) {
+         resp = (ResourceResponse) pap.resp;
+      }
+      return resp;
+   }
+
+   /**
+    * Producer method for the portlet mode. 
+    * @return
+    */
+   @Produces @Named("portletMode")
+   public static PortletMode producePortletMode() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getPortletMode();
+   }
+
+   /**
+    * Producer method for the window state. 
+    * @return
+    */
+   @Produces @Named("windowState")
+   public static WindowState produceWindowState() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getWindowState();
+   }
+
+   /**
+    * Producer method for the portlet preferences. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("portletPreferences")
+   public static PortletPreferences producePortletPreferences() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getPreferences();
+   }
+
+   /**
+    * Producer method for the cookies. 
+    * @return
+    */
+   @Produces @Named("cookies")
+   public static Cookie[] produceCookies() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getCookies();
+   }
+
+   /**
+    * Producer method for the portlet session. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("portletSession")
+   public static PortletSession producePortletSession() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getPortletSession();
+   }
+
+   /**
+    * Producer method for the window ID. 
+    * @return
+    */
+   @Produces @WindowId @Named("windowId")
+   public static String produceWindowID() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getWindowID();
+   }
+
+   /**
+    * Producer method for the Locale. 
+    * @return
+    */
+   @Produces @Named("locale")
+   public static Locale produceLocale() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getLocale();
+   }
+
+   /**
+    * Producer method for the window ID. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("locales") 
+   public static Enumeration<Locale> produceLocales() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getLocales();
+   }
+
+   /**
+    * Producer method for the window ID. 
+    * @return
+    */
+   @Produces @Namespace @Named("namespace")
+   public static String produceNamespace() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.resp.getNamespace();
+   }
+
+   /**
+    * Producer method for the context root. 
+    * @return
+    */
+   @Produces @ContextPath @Named("contextPath")
+   public static String produceContextPath() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return pap.req.getContextPath();
+   }
+
+   /**
+    * Producer method for the URL factory. 
+    * @return
+    */
+   @Produces @RequestScoped @Named("urlFactory")
+   public static URLFactory produceURLFactory() {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      return new URLFactoryImpl(pap.resp);
+   }
+   
+   /**
+    * Producer method for the parameter as String.
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @ActionParam("")
+   public static String getActionParameter(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String val = null;
+      if (pap.req instanceof ActionRequest) {
+         ActionRequest areq = (ActionRequest) pap.req;
+         ActionParam ap = (ActionParam) ip.getAnnotated().getAnnotation(ActionParam.class);
+         val = areq.getActionParameters().getValue(ap.value());
+         trace("@ActionParam", "String", ap.value(), val);
+      }
+      return val;
+   }
+   
+   /**
+    * Producer method for the parameter as String[].
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @ActionParam("")
+   public static String[] getActionParameterValues(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String[] vals = null;
+      if (pap.req instanceof ActionRequest) {
+         ActionRequest areq = (ActionRequest) pap.req;
+         ActionParam ap = (ActionParam) ip.getAnnotated().getAnnotation(ActionParam.class);
+         vals = areq.getActionParameters().getValues(ap.value());
+         trace("ActionParam", "String[]", ap.value(), Arrays.toString(vals));
+      }
+      return vals;
+   }
+   
+   /**
+    * Producer method for the parameter as String.
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @RenderParam("")
+   public static String getRenderParameter(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String val = null;
+      RenderParam rp = (RenderParam) ip.getAnnotated().getAnnotation(RenderParam.class);
+      val = pap.req.getRenderParameters().getValue(rp.value());
+      trace("@RenderParam", "String", rp.value(), val);
+      return val;
+   }
+   
+   /**
+    * Producer method for the parameter as String[].
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @RenderParam("")
+   public static String[] getRenderParameterValues(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String[] vals = null;
+      RenderParam rp = (RenderParam) ip.getAnnotated().getAnnotation(RenderParam.class);
+      vals = pap.req.getRenderParameters().getValues(rp.value());
+      trace("@RenderParam", "String[]", rp.value(), Arrays.toString(vals));
+      return vals;
+   }
+   
+   /**
+    * Producer method for the parameter as String.
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @ResourceParam("")
+   public static String getResourceParameter(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String val = null;
+      if (pap.req instanceof ResourceRequest) {
+         ResourceRequest rreq = (ResourceRequest) pap.req;
+         ResourceParam rp = (ResourceParam) ip.getAnnotated().getAnnotation(ResourceParam.class);
+         val = rreq.getResourceParameters().getValue(rp.value());
+         trace("@ResourceParam", "String", rp.value(), val);
+      }
+      return val;
+   }
+   
+   /**
+    * Producer method for the parameter as String[].
+    * <p>
+    * Dependent scoped to allow reading the injection point.
+    *  
+    * @param ip      The injection point
+    * @return
+    */
+   @Produces @ResourceParam("")
+   public static String[] getResourceParameterValues(InjectionPoint ip) {
+      PortletArtifactProducer pap = producers.get();
+      assert pap != null;
+      String[] vals = null;
+      if (pap.req instanceof ResourceRequest) {
+         ResourceRequest rreq = (ResourceRequest) pap.req;
+         ResourceParam rp = (ResourceParam) ip.getAnnotated().getAnnotation(ResourceParam.class);
+         vals = rreq.getResourceParameters().getValues(rp.value());
+         trace("@ResourceParam", "String[]", rp.value(), Arrays.toString(vals));
+      }
+      return vals;
+   }
+
+   
+   /**
+    * Private helper method to trace parameter injection
+    * 
+    * @param anno
+    * @param sig
+    * @param pname
+    * @param pval
+    */
+   private static void trace(String anno, String sig, String pname, String pval) {
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Parameter injection trace.");
+         txt.append(" Annotation: ").append(anno);
+         txt.append(" Signature: ").append(sig);
+         txt.append(" Param name: ").append(pname);
+         txt.append(" Param value(s): ").append(pval);
+         LOG.debug(txt.toString());
+      }
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
new file mode 100644
index 0000000..35d79c0
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletCDIExtension.java
@@ -0,0 +1,129 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.util.Set;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Scott
+ *
+ */
+public class PortletCDIExtension implements Extension {
+   private static final Logger LOG = LoggerFactory.getLogger(PortletCDIExtension.class);
+  
+   
+   // Holds deployment error descriptions and other information for display.
+   private final ConfigSummary summary = new ConfigSummary();
+
+   private final AnnotatedMethodStore ams = new AnnotatedMethodStore(summary);
+   private final PortletAnnotationRecognizer par = new PortletAnnotationRecognizer(ams, summary);
+   
+   private static AnnotatedConfigBean acb = null;
+   
+   public static AnnotatedConfigBean getConfig() {
+      return acb;
+   }
+
+
+   public PortletCDIExtension() {
+   }
+   
+   void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
+      LOG.debug("PortletCDIExtension - scanning.");
+   }
+
+   /**
+    * examine each annotated type for portlet annotations
+    * @param pat
+    * @throws InvalidAnnotationException
+    */
+   void processType(@Observes ProcessAnnotatedType<?> pat) throws InvalidAnnotationException {
+      par.checkAnnotatedType(pat);
+   }
+   
+   /**
+    * Add the context for the custom scope implementations.
+    * 
+    * @param abd
+    */
+   void addPortletSessionScopeContext(@Observes AfterBeanDiscovery abd) {
+      PortletSessionScopedContext pssc = new PortletSessionScopedContext();
+      abd.addContext(pssc);
+      
+      PortletStateScopedContext pstsc = new PortletStateScopedContext();
+      abd.addContext(pstsc);
+   }
+
+   /**
+    * After the bean container has validated the deployment from its point of view,
+    * do some checking from the portlet point of view. Activate the portlet deployment
+    * by passing in a bean manager in order to create the required portlet bean instances.
+    * 
+    * @param adv
+    * @param bm
+    * @throws InvalidAnnotationException
+    */
+   void afterDeploymentValidation(@Observes AfterDeploymentValidation adv, BeanManager bm)
+         throws InvalidAnnotationException {
+      par.activateDeployment(bm);
+      
+      // Done processing the annotations, so put the resulting configuration in an
+      // application scoped bean to pass it to the servlet
+      
+      LOG.debug("Now attempting to get the AnnotatedConfigBean ...");
+      Set<Bean<?>> beans = bm.getBeans(AnnotatedConfigBean.class);
+      @SuppressWarnings("unchecked")
+      Bean<AnnotatedConfigBean> bean = (Bean<AnnotatedConfigBean>) bm.resolve(beans);
+      if (bean != null) {
+         LOG.debug("Got AnnotatedConfigBean bean: " + bean.getBeanClass().getCanonicalName());
+         try {
+            CreationalContext<AnnotatedConfigBean> cc = bm.createCreationalContext(bean);
+            acb = (AnnotatedConfigBean) bm.getReference(bean, AnnotatedConfigBean.class, cc);
+            LOG.debug("Got AnnotatedConfigBean instance.");
+            acb.setMethodStore(ams);
+            acb.setSummary(summary);
+            acb.setStateScopedConfig(par.getStateScopedConfig());
+            acb.setSessionScopedConfig(par.getSessionScopedConfig());
+         } catch (Exception e) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Exception getting AnnotatedConfigBean bean instance: ");
+            txt.append(e.toString());
+            LOG.warn(txt.toString());
+         }
+      } else {
+         LOG.warn("AnnotatedConfigBean bean was null.");
+      }
+      LOG.info("Portlet CDI Extension complete. Config bean: " + acb);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
new file mode 100644
index 0000000..f7494cb
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletInvoker.java
@@ -0,0 +1,518 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.pluto.container.bean.processor;
+
+import static javax.portlet.ActionRequest.ACTION_NAME;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.EventPortlet;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.HeaderPortlet;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.Portlet;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.PortletResponse;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.ResourceServingPortlet;
+import javax.portlet.StateAwareResponse;
+import javax.portlet.annotations.HeaderMethod;
+import javax.portlet.annotations.RenderMethod;
+import javax.portlet.annotations.ServeResourceMethod;
+import javax.xml.namespace.QName;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides an easy-to-use facade for the portlet methods.
+ * 
+ * @author nick
+ *
+ */
+public class PortletInvoker implements Portlet, ResourceServingPortlet, EventPortlet, HeaderPortlet {
+   private static final Logger             LOG     = LoggerFactory.getLogger(PortletInvoker.class);
+   private static final boolean            isDebug = LOG.isDebugEnabled();
+
+   private final AnnotatedConfigBean acb;
+   private final String                    portletName;
+   private PortletConfig                   config;
+   
+   /**
+    * Construct for given portlet name.
+    */
+   public PortletInvoker(AnnotatedConfigBean acb, String portletName) {
+      this.acb = acb;
+      this.portletName = portletName;
+   }
+
+   // =======================================================================
+
+   /**
+    * Returns a list of methods to be invoked for the given method identifier.
+    * 
+    * @param mi
+    *           The method identifier
+    * @return A list of methods. may be empty.
+    */
+   private List<AnnotatedMethod> getMethods(MethodIdentifier mi) {
+
+      // get the method from the store. If the requested method cannot
+      // be found,
+      // retry with the default dispatch ID ("").
+
+      if (isDebug) {
+         LOG.debug("Retrieving method for method identifier: " + mi.toString());
+      }
+
+      List<AnnotatedMethod> meths = acb.getMethodStore().getMethods(mi);
+      if (meths.isEmpty()) {
+         Object id = mi.getId();
+         if ((id != null) && (id instanceof String) && ((String)id).length() > 0) {
+            mi.setId("");
+            if (isDebug) {
+               LOG.debug("Retrying retrieval with method identifier: " + mi.toString());
+            }
+            meths = acb.getMethodStore().getMethods(mi);
+         }
+      }
+
+      return meths;
+   }
+
+   /**
+    * To be called before bean method invocation begins
+    */
+   private void beforeInvoke(PortletRequest req, PortletResponse resp) {
+
+      // Set the portlet session bean holder for the thread & session
+      PortletSessionBeanHolder.setBeanHolder(req.getPortletSession());
+
+      // Set the portlet state scoped bean holder
+      PortletStateScopedBeanHolder.setBeanHolder(req, acb.getStateScopedConfig());
+
+      // Set up the artifact producer with request, response, and portlet config
+      PortletArtifactProducer.setPrecursors(req, resp, config);
+   }
+
+   /**
+    * must be called after all method invocations have taken place, even if an
+    * exception occurs.
+    */
+   private void afterInvoke(PortletResponse resp) {
+
+      // Remove the portlet session bean holder for the thread
+      PortletSessionBeanHolder.removeBeanHolder();
+
+      // Remove the portlet state bean holder. pass response if we're
+      // dealing with a StateAwareResponse. The response is used for state
+      // storage.
+
+      StateAwareResponse sar = null;
+      if (resp instanceof StateAwareResponse) {
+         sar = (StateAwareResponse) resp;
+      }
+      PortletStateScopedBeanHolder.removeBeanHolder(sar);
+
+      // remove the portlet artifact producer
+      PortletArtifactProducer.remove();
+
+   }
+
+   /**
+    * Invokes the given method, handling exceptions.
+    * 
+    * @param meth
+    *           The bean method to be invoked
+    * @param args
+    *           The method arguments
+    * @throws PortletException
+    *            If a portlet exception occurs
+    * @throws IOException
+    *            If an IO exception occurs
+    * @return The object returned by the invoked method
+    */
+   private Object invokePortletMethod(AnnotatedMethod meth, Object... args) throws PortletException, IOException {
+      Object result;
+
+      try {
+         // Now invoke the method
+         result = meth.invoke(args);
+      } catch (InvocationTargetException ite) {
+         Throwable t = ite.getCause();
+         if (t != null) {
+            if (t instanceof PortletException) {
+               throw (PortletException) t;
+            } else if (t instanceof IOException) {
+               throw (IOException) t;
+            } else if (t instanceof RuntimeException) {
+               throw (RuntimeException) t;
+            }
+         }
+         String msg = "Problem invoking " + meth.toString() + ". Unknown InvocationTargetException Cause. ";
+         throw new PortletException(msg, ite);
+      } catch (RuntimeException re) {
+         throw re;
+      } catch (Exception e) {
+         String msg = "Problem invoking " + meth.toString() + ". ";
+         throw new PortletException(msg + e.getMessage());
+      }
+      return result;
+   }
+
+   // =======================================================================
+
+   @Override
+   public void init(PortletConfig config) throws PortletException {
+      this.config = config;
+
+      MethodIdentifier mi = new MethodIdentifier(portletName, "", MethodType.INIT);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.size() == 0) {
+
+         // If no init method, log debug trace and return
+
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Init method not found for portlet: ").append(portletName);
+            LOG.debug(txt.toString());
+         }
+         return;
+      }
+      assert meths.size() == 1;
+      AnnotatedMethod meth = meths.get(0);
+
+      // Set up the method arguments and do the incovation
+
+      Object[] args = new Object[] { config };
+      try {
+         invokePortletMethod(meth, args);
+      } catch (Exception e) {}
+
+   }
+
+   @Override
+   public void destroy() {
+
+      MethodIdentifier mi = new MethodIdentifier(portletName, "", MethodType.DESTROY);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.size() == 0) {
+
+         // If no init method, log debug trace and return
+
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Destroy method not found for portlet: ").append(portletName);
+            LOG.debug(txt.toString());
+         }
+         return;
+      }
+      assert meths.size() == 1;
+      AnnotatedMethod meth = meths.get(0);
+
+      // Set up the method arguments and do the incovation
+
+      Object[] args = new Object[] {};
+      try {
+         invokePortletMethod(meth, args);
+      } catch (Exception e) {}
+   }
+
+   @Override
+   public void serveResource(ResourceRequest req, ResourceResponse resp) throws PortletException, IOException {
+
+      String id = (req.getResourceID() != null) ? req.getResourceID() : "";
+      MethodIdentifier mi = new MethodIdentifier(portletName, id, MethodType.RESOURCE);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.size() == 0) {
+
+         // If a resource URL was activated, but no resource method could be
+         // found, add appropriate error string.
+
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("ServeResource method not found. Resource ID=\"").append(id).append("\"");
+         LOG.warn(txt.toString());
+         return;
+      }
+
+      // now do the invocation
+
+      try {
+         beforeInvoke(req, resp);
+
+         for (AnnotatedMethod meth : meths) {
+
+            // Set the character encoding & content type, if available
+
+            ServeResourceMethod rm = (ServeResourceMethod) meth.getAnnotation();
+            if (rm != null) {
+               if (rm.characterEncoding().length() > 0) {
+                  resp.setCharacterEncoding(rm.characterEncoding());
+               }
+               if (rm.contentType().length() > 0) {
+                  resp.setContentType(rm.contentType());
+               }
+            }
+
+            // Set up the method arguments based on the signature variant
+
+            Object[] args = {};
+            Object result;
+            if (meth.getDescription().getVariant() == SignatureVariant.VOID_RESOURCEREQ_RESOURCERESP) {
+               args = new Object[] { req, resp };
+            }
+
+            // invoke the resource method
+
+            result = invokePortletMethod(meth, args);
+
+            // If output is to be expected, write it to the writer
+
+            if (meth.getDescription().getVariant() == SignatureVariant.STRING_VOID) {
+               if (result != null) {
+                  assert result instanceof String;
+                  resp.getWriter().write((String) result);
+               }
+            }
+
+            // If an include resource is provided, include it
+
+            if ((rm != null) && (rm.include().length() > 0)) {
+               PortletRequestDispatcher prd = config.getPortletContext().getRequestDispatcher(rm.include());
+               prd.include(req, resp);
+            }
+         }
+      } finally {
+         afterInvoke(resp);
+      }
+   }
+
+   @Override
+   public void processEvent(EventRequest req, EventResponse resp) throws PortletException, IOException {
+
+      QName qn = req.getEvent().getQName();
+      MethodIdentifier mi = new MethodIdentifier(portletName, qn, MethodType.EVENT);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.size() == 0) {
+         
+         // retry with empty string (for portlet class processEvent method, for example)
+         mi.setId("");
+         meths = getMethods(mi);
+         if (meths.size() == 0) {
+
+            // If an event to be processed, but event method could not be found,
+            // add appropriate error string.
+
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Event method not found. Event qname=").append(qn);
+            LOG.warn(txt.toString());
+            return;
+         }
+      }
+      assert meths.size() == 1;
+      AnnotatedMethod meth = meths.get(0);
+
+      // Set up the method arguments and do the incovation
+
+      Object[] args = new Object[] { req, resp };
+      try {
+         beforeInvoke(req, resp);
+         invokePortletMethod(meth, args);
+      } finally {
+         afterInvoke(resp);
+      }
+   }
+
+   @Override
+   public void processAction(ActionRequest req, ActionResponse resp) throws PortletException, IOException {
+
+      String an = req.getActionParameters().getValue(ACTION_NAME);
+      String id = (an != null) ? an : "";
+      MethodIdentifier mi = new MethodIdentifier(portletName, id, MethodType.ACTION);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.size() == 0) {
+
+         // If an action URL was activated, but action method could not be found,
+         // add appropriate error string.
+
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Action method not found. Action name=\"").append(an).append("\"");
+         LOG.warn(txt.toString());
+         return;
+      }
+      assert meths.size() == 1;
+      AnnotatedMethod meth = meths.get(0);
+
+      // Set up the method arguments and do the incovation
+
+      Object[] args = new Object[] { req, resp };
+      try {
+         beforeInvoke(req, resp);
+         invokePortletMethod(meth, args);
+      } finally {
+         afterInvoke(resp);
+      }
+
+   }
+
+   @Override
+   public void render(RenderRequest req, RenderResponse resp) throws PortletException, IOException {
+
+      String pm = req.getPortletMode().toString();
+      String id = (pm != null) ? pm.toUpperCase() : "";
+      MethodIdentifier mi = new MethodIdentifier(portletName, id, MethodType.RENDER);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.isEmpty()) {
+         // No render methods available
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Render method not found. Portlet mode: \"").append(pm).append("\"");
+         LOG.warn(txt.toString());
+         return;
+      }
+
+      try {
+         beforeInvoke(req, resp);
+
+         for (AnnotatedMethod meth : meths) {
+
+            // Set the content type, if available (determined by first render
+            // method)
+
+            RenderMethod rm = (RenderMethod) meth.getAnnotation();
+            if ((rm != null) && rm.contentType().length() > 0) {
+               resp.setContentType(rm.contentType());
+            }
+
+            // Set up the method arguments based on the signature variant
+
+            Object[] args = {};
+            Object result;
+            if (meth.getDescription().getVariant() == SignatureVariant.VOID_RENDERREQ_RENDERRESP) {
+               args = new Object[] { req, resp };
+            }
+
+            // invoke the render method
+
+            result = invokePortletMethod(meth, args);
+
+            // If output is to be expected, write it to the writer
+
+            if (meth.getDescription().getVariant() == SignatureVariant.STRING_VOID) {
+               if (result != null) {
+                  assert result instanceof String;
+                  resp.getWriter().write((String) result);
+               }
+            }
+
+            // If an include resource is provided, include it
+
+            if ((rm != null) && (rm.include().length() > 0)) {
+               PortletRequestDispatcher prd = config.getPortletContext().getRequestDispatcher(rm.include());
+               prd.include(req, resp);
+            }
+         }
+
+      } finally {
+         afterInvoke(resp);
+      }
+
+   }
+
+   @Override
+   public void renderHeaders(HeaderRequest req, HeaderResponse resp) throws PortletException, java.io.IOException {
+
+      String pm = req.getPortletMode().toString();
+      String id = (pm != null) ? pm.toUpperCase() : "";
+      MethodIdentifier mi = new MethodIdentifier(portletName, id, MethodType.HEADER);
+
+      List<AnnotatedMethod> meths = getMethods(mi);
+      if (meths.isEmpty()) {
+         // No header methods available
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Header method not found. Portlet mode: \"").append(pm).append("\"");
+         LOG.warn(txt.toString());
+         return;
+      }
+
+      try {
+         beforeInvoke(req, resp);
+
+         for (AnnotatedMethod meth : meths) {
+
+            // Set the content type, if available (determined by first render
+            // method)
+
+            HeaderMethod hm = (HeaderMethod) meth.getAnnotation();
+            if ((hm != null) && hm.contentType().length() > 0) {
+               resp.setContentType(hm.contentType());
+            }
+
+            // Set up the method arguments based on the signature variant
+
+            Object[] args = {};
+            Object result;
+            if (meth.getDescription().getVariant() == SignatureVariant.VOID_HEADERREQ_HEADERRESP) {
+               args = new Object[] { req, resp };
+            }
+
+            // invoke the render method
+
+            result = invokePortletMethod(meth, args);
+
+            // If output is to be expected, write it to the writer
+
+            if (meth.getDescription().getVariant() == SignatureVariant.STRING_VOID) {
+               if (result != null) {
+                  assert result instanceof String;
+                  resp.getWriter().write((String) result);
+               }
+            }
+
+            // If an include resource is provided, include it
+
+            if ((hm != null) && (hm.include().length() > 0)) {
+               PortletRequestDispatcher prd = config.getPortletContext().getRequestDispatcher(hm.include());
+               prd.include(req, resp);
+            }
+         }
+
+      } finally {
+         afterInvoke(resp);
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionBeanHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionBeanHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionBeanHolder.java
new file mode 100644
index 0000000..8491fa8
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionBeanHolder.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 org.apache.pluto.container.bean.processor;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.portlet.PortletSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is a container for PortletSessionScoped CDI beans.
+ * 
+ * @author nick
+ *
+ */
+public class PortletSessionBeanHolder implements HttpSessionBindingListener, Serializable {
+   private static final Logger LOG = LoggerFactory.getLogger(PortletSessionBeanHolder.class);
+   private static final boolean isDebug = LOG.isDebugEnabled();
+   
+
+   private static final long serialVersionUID = 4713451590109713169L;
+   private static final String ATTRIBNAME = "portletSessionBeanHolder";
+
+   private class BeanInstance<T> implements Serializable {
+      private static final long serialVersionUID = -2094530892049932082L;
+      CreationalContext<T>    crco;
+      T                       instance;
+   }
+   
+   // Each instance of the bean holder gets its own map
+   private Map<Contextual<?>, BeanInstance<?>> beans = 
+         new ConcurrentHashMap<Contextual<?>, BeanInstance<?>>();
+   
+   // The ThreadLocal manages the holders so that there is one holder per thread.
+   private static final ThreadLocal<PortletSessionBeanHolder> holders =
+         new ThreadLocal<PortletSessionBeanHolder>();
+   
+   /**
+    * private constructor
+    */
+   private PortletSessionBeanHolder() {
+   }
+
+   /**
+    * Sets the portlet session bean holder in a ThreadLocal object for the given 
+    * portlet session. If no bean holder exists in the session, a new one is created.
+    * 
+    * @param ps      The portlet session.
+    * @return        The portlet session bean holder
+    */
+   public static void setBeanHolder(PortletSession ps) {
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Setting portlet session bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         txt.append(", PortletSession=").append(ps.getId());
+         LOG.debug(txt.toString());
+      }
+      
+      PortletSessionBeanHolder holder = (PortletSessionBeanHolder) ps.getAttribute(ATTRIBNAME);
+      if (holder == null) {
+         holder = new PortletSessionBeanHolder();
+         ps.setAttribute(ATTRIBNAME, holder);
+
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder(80);
+            txt.append("Created new portlet session holder.");
+            LOG.debug(txt.toString());
+         }
+      }
+      holders.set(holder);
+   }
+   
+   /**
+    * Removes the bean holder for the current session.
+    */
+   public static void removeBeanHolder() {
+      holders.remove();
+
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removed portlet session bean holder.");
+         txt.append(" ThreadId=").append(Thread.currentThread().getId());
+         LOG.debug(txt.toString());
+      }
+   }
+   
+   /**
+    * Returns the portlet session bean holder that was set for the thread.
+    * 
+    * @return
+    */
+   public static PortletSessionBeanHolder getBeanHolder() {
+      return holders.get();
+   }
+   
+   /**
+    * Returns an instance for the contextual type, or null if none available.
+    * 
+    * @param bean       Contextual type (Bean) for which an instance is desired
+    * @return           The instance, or null if none exists
+    */
+   @SuppressWarnings("unchecked")
+   public <T> T getBean(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+  
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Getting bean: ");
+         if (bean instanceof Bean<?>) {
+            Bean<?> b = (Bean<?>) bean;
+            txt.append(b.getBeanClass().getSimpleName());
+         }
+         if (bi == null) {
+            txt.append(", instance is null.");
+         }
+         LOG.debug(txt.toString());
+      }
+
+      return (bi == null) ? null : (T) bi.instance;
+   }
+   
+   /**
+    * Adds a bean instance with associated creational context to the store for the
+    * given contextual object (bean).
+    * 
+    * @param bean          The bean type
+    * @param crco          The creational context
+    * @param instance      The bean instance
+    */
+   public <T> void putBeanInstance(Contextual<T> bean, CreationalContext<T> crco, T instance) {
+      BeanInstance<T> bi = new BeanInstance<T>();
+      bi.crco = crco;
+      bi.instance = instance;
+      beans.put(bean, bi);
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Added bean: ");
+         if (bean instanceof Bean<?>) {
+            Bean<?> b = (Bean<?>) bean;
+            txt.append(b.getBeanClass().getSimpleName());
+         }
+         LOG.debug(txt.toString());
+      }
+   }
+   
+   /**
+    * Removes & destroys the given bean
+    * @param bean
+    */
+   @SuppressWarnings("unchecked")
+   protected <T> void remove(Contextual<T> bean) {
+      BeanInstance<?> bi = beans.get(bean);
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(80);
+         txt.append("Removing bean: ");
+         if (bean instanceof Bean<?>) {
+            Bean<?> b = (Bean<?>) bean;
+            txt.append(b.getBeanClass().getSimpleName());
+         }
+         if (bi == null) {
+            txt.append(", instance is null.");
+         }
+         LOG.debug(txt.toString());
+      }
+
+      if (bi != null) {
+         beans.remove(bean);
+         bi.crco.release();
+         bean.destroy((T)bi.instance, (CreationalContext<T>)bi.crco);
+      }
+   }
+   
+   /**
+    * Remove & destroy all beans
+    */
+   protected void removeAll() {
+      for (Contextual<?> bean : beans.keySet()) {
+         remove(bean);
+      }
+   }
+
+   /**
+    * Session binding listener method - binding to session
+    * 
+    * @param arg0
+    */
+   @Override
+   public void valueBound(HttpSessionBindingEvent arg0) {
+   }
+
+   /**
+    * Session binding listener method - unbinding from session. 
+    * This occurs only when the session times out or is destroyed (in our case).
+    * 
+    * @param arg0
+    */
+   @Override
+   public void valueUnbound(HttpSessionBindingEvent evt) {
+      if (isDebug) {
+         LOG.debug("PortletSessionBeanHolder unbound from session. ID=" + evt.getName());
+      }
+      removeAll();
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedAnnotatedType.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedAnnotatedType.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedAnnotatedType.java
new file mode 100644
index 0000000..21fe4d4
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedAnnotatedType.java
@@ -0,0 +1,151 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.portlet.PortletSession;
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * A wrapper for a PortletSessionScoped annotated type with APPLICATION_SCOPE
+ * that replaces the <code>{@literal @}PortletSessionScoped</code> annotation with
+ * <code>{@literal @}SessionScoped</code> in order to allow the bean to be used
+ * within servlets in the same session outside of a portlet request, and also 
+ * obtain the application scope semantics.
+ * 
+ * @author Scott
+ *
+ */
+public class PortletSessionScopedAnnotatedType implements AnnotatedType<PortletSessionScoped> {
+
+   // to obtain annotation instances
+   @SessionScoped
+   @PortletSessionScoped(PortletSession.APPLICATION_SCOPE)
+   private class Dummy {}  
+   
+   // the wrapped type.
+   private final AnnotatedType<PortletSessionScoped> aType;
+   
+   // The set of annotations
+   private final Set<Annotation> annos = new HashSet<Annotation>();
+   
+   /**
+    * Construct the wrapper. 
+    */
+   public PortletSessionScopedAnnotatedType(AnnotatedType<PortletSessionScoped> type) {
+      aType = type;
+      annos.addAll(type.getAnnotations());
+      annos.remove(Dummy.class.getAnnotation(PortletSessionScoped.class));
+      annos.add(Dummy.class.getAnnotation(SessionScoped.class));
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.Annotated#getAnnotation(java.lang.Class)
+    */
+   @SuppressWarnings({"unchecked"})
+   @Override
+   public <U extends Annotation> U getAnnotation(Class<U> type) {
+      for (Annotation a : annos) {
+         if (type.equals(a.annotationType())) {
+            return (U) a;
+         }
+      }
+      return null;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.Annotated#getAnnotations()
+    */
+   @Override
+   public Set<Annotation> getAnnotations() {
+      return new HashSet<Annotation>(annos);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.Annotated#getBaseType()
+    */
+   @Override
+   public Type getBaseType() {
+      return aType.getBaseType();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.Annotated#getTypeClosure()
+    */
+   @Override
+   public Set<Type> getTypeClosure() {
+      return aType.getTypeClosure();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.Annotated#isAnnotationPresent(java.lang.Class)
+    */
+   @Override
+   public boolean isAnnotationPresent(Class<? extends Annotation> type) {
+      for (Annotation a : annos) {
+         if (type.equals(a.annotationType())) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.AnnotatedType#getConstructors()
+    */
+   @Override
+   public Set<AnnotatedConstructor<PortletSessionScoped>> getConstructors() {
+      return aType.getConstructors();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.AnnotatedType#getFields()
+    */
+   @Override
+   public Set<AnnotatedField<? super PortletSessionScoped>> getFields() {
+      return aType.getFields();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.AnnotatedType#getJavaClass()
+    */
+   @Override
+   public Class<PortletSessionScoped> getJavaClass() {
+      return aType.getJavaClass();
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.inject.spi.AnnotatedType#getMethods()
+    */
+   @Override
+   public Set<AnnotatedMethod<? super PortletSessionScoped>> getMethods() {
+      return aType.getMethods();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
new file mode 100644
index 0000000..5295a6d
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedConfig.java
@@ -0,0 +1,165 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.portlet.PortletSession;
+import javax.portlet.annotations.PortletSessionScoped;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Configuration for PortletStateScoped CDI beans with PORTLET_SCOPE.
+ * <p>
+ * ===================================
+ * === Only used for test purposes ===
+ * ===================================
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class PortletSessionScopedConfig  implements Serializable {
+   private static final long serialVersionUID = -5333145344722804837L;
+   private final Logger LOG = LoggerFactory.getLogger(PortletSessionScopedConfig.class);
+   private final boolean isDebug = LOG.isDebugEnabled();
+   
+   
+   // Maps the bean contextual to the annotation. The bean contextual is obtained
+   // during the activation process after all beans have been discovered.
+   // Note that synchronization is not needed since the map is only changed during the
+   // bean scanning phase.
+   private final Map<Contextual<?>, PortletSessionScoped> context2Anno = 
+         new HashMap<Contextual<?>, PortletSessionScoped>();
+
+   // Maps the bean class to the corresponding annotation. The entries are set
+   // while the extension is processing annotated types.
+   // Note that synchronization is not needed since the map is only changed during the
+   // bean scanning phase.
+   private final Map<Class<?>, PortletSessionScoped> class2Anno = 
+         new HashMap<Class<?>, PortletSessionScoped>();
+   
+   /**
+    * Called by the CDI extension during the scanning phase to add information about 
+    * a <code>{@literal @}PortletStateScoped</code> bean.
+    * 
+    * @param beanClass     The bean class
+    * @param anno          The annotation
+    */
+   public void addAnnotation(Class<?> beanClass, PortletSessionScoped anno) {
+      class2Anno.put(beanClass, anno);
+   }
+   
+   /** 
+    * Gets the concrete contextual for the bean and puts it into the context map.
+    * Called after bean discovery during the activation process.
+    * Finishes up the configuration process and provides a debug summary.
+    * 
+    * @param bm      The bean manager
+    */
+   public void activate(BeanManager bm) {
+      
+      // Activate the beans
+      
+      for (Class<?> cls : class2Anno.keySet()) {
+         Set<Bean<?>> beans = bm.getBeans(cls);
+         Bean<?> bean = bm.resolve(beans);
+         assert bean != null;
+         context2Anno.put(bean, class2Anno.get(cls));
+      }
+      
+      // dump configuration data to trace
+      
+      if (isDebug) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("PortletSessionScopedBeanHolder configuration: \n");
+         txt.append("\nAnnotatedBeans: ");
+         txt.append(getConfigAsString());
+         LOG.debug(txt.toString());
+      }
+   }
+   
+   /**
+    * Returns the portlet state scoped annotated classes. 
+    * <p>
+    * Used for test / validation purposes.
+    * 
+    * @return  Set of annotated classes
+    */
+   public Set<Class<?>> getBeanClasses() {
+      return class2Anno.keySet();
+   }
+   
+   /**
+    * Returns a portlet state scoped bean summary for display
+    * 
+    * @return  The configuration summary string
+    * 
+    */
+   public String getConfigAsString() {
+      StringBuilder txt = new StringBuilder(128);
+      for (Class<?> c : class2Anno.keySet()) {
+         txt.append("\n\tClass: ").append(c.getCanonicalName());
+         boolean ps = (class2Anno.get(c).value() == PortletSession.PORTLET_SCOPE);
+         txt.append(", Portlet scoped: ").append(ps);
+      }
+      return txt.toString();
+   }
+   
+   /**
+    * Determines whether the given bean class is portlet or application scoped.
+    * 
+    * @param bean    The bean class
+    * @return        <code>true</code> if the bean is portlet scoped
+    */
+   public Boolean isPortletScoped(Class<?> beanClass) {
+      Boolean ps = null;
+      for (Contextual<?> b : context2Anno.keySet()) {
+         if (b instanceof Bean) {
+            Bean<?> bean = (Bean<?>)b;
+            if (beanClass.isAssignableFrom(bean.getBeanClass())) {
+               ps = (context2Anno.get(b).value() == PortletSession.PORTLET_SCOPE);
+               break;
+            }
+         }
+      }
+      return ps;
+   }
+   
+   /**
+    * Determines whether the given bean is portlet or application scoped.
+    * 
+    * @param bean    The bean
+    * @return        <code>true</code> if the bean is portlet scoped
+    */
+   public Boolean isPortletScoped(Bean<?> bean) {
+      PortletSessionScoped anno = context2Anno.get(bean);
+      assert anno != null;
+      return (anno.value() == PortletSession.PORTLET_SCOPE);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedContext.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedContext.java b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedContext.java
new file mode 100644
index 0000000..b9c85cc
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/bean/processor/PortletSessionScopedContext.java
@@ -0,0 +1,90 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor;
+
+import java.lang.annotation.Annotation;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * This is the Context implementation for the PortletSessionScoped custom CDI scope.
+ * 
+ * @author nick
+ *
+ */
+public class PortletSessionScopedContext implements Context {
+
+   public PortletSessionScopedContext() {
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean) {
+      PortletSessionBeanHolder holder = PortletSessionBeanHolder.getBeanHolder();
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet session context is not active.");
+      }
+      return holder.getBean(bean);
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#get(javax.enterprise.context.spi.Contextual, javax.enterprise.context.spi.CreationalContext)
+    */
+   @Override
+   public <T> T get(Contextual<T> bean, CreationalContext<T> crco) {
+      PortletSessionBeanHolder holder = PortletSessionBeanHolder.getBeanHolder();
+      
+      if (holder == null) {
+         throw new ContextNotActiveException("The portlet session context is not active.");
+      }
+      
+      T inst = holder.getBean(bean);
+      if (inst == null) {
+         inst = bean.create(crco);
+         holder.putBeanInstance(bean, crco, inst);
+      }
+      
+      return inst;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#getScope()
+    */
+   @Override
+   public Class<? extends Annotation> getScope() {
+      return PortletSessionScoped.class;
+   }
+
+   /* (non-Javadoc)
+    * @see javax.enterprise.context.spi.Context#isActive()
+    */
+   @Override
+   public boolean isActive() {
+      PortletSessionBeanHolder holder = PortletSessionBeanHolder.getBeanHolder();
+      return (holder != null);
+   }
+
+}


[26/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/impl/HttpServletPortletRequestWrapper.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/HttpServletPortletRequestWrapper.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/HttpServletPortletRequestWrapper.java
index e4baac5..74a7fb7 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/HttpServletPortletRequestWrapper.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/HttpServletPortletRequestWrapper.java
@@ -1,1465 +1,1462 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.impl;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.Principal;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.portlet.ClientDataRequest;
-import javax.portlet.PortletRequest;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpSession;
-
-import org.apache.pluto.container.PortletInvokerService;
-import org.apache.pluto.container.PortletRequestContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
- * @version $Id$
- */
-public class HttpServletPortletRequestWrapper extends HttpServletRequestWrapper
-{
-    private static final Logger logger = LoggerFactory.getLogger(HttpServletPortletRequestWrapper.class);
-    
-    protected static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
-    protected static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
-    protected static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
-    protected static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
-    protected static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
-    protected static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
-    protected static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
-    protected static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
-    protected static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
-    protected static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
-
-    protected static final String[] PATH_ATTRIBUTE_INCLUDE_NAMES = { INCLUDE_CONTEXT_PATH,
-                                                                     INCLUDE_PATH_INFO,
-                                                                     INCLUDE_QUERY_STRING,
-                                                                     INCLUDE_REQUEST_URI,
-                                                                     INCLUDE_SERVLET_PATH };
-
-    protected static final String[] PATH_ATTRIBUTE_FORWARD_NAMES = { FORWARD_CONTEXT_PATH,
-                                                                     FORWARD_PATH_INFO,
-                                                                     FORWARD_QUERY_STRING,
-                                                                     FORWARD_REQUEST_URI,
-                                                                     FORWARD_SERVLET_PATH };
-
-    protected static final String[] PATH_ATTRIBUTE_NAMES = { INCLUDE_CONTEXT_PATH,
-                                                             INCLUDE_PATH_INFO,
-                                                             INCLUDE_QUERY_STRING,
-                                                             INCLUDE_REQUEST_URI,
-                                                             INCLUDE_SERVLET_PATH,
-                                                             FORWARD_CONTEXT_PATH,
-                                                             FORWARD_PATH_INFO,
-                                                             FORWARD_QUERY_STRING,
-                                                             FORWARD_REQUEST_URI,
-                                                             FORWARD_SERVLET_PATH };
-    
-    protected static final HashSet<String> PATH_ATTRIBUTE_NAMES_SET = 
-        new HashSet<String>(Arrays.asList(PATH_ATTRIBUTE_NAMES));
-    
-    /**
-     * PathMethodValues contains the values of a HttpServletRequest PATH methods.
-     */
-    protected static final class PathMethodValues
-    {
-        String contextPath;
-        String servletPath;
-        String pathInfo;
-        String queryString;
-        String requestURI;
-        
-        PathMethodValues(){}
-                
-        PathMethodValues copy(PathMethodValues pmv)
-        {
-            this.contextPath = pmv.contextPath;
-            this.servletPath = pmv.servletPath;
-            this.pathInfo = pmv.pathInfo;
-            this.queryString = pmv.queryString;
-            this.requestURI = pmv.requestURI;
-            return this;
-        }
-    }
-    
-    protected static final String[] DEFAULT_SERVLET_CONTAINER_MANAGED_ATTRIBUTES = { "org.apache.catalina.core.DISPATCHER_TYPE", 
-    																				 "org.apache.catalina.core.DISPATCHER_REQUEST_PATH" };
-    
-    /**
-     * <p>
-     * Some servlet containers like Tomcat (Catalina) use "injected" request attributes within their own Request (dispatch)
-     * wrapper objects to keep track of their current state. Such "injected" attributes are never really "set" or (supposed to be)
-     * visible by the current application request processing logic.
-     * </p><p>
-     * Such special attributes therefore cannot be reliably "managed" or isolated per (portlet) servlet request window as it never
-     * can be known if or when such attributes (value) might change.
-     * </p><p>
-     * And, as these attributes are used internally by the servlet container providing back the wrong (or no) value very easily
-     * can break the expected behavior.
-     * </p><p>
-     * On Tomcat this for instance happens when a forwarded portlet request itself would try an (servlet) include request. Then, its
-     * internal state using "injected" attribute "org.apache.catalina.DISPATCHER_TYPE" is changed.
-     * </p><p>
-     * To support such servlet container internal/injected attribute handling, a static servletContainerManagedAttributes HashSet
-     * is maintained containing the attribute names which value should <em>always</em> be retrieved from the current (injected) parent request.
-     * </p><p>
-     * As default the currently known two Tomcat internal/injected attribute names are used.
-     * </p><p>
-     * For other containers which might use a similar approach these reserved attribute names can be (re)set through the static
-     * method setServletContainerManagedAttributes(String[]), e.g. like with a Springframework based initialization of the container.
-     * </p>
-     */
-    protected static HashSet<String> servletContainerManagedAttributes =
-    	new HashSet<String>(Arrays.asList(DEFAULT_SERVLET_CONTAINER_MANAGED_ATTRIBUTES));
-    
-    /**
-     * DispatchDetection defines how a (nested) RequestDispatcher include/forward call will be detected.
-     * <p>
-     * The dispatch detection is used to optimize building the custom parameters map as returned from the
-     * getParametersMap method as rebuilding the parameters map for each and every access can be quite expensive.
-     * </p>
-     * <p>
-     * A parameter map is constant within the scope of one (level of) request dispatching, but a nested request
-     * dispatch using an additional query string on the dispatch path requires merging of its query string parameters
-     * for the duration of that (nested) dispatch.
-     * </p>
-     * <p>
-     * DispatchDetection defines how such a nested dispatch is detected:
-     * <ul>
-     *   <li>CHECK_STATE: full compare of the current getRequest().getParameterMap() against the initial getParameterMap()</li>
-     *   <li>CHECK_REQUEST_WRAPPER_STACK: check if the webcontainer injected a HttpServletRequestWrapper <em>above</em> this
-     *       request as Tomcat does (which usually will be less time/cpu consuming if many parameters are passed in)</li>
-     *   <li>EVALUATE:  auto detect on first getParameterMap() call if CHECK_REQUEST_WRAPPER_STACK can be used and then switch
-     *       to either CHECK_STATE or CHECK_REQUEST_WRAPPER_STACK DispatchDetection</li>
-     * </ul>
-     * </p>
-     * <p>
-     * By default the CHECK_STATE method is used which in most cases is more optimal except when often many request parameters are used.
-     * </p>
-     */
-    static enum DispatchDetection { CHECK_STATE, CHECK_REQUEST_WRAPPER_STACK, EVALUATE };
-    
-    /**
-     * Current DispatchDetection mode used, defaults to DispatchDetection.CHECK_STATE
-     */
-    static volatile DispatchDetection dispatchDetection = DispatchDetection.CHECK_STATE;
-    
-    /**
-     * Cache for parsed dateHeader values.
-     */
-    protected static final HashMap<String,Long> dateHeaderParseCache = new HashMap<String,Long>();
-    
-    /**
-     * The set of SimpleDateFormat formats to use in getDateHeader().
-     *
-     * Notice that because SimpleDateFormat is not thread-safe, we can't
-     * declare formats[] as a static variable.
-     */
-    protected SimpleDateFormat dateHeaderFormats[] = 
-    {
-        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
-        new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
-        new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
-    };
-
-    /**
-     * Map of the current, web container provided, PATH_ATTRIBUTE_NAMES attribute values.
-     */
-    protected Map<String,Object> currPathAttributeValues = new HashMap<String,Object>();
-    
-    /**
-     * Map of the first, or first after a (PortletRequestDispatcher initiated nested dispatch, web container provided, PATH_ATTRIBUTE_NAMES attribute values.
-     */
-    protected Map<String,Object> dispPathAttributeValues = new HashMap<String, Object>();
-    
-    /**
-     * Map of the PATH_ATTRIBUTE_NAMES attribute values provided to the invoking servlet as derived for the current (initial or nested) request dispatch.
-     */
-    protected Map<String,Object> pathAttributeValues = new HashMap<String, Object>();
-    
-    /**
-     * Cache of PATH_ATTRIBUTE_NAMES attribute values possibly set using setAttribute.
-     * <p>
-     * This read-through cache protects against concurrent writing to the client request attribute map(s) when using multi-threaded rendering.
-     * </p>
-     */
-    protected Map<String,Object> pathAttributeCache = new HashMap<String, Object>();
-    
-    /**
-     * Current getRequest() PATH method values
-     */
-    protected PathMethodValues currPathMethodValues = new PathMethodValues();
-    
-    /**
-     * The first, or first after a (PortletRequestDispatcher initiated nested dispatch, web container provided, PATH method values.
-     */
-    protected PathMethodValues dispPathMethodValues = new PathMethodValues();
-    
-    /**
-     * PATH method values provided to the invoking servlet as derived for the current (initial or nested) request dispatch
-     */
-    protected PathMethodValues pathMethodValues = new PathMethodValues();
-    
-    /**
-     * The initial, web container provided, PATH method values.
-     * <p>
-     * These values are kept separately from the dispPathMethodValues are the Portlet API retaining those for all further (nested) dispatching.
-     * But this actually only makes sense if the fist dispatch is not done using a NamedDispatcher.
-     * </p>
-     */
-    protected PathMethodValues initPathMethodValues;
-    
-    /**
-     * Flag indicating if the current, web container provided, PATH_ATTRIBUTE_INCLUDE_NAMES attribute values are modified
-     */
-    protected boolean attributeIncludeValuesModified;
-
-    /**
-     * Flag indicating if the current, web container provided, PATH_ATTRIBUTE_FORWARD_NAMES attribute values are modified
-     */
-    protected boolean attributeForwardValuesModified;
-
-    /**
-     * Flag indicating if the current, web container provided, PATH method values are modified
-     */
-    protected boolean methodValuesModified;
-    
-    /**
-     * Flag indicating if the current (possibly nested) request dispatch is based upon a NamedDispatcher.
-     */
-    protected boolean namedDispatch;
-    
-    /**
-     * Flag indicating if the current (possibly nested) request dispatch is <em>intentionally</em> using RequestDispatcher.forward.
-     * <p>Note: it depends on isForwardingPossible() if an actual forward is used or "faked" while performing an include call.</p>
-     */
-    protected boolean forwarded;
-    
-    /**
-     * Flag indicating if the initial level of dispatch is detected.
-     */
-    protected boolean dispatched;
-    
-    /**
-     * Flag indicating if a nested dispatch is detected.
-     */
-    protected boolean nested;
-
-    /**
-     * Current size of the nested HttpServletRequestWrapper stack size, counted from this request up.
-     * <p>
-     * Used together with DispatchDetection mode CHECK_REQUEST_WRAPPER_STACK or EVALUATE to determine if
-     * the current request dispatching "stack" has changed and thus the parameter map needs rebuilding.
-     * </p>
-     * <p>
-     * This type of DispatchDetection only works for web containers like Tomcat which "inject" (and remove) a HttpServletRequestWrapper
-     * of their own on each nested request dispatch call.
-     * </p>
-     */
-    protected int requestWrapperStackSize;
-    
-    /**
-     * Initial parameters map as provided by the web container <em>before</em> the initial request dispatch.
-     * <p>
-     * Used for comparision with the current web container provided parameters map to calculate (possible)
-     * merged parameters when the initial (or a nested) request dispatcher was created using additional query string parameters.
-     * </p>
-     */
-    protected Map<String, String[]> origParameterMap;
-    
-    /**
-     * Cache of current parameters map as provided by the web container.
-     * <p>
-     * Only used with DispatchDetection != CHECK_REQUEST_WRAPPER_STACK for comparision with the current
-     * current web container provided parameters map to detect a possible nested request dispatch
-     * with additional query string parameters (or a return thereof).
-     * </p>
-     */
-    protected Map<String, String[]> currParameterMap;
-    
-    /**
-     * Cache of the derived parameters map to be provided to invoking servlet.
-     * <p>
-     * This parameter map is (re)build on first access to getParametersMap after a (nested) request dispatch or a
-     * return thereof.
-     * </p>
-     */
-    protected Map<String, String[]> parameterMap;
-    
-    protected final PortletRequestContext requestContext;
-    protected final ServletContext servletContext;
-    protected final PortletRequest portletRequest;
-    protected final ClientDataRequest clientDataRequest;
-    protected final String lifecyclePhase;
-    protected final boolean renderPhase;
-    
-    protected HttpSession session;
-    
-    /**
-     * Set the Servlet container managed (projected) attribute names which cannot be isolated per portlet/servlet request window
-     * and therefore need to be retrieved directly from the parent (injected) servlet request object.
-     * @param names array of protected servlet container attribute names
-     */
-    public static void setServletContainerManagedAttributes(String[] names)
-    {
-    	if (names == null)
-    	{
-    		servletContainerManagedAttributes.clear();
-    	}
-    	else
-    	{
-    		servletContainerManagedAttributes = new HashSet<String>(Arrays.asList(names));
-    	}
-    }
-    
-    @SuppressWarnings("unchecked")
-    public HttpServletPortletRequestWrapper(HttpServletRequest request, ServletContext servletContext, HttpSession session, PortletRequest portletRequest, boolean included, boolean namedDispatch)
-    {
-        super(request);
-        this.servletContext = servletContext;
-        this.session = session;
-        this.portletRequest = portletRequest;
-        lifecyclePhase = (String)portletRequest.getAttribute(PortletRequest.LIFECYCLE_PHASE);
-        clientDataRequest = PortletRequest.ACTION_PHASE.equals(lifecyclePhase) || PortletRequest.RESOURCE_PHASE.equals(lifecyclePhase) ? (ClientDataRequest)portletRequest : null;
-        renderPhase = PortletRequest.RENDER_PHASE.equals(lifecyclePhase);
-        requestContext = (PortletRequestContext )portletRequest.getAttribute(PortletInvokerService.REQUEST_CONTEXT);
-        this.forwarded = !included;
-        this.namedDispatch = namedDispatch;
-        origParameterMap = new HashMap<String,String[]>(request.getParameterMap());
-        currParameterMap = origParameterMap;
-        for (String name : PATH_ATTRIBUTE_NAMES)
-        {
-            currPathAttributeValues.put(name,request.getAttribute(name));
-        }
-        currPathMethodValues.contextPath = request.getContextPath();
-        currPathMethodValues.servletPath = request.getServletPath();
-        currPathMethodValues.pathInfo = request.getPathInfo();
-        currPathMethodValues.queryString = request.getQueryString();
-        currPathMethodValues.requestURI = request.getRequestURI();
-        if (dispatchDetection != DispatchDetection.CHECK_STATE)
-        {            
-            HttpServletRequestWrapper currentRequest = this;
-            while ((currentRequest.getRequest()) instanceof HttpServletRequestWrapper)
-            {
-                requestWrapperStackSize++;
-                currentRequest = (HttpServletRequestWrapper)currentRequest.getRequest();
-            }
-        }
-    }
-    
-    /**
-     * Try to parse the given date as a HTTP date. Borrowed and adapted from
-     * Tomcat FastHttpDateFormat
-     */
-    private long parseDateHeader(String value)
-    {
-        Long dateValue = null;
-        try
-        {
-            dateValue = dateHeaderParseCache.get(value);
-        }
-        catch (Exception e)
-        {
-        }
-        if (dateValue == null)
-        {
-            for (int i = 0; i < dateHeaderFormats.length; i++)
-            {
-                try
-                {
-                    Date date = dateHeaderFormats[i].parse(value);
-                    dateValue = new Long(date.getTime());
-                }
-                catch (ParseException e)
-                {
-                }
-            }
-            if (dateValue != null)
-            {
-                synchronized (dateHeaderParseCache)
-                {
-                    if (dateHeaderParseCache.size() > 1000)
-                    {
-                        dateHeaderParseCache.clear();
-                    }
-                    dateHeaderParseCache.put(value, dateValue);
-                }
-            }
-            else
-            {
-                throw new IllegalArgumentException(value);
-            }
-        }
-        return dateValue.longValue();
-    }
-    
-    boolean isForwardingPossible()
-    {
-        return !renderPhase;
-    }
-    
-    /**
-     * Returns the current forwarding state to be cached by the PortletRequestDispatcherImpl
-     * during a nested forward. This state needs to be restored with the restoreFromNestedForward method afterwards.
-     */
-    boolean isForwarded()
-    {
-        return forwarded;
-    }
-    
-    /**
-     * Returns the current namedDispatch state to be cached by the PortletRequestDispatcherImpl
-     * during a nested forward. This state needs to be restored with the restoreFromNestedForward method afterwards.
-     */
-    boolean isNamedDispatch()
-    {
-        return namedDispatch;
-    }
-    
-    /**
-     * Returns a <em>copy</em> of the current dispPathAttributeValues to be cached by the PortletRequestDispatcherImpl
-     * during a nested forward. These need to be restored with the restoreFromNestedForward method afterwards.
-     */
-    Map<String, Object> getPathAttributeValues()
-    {
-        return new HashMap<String, Object>(dispPathAttributeValues);
-    }
-    
-    /**
-     * Returns a <em>copy</em> of the current initPathMethodValues (or null) to be cached by the PortletRequestDispatcherImpl
-     * during a nested forward. These need to be restored with the restoreFromNestedForward method afterwards.
-     */
-    PathMethodValues getInitPathMethodValues()
-    {
-        return initPathMethodValues != null ? new PathMethodValues().copy(initPathMethodValues) : null;
-    }
-    
-    /**
-     * Initiates a nested forward from the PortletRequestDispatcherImpl.
-     */
-    void setNestedForward()
-    {
-        dispatched = false;        
-        forwarded = true;
-        namedDispatch = false;
-    }
-    
-    /**
-     * Restores the previous request path state as cached by the PortletRequestDispatcherImpl after returning from a nested forward.
-     */
-    void restoreFromNestedForward(boolean forwarded, boolean namedDispatch, 
-                                  PathMethodValues pathMethodValues, Map<String, Object> pathAttributeValues)
-    {
-        this.forwarded = forwarded;
-        this.namedDispatch = namedDispatch;
-        dispPathAttributeValues.clear();
-        dispPathAttributeValues.putAll(pathAttributeValues);
-        updateRequestPathState();
-    }
-    
-    /**
-     * Method to check the current web container provided request path state with the cached state to determine if a (nested)
-     * request dispatch has occurred.
-     * <p>
-     * If a (nested) request dispatch has been determined, the derived pathMethodValues and pathAttributeValues are (re)created
-     * to be provided to the invoking servlet as override of the web container "view" of this state.
-     * </p>
-     */
-    protected void updateRequestPathState()
-    {
-        // synchronize current web container path method and attribute values and detect modifications
-        syncDispatcherPathValues();
-        
-        // check and evaluate (significant) modifications to the path state
-        if (checkDispatcherPathValuesChanged())
-        {
-            // dispatch detected
-            
-            if (!dispatched)
-            {
-                //initial dispatch or initial dispatch after a nested forward (from PortletRequestDispatcherImpl) detected
-                initFirstDispatchPathValues();
-            }
-            else
-            {
-                // check if (still) within a nested dispatch or returning back to the initial dispatch
-                checkNestedDispatch();
-            }
-            if (!nested)
-            {
-                // (back to) initial dispatch
-                setupFirstDispatchPathValues();
-            }
-            else // nested
-            {
-                // (still) within a nested dispatch
-                setupNestedDispatchPathValues();
-            }
-        }
-    }
-    
-    private static boolean compareAttributes(Object o1, Object o2)
-    {
-        return (o1 == null && o2 == null) || (o1 != null && o2 != null && o1.equals(o2));
-    }
-    
-    private static String asString(Object o)
-    {
-        return o != null ? o.toString() : null;
-    }
-    
-    /**
-     * Synchronize and compare current web container provided path state with the previously determined path state.
-     */
-    protected void syncDispatcherPathValues()
-    {
-        HttpServletRequest request = (HttpServletRequest)getRequest();
-        Object attrValue;
-        String methodValue;
-
-        attributeIncludeValuesModified = false;
-        attributeForwardValuesModified = false;
-        methodValuesModified = false;
-        
-        for (String name : PATH_ATTRIBUTE_INCLUDE_NAMES)
-        {
-            // first check possible cached path attributes as set through setAttribute
-            attrValue = pathAttributeCache.get(name);
-            if (attrValue == null)
-            {
-                // not cached: get current value from web container
-                attrValue = request.getAttribute(name);
-            }
-            // determine if modified
-            attributeIncludeValuesModified = !attributeIncludeValuesModified ? !compareAttributes(currPathAttributeValues.get(name), attrValue) : true;
-            // save new value for further usage and future modification check
-            currPathAttributeValues.put(name, attrValue);
-        }
-        for (String name : PATH_ATTRIBUTE_FORWARD_NAMES)
-        {
-            // first check possible cached path attributes as set through setAttribute
-            attrValue = pathAttributeCache.get(name);
-            if (attrValue == null)
-            {
-                // not cached: get current value from web container
-                attrValue = request.getAttribute(name);
-            }
-            // determine if modified
-            attributeForwardValuesModified = !attributeForwardValuesModified ? !compareAttributes(currPathAttributeValues.get(name), attrValue) : true;
-            // save new value for further usage and future modification check
-            currPathAttributeValues.put(name, attrValue);
-        }
-        
-        // for all path method values:
-        //   retrieve them from the current web container
-        //   determine if modified
-        //   save them further usage and future modification check
-        
-        methodValue = request.getContextPath();
-        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.contextPath, methodValue);
-        currPathMethodValues.contextPath = methodValue;
-        
-        methodValue = request.getServletPath();
-        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.servletPath, methodValue);
-        currPathMethodValues.servletPath = methodValue;
-
-        methodValue = request.getPathInfo();
-        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.pathInfo, methodValue);
-        currPathMethodValues.pathInfo = methodValue;
-
-        methodValue = request.getQueryString();
-        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.queryString, methodValue);
-        currPathMethodValues.queryString = methodValue;
-
-        methodValue = request.getRequestURI();
-        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.requestURI, methodValue);
-        currPathMethodValues.requestURI = methodValue;
-    }
-    
-    /**
-     * Check and evaluate (significant) modifications to the path state.
-     */
-    protected boolean checkDispatcherPathValuesChanged()
-    {
-        // initial "clearing" of current request path method and/or attribute values might be done by the container while
-        // still preparing for the dispatch: ignore and "swallow" those changes
-        if (methodValuesModified && currPathMethodValues.servletPath == null)
-        {
-            methodValuesModified = false;
-        }
-        if (attributeIncludeValuesModified && currPathAttributeValues.get(INCLUDE_SERVLET_PATH) == null)
-        {
-            attributeIncludeValuesModified = false;
-        }
-        if (attributeForwardValuesModified && currPathAttributeValues.get(FORWARD_SERVLET_PATH) == null)
-        {
-            attributeForwardValuesModified = false;
-        }
-        return (attributeIncludeValuesModified || attributeForwardValuesModified || methodValuesModified);
-    }
-    
-    /**
-     * Initialize first dispatch path state
-     */
-    protected void initFirstDispatchPathValues()
-    {
-        dispatched = true;
-        dispPathMethodValues.copy(currPathMethodValues);
-        dispPathAttributeValues.putAll(currPathAttributeValues);
-    }
-    
-    /**
-     * Determine if new dispatch path state represents the first dispatch or the first after a nested forward initiated from
-     * RequestDispatcherImpl, or a nested dispatch through ServletContext.getRequestDispatcher() or an include initiated from
-     * PortletRequestDispatcherImpl.
-     */
-    protected void checkNestedDispatch()
-    {
-        nested = false;
-        for (String name : PATH_ATTRIBUTE_NAMES)
-        {
-            if (!compareAttributes(dispPathAttributeValues.get(name), currPathAttributeValues.get(name)))
-            {
-                nested = true;
-                break;
-            }
-        }
-        nested = nested ? true : !compareAttributes(dispPathMethodValues.contextPath, currPathMethodValues.contextPath);
-        nested = nested ? true : !compareAttributes(dispPathMethodValues.servletPath, currPathMethodValues.servletPath);
-        nested = nested ? true : !compareAttributes(dispPathMethodValues.pathInfo, currPathMethodValues.pathInfo);
-        nested = nested ? true : !compareAttributes(dispPathMethodValues.queryString, currPathMethodValues.queryString);
-        nested = nested ? true : !compareAttributes(dispPathMethodValues.requestURI, currPathMethodValues.requestURI);
-    }
-    
-    /**
-     * Deriving the path state values as should be provided to the invoking servlet for the first dispatch level.
-     * <p>
-     * Note: we also come here after returning back to the initial dispatch from a nested dispatch
-     * </p>
-     * <pre>
-     * If (namedDispatch):
-     *   - All request attribute path values should be "hidden"
-     *   - No path method values can/should be provided either, except for getContextPath()
-     *     Note: this is a use-case not properly recognized in the portlet spec!
-     *     Possibly, we might be *required* to keep the existing path method values as provided by the
-     *     web container or maybe provide (only) a "/" as servletPath?
-     * else:
-     *   - If (!forwarded) || (forwarded && !isForwardingPossible()):
-     *        if (initial path method values determined) // see next If step below
-     *          - use initial path method values
-     *        else
-     *          - use javax.servlet.include.* request attribute values as derived path method values (PLT.19.3.8)
-     *     else: // (forwarded && isForwardingPossible())
-     *       current (forward) path method values are OK
-     *   - If (first dispatched && !namedDispatch)
-     *       The current path method values need to be retained for all further (nested) dispatching (see above and below)
-     *       - save current path method values as initial path values
-     *   - If (!forwarded):
-     *       - current javax.servlet.include.* request attribute values are OK
-     *       - "hide" possible javax.servlet.forward.* request attribute values
-     *   - else if (initial path method values determined) // see previous If step above
-     *       - use initial path method values for javax.servlet.forward.* request attribute values
-     *   - else if (forwarded && isForwardingPossible()):
-     *       - use current path method values for javax.servlet.forward.* request attribute values (PLT.19.4.2)
-     *       - "hide" possible javax.servlet.include.* request attribute values
-     *   - else: // (forwarded && !isForwardingPossible())
-     *       - remap javax.servlet.include.* request attribute values to javax.servlet.forward.* values
-     *       - "hide" javax.servlet.include.* request attribute values
-     * </pre>
-     */
-    protected void setupFirstDispatchPathValues()
-    {
-      // Clear possible previously derived pathAttributeValues from a nested dispatch
-      pathAttributeValues.clear();
-      if (namedDispatch)
-      {
-          // only can/must support request.getContextPath()
-          pathMethodValues.contextPath = dispPathMethodValues.contextPath;
-      }
-      else
-      {
-          if (!forwarded || !isForwardingPossible())
-          {
-              if (initPathMethodValues != null)
-              {
-                  pathMethodValues.copy(initPathMethodValues);
-              }
-              else
-              {
-                  pathMethodValues.contextPath = asString(dispPathAttributeValues.get(INCLUDE_CONTEXT_PATH));
-                  pathMethodValues.servletPath = asString(dispPathAttributeValues.get(INCLUDE_SERVLET_PATH));
-                  pathMethodValues.pathInfo = asString(dispPathAttributeValues.get(INCLUDE_PATH_INFO));
-                  pathMethodValues.queryString = asString(dispPathAttributeValues.get(INCLUDE_QUERY_STRING));
-                  pathMethodValues.requestURI = asString(dispPathAttributeValues.get(INCLUDE_REQUEST_URI));
-              }
-          }
-          else // forwarded && isForwardingPossible()
-          {
-              pathMethodValues.copy(dispPathMethodValues);
-          }
-          
-          // Save *first time* path method values as the portlet spec requires
-          // retaining those for all further (nested) dispatching:
-          // - includes: these values will override the path method values
-          // - forwards: these values will override the forward attribute values
-          // Note: this only make "sense" after a first !namedDispatch dispatch, e.g. .servletPath != null
-          if (initPathMethodValues == null && pathMethodValues.servletPath != null)
-          {
-              initPathMethodValues = new PathMethodValues().copy(pathMethodValues);
-          }
-          
-          if (!forwarded)
-          {
-              pathAttributeValues.put(INCLUDE_CONTEXT_PATH, dispPathAttributeValues.get(INCLUDE_CONTEXT_PATH));
-              pathAttributeValues.put(INCLUDE_SERVLET_PATH, dispPathAttributeValues.get(INCLUDE_SERVLET_PATH));
-              pathAttributeValues.put(INCLUDE_PATH_INFO, dispPathAttributeValues.get(INCLUDE_PATH_INFO));
-              pathAttributeValues.put(INCLUDE_QUERY_STRING, dispPathAttributeValues.get(INCLUDE_QUERY_STRING));
-              pathAttributeValues.put(INCLUDE_REQUEST_URI, dispPathAttributeValues.get(INCLUDE_REQUEST_URI));
-          }
-          else if (initPathMethodValues != null)
-          {
-              pathAttributeValues.put(FORWARD_CONTEXT_PATH, initPathMethodValues.contextPath);
-              pathAttributeValues.put(FORWARD_SERVLET_PATH, initPathMethodValues.servletPath);
-              pathAttributeValues.put(FORWARD_PATH_INFO, initPathMethodValues.pathInfo);
-              pathAttributeValues.put(FORWARD_QUERY_STRING, initPathMethodValues.queryString);
-              pathAttributeValues.put(FORWARD_REQUEST_URI, initPathMethodValues.requestURI);
-          }
-          else if (forwarded && isForwardingPossible())
-          {
-              pathAttributeValues.put(FORWARD_CONTEXT_PATH, dispPathMethodValues.contextPath);
-              pathAttributeValues.put(FORWARD_SERVLET_PATH, dispPathMethodValues.servletPath);
-              pathAttributeValues.put(FORWARD_PATH_INFO, dispPathMethodValues.pathInfo);
-              pathAttributeValues.put(FORWARD_QUERY_STRING, dispPathMethodValues.queryString);
-              pathAttributeValues.put(FORWARD_REQUEST_URI, dispPathMethodValues.requestURI);
-          }
-          else // forwarded && !isForwardingPossible()
-          {
-              pathAttributeValues.put(FORWARD_CONTEXT_PATH, dispPathAttributeValues.get(INCLUDE_CONTEXT_PATH));
-              pathAttributeValues.put(FORWARD_SERVLET_PATH, dispPathAttributeValues.get(INCLUDE_SERVLET_PATH));
-              pathAttributeValues.put(FORWARD_PATH_INFO, dispPathAttributeValues.get(INCLUDE_PATH_INFO));
-              pathAttributeValues.put(FORWARD_QUERY_STRING, dispPathAttributeValues.get(INCLUDE_QUERY_STRING));
-              pathAttributeValues.put(FORWARD_REQUEST_URI, dispPathAttributeValues.get(INCLUDE_REQUEST_URI));
-          }
-      }
-    }
-    
-    /**
-     * Deriving the path state values as should be provided to the invoking servlet for a nested dispatch.
-     * <p>
-     * We are not properly in "control" here anymore but can only assume the nested dispatch is still within
-     * the current portlet application and therefore need to reset to the initial path method values during includes.
-     * </p>
-     * <p>
-     * Furthermore, we assume at least the path INCLUDE attribute values as/if provided by the web container to be correct.
-     * </p>
-     * <p>
-     * However we need to retain the initial dispatch forward path attribute values <em>if</em> no new values are provided.
-     * </p>
-     */
-    protected void setupNestedDispatchPathValues()
-    {
-        if (namedDispatch)
-        {
-            // only can/must support request.getContextPath()
-            pathMethodValues.contextPath = dispPathMethodValues.contextPath;
-        }
-        else
-        {
-            if (!forwarded || !isForwardingPossible())
-            {
-                pathMethodValues.copy(initPathMethodValues);
-            }
-            else // forwarded && isForwardingPossible()
-            {
-                pathMethodValues.copy(dispPathMethodValues);
-            }
-        }
-        
-        // whatever the current attribute include path values: assume them correct (even if null)
-        pathAttributeValues.put(INCLUDE_CONTEXT_PATH, currPathAttributeValues.get(INCLUDE_CONTEXT_PATH));
-        pathAttributeValues.put(INCLUDE_SERVLET_PATH, currPathAttributeValues.get(INCLUDE_SERVLET_PATH));
-        pathAttributeValues.put(INCLUDE_PATH_INFO, currPathAttributeValues.get(INCLUDE_PATH_INFO));
-        pathAttributeValues.put(INCLUDE_QUERY_STRING, currPathAttributeValues.get(INCLUDE_QUERY_STRING));
-        pathAttributeValues.put(INCLUDE_REQUEST_URI, currPathAttributeValues.get(INCLUDE_REQUEST_URI));
-        
-        // However: we need to retain our initial dispatch forward path attribute values *if* no new values are provided
-        // To determine if current forward path attributes are set, only need to check the context path
-        if (attributeForwardValuesModified && currPathAttributeValues.get(FORWARD_CONTEXT_PATH) != null)
-        {
-            pathAttributeValues.put(FORWARD_CONTEXT_PATH, currPathAttributeValues.get(FORWARD_CONTEXT_PATH));
-            pathAttributeValues.put(FORWARD_SERVLET_PATH, currPathAttributeValues.get(FORWARD_SERVLET_PATH));
-            pathAttributeValues.put(FORWARD_PATH_INFO, currPathAttributeValues.get(FORWARD_PATH_INFO));
-            pathAttributeValues.put(FORWARD_QUERY_STRING, currPathAttributeValues.get(FORWARD_QUERY_STRING));
-            pathAttributeValues.put(FORWARD_REQUEST_URI, currPathAttributeValues.get(FORWARD_REQUEST_URI));
-        }
-    }
-    
-    /**
-     * Determine if the web container modified the current HttpServletRequestWrapper stack.
-     * <p>
-     * The current HttpServletRequestWrapper hierachy (stack) size is determined and compared against
-     * the previous size.
-     * </p>
-     * <p>
-     * If the size is different the web container "injected" (or removed) a request wrapper of its own
-     * to manage request dispatcher logic like merging additional dispatcher query string parameters.
-     * </p>
-     * <p>
-     * This DispatchDetection solution only works on web containers like Tomcat.
-     * </p>
-     * @return true if the request wrapper stack (size) changed.
-     */
-    protected boolean isRequestWrapperStackChanged()
-    {
-        HttpServletRequestWrapper currentRequest = this;
-        int currentRequestWrapperStackSize = 0;
-        while ((currentRequest.getRequest()) instanceof HttpServletRequestWrapper)
-        {
-            currentRequestWrapperStackSize++;
-            currentRequest = (HttpServletRequestWrapper)currentRequest.getRequest();
-        }
-        if (currentRequestWrapperStackSize != requestWrapperStackSize)
-        {
-            requestWrapperStackSize = currentRequestWrapperStackSize;
-            return true;
-        }
-        return false;
-    }
-    /**
-     * Returns a derived parameters map for the invoking servlet, merging the web container provided parameter map with the portletRequest parameter map
-     * which might contain additional parameters like public render parameters.
-     * <p>
-     * The derived parameters map is cached for the duration of the current request dispatch, and rebuild for every nested dispatch or return thereof.
-     * </p>
-     * <p>
-     * To determine if a nested dispatch occurred (or a return thereof), the current DispatchDetection mode is used:
-     * <ul>
-     *   <li>CHECK_STATE: full compare of the current getRequest().getParameterMap() against the initial getParameterMap()</li>
-     *   <li>CHECK_REQUEST_WRAPPER_STACK: check if the webcontainer injected a HttpServletRequestWrapper <em>above</em> this
-     *       request as Tomcat does (which usually will be less time/cpu consuming if many parameters are passed in)</li>
-     *   <li>EVALUATE:  auto detect on first getParameterMap() call if CHECK_REQUEST_WRAPPER_STACK can be used and then switch
-     *       to either CHECK_STATE or CHECK_REQUEST_WRAPPER_STACK DispatchDetection</li>
-     * </ul>
-     * </p>
-     */
-    @SuppressWarnings("unchecked")
-    @Override
-    public Map<String, String[]> getParameterMap()
-    {
-        boolean dispatchDetected = false;
-        Map<String, String[]> newParameterMap = null;
-        
-        if (dispatchDetection == DispatchDetection.CHECK_REQUEST_WRAPPER_STACK)
-        {
-            if (isRequestWrapperStackChanged())
-            {
-                dispatchDetected = true;
-            }
-        }
-        else
-        {
-            if (dispatchDetection == DispatchDetection.EVALUATE)
-            {
-                if (isRequestWrapperStackChanged())
-                {
-                    dispatchDetected = true;
-                    
-                    if (logger.isDebugEnabled())
-                    {
-                        logger.debug("DispatchDetection: changing from EVALUATE to CHECK_WEBCONTAINER_REQUEST");
-                    }
-                    dispatchDetection = DispatchDetection.CHECK_REQUEST_WRAPPER_STACK;
-                }
-            }
-            if (!dispatchDetected)
-            {
-                // Use parameters maps comparision to determine if a (nested) dispatch occurred or a return thereof.
-                // Note: if a nested dispatch didn't use additional query string parameters,
-                // no change will (need to) be detected.
-                newParameterMap = getRequest().getParameterMap();
-                if (newParameterMap.size() != currParameterMap.size())
-                {
-                    dispatchDetected = true;
-                }
-                else
-                {
-                    for (Map.Entry<String,String[]> entry : newParameterMap.entrySet())
-                    {
-                        String[] newValues = entry.getValue();
-                        String[] currValues = currParameterMap.get(entry.getKey());
-                        if (currValues == null || newValues.length != currValues.length)
-                        {
-                            // no need to compare the actual parameter values as per the servlet spec additional
-                            // query string parameters always must be prepended so doing a length check is enough.
-                            dispatchDetected = true;
-                            break;
-                        }
-                    }
-                }
-                if (dispatchDetected && dispatchDetection == DispatchDetection.EVALUATE)
-                {
-                    if (logger.isDebugEnabled())
-                    {
-                        logger.debug("DispatchDetection: changing from EVALUATE to CHECK_STATE");
-                    }
-                    dispatchDetection = DispatchDetection.CHECK_STATE;
-                }
-            }
-        }
-
-        if (dispatchDetected || parameterMap == null)
-        {
-            if (newParameterMap == null)
-            {
-                newParameterMap = getRequest().getParameterMap();
-            }
-            
-            if (dispatchDetection != DispatchDetection.CHECK_REQUEST_WRAPPER_STACK)
-            {
-                // Save the current parameters map for future comparision
-                // Note: this *must* be a copy as some web containers like WebSphere use
-                // a "dynamic" parameters map where the content of the current
-                // parameters map itself is modified...
-                currParameterMap = new HashMap<String,String[]>(newParameterMap);
-            }
-            Map<String, String[]> diffParameterMap = new HashMap<String, String[]>();
-            
-            // determine the "diff" between the original parameters map and the current one
-            for (Map.Entry<String,String[]> entry : newParameterMap.entrySet())
-            {
-                String[] values = entry.getValue();
-                String[] original = origParameterMap.get(entry.getKey());
-                String[] diff = null;
-                if ( original == null )
-                {
-                    // a new parameter
-                    diff = values.clone();
-                }
-                else if ( values.length > original.length )
-                {
-                    // we've got some additional query string parameter value(s)
-                    diff = new String[values.length - original.length];
-                    System.arraycopy(values,0,diff,0,values.length-original.length);
-                }
-                if ( diff != null )
-                {
-                    diffParameterMap.put(entry.getKey(), diff);
-                }
-            }
-            // we might actually see an empty diff when using DispatchDetection.CHECK_REQUEST_WRAPPER_STACK
-            // in which case the work above turned out to be not needed after all and we can retain the
-            // current cached parametersMap...
-            if (!diffParameterMap.isEmpty())
-            {
-                // build a new parametersMap by merging the diffParametersMap with the portletRequest.parametersMap
-                newParameterMap = new HashMap<String,String[]>(portletRequest.getParameterMap());
-                for (Map.Entry<String, String[]> entry : diffParameterMap.entrySet())
-                {
-                    String[] diff = entry.getValue();
-                    String[] curr = newParameterMap.get(entry.getKey());
-                    if ( curr == null )
-                    {
-                        newParameterMap.put(entry.getKey(), diff);
-                    }
-                    else
-                    {
-                        // we've got some additional query string parameter value(s)
-                        String[] copy = new String[curr.length+diff.length];
-                        System.arraycopy(diff,0,copy,0,diff.length);
-                        System.arraycopy(curr,0,copy,diff.length,curr.length);
-                        newParameterMap.put(entry.getKey(), copy);
-                    }
-                }
-                parameterMap = Collections.unmodifiableMap(newParameterMap);
-            }
-        }        
-        if (parameterMap == null)
-        {
-            // first time and no web container provided parameters
-            parameterMap = portletRequest.getParameterMap();
-        }
-        return parameterMap;
-    }
-
-    @Override
-    public String getParameter(String name)
-    {
-        // derive from getParametersMap() to ensure the cached parameters map is rebuild
-        // when needed for the current (nested) request dispatch
-        String[] values = this.getParameterMap().get(name);
-        return values != null ? values[0] : null;
-    }
-    
-    @Override
-    public Enumeration<String> getParameterNames()
-    {
-        // derive from getParametersMap() to ensure the cached parameters map is rebuild
-        // when needed for the current (nested) request dispatch
-        return Collections.enumeration(this.getParameterMap().keySet());
-    }
-
-    @Override
-    public String[] getParameterValues(String name)
-    {
-        // derive from getParametersMap() to ensure the cached parameters map is rebuild
-        // when needed for the current (nested) request dispatch
-        return this.getParameterMap().get(name);
-    }
-
-    @Override
-    public String getContextPath()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // return the derived path method value
-        return pathMethodValues.contextPath;
-    }
-
-    @Override
-    public String getPathInfo()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // return the derived path method value
-        return pathMethodValues.pathInfo;
-    }
-
-    @Override
-    public String getPathTranslated()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // base the return value on the derived path method value
-        if (pathMethodValues.pathInfo != null && pathMethodValues.contextPath.equals(portletRequest.getContextPath()))
-        {
-            // can only (and possibly) do this while still within the same context
-            return servletContext.getRealPath(pathMethodValues.pathInfo);
-        }
-        return null;
-    }
-
-    @Override
-    public String getQueryString()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // return the derived path method value
-        return pathMethodValues.queryString;
-    }
-
-    @Override
-    public String getRequestURI()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // return the derived path method value
-        return pathMethodValues.requestURI;
-    }
-
-    @Override
-    public String getServletPath()
-    {
-        // synchronize the derived path state values first
-        updateRequestPathState();
-        // return the derived path method value
-        return pathMethodValues.servletPath;
-    }
-
-    @Override
-    public Object getAttribute(String name)
-    {
-        if (PATH_ATTRIBUTE_NAMES_SET.contains(name))
-        {
-            // synchronize the derived path state values first
-            updateRequestPathState();
-            // return the derived path attribute value
-            return pathAttributeValues.get(name);
-        }
-        // First try to retrieve the attribute from the (possibly buffered/cached/previously set) portletRequest
-        // except for servlet container injected (managed) attributes which cannot reliably be retrieved from the portletRequest
-        Object value = servletContainerManagedAttributes.contains(name) ? null : portletRequest.getAttribute(name);
-        // if null, fall back to retrieve the attribute from the web container itself
-        return value != null ? value : requestContext.getAttribute(name, getRequest());
-    }
-
-    @Override
-    public void setAttribute(String name, Object o)
-    {
-        if (PATH_ATTRIBUTE_NAMES_SET.contains(name))
-        {
-            // path attributes are never set/removed directly to/from the
-            // web container but maintained in a separate cache map to 
-            // protect against concurrent writing to the client request attribute map(s)
-            // when using multi-threaded rendering.
-            pathAttributeCache.put(name, o);
-        }
-        else
-        {
-            portletRequest.setAttribute(name, o);
-        }
-    }
-
-    @Override
-    public void removeAttribute(String name)
-    {
-        if (PATH_ATTRIBUTE_NAMES_SET.contains(name))
-        {
-            // path attributes are never set/removed directly to/from the
-            // web container but maintained in a separate cache map to 
-            // protect against concurrent writing to the client request attribute map(s)
-            // when using multi-threaded rendering.
-            pathAttributeCache.remove(name);
-        }
-        else
-        {
-            portletRequest.removeAttribute(name);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public Enumeration<String> getAttributeNames()
-    {
-        HashSet<String> names = new HashSet<String>();
-        Enumeration<String> e;
-        for (e = getRequest().getAttributeNames(); e.hasMoreElements();  )
-        {
-            try
-            {
-                names.add(e.nextElement());
-            }
-            catch(NoSuchElementException nse)
-            {
-                // ignore potential concurrent changes when run in parallel mode
-            }
-        }
-        for (e = portletRequest.getAttributeNames(); e.hasMoreElements();  )
-        {
-            try
-            {
-                names.add(e.nextElement());
-            }
-            catch(NoSuchElementException nse)
-            {
-                // ignore potential concurrent changes when run in parallel mode
-            }
-        }
-        // now synchronize the derived path state values before overriding with (or possibly removing from)
-        // the actual names set to enumerate
-        updateRequestPathState();
-        for (String name : PATH_ATTRIBUTE_NAMES)
-        {
-            if (pathAttributeValues.get(name) != null)
-            {
-                // ensure the derived path attribute name is present in the set
-                names.add(name);
-            }
-            else
-            {
-                // remove a possibly web container provided path attribute name
-                // if it currently should not be present based on our derived path state
-                names.remove(name);
-            }
-        }
-        return Collections.enumeration(names);
-    }
-
-    @Override
-    public RequestDispatcher getRequestDispatcher(String path)
-    {
-        if (path != null)
-        {
-            // first determine if the web container does know how to dispatch to this path
-            RequestDispatcher dispatcher = super.getRequestDispatcher(path);
-            if (dispatcher != null)
-            {
-                // we have a RequestDispatcher
-                if (!dispatched)
-                {
-                    // unlikely, but for sanity sake making sure our internal initial state is created
-                    updateRequestPathState();
-                }
-                
-                if (forwarded && isForwardingPossible())
-                {
-                    // The webcontainer already will have set the initial request forward path attributes
-                    // and a subsequent forward (or include) won't need any further special handling
-                    // therefore we can simply let the webcontainer handle this itself
-                    return dispatcher;
-                }
-                else
-                {
-                    // !forwarded || !isForwardingPossible() can and needs to be handled by PortletRequestDispatcherImpl
-                    // when the dispatch is going to be done using forward because that will require special overriding
-                    // handling because of portlet spec requirements.
-                    return new PortletRequestDispatcherImpl(dispatcher, false);
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public long getDateHeader(String name)
-    {
-        String value = portletRequest.getProperty(name);
-        if (value == null)
-        { 
-            return (-1L);
-        }
-        // Attempt to convert the date header in a variety of formats
-        return parseDateHeader(value);
-    }
-
-    @Override
-    public String getAuthType()
-    {
-        return portletRequest.getAuthType();
-    }
-
-    @Override
-    public Cookie[] getCookies()
-    {
-        return portletRequest.getCookies();
-    }
-
-    @Override
-    public String getHeader(String name)
-    {
-        return portletRequest.getProperty(name);
-    }
-
-    @Override
-    public Enumeration<String> getHeaderNames()
-    {
-        return portletRequest.getPropertyNames();
-    }
-
-    @Override
-    public Enumeration<String> getHeaders(String name)
-    {
-        return portletRequest.getProperties(name);
-    }
-
-    @Override
-    public int getIntHeader(String name)
-    {
-        String property = portletRequest.getProperty(name);
-        if (property == null)
-        {
-            return -1;
-        }
-        return Integer.parseInt(property);
-    }
-
-    @Override
-    public String getMethod()
-    {
-        return renderPhase ? "GET" : super.getMethod();
-    }
-    
-    @Override
-    public HttpSession getSession()
-    {
-        return session !=  null ? session : super.getSession();
-    }
-
-    @Override
-    public HttpSession getSession(boolean create)
-    {
-        return session != null ? session : super.getSession(create);
-    }
-
-    @Override
-    public String getRemoteUser()
-    {
-        return portletRequest.getRemoteUser();
-    }
-
-    @Override
-    public String getRequestedSessionId()
-    {
-        return portletRequest.getRequestedSessionId();
-    }
-
-    @Override
-    public StringBuffer getRequestURL()
-    {
-        return null;
-    }
-
-    @Override
-    public Principal getUserPrincipal()
-    {
-        return portletRequest.getUserPrincipal();
-    }
-
-    @Override
-    public boolean isRequestedSessionIdValid()
-    {
-        return portletRequest.isRequestedSessionIdValid();
-    }
-
-    @Override
-    public boolean isUserInRole(String role)
-    {
-        return portletRequest.isUserInRole(role);
-    }
-
-    @Override
-    public String getCharacterEncoding()
-    {
-        return clientDataRequest != null ? clientDataRequest.getCharacterEncoding() : null;
-    }
-
-    @Override
-    public void setCharacterEncoding(String enc) throws UnsupportedEncodingException
-    {
-        if (clientDataRequest != null)
-        {
-            clientDataRequest.setCharacterEncoding(enc);
-        }
-    }    
-    
-    @Override
-    public int getContentLength()
-    {
-        return clientDataRequest != null ? clientDataRequest.getContentLength() : 0;
-    }
-
-    @Override
-    public String getContentType()
-    {
-        return clientDataRequest != null ? clientDataRequest.getContentType() : null;
-    }
-
-    @Override
-    public ServletInputStream getInputStream() throws IOException
-    {
-        return clientDataRequest != null ? (ServletInputStream)clientDataRequest.getPortletInputStream() : null;
-    }
-
-    @Override
-    public String getLocalAddr()
-    {
-        return null;
-    }
-
-    @Override
-    public Locale getLocale()
-    {
-        return portletRequest.getLocale();
-    }
-
-    @Override
-    public Enumeration<Locale> getLocales()
-    {
-        return portletRequest.getLocales();
-    }
-
-    @Override
-    public String getLocalName()
-    {
-        return null;
-    }
-
-    @Override
-    public int getLocalPort()
-    {
-        return 0;
-    }
-
-    @Override
-    public String getProtocol()
-    {
-        return "HTTP/1.1";
-    }
-
-    @Override
-    public BufferedReader getReader() throws IOException
-    {
-        return clientDataRequest != null ? clientDataRequest.getReader() : null;
-    }
-
-    @Override
-    public String getRealPath(String path)
-    {
-        return null;
-    }
-
-    @Override
-    public String getRemoteAddr()
-    {
-        return null;
-    }
-
-    @Override
-    public String getRemoteHost()
-    {
-        return null;
-    }
-
-    @Override
-    public int getRemotePort()
-    {
-        return 0;
-    }
-
-    @Override
-    public String getScheme()
-    {
-        return portletRequest.getScheme();
-    }
-
-    @Override
-    public String getServerName()
-    {
-        return portletRequest.getServerName();
-    }
-
-    @Override
-    public int getServerPort()
-    {
-        return portletRequest.getServerPort();
-    }
-
-    @Override
-    public boolean isSecure()
-    {
-        return portletRequest.isSecure();
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.impl;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import javax.portlet.ClientDataRequest;
+import javax.portlet.PortletRequest;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
+
+import org.apache.pluto.container.PortletInvokerService;
+import org.apache.pluto.container.PortletRequestContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
+ * @version $Id$
+ */
+public class HttpServletPortletRequestWrapper extends HttpServletRequestWrapper
+{
+    private static final Logger logger = LoggerFactory.getLogger(HttpServletPortletRequestWrapper.class);
+    
+    protected static final String INCLUDE_CONTEXT_PATH = "javax.servlet.include.context_path";
+    protected static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
+    protected static final String INCLUDE_QUERY_STRING = "javax.servlet.include.query_string";
+    protected static final String INCLUDE_REQUEST_URI = "javax.servlet.include.request_uri";
+    protected static final String INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
+    protected static final String FORWARD_CONTEXT_PATH = "javax.servlet.forward.context_path";
+    protected static final String FORWARD_PATH_INFO = "javax.servlet.forward.path_info";
+    protected static final String FORWARD_QUERY_STRING = "javax.servlet.forward.query_string";
+    protected static final String FORWARD_REQUEST_URI = "javax.servlet.forward.request_uri";
+    protected static final String FORWARD_SERVLET_PATH = "javax.servlet.forward.servlet_path";
+
+    protected static final String[] PATH_ATTRIBUTE_INCLUDE_NAMES = { INCLUDE_CONTEXT_PATH,
+                                                                     INCLUDE_PATH_INFO,
+                                                                     INCLUDE_QUERY_STRING,
+                                                                     INCLUDE_REQUEST_URI,
+                                                                     INCLUDE_SERVLET_PATH };
+
+    protected static final String[] PATH_ATTRIBUTE_FORWARD_NAMES = { FORWARD_CONTEXT_PATH,
+                                                                     FORWARD_PATH_INFO,
+                                                                     FORWARD_QUERY_STRING,
+                                                                     FORWARD_REQUEST_URI,
+                                                                     FORWARD_SERVLET_PATH };
+
+    protected static final String[] PATH_ATTRIBUTE_NAMES = { INCLUDE_CONTEXT_PATH,
+                                                             INCLUDE_PATH_INFO,
+                                                             INCLUDE_QUERY_STRING,
+                                                             INCLUDE_REQUEST_URI,
+                                                             INCLUDE_SERVLET_PATH,
+                                                             FORWARD_CONTEXT_PATH,
+                                                             FORWARD_PATH_INFO,
+                                                             FORWARD_QUERY_STRING,
+                                                             FORWARD_REQUEST_URI,
+                                                             FORWARD_SERVLET_PATH };
+    
+    protected static final HashSet<String> PATH_ATTRIBUTE_NAMES_SET = 
+        new HashSet<String>(Arrays.asList(PATH_ATTRIBUTE_NAMES));
+    
+    /**
+     * PathMethodValues contains the values of a HttpServletRequest PATH methods.
+     */
+    protected static final class PathMethodValues
+    {
+        String contextPath;
+        String servletPath;
+        String pathInfo;
+        String queryString;
+        String requestURI;
+        
+        PathMethodValues(){}
+                
+        PathMethodValues copy(PathMethodValues pmv)
+        {
+            this.contextPath = pmv.contextPath;
+            this.servletPath = pmv.servletPath;
+            this.pathInfo = pmv.pathInfo;
+            this.queryString = pmv.queryString;
+            this.requestURI = pmv.requestURI;
+            return this;
+        }
+    }
+    
+    protected static final String[] DEFAULT_SERVLET_CONTAINER_MANAGED_ATTRIBUTES = { "org.apache.catalina.core.DISPATCHER_TYPE", 
+    																				 "org.apache.catalina.core.DISPATCHER_REQUEST_PATH" };
+    
+    /**
+     * <p>
+     * Some servlet containers like Tomcat (Catalina) use "injected" request attributes within their own Request (dispatch)
+     * wrapper objects to keep track of their current state. Such "injected" attributes are never really "set" or (supposed to be)
+     * visible by the current application request processing logic.
+     * </p><p>
+     * Such special attributes therefore cannot be reliably "managed" or isolated per (portlet) servlet request window as it never
+     * can be known if or when such attributes (value) might change.
+     * </p><p>
+     * And, as these attributes are used internally by the servlet container providing back the wrong (or no) value very easily
+     * can break the expected behavior.
+     * </p><p>
+     * On Tomcat this for instance happens when a forwarded portlet request itself would try an (servlet) include request. Then, its
+     * internal state using "injected" attribute "org.apache.catalina.DISPATCHER_TYPE" is changed.
+     * </p><p>
+     * To support such servlet container internal/injected attribute handling, a static servletContainerManagedAttributes HashSet
+     * is maintained containing the attribute names which value should <em>always</em> be retrieved from the current (injected) parent request.
+     * </p><p>
+     * As default the currently known two Tomcat internal/injected attribute names are used.
+     * </p><p>
+     * For other containers which might use a similar approach these reserved attribute names can be (re)set through the static
+     * method setServletContainerManagedAttributes(String[]), e.g. like with a Springframework based initialization of the container.
+     * </p>
+     */
+    protected static HashSet<String> servletContainerManagedAttributes =
+    	new HashSet<String>(Arrays.asList(DEFAULT_SERVLET_CONTAINER_MANAGED_ATTRIBUTES));
+    
+    /**
+     * DispatchDetection defines how a (nested) RequestDispatcher include/forward call will be detected.
+     * <p>
+     * The dispatch detection is used to optimize building the custom parameters map as returned from the
+     * getParametersMap method as rebuilding the parameters map for each and every access can be quite expensive.
+     * </p>
+     * <p>
+     * A parameter map is constant within the scope of one (level of) request dispatching, but a nested request
+     * dispatch using an additional query string on the dispatch path requires merging of its query string parameters
+     * for the duration of that (nested) dispatch.
+     * </p>
+     * <p>
+     * DispatchDetection defines how such a nested dispatch is detected:
+     * <ul>
+     *   <li>CHECK_STATE: full compare of the current getRequest().getParameterMap() against the initial getParameterMap()</li>
+     *   <li>CHECK_REQUEST_WRAPPER_STACK: check if the webcontainer injected a HttpServletRequestWrapper <em>above</em> this
+     *       request as Tomcat does (which usually will be less time/cpu consuming if many parameters are passed in)</li>
+     *   <li>EVALUATE:  auto detect on first getParameterMap() call if CHECK_REQUEST_WRAPPER_STACK can be used and then switch
+     *       to either CHECK_STATE or CHECK_REQUEST_WRAPPER_STACK DispatchDetection</li>
+     * </ul>
+     * </p>
+     * <p>
+     * By default the CHECK_STATE method is used which in most cases is more optimal except when often many request parameters are used.
+     * </p>
+     */
+    static enum DispatchDetection { CHECK_STATE, CHECK_REQUEST_WRAPPER_STACK, EVALUATE };
+    
+    /**
+     * Current DispatchDetection mode used, defaults to DispatchDetection.CHECK_STATE
+     */
+    static volatile DispatchDetection dispatchDetection = DispatchDetection.CHECK_STATE;
+    
+    /**
+     * Cache for parsed dateHeader values.
+     */
+    protected static final HashMap<String,Long> dateHeaderParseCache = new HashMap<String,Long>();
+    
+    /**
+     * The set of SimpleDateFormat formats to use in getDateHeader().
+     *
+     * Notice that because SimpleDateFormat is not thread-safe, we can't
+     * declare formats[] as a static variable.
+     */
+    protected SimpleDateFormat dateHeaderFormats[] = 
+    {
+        new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
+        new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
+        new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US)
+    };
+
+    /**
+     * Map of the current, web container provided, PATH_ATTRIBUTE_NAMES attribute values.
+     */
+    protected Map<String,Object> currPathAttributeValues = new HashMap<String,Object>();
+    
+    /**
+     * Map of the first, or first after a (PortletRequestDispatcher initiated nested dispatch, web container provided, PATH_ATTRIBUTE_NAMES attribute values.
+     */
+    protected Map<String,Object> dispPathAttributeValues = new HashMap<String, Object>();
+    
+    /**
+     * Map of the PATH_ATTRIBUTE_NAMES attribute values provided to the invoking servlet as derived for the current (initial or nested) request dispatch.
+     */
+    protected Map<String,Object> pathAttributeValues = new HashMap<String, Object>();
+    
+    /**
+     * Cache of PATH_ATTRIBUTE_NAMES attribute values possibly set using setAttribute.
+     * <p>
+     * This read-through cache protects against concurrent writing to the client request attribute map(s) when using multi-threaded rendering.
+     * </p>
+     */
+    protected Map<String,Object> pathAttributeCache = new HashMap<String, Object>();
+    
+    /**
+     * Current getRequest() PATH method values
+     */
+    protected PathMethodValues currPathMethodValues = new PathMethodValues();
+    
+    /**
+     * The first, or first after a (PortletRequestDispatcher initiated nested dispatch, web container provided, PATH method values.
+     */
+    protected PathMethodValues dispPathMethodValues = new PathMethodValues();
+    
+    /**
+     * PATH method values provided to the invoking servlet as derived for the current (initial or nested) request dispatch
+     */
+    protected PathMethodValues pathMethodValues = new PathMethodValues();
+    
+    /**
+     * The initial, web container provided, PATH method values.
+     * <p>
+     * These values are kept separately from the dispPathMethodValues are the Portlet API retaining those for all further (nested) dispatching.
+     * But this actually only makes sense if the fist dispatch is not done using a NamedDispatcher.
+     * </p>
+     */
+    protected PathMethodValues initPathMethodValues;
+    
+    /**
+     * Flag indicating if the current, web container provided, PATH_ATTRIBUTE_INCLUDE_NAMES attribute values are modified
+     */
+    protected boolean attributeIncludeValuesModified;
+
+    /**
+     * Flag indicating if the current, web container provided, PATH_ATTRIBUTE_FORWARD_NAMES attribute values are modified
+     */
+    protected boolean attributeForwardValuesModified;
+
+    /**
+     * Flag indicating if the current, web container provided, PATH method values are modified
+     */
+    protected boolean methodValuesModified;
+    
+    /**
+     * Flag indicating if the current (possibly nested) request dispatch is based upon a NamedDispatcher.
+     */
+    protected boolean namedDispatch;
+    
+    /**
+     * Flag indicating if the current (possibly nested) request dispatch is <em>intentionally</em> using RequestDispatcher.forward.
+     * <p>Note: it depends on isForwardingPossible() if an actual forward is used or "faked" while performing an include call.</p>
+     */
+    protected boolean forwarded;
+    
+    /**
+     * Flag indicating if the initial level of dispatch is detected.
+     */
+    protected boolean dispatched;
+    
+    /**
+     * Flag indicating if a nested dispatch is detected.
+     */
+    protected boolean nested;
+
+    /**
+     * Current size of the nested HttpServletRequestWrapper stack size, counted from this request up.
+     * <p>
+     * Used together with DispatchDetection mode CHECK_REQUEST_WRAPPER_STACK or EVALUATE to determine if
+     * the current request dispatching "stack" has changed and thus the parameter map needs rebuilding.
+     * </p>
+     * <p>
+     * This type of DispatchDetection only works for web containers like Tomcat which "inject" (and remove) a HttpServletRequestWrapper
+     * of their own on each nested request dispatch call.
+     * </p>
+     */
+    protected int requestWrapperStackSize;
+    
+    /**
+     * Initial parameters map as provided by the web container <em>before</em> the initial request dispatch.
+     * <p>
+     * Used for comparision with the current web container provided parameters map to calculate (possible)
+     * merged parameters when the initial (or a nested) request dispatcher was created using additional query string parameters.
+     * </p>
+     */
+    protected Map<String, String[]> origParameterMap;
+    
+    /**
+     * Cache of current parameters map as provided by the web container.
+     * <p>
+     * Only used with DispatchDetection != CHECK_REQUEST_WRAPPER_STACK for comparision with the current
+     * current web container provided parameters map to detect a possible nested request dispatch
+     * with additional query string parameters (or a return thereof).
+     * </p>
+     */
+    protected Map<String, String[]> currParameterMap;
+    
+    /**
+     * Cache of the derived parameters map to be provided to invoking servlet.
+     * <p>
+     * This parameter map is (re)build on first access to getParametersMap after a (nested) request dispatch or a
+     * return thereof.
+     * </p>
+     */
+    protected Map<String, String[]> parameterMap;
+    
+    protected final PortletRequestContext requestContext;
+    protected final ServletContext servletContext;
+    protected final PortletRequest portletRequest;
+    protected final ClientDataRequest clientDataRequest;
+    protected final String lifecyclePhase;
+    protected final boolean renderPhase;
+    
+    protected HttpSession session;
+    
+    /**
+     * Set the Servlet container managed (projected) attribute names which cannot be isolated per portlet/servlet request window
+     * and therefore need to be retrieved directly from the parent (injected) servlet request object.
+     * @param names array of protected servlet container attribute names
+     */
+    public static void setServletContainerManagedAttributes(String[] names)
+    {
+    	if (names == null)
+    	{
+    		servletContainerManagedAttributes.clear();
+    	}
+    	else
+    	{
+    		servletContainerManagedAttributes = new HashSet<String>(Arrays.asList(names));
+    	}
+    }
+    
+    public HttpServletPortletRequestWrapper(HttpServletRequest request, ServletContext servletContext, HttpSession session, PortletRequest portletRequest, boolean included, boolean namedDispatch)
+    {
+        super(request);
+        this.servletContext = servletContext;
+        this.session = session;
+        this.portletRequest = portletRequest;
+        lifecyclePhase = (String)portletRequest.getAttribute(PortletRequest.LIFECYCLE_PHASE);
+        clientDataRequest = PortletRequest.ACTION_PHASE.equals(lifecyclePhase) || PortletRequest.RESOURCE_PHASE.equals(lifecyclePhase) ? (ClientDataRequest)portletRequest : null;
+        renderPhase = PortletRequest.RENDER_PHASE.equals(lifecyclePhase);
+        requestContext = (PortletRequestContext )portletRequest.getAttribute(PortletInvokerService.REQUEST_CONTEXT);
+        this.forwarded = !included;
+        this.namedDispatch = namedDispatch;
+        origParameterMap = new HashMap<String,String[]>(request.getParameterMap());
+        currParameterMap = origParameterMap;
+        for (String name : PATH_ATTRIBUTE_NAMES)
+        {
+            currPathAttributeValues.put(name,request.getAttribute(name));
+        }
+        currPathMethodValues.contextPath = request.getContextPath();
+        currPathMethodValues.servletPath = request.getServletPath();
+        currPathMethodValues.pathInfo = request.getPathInfo();
+        currPathMethodValues.queryString = request.getQueryString();
+        currPathMethodValues.requestURI = request.getRequestURI();
+        if (dispatchDetection != DispatchDetection.CHECK_STATE)
+        {            
+            HttpServletRequestWrapper currentRequest = this;
+            while ((currentRequest.getRequest()) instanceof HttpServletRequestWrapper)
+            {
+                requestWrapperStackSize++;
+                currentRequest = (HttpServletRequestWrapper)currentRequest.getRequest();
+            }
+        }
+    }
+    
+    /**
+     * Try to parse the given date as a HTTP date. Borrowed and adapted from
+     * Tomcat FastHttpDateFormat
+     */
+    private long parseDateHeader(String value)
+    {
+        Long dateValue = null;
+        try
+        {
+            dateValue = dateHeaderParseCache.get(value);
+        }
+        catch (Exception e)
+        {
+        }
+        if (dateValue == null)
+        {
+            for (int i = 0; i < dateHeaderFormats.length; i++)
+            {
+                try
+                {
+                    Date date = dateHeaderFormats[i].parse(value);
+                    dateValue = new Long(date.getTime());
+                }
+                catch (ParseException e)
+                {
+                }
+            }
+            if (dateValue != null)
+            {
+                synchronized (dateHeaderParseCache)
+                {
+                    if (dateHeaderParseCache.size() > 1000)
+                    {
+                        dateHeaderParseCache.clear();
+                    }
+                    dateHeaderParseCache.put(value, dateValue);
+                }
+            }
+            else
+            {
+                throw new IllegalArgumentException(value);
+            }
+        }
+        return dateValue.longValue();
+    }
+    
+    boolean isForwardingPossible()
+    {
+        return !renderPhase;
+    }
+    
+    /**
+     * Returns the current forwarding state to be cached by the PortletRequestDispatcherImpl
+     * during a nested forward. This state needs to be restored with the restoreFromNestedForward method afterwards.
+     */
+    boolean isForwarded()
+    {
+        return forwarded;
+    }
+    
+    /**
+     * Returns the current namedDispatch state to be cached by the PortletRequestDispatcherImpl
+     * during a nested forward. This state needs to be restored with the restoreFromNestedForward method afterwards.
+     */
+    boolean isNamedDispatch()
+    {
+        return namedDispatch;
+    }
+    
+    /**
+     * Returns a <em>copy</em> of the current dispPathAttributeValues to be cached by the PortletRequestDispatcherImpl
+     * during a nested forward. These need to be restored with the restoreFromNestedForward method afterwards.
+     */
+    Map<String, Object> getPathAttributeValues()
+    {
+        return new HashMap<String, Object>(dispPathAttributeValues);
+    }
+    
+    /**
+     * Returns a <em>copy</em> of the current initPathMethodValues (or null) to be cached by the PortletRequestDispatcherImpl
+     * during a nested forward. These need to be restored with the restoreFromNestedForward method afterwards.
+     */
+    PathMethodValues getInitPathMethodValues()
+    {
+        return initPathMethodValues != null ? new PathMethodValues().copy(initPathMethodValues) : null;
+    }
+    
+    /**
+     * Initiates a nested forward from the PortletRequestDispatcherImpl.
+     */
+    void setNestedForward()
+    {
+        dispatched = false;        
+        forwarded = true;
+        namedDispatch = false;
+    }
+    
+    /**
+     * Restores the previous request path state as cached by the PortletRequestDispatcherImpl after returning from a nested forward.
+     */
+    void restoreFromNestedForward(boolean forwarded, boolean namedDispatch, 
+                                  PathMethodValues pathMethodValues, Map<String, Object> pathAttributeValues)
+    {
+        this.forwarded = forwarded;
+        this.namedDispatch = namedDispatch;
+        dispPathAttributeValues.clear();
+        dispPathAttributeValues.putAll(pathAttributeValues);
+        updateRequestPathState();
+    }
+    
+    /**
+     * Method to check the current web container provided request path state with the cached state to determine if a (nested)
+     * request dispatch has occurred.
+     * <p>
+     * If a (nested) request dispatch has been determined, the derived pathMethodValues and pathAttributeValues are (re)created
+     * to be provided to the invoking servlet as override of the web container "view" of this state.
+     * </p>
+     */
+    protected void updateRequestPathState()
+    {
+        // synchronize current web container path method and attribute values and detect modifications
+        syncDispatcherPathValues();
+        
+        // check and evaluate (significant) modifications to the path state
+        if (checkDispatcherPathValuesChanged())
+        {
+            // dispatch detected
+            
+            if (!dispatched)
+            {
+                //initial dispatch or initial dispatch after a nested forward (from PortletRequestDispatcherImpl) detected
+                initFirstDispatchPathValues();
+            }
+            else
+            {
+                // check if (still) within a nested dispatch or returning back to the initial dispatch
+                checkNestedDispatch();
+            }
+            if (!nested)
+            {
+                // (back to) initial dispatch
+                setupFirstDispatchPathValues();
+            }
+            else // nested
+            {
+                // (still) within a nested dispatch
+                setupNestedDispatchPathValues();
+            }
+        }
+    }
+    
+    private static boolean compareAttributes(Object o1, Object o2)
+    {
+        return (o1 == null && o2 == null) || (o1 != null && o2 != null && o1.equals(o2));
+    }
+    
+    private static String asString(Object o)
+    {
+        return o != null ? o.toString() : null;
+    }
+    
+    /**
+     * Synchronize and compare current web container provided path state with the previously determined path state.
+     */
+    protected void syncDispatcherPathValues()
+    {
+        HttpServletRequest request = (HttpServletRequest)getRequest();
+        Object attrValue;
+        String methodValue;
+
+        attributeIncludeValuesModified = false;
+        attributeForwardValuesModified = false;
+        methodValuesModified = false;
+        
+        for (String name : PATH_ATTRIBUTE_INCLUDE_NAMES)
+        {
+            // first check possible cached path attributes as set through setAttribute
+            attrValue = pathAttributeCache.get(name);
+            if (attrValue == null)
+            {
+                // not cached: get current value from web container
+                attrValue = request.getAttribute(name);
+            }
+            // determine if modified
+            attributeIncludeValuesModified = !attributeIncludeValuesModified ? !compareAttributes(currPathAttributeValues.get(name), attrValue) : true;
+            // save new value for further usage and future modification check
+            currPathAttributeValues.put(name, attrValue);
+        }
+        for (String name : PATH_ATTRIBUTE_FORWARD_NAMES)
+        {
+            // first check possible cached path attributes as set through setAttribute
+            attrValue = pathAttributeCache.get(name);
+            if (attrValue == null)
+            {
+                // not cached: get current value from web container
+                attrValue = request.getAttribute(name);
+            }
+            // determine if modified
+            attributeForwardValuesModified = !attributeForwardValuesModified ? !compareAttributes(currPathAttributeValues.get(name), attrValue) : true;
+            // save new value for further usage and future modification check
+            currPathAttributeValues.put(name, attrValue);
+        }
+        
+        // for all path method values:
+        //   retrieve them from the current web container
+        //   determine if modified
+        //   save them further usage and future modification check
+        
+        methodValue = request.getContextPath();
+        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.contextPath, methodValue);
+        currPathMethodValues.contextPath = methodValue;
+        
+        methodValue = request.getServletPath();
+        methodValuesModified = methodValuesModified ? true : !compareAttributes(currPathMethodValues.servletPath, methodValue);
+        currPathMethodValues.servletPath = methodValue;
+
+        methodValue = request.getPathInfo();
+        methodValuesModified = me

<TRUNCATED>

[07/35] portals-pluto git commit: Added configuration by annotation for V3 portlets. For v3 portlets, neither the web application deployment descriptor nor the portlet deployment descriptor are necessary. * Annotations provided for all portlet config

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
index 53e6a2b..e5f5b9d 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286Gen.java
@@ -34,7 +34,6 @@ import org.apache.pluto.container.om.portlet20.impl.PortletAppType;
 import org.apache.pluto.container.om.portlet20.impl.PortletType;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Low-level test to read a deployment descriptor

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
index 232eb37..b509250 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest286NC.java
@@ -30,7 +30,6 @@ import org.apache.pluto.container.om.portlet20.impl.PortletAppType;
 import org.apache.pluto.container.om.portlet20.impl.PortletType;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Low-level test to read a deployment descriptor

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
index 286310a..eaf09db 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest362Gen.java
@@ -30,7 +30,6 @@ import org.apache.pluto.container.om.portlet30.impl.PortletAppType;
 import org.apache.pluto.container.om.portlet30.impl.PortletType;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Low-level test to read a deployment descriptor
@@ -93,12 +92,10 @@ public class JaxbReadTest362Gen {
       assertEquals("portlet-mode", portletApp.getCustomPortletMode().get(0).getPortletMode().getValue());
       assertEquals("window-state", portletApp.getCustomWindowState().get(0).getWindowState().getValue());
       assertEquals("name", portletApp.getUserAttribute().get(0).getName().getValue());
-      assertEquals("portlet362", portletApp.getSecurityConstraint().get(0)
-            .getPortletCollection().getPortletName().get(0).getValue());
       
       // Some additional stuff from old test suite
       assertTrue(portlet.getPortletClass().equals("org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet"));
-      assertTrue(portlet.getPortletInfo().getTitle().getValue().equals("title"));
+      assertTrue(portlet.getPortletInfo().getTitle().get(0).getValue().equals("title"));
       assertEquals( "supports size should be 3", 3, portlet.getSupports().size());
       
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType", portletApp.getEventDefinition().get(0).getValueType());

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilter.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilter.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilter.java
new file mode 100644
index 0000000..ff1c3dd
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedFilter.java
@@ -0,0 +1,88 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import java.io.IOException;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.PortletException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletRequestFilter;
+import javax.portlet.filter.FilterChain;
+import javax.portlet.filter.FilterConfig;
+import javax.portlet.filter.HeaderFilter;
+import javax.portlet.filter.HeaderFilterChain;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
+
+/**
+ * Some tests for filter annotations
+ *
+ */
+@ApplicationScoped
+@PortletRequestFilter(portletNames = {"portlet362"}, 
+                      ordinal = 100,
+                      filterName = "aFilter",
+                      initParams = {
+                         @InitParameter(name = "execute", value = "true"),
+                         @InitParameter(name = "id", value = "ego")},
+                      description = {
+                         @LocaleString("Quite the filter"),
+                         @LocaleString(locale="DE", value = "Ein ordentlicher Filter")},
+                      displayName = {
+                         @LocaleString("A Filter"),
+                         @LocaleString(locale="DE", value = "Ein Filter")})
+public class TestAnnotatedFilter implements RenderFilter,
+      ResourceFilter, HeaderFilter {
+
+   @Override
+   public void init(FilterConfig filterConfig) throws PortletException {
+   }
+
+   @Override
+   public void destroy() {
+   }
+
+   @Override
+   public void doFilter(ResourceRequest request, ResourceResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(RenderRequest request, RenderResponse response,
+         FilterChain chain) throws IOException, PortletException {
+
+   }
+
+   @Override
+   public void doFilter(HeaderRequest request, HeaderResponse response, HeaderFilterChain chain) throws IOException,
+         PortletException {
+      
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedGenericPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedGenericPortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedGenericPortlet.java
new file mode 100644
index 0000000..2ebda44
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedGenericPortlet.java
@@ -0,0 +1,60 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.GenericPortlet;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+
+/**
+ * This test class carries a portlet application annotation to define the portlet
+ * app along with a portlet configurations annotation that contains configuration 
+ * information for two portlets.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+@PortletConfiguration(portletName="Annotated Generic Portlet", 
+initParams = {
+      @InitParameter(name="AnnoName", value="value", description= {@LocaleString(locale="DE", value="Beschreibung")}),
+      @InitParameter(name="ipname", value="ipvalue", description= {@LocaleString("description")}),
+      @InitParameter(name="nullValueParam", value="")
+   },
+   description={
+      @LocaleString("Portlet displaying the time in different time zones"),
+      @LocaleString(locale="de", value="Dieses Portlet zeigt die Zeit in verschiedenen Zeitzonen an")
+   }, displayName={
+      @LocaleString("Time Zone Clock Portlet"),
+      @LocaleString(locale="de", value="ZeitzonenPortlet")
+   }, title={
+      @LocaleString("Annotated Portlet"),
+      @LocaleString(locale="DE", value="Annotiertes Portlet")
+   }, shortTitle={
+      @LocaleString("Anno Portlet"),
+      @LocaleString(locale="DE", value="Ein Portlet")
+   }, keywords={
+      @LocaleString("One, Two, Three"),
+      @LocaleString(locale="DE", value="Eins, Zwei, Drei")
+   }
+)
+public class TestAnnotatedGenericPortlet extends GenericPortlet {
+   // add portlet methods
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
new file mode 100644
index 0000000..bed73a4
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestAnnotatedPortlet.java
@@ -0,0 +1,82 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.annotations.Dependency;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.Preference;
+import javax.portlet.annotations.RuntimeOption;
+import javax.portlet.annotations.SecurityRoleRef;
+import javax.portlet.annotations.Supports;
+
+/**
+ * @author nick
+ *
+ */
+@PortletConfiguration(portletName="AnnotatedPortlet",
+   initParams = {
+      @InitParameter(name="AnnoName", value="value", description= {@LocaleString(locale="DE", value="Beschreibung")}),
+      @InitParameter(name="ipname", value="ipvalue", description= {@LocaleString("description")}),
+      @InitParameter(name="nullValueParam", value="")
+   },
+   description={
+      @LocaleString("Portlet displaying the time in different time zones"),
+      @LocaleString(locale="de", value="Dieses Portlet zeigt die Zeit in verschiedenen Zeitzonen an")
+   }, displayName={
+      @LocaleString("Time Zone Clock Portlet"),
+      @LocaleString(locale="de", value="ZeitzonenPortlet")
+   }, title={
+      @LocaleString("Annotated Portlet"),
+      @LocaleString(locale="DE", value="Annotiertes Portlet")
+   }, shortTitle={
+      @LocaleString("Anno Portlet"),
+      @LocaleString(locale="DE", value="Ein Portlet")
+   }, keywords={
+      @LocaleString("One, Two, Three"),
+      @LocaleString(locale="DE", value="Eins, Zwei, Drei")
+   }, prefs = {
+      @Preference(name="aPref", values="aValue"),
+      @Preference(name="bPref", values="bValue")
+   },
+   publicParams = {"color", "aPrp"},
+   resourceBundle = "org.apache.pluto.container.om.portlet.GoodBundle",
+   roleRefs = {
+      @SecurityRoleRef(roleName="aRole", roleLink="aLink", description= {@LocaleString(locale="de", value="Beschreibung")})
+   }, supports = {
+      @Supports(mimeType="aMimeType", portletModes= {"aMode"}, windowStates= {"aWS"}),
+      @Supports(mimeType="aMimeType2", portletModes= {"aMode2"}, windowStates= {"aWS2"}),
+      @Supports(mimeType="mime-type3", portletModes= {"aMode3"}, windowStates= {"aWS3"})
+   }, supportedLocales = {"Locale1"},
+   cacheExpirationTime = 30,
+   cacheScopePublic = false,
+   runtimeOptions = {
+      @RuntimeOption(name="aRTO", values= {"true", "false"}),
+      @RuntimeOption(name="Runtime-Option2", values= {"value2"})
+   }, dependencies = {
+      @Dependency(name="Dojo", minVersion="3.1.4"),
+      @Dependency(name="AngularJS", minVersion="1.4.8")
+   }
+   
+)
+public class TestAnnotatedPortlet {
+   // add portlet methods
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
new file mode 100644
index 0000000..c8e47fe
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestMultiAnnotatedPortlet.java
@@ -0,0 +1,74 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+import javax.portlet.GenericPortlet;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+
+/**
+ * @author nick
+ *
+ */
+@PortletApplication(
+      defaultNamespaceURI="https://www.apache.org/",
+      resourceBundle="org.apache.pluto.container.om.portlet.GoodBundle",
+      version = "3.0"
+)
+@PortletConfigurations( {
+   @PortletConfiguration(portletName="Portlet1", 
+   initParams = {
+         @InitParameter(name="color", value="#cafeba"),
+      },
+      description={
+         @LocaleString("Portlet displaying the time in different time zones"),
+      }, displayName={
+         @LocaleString("Time Zone Clock Portlet"),
+      }, title={
+         @LocaleString("Annotated Portlet"),
+      }, shortTitle={
+         @LocaleString("Anno Portlet"),
+      }, keywords={
+         @LocaleString("One, Two, Three"),
+      }
+   ),
+   @PortletConfiguration(portletName="Portlet2", 
+   initParams = {
+         @InitParameter(name="color", value="#def"),
+      },
+      description={
+         @LocaleString(locale="de", value="Dieses Portlet zeigt die Zeit in verschiedenen Zeitzonen an")
+      }, displayName={
+         @LocaleString(locale="de", value="ZeitzonenPortlet")
+      }, title={
+         @LocaleString(locale="DE", value="Annotiertes Portlet")
+      }, shortTitle={
+         @LocaleString(locale="DE", value="Ein Portlet")
+      }, keywords={
+         @LocaleString(locale="DE", value="Eins, Zwei, Drei")
+      }
+   )
+})
+public class TestMultiAnnotatedPortlet extends GenericPortlet {
+   // add portlet methods
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestPortletAppAnnotatedClass.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestPortletAppAnnotatedClass.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestPortletAppAnnotatedClass.java
new file mode 100644
index 0000000..5212e52
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/fixtures/TestPortletAppAnnotatedClass.java
@@ -0,0 +1,118 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.fixtures;
+
+
+import javax.portlet.annotations.CustomPortletMode;
+import javax.portlet.annotations.CustomWindowState;
+import javax.portlet.annotations.EventDefinition;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletQName;
+import javax.portlet.annotations.PublicRenderParameterDefinition;
+import javax.portlet.annotations.RuntimeOption;
+import javax.portlet.annotations.UserAttribute;
+
+/**
+ * Test class annotated with @PortletAnnotation for testing the configuration
+ * reader.
+ * 
+ * @author Scott Nicklous
+ */
+@PortletApplication(
+      userAttributes = {
+         @UserAttribute(
+            description = @LocaleString("User Given Name"),
+            name = "user.name.given"
+         ),
+         @UserAttribute(
+            description = @LocaleString("User Last Name"),
+            name = "user.name.family"
+         ),
+         @UserAttribute(
+            description = @LocaleString("User eMail"),
+            name = "user.home-info.online.email"
+         ),
+         @UserAttribute(
+            description = @LocaleString("Company Organization"),
+            name = "user.business-info.postal.organization"
+         ),
+      },
+      runtimeOptions = {
+         @RuntimeOption(name = "javax.portlet.renderHeaders", values = "true"),    
+         @RuntimeOption(name = "runtime.option", values = "value")    
+      },
+      publicParams = {
+            @PublicRenderParameterDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "http:some.org/", 
+                        localPart = "imgName"),
+                  identifier = "imgName"
+                  ),
+            @PublicRenderParameterDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "http:some.org/", 
+                        localPart = "color"),
+                  identifier = "color",
+                  description = {@LocaleString("Some description.")},
+                  displayName = {@LocaleString("Company Organization")}
+                  ),
+      },
+      events = {
+            @EventDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "https://www.some.org/", 
+                        localPart = "supported-event"),
+                  payloadType = String.class),
+            @EventDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "https://www.some.org/", 
+                        localPart = "another-event"),
+                  payloadType = String.class,
+                  description = {@LocaleString("Some description.")},
+                  displayName = {@LocaleString("Company Organization")}
+                  )
+      },
+      defaultNamespaceURI="https://www.some.org/",
+      resourceBundle="org.apache.pluto.container.om.portlet.AnotherBundle",
+      version = "3.0",
+      customWindowStates = {
+            @CustomWindowState(description = {
+                  @LocaleString("Occupies 50% of the portal page"),
+                  @LocaleString(locale="de", value = "Verwendet 50% der Portal-Seite")
+            },
+            name = "half_page"),
+            @CustomWindowState(
+            name = "quarter_page")
+      },
+      customPortletModes={
+            @CustomPortletMode(description={
+                  @LocaleString("Provides administration functions"),
+                  @LocaleString(locale="de", value="Verwaltungsfunktionen")
+            }, 
+            name = "admin", 
+            portalManaged=true),
+            @CustomPortletMode(
+            name = "aMode", 
+            portalManaged=true) 
+})
+public class TestPortletAppAnnotatedClass {
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomPortletMode168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomPortletMode168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomPortletMode168ImplTest.java
index 436b1f4..dcfc35c 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomPortletMode168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomPortletMode168ImplTest.java
@@ -53,7 +53,7 @@ public class CustomPortletMode168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -85,7 +85,7 @@ public class CustomPortletMode168ImplTest {
       Locale loc = new Locale("de");
       Description d = cpm.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -117,9 +117,9 @@ public class CustomPortletMode168ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomWindowState168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomWindowState168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomWindowState168ImplTest.java
index 46f1b7f..14886ff 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomWindowState168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/CustomWindowState168ImplTest.java
@@ -53,7 +53,7 @@ public class CustomWindowState168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -85,7 +85,7 @@ public class CustomWindowState168ImplTest {
       Locale loc = new Locale("de");
       Description d = cws.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -117,9 +117,9 @@ public class CustomWindowState168ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletApplicationDefinition168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletApplicationDefinition168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletApplicationDefinition168ImplTest.java
index 316eccd..c1d7e2c 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletApplicationDefinition168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletApplicationDefinition168ImplTest.java
@@ -50,7 +50,7 @@ public class PortletApplicationDefinition168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletDefinition168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletDefinition168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletDefinition168ImplTest.java
index 34bbfc2..900105c 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletDefinition168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/PortletDefinition168ImplTest.java
@@ -52,7 +52,7 @@ public class PortletDefinition168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -90,7 +90,7 @@ public class PortletDefinition168ImplTest {
       Locale loc = new Locale("de");
       Description d = ip.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    @Test
@@ -250,7 +250,7 @@ public class PortletDefinition168ImplTest {
       assertEquals("role-link", srr.getRoleLink());
       Description d = srr.getDescription(new Locale("de"));
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
       
    }
 
@@ -303,7 +303,7 @@ public class PortletDefinition168ImplTest {
       Locale loc = new Locale("DE");
       Description desc = cut.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("multi line description", desc.getDescription());
+      assertEquals("multi line description", desc.getText());
    }
 
    @Test
@@ -311,7 +311,7 @@ public class PortletDefinition168ImplTest {
       List<Description> list = cut.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("multi line description", list.get(0).getDescription());
+      assertEquals("multi line description", list.get(0).getText());
    }
 
    @Test
@@ -326,9 +326,9 @@ public class PortletDefinition168ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("multi line description", desc.getDescription());
+            assertEquals("multi line description", desc.getText());
          }
       }
    }
@@ -338,7 +338,7 @@ public class PortletDefinition168ImplTest {
       Locale loc = new Locale("DE");
       DisplayName name = cut.getDisplayName(loc);
       assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
+      assertEquals("display-name", name.getText());
    }
 
    @Test
@@ -346,7 +346,7 @@ public class PortletDefinition168ImplTest {
       List<DisplayName> list = cut.getDisplayNames();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
+      assertEquals("display-name", list.get(0).getText());
    }
 
    @Test
@@ -361,9 +361,9 @@ public class PortletDefinition168ImplTest {
       assertEquals(2, list.size());
       for (DisplayName desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("display-name", desc.getDisplayName());
+            assertEquals("display-name", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/SecurityConstraint168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/SecurityConstraint168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/SecurityConstraint168ImplTest.java
index fc261da..d12e85b 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/SecurityConstraint168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/SecurityConstraint168ImplTest.java
@@ -36,7 +36,7 @@ public class SecurityConstraint168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -70,7 +70,7 @@ public class SecurityConstraint168ImplTest {
       Locale loc = new Locale("DE");
       DisplayName name = constraint.getDisplayName(loc);
       assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
+      assertEquals("display-name", name.getText());
    }
 
    @Test
@@ -78,7 +78,7 @@ public class SecurityConstraint168ImplTest {
       List<DisplayName> list = constraint.getDisplayNames();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
+      assertEquals("display-name", list.get(0).getText());
    }
 
    @Test
@@ -93,9 +93,9 @@ public class SecurityConstraint168ImplTest {
       assertEquals(2, list.size());
       for (DisplayName desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("display-name", desc.getDisplayName());
+            assertEquals("display-name", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserAttribute168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserAttribute168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserAttribute168ImplTest.java
index 327f465..48663a1 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserAttribute168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserAttribute168ImplTest.java
@@ -58,7 +58,7 @@ public class UserAttribute168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -94,7 +94,7 @@ public class UserAttribute168ImplTest {
       Locale loc = new Locale("DE");
       Description desc = ua.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
+      assertEquals("description", desc.getText());
    }
 
    /**
@@ -105,7 +105,7 @@ public class UserAttribute168ImplTest {
       List<Description> list = ua.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
+      assertEquals("description", list.get(0).getText());
    }
 
    /**
@@ -123,9 +123,9 @@ public class UserAttribute168ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserDataConstraint168ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserDataConstraint168ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserDataConstraint168ImplTest.java
index 7ce4d56..0881621 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserDataConstraint168ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr168/UserDataConstraint168ImplTest.java
@@ -34,7 +34,7 @@ public class UserDataConstraint168ImplTest {
       InputStream in = PortletApplicationDefinition168ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -66,7 +66,7 @@ public class UserDataConstraint168ImplTest {
       Locale loc = new Locale("DE");
       Description desc = udc.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
+      assertEquals("description", desc.getText());
    }
 
    /**
@@ -77,7 +77,7 @@ public class UserDataConstraint168ImplTest {
       List<Description> list = udc.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
+      assertEquals("description", list.get(0).getText());
    }
 
    /**
@@ -95,9 +95,9 @@ public class UserDataConstraint168ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomPortletMode286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomPortletMode286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomPortletMode286ImplTest.java
index f0d228d..8518f6b 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomPortletMode286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomPortletMode286ImplTest.java
@@ -53,7 +53,7 @@ public class CustomPortletMode286ImplTest {
       InputStream in = CustomPortletMode286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -97,7 +97,7 @@ public class CustomPortletMode286ImplTest {
       Locale loc = new Locale("de");
       Description d = cpm.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -129,9 +129,9 @@ public class CustomPortletMode286ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomWindowState286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomWindowState286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomWindowState286ImplTest.java
index 4985240..2c6fea5 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomWindowState286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/CustomWindowState286ImplTest.java
@@ -53,7 +53,7 @@ public class CustomWindowState286ImplTest {
       InputStream in = CustomWindowState286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -85,7 +85,7 @@ public class CustomWindowState286ImplTest {
       Locale loc = new Locale("de");
       Description d = cws.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -117,9 +117,9 @@ public class CustomWindowState286ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
index 9faab59..2c194b4 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletApplicationDefinition286ImplTest.java
@@ -91,7 +91,7 @@ public class PortletApplicationDefinition286ImplTest {
       InputStream in = PortletApplicationDefinition286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      cfp = new ConfigurationHolder(pad);
+      cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -436,8 +436,8 @@ public class PortletApplicationDefinition286ImplTest {
       Filter filter = cut.getFilters().get(0);
       assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter", 
             filter.getFilterClass());
-      assertEquals("description", filter.getDescription(new Locale("de")).getDescription());
-      assertEquals("display-name", filter.getDisplayName(new Locale("de")).getDisplayName());
+      assertEquals("description", filter.getDescription(new Locale("de")).getText());
+      assertEquals("display-name", filter.getDisplayName(new Locale("de")).getText());
       assertEquals("lifecycle", filter.getLifecycles().get(0));
       assertEquals("value", filter.getInitParam("name").getParamValue());
    }
@@ -460,8 +460,10 @@ public class PortletApplicationDefinition286ImplTest {
    @Test
    public void testAddFilter() {
       String newItem = "newFilter";
-      Filter prp = new FilterImpl(newItem);
-      cut.addFilter(prp);
+      String filCls = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass(filCls);
+      cut.addFilter(fil);
       
       List<Filter> list = cut.getFilters();
       assertNotNull(list);
@@ -499,8 +501,9 @@ public class PortletApplicationDefinition286ImplTest {
    @Test
    public void testAddFilterMapping() {
       String newItem = "newFilter";
-      FilterMapping prp = new FilterMappingImpl(newItem);
-      cut.addFilterMapping(prp);
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName("portlet286");
+      cut.addFilterMapping(fm);
       
       List<FilterMapping> list = cut.getFilterMappings();
       assertNotNull(list);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
index 62e6cd2..422fcb1 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/PortletDefinition286ImplTest.java
@@ -58,7 +58,7 @@ public class PortletDefinition286ImplTest {
       InputStream in = PortletDefinition286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -96,7 +96,7 @@ public class PortletDefinition286ImplTest {
       Locale loc = new Locale("de");
       Description d = ip.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    @Test
@@ -323,7 +323,7 @@ public class PortletDefinition286ImplTest {
       assertEquals("role-link", srr.getRoleLink());
       Description d = srr.getDescription(new Locale("de"));
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
       
    }
 
@@ -391,7 +391,7 @@ public class PortletDefinition286ImplTest {
       Locale loc = new Locale("DE");
       Description desc = cut.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("multi line description", desc.getDescription());
+      assertEquals("multi line description", desc.getText());
    }
 
    @Test
@@ -399,7 +399,7 @@ public class PortletDefinition286ImplTest {
       List<Description> list = cut.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("multi line description", list.get(0).getDescription());
+      assertEquals("multi line description", list.get(0).getText());
    }
 
    @Test
@@ -414,9 +414,9 @@ public class PortletDefinition286ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("multi line description", desc.getDescription());
+            assertEquals("multi line description", desc.getText());
          }
       }
    }
@@ -426,7 +426,7 @@ public class PortletDefinition286ImplTest {
       Locale loc = new Locale("DE");
       DisplayName name = cut.getDisplayName(loc);
       assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
+      assertEquals("display-name", name.getText());
    }
 
    @Test
@@ -434,7 +434,7 @@ public class PortletDefinition286ImplTest {
       List<DisplayName> list = cut.getDisplayNames();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
+      assertEquals("display-name", list.get(0).getText());
    }
 
    @Test
@@ -449,9 +449,9 @@ public class PortletDefinition286ImplTest {
       assertEquals(2, list.size());
       for (DisplayName desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("display-name", desc.getDisplayName());
+            assertEquals("display-name", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/SecurityConstraint286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/SecurityConstraint286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/SecurityConstraint286ImplTest.java
index a48c370..89792f4 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/SecurityConstraint286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/SecurityConstraint286ImplTest.java
@@ -36,7 +36,7 @@ public class SecurityConstraint286ImplTest {
       InputStream in = SecurityConstraint286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -70,7 +70,7 @@ public class SecurityConstraint286ImplTest {
       Locale loc = new Locale("DE");
       DisplayName name = constraint.getDisplayName(loc);
       assertNotNull(name);
-      assertEquals("display-name", name.getDisplayName());
+      assertEquals("display-name", name.getText());
    }
 
    @Test
@@ -78,7 +78,7 @@ public class SecurityConstraint286ImplTest {
       List<DisplayName> list = constraint.getDisplayNames();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("display-name", list.get(0).getDisplayName());
+      assertEquals("display-name", list.get(0).getText());
    }
 
    @Test
@@ -93,9 +93,9 @@ public class SecurityConstraint286ImplTest {
       assertEquals(2, list.size());
       for (DisplayName desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDisplayName());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("display-name", desc.getDisplayName());
+            assertEquals("display-name", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserAttribute286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserAttribute286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserAttribute286ImplTest.java
index 1d7e3c3..e2b1519 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserAttribute286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserAttribute286ImplTest.java
@@ -58,7 +58,7 @@ public class UserAttribute286ImplTest {
       InputStream in = UserAttribute286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -94,7 +94,7 @@ public class UserAttribute286ImplTest {
       Locale loc = new Locale("DE");
       Description desc = ua.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
+      assertEquals("description", desc.getText());
    }
 
    /**
@@ -105,7 +105,7 @@ public class UserAttribute286ImplTest {
       List<Description> list = ua.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
+      assertEquals("description", list.get(0).getText());
    }
 
    /**
@@ -123,9 +123,9 @@ public class UserAttribute286ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserDataConstraint286ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserDataConstraint286ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserDataConstraint286ImplTest.java
index fae0813..4af161e 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserDataConstraint286ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr286/UserDataConstraint286ImplTest.java
@@ -34,7 +34,7 @@ public class UserDataConstraint286ImplTest {
       InputStream in = UserDataConstraint286ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -66,7 +66,7 @@ public class UserDataConstraint286ImplTest {
       Locale loc = new Locale("DE");
       Description desc = udc.getDescription(loc);
       assertNotNull(desc);
-      assertEquals("description", desc.getDescription());
+      assertEquals("description", desc.getText());
    }
 
    /**
@@ -77,7 +77,7 @@ public class UserDataConstraint286ImplTest {
       List<Description> list = udc.getDescriptions();
       assertNotNull(list);
       assertEquals(1, list.size());
-      assertEquals("description", list.get(0).getDescription());
+      assertEquals("description", list.get(0).getText());
    }
 
    /**
@@ -95,9 +95,9 @@ public class UserDataConstraint286ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
    }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomPortletMode362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomPortletMode362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomPortletMode362ImplTest.java
index e78d3b9..4ed6065 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomPortletMode362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomPortletMode362ImplTest.java
@@ -36,7 +36,6 @@ import org.junit.Test;
 
 /**
  * @author Scott Nicklous
- *
  */
 public class CustomPortletMode362ImplTest {
 
@@ -53,7 +52,7 @@ public class CustomPortletMode362ImplTest {
       InputStream in = CustomPortletMode362ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -97,7 +96,7 @@ public class CustomPortletMode362ImplTest {
       Locale loc = new Locale("de");
       Description d = cpm.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -129,9 +128,9 @@ public class CustomPortletMode362ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomWindowState362ImplTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomWindowState362ImplTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomWindowState362ImplTest.java
index 3c591d1..59ec66c 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomWindowState362ImplTest.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/CustomWindowState362ImplTest.java
@@ -53,7 +53,7 @@ public class CustomWindowState362ImplTest {
       InputStream in = CustomWindowState362ImplTest.class
             .getClassLoader().getResourceAsStream(XML_FILE);
       
-      ConfigurationHolder cfp = new ConfigurationHolder(pad);
+      ConfigurationHolder cfp = new ConfigurationHolder();
       try {
          cfp.processPortletDD(in);
          pad = cfp.getPad();
@@ -85,7 +85,7 @@ public class CustomWindowState362ImplTest {
       Locale loc = new Locale("de");
       Description d = cws.getDescription(loc);
       assertNotNull(d);
-      assertEquals("description", d.getDescription());
+      assertEquals("description", d.getText());
    }
 
    /**
@@ -117,9 +117,9 @@ public class CustomWindowState362ImplTest {
       assertEquals(2, list.size());
       for (Description desc : list) {
          if (desc.getLocale().equals(loc)) {
-            assertEquals(text, desc.getDescription());
+            assertEquals(text, desc.getText());
          } else {
-            assertEquals("description", desc.getDescription());
+            assertEquals("description", desc.getText());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/ExtendingPortletInterfaceAnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/ExtendingPortletInterfaceAnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/ExtendingPortletInterfaceAnnotationTest.java
new file mode 100644
index 0000000..d1027c6
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/ExtendingPortletInterfaceAnnotationTest.java
@@ -0,0 +1,266 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.Description;
+import org.apache.pluto.container.om.portlet.InitParam;
+import org.apache.pluto.container.om.portlet.LocaleText;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.PortletInfo;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
+import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedGenericPortlet;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for a portlet configuration annotation applied to a class
+ * that extends the Portlet interface.
+ * <p>
+ * Test Class: TestAnnotatedGenericPortlet
+ * 
+ * @author Scott Nicklous
+ */
+public class ExtendingPortletInterfaceAnnotationTest {
+
+   private static final Class<?>               TEST_ANNOTATED_CLASS = TestAnnotatedGenericPortlet.class;
+
+   private static PortletApplicationDefinition pad;
+
+   // Class under test
+   private PortletDefinition                   cut;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertEquals(1, pad.getPortlets().size());
+      cut = new PortletDefinitionImpl(pad.getPortlets().get(0));
+   }
+
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(cut.getPortletName());
+      assertEquals("Annotated Generic Portlet", cut.getPortletName());
+   }
+
+   @Test
+   public void testGetApplication() {
+      assertNotNull(cut.getApplication());
+      assertTrue(cut.getApplication() instanceof PortletApplicationDefinition);
+   }
+
+   @Test
+   public void testGetInitParam() {
+      String name = "AnnoName";
+      String val = "value";
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(val, ip.getParamValue());
+      assertEquals(1, ip.getDescriptions().size());
+      Locale loc = new Locale("de");
+      Description d = ip.getDescription(loc);
+      assertNotNull(d);
+      assertEquals("Beschreibung", d.getText());
+   }
+
+   @Test
+   public void testGetInitParamNullValue() {
+      InitParam ip = cut.getInitParam("nullValueParam");
+      assertNotNull(ip);
+      assertEquals("nullValueParam", ip.getParamName());
+      assertEquals("", ip.getParamValue());
+   }
+
+   @Test
+   public void testGetInitParams() {
+      String name = "AnnoName";
+      String name2 = "ipname";
+      String val = "value";
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(3, ips.size());
+      
+      InitParam ip = new InitParamImpl(name, val);
+      assertTrue(ips.contains(ip));
+      ip = new InitParamImpl(name2, val);
+      assertTrue(ips.contains(ip));
+      
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNotNull(cut.getPortletClass());
+      assertEquals(TEST_ANNOTATED_CLASS.getCanonicalName(), cut.getPortletClass());
+   }
+
+   @Test
+   public void testGetTitle() {
+      String txt1 = "Annotated Portlet";
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddTitle() {
+      String txt1 = "Annotated Portlet";
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(3, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupTitle() {
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetShortTitle() {
+      String txt1 = "Anno Portlet";
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddShortTitle() {
+      String txt1 = "Anno Portlet";
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(3, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupShortTitle() {
+      String txt2 = "Ein Portlet";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Short Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetKeywords() {
+      String txt1 = "One, Two, Three";
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddKeywords() {
+      String txt1 = "One, Two, Three";
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(3, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testAddDupKeywords() {
+      String txt1 = "One, Two, Three";
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "andre Schlagwörter";
+      LocaleText lt = new LocaleTextImpl(Locale.GERMAN, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.GERMAN).getText());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletAppAnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletAppAnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletAppAnnotationTest.java
new file mode 100644
index 0000000..2f5d2b4
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletAppAnnotationTest.java
@@ -0,0 +1,385 @@
+/*  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.some.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.CustomPortletMode;
+import org.apache.pluto.container.om.portlet.CustomWindowState;
+import org.apache.pluto.container.om.portlet.EventDefinition;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PublicRenderParameter;
+import org.apache.pluto.container.om.portlet.UserAttribute;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.CustomPortletModeImpl;
+import org.apache.pluto.container.om.portlet.impl.CustomWindowStateImpl;
+import org.apache.pluto.container.om.portlet.impl.EventDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PublicRenderParameterImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortletAppAnnotatedClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class JSR362PortletAppAnnotationTest {
+   
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestPortletAppAnnotatedClass.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for version from annotation
+    */
+   @Test
+   public void testGetVersion() {
+      String val = cut.getVersion();
+      assertEquals("3.0", val);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getResourceBundle()}.
+    */
+   @Test
+   public void testGetResourceBundle() {
+      String val = cut.getResourceBundle();
+      assertEquals("org.apache.pluto.container.om.portlet.AnotherBundle", val);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getDefaultNamespace()}.
+    */
+   @Test
+   public void testGetDefaultNamespace() {
+      String val = cut.getDefaultNamespace();
+      assertEquals("https://www.some.org/", val);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getEventDefinitions()}.
+    */
+   @Test
+   public void testGetEventDefinitions() {
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      boolean ok = false;
+      QName qn = new QName("https://www.some.org/", "supported-event");
+      for (EventDefinition item : list) {
+         if (item.getQName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getEventDefinition(javax.xml.namespace.QName)}.
+    */
+   @Test
+   public void testGetEventDefinition() {
+      QName qn = new QName("https://www.some.org/", "supported-event");
+      EventDefinition item = cut.getEventDefinition(qn);
+      assertNotNull(item);
+      assertEquals(qn, item.getQName());
+
+      qn = new QName("https://www.some.org/", "another-event");
+      item = cut.getEventDefinition(qn);
+      assertNotNull(item);
+      assertEquals(qn, item.getQName());
+      assertNotNull(item.getDescription(Locale.ENGLISH));
+      assertEquals("Some description.", item.getDescription(Locale.ENGLISH).getText());
+      assertNotNull(item.getDisplayName(Locale.ENGLISH));
+      assertEquals("Company Organization", item.getDisplayName(Locale.ENGLISH).getText());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addEventDefinition(org.apache.pluto.container.om.portlet.EventDefinition)}.
+    */
+   @Test
+   public void testAddEventDefinition() {
+      QName qn = new QName("https://www.ibm.com/", "some-other-event");
+      EventDefinition ed = new EventDefinitionImpl(qn);
+      cut.addEventDefinition(ed);
+
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      boolean ok = false;
+      for (EventDefinition item : list) {
+         if (item.getQName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getPublicRenderParameter(java.lang.String)}.
+    */
+   @Test
+   public void testGetPublicRenderParameter() {
+      String prpid = "imgName";
+      PublicRenderParameter prp = cut.getPublicRenderParameter(prpid);
+      assertNotNull(prp);
+      assertEquals(prpid, prp.getIdentifier());
+      assertEquals(prpid, prp.getQName().getLocalPart());
+      assertEquals("http:some.org/", prp.getQName().getNamespaceURI());
+
+      prpid = "color";
+      prp = cut.getPublicRenderParameter(prpid);
+      assertNotNull(prp);
+      assertEquals(prpid, prp.getIdentifier());
+      assertEquals(prpid, prp.getQName().getLocalPart());
+      assertEquals("http:some.org/", prp.getQName().getNamespaceURI());
+      assertNotNull(prp.getDescription(Locale.ENGLISH));
+      assertEquals("Some description.", prp.getDescription(Locale.ENGLISH).getText());
+      assertNotNull(prp.getDisplayName(Locale.ENGLISH));
+      assertEquals("Company Organization", prp.getDisplayName(Locale.ENGLISH).getText());
+      
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getPublicRenderParameters()}.
+    */
+   @Test
+   public void testGetPublicRenderParameters() {
+      String prpid = "imgName";
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(2, prps.size());
+      assertEquals(prpid, prps.get(0).getIdentifier());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addPublicRenderParameter(org.apache.pluto.container.om.portlet.PublicRenderParameter)}.
+    */
+   @Test
+   public void testAddPublicRenderParameter() {
+      String prpid = "newprp";
+      QName qn = new QName("https://www.ibm.com/", "some-other-prp");
+      PublicRenderParameter prp = new PublicRenderParameterImpl(qn, prpid);
+      cut.addPublicRenderParameter(prp);
+      
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(3, prps.size());
+      assertEquals(prpid, prps.get(2).getIdentifier());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomPortletMode(java.lang.String)}.
+    */
+   @Test
+   public void testGetCustomPortletMode() {
+      String newItem = "admin";
+      CustomPortletMode item = cut.getCustomPortletMode(newItem);
+      assertNotNull(item);
+      assertTrue(item.isPortalManaged());
+      assertNotNull(item.getDescription(Locale.GERMAN));
+      assertEquals("Verwaltungsfunktionen", item.getDescription(Locale.GERMAN).getText());
+  }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomPortletModes()}.
+    */
+   @Test
+   public void testGetCustomPortletModes() {
+      String newItem = "admin";
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getPortletMode());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addCustomPortletMode(org.apache.pluto.container.om.portlet.CustomPortletMode)}.
+    */
+   @Test
+   public void testAddCustomPortletMode() {
+      String newItem = "newMode";
+      CustomPortletMode pm = new CustomPortletModeImpl(newItem);
+      cut.addCustomPortletMode(pm);
+      
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(list.contains(pm));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomWindowState(java.lang.String)}.
+    */
+   @Test
+   public void testGetCustomWindowState() {
+      String newItem = "half_page";
+      CustomWindowState item = cut.getCustomWindowState(newItem);
+      assertNotNull(item);
+      assertNotNull(item.getDescription(Locale.GERMAN));
+      assertEquals("Verwendet 50% der Portal-Seite", item.getDescription(Locale.GERMAN).getText());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getCustomWindowStates()}.
+    */
+   @Test
+   public void testGetCustomWindowStates() {
+      String newItem = "half_page";
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertTrue(list.contains(new CustomWindowStateImpl(newItem)));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addCustomWindowState(org.apache.pluto.container.om.portlet.CustomWindowState)}.
+    */
+   @Test
+   public void testAddCustomWindowState() {
+      String newItem = "newWindowState";
+      CustomWindowState prp = new CustomWindowStateImpl(newItem);
+      cut.addCustomWindowState(prp);
+      
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertEquals(newItem, list.get(2).getWindowState());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getUserAttribute(java.lang.String)}.
+    */
+   @Test
+   public void testGetUserAttribute() {
+      String newItem = "user.name.given";
+      UserAttribute item = cut.getUserAttribute(newItem);
+      assertNotNull(item);
+      assertEquals("User Given Name",  item.getDescription(Locale.ENGLISH).getText());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getUserAttributes()}.
+    */
+   @Test
+   public void testGetUserAttributes() {
+      String newItem = "user.name.given";
+      List<UserAttribute> list = cut.getUserAttributes();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      assertEquals(newItem, list.get(0).getName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getContainerRuntimeOption(java.lang.String)}.
+    */
+   @Test
+   public void testGetContainerRuntimeOption() {
+      String newItem = "javax.portlet.renderHeaders";
+      ContainerRuntimeOption item = cut.getContainerRuntimeOption(newItem);
+      assertEquals("true", item.getValues().get(0));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getContainerRuntimeOptions()}.
+    */
+   @Test
+   public void testGetContainerRuntimeOptions() {
+      String newItem = "javax.portlet.renderHeaders";
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(0).getName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addLocaleEncodingMapping(java.util.Locale, java.lang.String)}.
+    */
+   @Test
+   public void testAddLocaleEncodingMapping() {
+      ArrayList<Locale> testlocs = new ArrayList<Locale>(Arrays.asList(new Locale[]{
+            Locale.forLanguageTag("de"), Locale.forLanguageTag("ja") }));
+      String[] testencs = {"UTF-8", "Shift_JIS"};
+      for (Locale loc : testlocs) {
+         int ind = testlocs.indexOf(loc);
+         cut.addLocaleEncodingMapping(loc, testencs[ind]);
+      }
+      
+      Map<Locale, String> localemap = cut.getLocaleEncodingMappings();
+      assertEquals(2, localemap.size());
+      for (Locale loc : localemap.keySet()) {
+         assertTrue(testlocs.contains(loc));
+         int ind = testlocs.indexOf(loc);
+         assertEquals(testencs[ind], localemap.get(loc));
+      }
+   }
+   
+   /**
+    * Make sure validate() throws no exceptions
+    */
+   @Test
+   public void testValidate() {
+         cfp.validate();
+   }
+
+}


[24/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 4ee9954..891259b 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -18,13 +18,17 @@
 
 package org.apache.pluto.container.om.portlet.impl;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
 import javax.portlet.Portlet;
 import javax.portlet.PortletRequest;
 import javax.portlet.PortletURLGenerationListener;
@@ -44,10 +48,17 @@ import javax.portlet.filter.EventFilter;
 import javax.portlet.filter.HeaderFilter;
 import javax.portlet.filter.RenderFilter;
 import javax.portlet.filter.ResourceFilter;
-import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
 
+import org.apache.pluto.container.bean.processor.AnnotatedMethod;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.MethodType;
+
+import static org.apache.pluto.container.bean.processor.MethodDescription.*;
+
+import org.apache.pluto.container.bean.processor.MethodDescription;
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
 import org.apache.pluto.container.om.portlet.CustomPortletMode;
 import org.apache.pluto.container.om.portlet.CustomWindowState;
@@ -111,9 +122,9 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
    /** Logger. */
    private static final Logger  LOG     = LoggerFactory.getLogger(JSR362ConfigurationProcessor.class);
-   // private static final boolean isDebug = LOG.isDebugEnabled();
+   private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean isTrace = LOG.isTraceEnabled();
-
+   
    // For holding the preference validators while the portlet configuration
    // annotations are being processed.
    private Map<PortletPreferencesValidator, String> prefValidators =
@@ -160,8 +171,6 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
       if (app.getDefaultNamespace() != null && !app.getDefaultNamespace().equals("")) {
          pad.setDefaultNamespace(app.getDefaultNamespace());
-      } else {
-         pad.setDefaultNamespace(XMLConstants.NULL_NS_URI);
       }
 
       if (app.getResourceBundle() != null && app.getResourceBundle().getValue() != null
@@ -348,11 +357,11 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
          // validate data. Empty class allowed if annotated config present
          if ((name == null) || (name.length() == 0) || (pad.getListener(name) == null)) {
-         if (item.getListenerClass() == null || item.getListenerClass().length() == 0) {
-            String warning = "Bad Listener definition. Class was null.";
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
+            if (item.getListenerClass() == null || item.getListenerClass().length() == 0) {
+               String warning = "Bad Listener definition. Class was null.";
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
          }
          
          if (name == null || name.length() == 0) {
@@ -368,7 +377,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          for (DisplayName dispName : handleDisplayNames(item.getDisplayName())) {
             newitem.addDisplayName(dispName);
          }
-
+         
          newitem.setOrdinal((item.getOrdinal() == null) ? 0 : item.getOrdinal());
 
          newitem.setListenerName(name);
@@ -816,7 +825,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
                   newprefs.setPreferencesValidator(clsName);
                }
             }
-
+            
             for (Preference p : handlePreferences(prefs.getPreference())) {
                newprefs.addPreference(p);
             }
@@ -976,8 +985,12 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       pad.setVersion(app.version());
 
       // default namespace & resource bundle
-      pad.setDefaultNamespace(app.defaultNamespaceURI());
-      pad.setResourceBundle(app.resourceBundle());
+      if (app.defaultNamespaceURI().length() > 0) {
+         pad.setDefaultNamespace(app.defaultNamespaceURI());
+      }
+      if (app.resourceBundle().length() > 0) {
+         pad.setResourceBundle(app.resourceBundle());
+      }
 
       // runtime options
       for (RuntimeOption ro : app.runtimeOptions()) {
@@ -1012,7 +1025,11 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
       // Event defs
       for (javax.portlet.annotations.EventDefinition ed : app.events()) {
-         QName qn = new QName(ed.qname().namespaceURI(), ed.qname().localPart());
+         String nsuri = ed.qname().namespaceURI();
+         if (nsuri.length() == 0) {
+            nsuri = pad.getDefaultNamespace();
+         }
+         QName qn = new QName(nsuri, ed.qname().localPart());
          EventDefinition evt = new EventDefinitionImpl(qn);
          for (LocaleString ls : ed.description()) {
             Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
@@ -1022,7 +1039,9 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
             evt.addDisplayName(d);
          }
-         evt.setValueType(ed.payloadType().getCanonicalName());
+         if (!ed.payloadType().equals(void.class)) {
+            evt.setValueType(ed.payloadType().getCanonicalName());
+         }
          pad.addEventDefinition(evt);
       }
 
@@ -1093,7 +1112,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
          // prepare the filter definition
          String clsName = cls.getCanonicalName();
-         String fn = prf.filterName();
+           String fn = prf.filterName();
          if (fn.length() == 0) {
             fn = genUniqueName();
          }
@@ -1372,4 +1391,254 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       }
    }
 
+   @Override
+   public void reconcileBeanConfig(AnnotatedMethodStore ams) {
+
+      ams.setDefaultNamespace(pad.getDefaultNamespace());
+      
+      for (String pn : ams.getPortletNames()) {
+         
+         PortletDefinition pd = pad.getPortlet(pn);
+         if (pd == null) {
+            pd = new PortletDefinitionImpl(pn, pad);
+         }
+         
+         List<EventDefinitionReference> edrs = pd.getSupportedProcessingEvents();
+         for (QName qn : ams.getProcessingEventRefs(pn)) {
+            EventDefinition ed = pad.getEventDefinition(qn);
+            if (ed == null) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("No event definition found for annotated processing event reference.");
+               txt.append(" Portlet name: ").append(pn);
+               txt.append(", QName: ").append(qn);
+               LOG.warn(txt.toString());
+               
+               // remove the defective method from the store
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), qn, MethodType.EVENT);
+               ams.removeMethod(mi);
+               
+               continue;
+            }
+            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
+            if (!edrs.contains(newedr)) {
+               pd.addSupportedProcessingEvent(newedr);
+            }
+         }
+         
+         edrs = pd.getSupportedPublishingEvents();
+         for (QName qn : ams.getPublishingEventRefs(pn)) {
+            EventDefinition ed = pad.getEventDefinition(qn);
+            if (ed == null) {
+               StringBuilder txt = new StringBuilder(128);
+               txt.append("No event definition found for annotated publishing event reference.");
+               txt.append(" Portlet name: ").append(pn);
+               txt.append(", QName: ").append(qn);
+               LOG.warn(txt.toString());
+               continue;
+            }
+            EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qn);
+            if (!edrs.contains(newedr)) {
+               pd.addSupportedPublishingEvent(newedr);
+            }
+         }
+         
+         pad.addPortlet(pd);
+      }
+      
+      // Now add the declared portlet class methods to the store
+      
+      List<PortletDefinition> badPortlets = new ArrayList<PortletDefinition>();
+      for (PortletDefinition pd : pad.getPortlets()) {
+         Class<?> cls = null;
+
+         String clsName = pd.getPortletClass();
+         if (isValidIdentifier(clsName)) {
+            
+            // Make sure the class can be loaded
+            Class<?> valClass = null;
+            StringBuilder txt = new StringBuilder(128);
+            try {
+               ClassLoader cl = Thread.currentThread().getContextClassLoader();
+               if (cl == null) {
+                  cl = this.getClass().getClassLoader();
+               }
+               valClass = cl.loadClass(clsName);
+               if (Portlet.class.isAssignableFrom(valClass)) {
+                  cls = valClass;
+               } else {
+                  txt.append("Specified portlet class does not implement the Portlet interface.");
+               }
+            } catch (Exception e) {
+               txt.append("Specified portlet class could not be loaded.");
+            } finally {
+               if (cls == null) {
+                  txt.append(" Portlet name: ").append(pd.getPortletName());
+                  txt.append(", Portlet class: ").append(clsName);
+                  LOG.warn(txt.toString());
+               }
+            }
+         }
+         
+         Object instance = null;
+         if (cls != null) {
+            
+            // Let CDI instantiate the portlet to allow for injection. 
+            // Get the single bean instance for the portlet class.
+            
+            StringBuilder txt = new StringBuilder(128);
+            BeanManager bm = ams.getBeanMgr();
+            if (bm == null) {
+               txt.append("Could not instantiate portlet class. Bean manager is null.");
+            } else {
+               Set<Bean<?>> beans = bm.getBeans(cls);
+               if (beans == null || beans.size() == 0) {
+                  txt.append("Could not instantiate portlet class. No beans found.");
+               } else {
+                  Bean<?> bean = bm.resolve(beans);
+                  if (bean == null) {
+                     txt.append("Could not instantiate portlet class. Could not resolve bean.");
+                  } else {
+                     instance = bm.getReference(bean, bean.getBeanClass(), bm.createCreationalContext(bean));
+                     if (instance == null) {
+                        txt.append("Could not instantiate portlet class. Could not get bean instance.");
+                     }
+                  }
+               }
+            }
+            
+            if (txt.length() > 0) {
+               txt.append(" Portlet name: ").append(pd.getPortletName());
+               txt.append(", portlet class: ").append(cls);
+               LOG.warn(txt.toString());
+            }
+         }
+
+         if (instance != null) {
+            
+            // The annotated method store might contain methods from the configured
+            // portlet class being processed. For example, this may occur when an action
+            // or event method in the portlet class is annotated to specify processing or
+            // publishing event references. Such annotated methods must use the same bean
+            // instance, so fix up the method store.
+            
+            ams.setPortletClassInstance(cls, instance);
+
+            // extract the methods from the portlet class and add them to the method store
+            // as long there is no corresponding annotated method already present.
+            // (annotated methods take precedence over portlet class methods). 
+            
+            AnnotatedMethod am;
+            am = getMethod(instance, "init", METH_INI);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.INIT);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "destroy", METH_DES);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.DESTROY);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "processAction", METH_ACT);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.ACTION);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "processEvent", METH_EVT);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.EVENT);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "render", METH_REN);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RENDER);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "renderHeaders", METH_HDR);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.HEADER);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+            
+            am = getMethod(instance, "serveResource", METH_RES);
+            if (am != null) {
+               MethodIdentifier mi = new MethodIdentifier(pd.getPortletName(), "", MethodType.RESOURCE);
+               if (ams.getMethods(mi).size() == 0) {
+                  ams.addMethod(mi, am);
+               }
+            }
+
+         }
+         
+         // and finally make sure that the portlet has at least one render, header, or serveResource
+         // method. If not, delete it.
+         
+         boolean methodsOK = false;
+         for (MethodIdentifier mi : ams.getMethodIDsForPortlet(pd.getPortletName())) {
+            if ((mi.getType() == MethodType.RENDER) || (mi.getType() == MethodType.RESOURCE) ||
+                  (mi.getType() == MethodType.HEADER)) {
+               methodsOK = true;
+               break;
+            }
+         }
+         if (!methodsOK) {
+            
+            ams.removeMethodsForPortlet(pd.getPortletName());
+            badPortlets.add(pd);
+            
+            StringBuilder txt = new StringBuilder();
+            txt.append("Portlet does not have a render, resource, or header method, so cannot be taken into service. ");
+            txt.append("Portlet name: ").append(pd.getPortletName());
+            LOG.warn(txt.toString());
+         }
+      }
+      
+      // if there are bad portlets, delete them from the config
+      for (PortletDefinition pd : badPortlets) {
+         pad.removePortlet(pd);
+      }
+      
+   }
+   
+   /**
+    * helper method for extracting the portlet methods from the portlet class.
+    * @param cls
+    * @param name
+    * @param md
+    * @return
+    */
+   private AnnotatedMethod getMethod(Object instance, String name, MethodDescription md) {
+      AnnotatedMethod am = null;
+      Class<?> cls = instance.getClass();
+      try {
+         Method meth = cls.getMethod(name, md.getArgTypes());
+         am = new AnnotatedMethod(cls, instance, meth, md);
+      } catch (Exception e) {
+         if (isDebug) {
+            StringBuilder txt = new StringBuilder();
+            txt.append("Could not retrieve method from portlet class.");
+            txt.append(" Method name: ").append(name);
+            txt.append(", Class: ").append(cls.getCanonicalName());
+            txt.append(", Argument types: ").append(md.getArgTypes());
+            LOG.debug(txt.toString());
+         }
+      }
+      return am;
+   }
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
index 722d5c2..be2708f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
+import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
 
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
@@ -214,7 +215,7 @@ public class PortletApplicationDefinitionImpl implements
     */
    @Override
    public String getDefaultNamespace() {
-      return defaultNamespace;
+      return (defaultNamespace == null) ? XMLConstants.NULL_NS_URI : defaultNamespace;
    }
 
    /* (non-Javadoc)
@@ -270,7 +271,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       portlets.add( pd);
    }
-   
+
    @Override
    public boolean removePortlet(PortletDefinition pd) {
       return portlets.remove(pd);
@@ -303,7 +304,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       events.add(ed);
    }
-   
+
    @Override
    public boolean removeEventDefinition(EventDefinition ed) {
       return events.remove(ed);
@@ -345,7 +346,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       prps.add(prp);
    }
-   
+
    @Override
    public boolean removePublicRenderParameter(PublicRenderParameter prp) {
       return prps.remove(prp);
@@ -378,7 +379,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       cpms.add(cpm);
    }
-   
+
    @Override
    public boolean removeCustomPortletMode(CustomPortletMode pm) {
       return cpms.remove(pm);
@@ -411,7 +412,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       cwss.add(cws);
    }
-   
+
    @Override
    public boolean removeCustomWindowState(CustomWindowState ws) {
       return cwss.remove(ws);
@@ -444,7 +445,7 @@ public class PortletApplicationDefinitionImpl implements
       }
       uattrs.add(ua);
    }
-   
+
    @Override
    public boolean removeUserAttribute(UserAttribute ua) {
       return uattrs.remove(ua);
@@ -491,7 +492,7 @@ public class PortletApplicationDefinitionImpl implements
          removeFilterMapping(getFilterMapping(filter.getFilterName()));
       }
    }
-   
+
    @Override
    public boolean removeFilter(Filter filter) {
       return filters.remove(filter);
@@ -529,7 +530,7 @@ public class PortletApplicationDefinitionImpl implements
          LOG.debug("No portlet names for filter mapping. Filter name: " + fm.getFilterName());
       }
    }
-   
+
    @Override
    public boolean removeFilterMapping(FilterMapping fm) {
       return fmaps.remove(fm);
@@ -562,12 +563,12 @@ public class PortletApplicationDefinitionImpl implements
       }
       cros.add(cro);
    }
-   
+
    @Override
    public boolean removeRuntimeOption(ContainerRuntimeOption cro) {
       return cros.remove(cro);
    }
-
+   
    @Override
    public Listener getListener(String name) {
       for (Listener l : listeners) {
@@ -604,13 +605,13 @@ public class PortletApplicationDefinitionImpl implements
       } else {
 
          // If the listener class is null, remove the listener definition, otherwise replace it
-      if (listeners.remove(listener)) {
+         if (listeners.remove(listener)) {
             LOG.debug("Removed duplicate listener for class: " + listener.getListenerClass());
-      }
+         } 
       } 
       
       if (listener.getListenerClass() != null && listener.getListenerClass().length() > 0) {
-      listeners.add(listener);
+         listeners.add(listener);
          // sort by ordinal. for JSR286 portlets, the ordinal will always be 0, so
          // the list will remain in the original order.
          Collections.sort(listeners, new ListenerComparator());
@@ -618,7 +619,7 @@ public class PortletApplicationDefinitionImpl implements
          LOG.debug("No listener class for listener: " + listener.getListenerName());
       }
    }
-   
+
    @Override
    public boolean removeListener(Listener listener) {
       return listeners.remove(listener);

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/java/org/apache/pluto/container/util/ClasspathScanner.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/util/ClasspathScanner.java b/pluto-container/src/main/java/org/apache/pluto/container/util/ClasspathScanner.java
index 79a18ec..090a58e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/util/ClasspathScanner.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/util/ClasspathScanner.java
@@ -1,116 +1,115 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.util;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClasspathScanner {
-
-    private static final Logger LOG = LoggerFactory.getLogger(ClasspathScanner.class);
-
-    /**
-     * Retrieve a lit of all urls matching the specified
-     * path.
-     *
-     * @param path
-     * @throws IOException
-     */
-    public static List<URL> scan(String path) throws IOException {
-        List<URL> list = scan(path, ClasspathScanner.class.getClassLoader());
-        list.addAll(scan(path, Thread.currentThread().getContextClassLoader()));
-        list.add(ClasspathScanner.class.getResource(path));
-
-        if(LOG.isInfoEnabled()) {
-            LOG.info("Found "+list.size()+" resources for path '"+path+"'.");
-        }
-
-        return list;
-    }
-
-    /**
-     * Retrieve a list of all urls massing the specified path
-     * for the specified classloader.
-     *
-     * @param path
-     * @param loader
-     * @throws IOException
-     */
-    public static List<URL> scan(String path, ClassLoader loader) throws IOException {
-        ArrayList<URL> list = new ArrayList<URL>();
-        if (loader == null) {
-            return list;
-        }
-
-        Enumeration<URL> enumeration = loader.getResources(path);
-        while (enumeration.hasMoreElements()) {
-            list.add(enumeration.nextElement());
-        }
-        return list;
-    }
-
-    /**
-     * Mechanism for finding all implementations of the specified
-     * interface.  This method is used for resolving low level
-     * implementations of interfaces needed by static and/or non
-     * services.  These implementations are not bound to their
-     * container, but instead, are bound to the global application
-     * environment.
-     *
-     * @param implemented interface implemnted by configured impls
-     * @return list of classes
-     * @throws java.io.IOException if an error occurs during classpath scanning.
-     */
-    @SuppressWarnings("unchecked")
-    public static List findConfiguredImplementations(Class implemented)
-    throws IOException {
-        List classes = new ArrayList();
-        List resources = scan("/META-INF/pluto.properties");
-        Iterator i = resources.iterator();
-
-        Properties p = new Properties();
-        while (i.hasNext()) {
-            URL url = (URL) i.next();
-            p.load(url.openStream());
-            String impl = p.getProperty(implemented.getName());
-            if (impl != null) {
-                StringTokenizer st = new StringTokenizer(impl, ",", false);
-                while (st.hasMoreTokens()) {
-                    String token = st.nextToken().trim();
-                    if (token.length() > 0) {
-                        try {
-                            classes.add(Class.forName(token));
-                        } catch (ClassNotFoundException cnfe) {
-                            LOG.warn("Unable to find configured implementation " + impl + " of interface " + implemented.getName());
-                        }
-                    }
-                }
-            }
-            p.clear();
-        }
-        return classes;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.util;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClasspathScanner {
+
+    private static final Logger LOG = LoggerFactory.getLogger(ClasspathScanner.class);
+
+    /**
+     * Retrieve a lit of all urls matching the specified
+     * path.
+     *
+     * @param path
+     * @throws IOException
+     */
+    public static List<URL> scan(String path) throws IOException {
+        List<URL> list = scan(path, ClasspathScanner.class.getClassLoader());
+        list.addAll(scan(path, Thread.currentThread().getContextClassLoader()));
+        list.add(ClasspathScanner.class.getResource(path));
+
+        if(LOG.isInfoEnabled()) {
+            LOG.info("Found "+list.size()+" resources for path '"+path+"'.");
+        }
+
+        return list;
+    }
+
+    /**
+     * Retrieve a list of all urls massing the specified path
+     * for the specified classloader.
+     *
+     * @param path
+     * @param loader
+     * @throws IOException
+     */
+    public static List<URL> scan(String path, ClassLoader loader) throws IOException {
+        ArrayList<URL> list = new ArrayList<URL>();
+        if (loader == null) {
+            return list;
+        }
+
+        Enumeration<URL> enumeration = loader.getResources(path);
+        while (enumeration.hasMoreElements()) {
+            list.add(enumeration.nextElement());
+        }
+        return list;
+    }
+
+    /**
+     * Mechanism for finding all implementations of the specified
+     * interface.  This method is used for resolving low level
+     * implementations of interfaces needed by static and/or non
+     * services.  These implementations are not bound to their
+     * container, but instead, are bound to the global application
+     * environment.
+     *
+     * @param implemented interface implemnted by configured impls
+     * @return list of classes
+     * @throws java.io.IOException if an error occurs during classpath scanning.
+     */
+    public static List<Class<?>> findConfiguredImplementations(Class<?> implemented)
+    throws IOException {
+        List<Class<?>> classes = new ArrayList<Class<?>>();
+        List<URL> resources = scan("/META-INF/pluto.properties");
+        Iterator<URL> i = resources.iterator();
+
+        Properties p = new Properties();
+        while (i.hasNext()) {
+            URL url = (URL) i.next();
+            p.load(url.openStream());
+            String impl = p.getProperty(implemented.getName());
+            if (impl != null) {
+                StringTokenizer st = new StringTokenizer(impl, ",", false);
+                while (st.hasMoreTokens()) {
+                    String token = st.nextToken().trim();
+                    if (token.length() > 0) {
+                        try {
+                            classes.add(Class.forName(token));
+                        } catch (ClassNotFoundException cnfe) {
+                            LOG.warn("Unable to find configured implementation " + impl + " of interface " + implemented.getName());
+                        }
+                    }
+                }
+            }
+            p.clear();
+        }
+        return classes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/pluto-container/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
new file mode 100644
index 0000000..0d229e2
--- /dev/null
+++ b/pluto-container/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
@@ -0,0 +1 @@
+org.apache.pluto.container.bean.processor.PortletCDIExtension
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/InvocationResults.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/InvocationResults.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/InvocationResults.java
new file mode 100644
index 0000000..5c2e24c
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/InvocationResults.java
@@ -0,0 +1,74 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.context.ApplicationScoped;
+
+/**
+ * @author Scott
+ *
+ */
+@ApplicationScoped
+public class InvocationResults {
+
+   private List<String> methods = new ArrayList<String>();
+   boolean configExists = false;
+
+   /**
+    * @return the methods
+    */
+   public List<String> getMethods() {
+      return methods;
+   }
+   
+   /**
+    * clears all methods
+    */
+   public void reset() {
+      methods.clear();
+      configExists = false;
+   }
+   
+   /**
+    * adds method to results
+    * 
+    * @param meth
+    */
+   public void addMethod(String meth) {
+      methods.add(meth);
+   }
+
+   /**
+    * @return the configExists
+    */
+   public boolean isConfigExists() {
+      return configExists;
+   }
+
+   /**
+    * @param configExists the configExists to set
+    */
+   public void setConfigExists(boolean configExists) {
+      this.configExists = configExists;
+   }
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedBadClass.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedBadClass.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedBadClass.java
new file mode 100644
index 0000000..09111ca
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedBadClass.java
@@ -0,0 +1,33 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import javax.portlet.annotations.PortletStateScoped;
+
+/**
+ * Verifies that an {@literal @}PortletStateScoped bean not implementing 
+ * <code>PortletSerializable</code> is recognized.
+ *  
+ * @author Scott Nicklous
+ */
+@PortletStateScoped
+public class PortletStateScopedBadClass {
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedClass.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedClass.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedClass.java
new file mode 100644
index 0000000..3aa7dc1
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedClass.java
@@ -0,0 +1,43 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import javax.portlet.annotations.PortletSerializable;
+import javax.portlet.annotations.PortletStateScoped;
+
+/**
+ * Verifies that an {@literal @}PortletStateScoped bean is recognized when a parameter name
+ * is provided.
+ *  
+ * @author Scott Nicklous
+ */
+@PortletStateScoped(paramName="param1")
+public class PortletStateScopedClass implements PortletSerializable {
+
+   @Override
+   public void deserialize(String[] arg0) {
+   }
+
+   @Override
+   public String[] serialize() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedNoParamNameClass.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedNoParamNameClass.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedNoParamNameClass.java
new file mode 100644
index 0000000..2e49abf
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/PortletStateScopedNoParamNameClass.java
@@ -0,0 +1,42 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import javax.portlet.annotations.PortletSerializable;
+import javax.portlet.annotations.PortletStateScoped;
+
+/**
+ * Verifies that an {@literal @}PortletStateScoped bean is recognized.
+ *  
+ * @author Scott Nicklous
+ */
+@PortletStateScoped
+public class PortletStateScopedNoParamNameClass implements PortletSerializable {
+
+   @Override
+   public void deserialize(String[] arg0) {
+   }
+
+   @Override
+   public String[] serialize() {
+      return null;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedApp1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedApp1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedApp1.java
new file mode 100644
index 0000000..8cdae12
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedApp1.java
@@ -0,0 +1,38 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.PortletSession;
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with APPLICATION_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped(PortletSession.APPLICATION_SCOPE)
+public class SessionScopedApp1  implements Serializable {
+   private static final long serialVersionUID = -65231174707289554L;
+   
+   public String sayHi() {return "Hi!";}
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet1.java
new file mode 100644
index 0000000..fe6378e
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet1.java
@@ -0,0 +1,35 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with PORTLET_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped
+public class SessionScopedPortlet1 implements Serializable {
+   private static final long serialVersionUID = 341639512640247390L;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet2.java
new file mode 100644
index 0000000..268061c
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortlet2.java
@@ -0,0 +1,36 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.PortletSession;
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with PORTLET_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped(PortletSession.PORTLET_SCOPE)
+public class SessionScopedPortlet2  implements Serializable {
+   private static final long serialVersionUID = -65231174707289554L;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad1.java
new file mode 100644
index 0000000..fe5bb29
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad1.java
@@ -0,0 +1,35 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with PORTLET_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped(0)
+public class SessionScopedPortletBad1 implements Serializable {
+   private static final long serialVersionUID = 3289136406613566858L;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad2.java
new file mode 100644
index 0000000..97f9a8f
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad2.java
@@ -0,0 +1,35 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with PORTLET_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped(1200)
+public class SessionScopedPortletBad2 implements Serializable {
+   private static final long serialVersionUID = -5293096810065550573L;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad3.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad3.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad3.java
new file mode 100644
index 0000000..634a985
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/SessionScopedPortletBad3.java
@@ -0,0 +1,35 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures;
+
+import java.io.Serializable;
+
+import javax.portlet.annotations.PortletSessionScoped;
+
+/**
+ * PortletSessionScoped bean with PORTLET_SCOPE
+ * @author Scott Nicklous
+ *
+ */
+@PortletSessionScoped(-70)
+public class SessionScopedPortletBad3 implements Serializable {
+   private static final long serialVersionUID = 7637697641701569291L;
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action1.java
new file mode 100644
index 0000000..a0a03d9
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action1.java
@@ -0,0 +1,53 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.action;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Action1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @ActionMethod(portletName="portlet1", 
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub1")
+         })
+   public void action1(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action1");
+   }
+   
+   @ActionMethod(portletName="portlet2")
+   public void action2(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action2");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action2.java
new file mode 100644
index 0000000..360a20c
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/Action2.java
@@ -0,0 +1,95 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.action;
+
+import javax.inject.Inject;
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.annotations.ActionMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Action2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @ActionMethod(portletName="portlet3",
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub1")
+         })
+   public void action1a(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action1a");
+   }
+   
+   @ActionMethod(portletName="portlet3", actionName="Fred",
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub2")
+         })
+   public void action1b(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action1b");
+   }
+   
+   @ActionMethod(portletName="portlet3", actionName="Barney",
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub3"),
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub4")
+         })
+   public void action1c(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action1c");
+   }
+   
+   // duplicate method
+   @ActionMethod(portletName="portlet2")
+   public void action2(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action2");
+   }
+   
+   // invalid signature
+   @ActionMethod(portletName="portlet4")
+   public void action4(ActionRequest req, ActionResponse resp, int y) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action3");
+   }
+   
+   // invalid signature
+   @ActionMethod(portletName="portlet5")
+   public String action5(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action5");
+      return null;
+   }
+
+   // duplicate method, same action name
+   @ActionMethod(portletName="portlet6", actionName="Wilma")
+   public void action6(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action6");
+   }
+
+   // duplicate method, same action name
+   @ActionMethod(portletName="portlet6", actionName="Wilma")
+   public void action7(ActionRequest req, ActionResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#action7");
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/package-info.java
new file mode 100644
index 0000000..d65bfc5
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/action/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.action;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy1.java
new file mode 100644
index 0000000..b2c044e
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy1.java
@@ -0,0 +1,47 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.destroy;
+
+import javax.inject.Inject;
+import javax.portlet.annotations.DestroyMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Destroy1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @DestroyMethod("portlet1")
+   public void destroy1() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy1");
+   }
+   
+   @DestroyMethod("portlet2")
+   public void destroy2() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy2");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy2.java
new file mode 100644
index 0000000..af20179
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/Destroy2.java
@@ -0,0 +1,61 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.destroy;
+
+import javax.inject.Inject;
+import javax.portlet.annotations.DestroyMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Destroy2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @DestroyMethod("portlet3")
+   public void destroy1() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy1");
+   }
+   
+   // duplicate method
+   @DestroyMethod("portlet2")
+   public void destroy2() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy2");
+   }
+   
+   // invalid signature
+   @DestroyMethod("portlet4")
+   public void destroy4(String x) {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy4");
+   }
+   
+   // invalid signature
+   @DestroyMethod("portlet5")
+   public String destroy5() {
+      meths.addMethod(this.getClass().getSimpleName() + "#destroy5");
+      return null;
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/package-info.java
new file mode 100644
index 0000000..bcbed4f
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/destroy/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.destroy;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event1.java
new file mode 100644
index 0000000..1d90cff
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event1.java
@@ -0,0 +1,59 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.event;
+
+import javax.inject.Inject;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Event1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @EventMethod(portletName="portlet1", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc1")
+         },
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub1")
+         })
+   public void event1(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event1");
+   }
+   
+   @EventMethod(portletName="portlet2", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc2")
+         })
+   public void event2(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event2");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event2.java
new file mode 100644
index 0000000..88fe4f2
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/Event2.java
@@ -0,0 +1,120 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.event;
+
+import javax.inject.Inject;
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+import javax.portlet.annotations.EventMethod;
+import javax.portlet.annotations.PortletQName;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Event2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @EventMethod(portletName="portlet3",
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc3a")
+         },
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub1")
+         })
+   public void event1a(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event1a");
+   }
+   
+   @EventMethod(portletName="portlet3",
+         processingEvents= {
+            @PortletQName(namespaceURI="", localPart="proc3b")
+         },
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub2")
+         })
+   public void event1b(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event1b");
+   }
+   
+   @EventMethod(portletName="portlet3",
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc3c")
+         },
+         publishingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="pub3"),
+            @PortletQName(namespaceURI="", localPart="pub4")
+         })
+   public void event1c(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event1c");
+   }
+   
+   // duplicate method
+   @EventMethod(portletName="portlet2", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc2")
+         })
+   public void event2(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event2");
+   }
+   
+   // invalid signature
+   @EventMethod(portletName="portlet4", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc4")
+         })
+   public void event4(EventRequest req, EventResponse resp, int y) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event4");
+   }
+   
+   // invalid signature
+   @EventMethod(portletName="portlet5", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc5")
+         })
+   public String event5(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event5");
+      return null;
+   }
+
+   // duplicate method in same class
+   @EventMethod(portletName="portlet6", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc6")
+         })
+   public void event6(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event6");
+   }
+
+   // duplicate method in same class
+   @EventMethod(portletName="portlet6", 
+         processingEvents= {
+            @PortletQName(namespaceURI="http://www.apache.org", localPart="proc6")
+         })
+   public void event7(EventRequest req, EventResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#event7");
+   }
+
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/package-info.java
new file mode 100644
index 0000000..1a99666
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/event/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.event;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header1.java
new file mode 100644
index 0000000..c5eff06
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header1.java
@@ -0,0 +1,91 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.header;
+
+import javax.inject.Inject;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.annotations.HeaderMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Header1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @HeaderMethod(portletNames="portlet1")
+   public void header1a(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header1a");
+   }
+   
+   @HeaderMethod(portletNames="portlet1")
+   public void header1b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#header1b");
+   }
+   
+   @HeaderMethod(portletNames="portlet1")
+   public String header1c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#header1c");
+      return null;
+   }
+   
+   @HeaderMethod(portletNames="portlet2", portletMode="help")
+   public void header2a(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header2a");
+   }
+   
+   @HeaderMethod(portletNames="portlet2", portletMode="edit")
+   public void header2b(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header2b");
+   }
+   
+   @HeaderMethod(portletNames="portlet2", portletMode="config")
+   public void header2c(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header2c");
+   }
+   
+   @HeaderMethod(portletNames="portlet3", ordinal=200)
+   public void header3a(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header3a");
+   }
+   
+   @HeaderMethod(portletNames="portlet3", ordinal=300)
+   public void header3b() {
+      meths.addMethod(this.getClass().getSimpleName() + "#header3b");
+   }
+   
+   @HeaderMethod(portletNames="portlet3", ordinal=-42)
+   public String header3c() {
+      meths.addMethod(this.getClass().getSimpleName() + "#header3c");
+      return null;
+   }
+   
+   @HeaderMethod(portletNames="portlet3", ordinal=300, portletMode="help")
+   public void header3e() {
+      meths.addMethod(this.getClass().getSimpleName() + "#header3e");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header2.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header2.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header2.java
new file mode 100644
index 0000000..0aee0ef
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/Header2.java
@@ -0,0 +1,86 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.header;
+
+import javax.activity.InvalidActivityException;
+import javax.inject.Inject;
+import javax.portlet.HeaderRequest;
+import javax.portlet.HeaderResponse;
+import javax.portlet.annotations.HeaderMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott Nicklous
+ *
+ */
+public class Header2 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @HeaderMethod(portletNames="portlet2", portletMode="edit", ordinal=-100)
+   public void header2c(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header2c");
+   }
+   
+   @HeaderMethod(portletNames="portlet2", portletMode="edit", ordinal=100)
+   public void header2d(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header2d");
+   }
+   
+   // invalid signature
+   @HeaderMethod(portletNames="portlet4")
+   public void header4(String x, HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header4");
+   }
+   
+   // invalid signature
+   @HeaderMethod(portletNames="portlet5", portletMode="edit")
+   public String header5(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header5");
+      return null;
+   }
+   
+   // invalid signature, bad exception
+   @HeaderMethod(portletNames="portlet8")
+   public String header8(HeaderRequest req, HeaderResponse resp) throws InvalidActivityException {
+      meths.addMethod(this.getClass().getSimpleName() + "#header8");
+      return null;
+   }
+   
+   @HeaderMethod(portletNames= {"portlet6", "portlet7"})
+   public void header6and7(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header6and7");
+   }
+   
+   // ignored asterisk
+   @HeaderMethod(portletNames= {"portlet6", "*"}, ordinal=100)
+   public void header6andStar(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#header6andStar");
+   }
+   
+   @HeaderMethod(portletNames="*", portletMode="admin")
+   public void headerAll(HeaderRequest req, HeaderResponse resp) {
+      meths.addMethod(this.getClass().getSimpleName() + "#headerAll");
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/package-info.java
new file mode 100644
index 0000000..d6f5e3e
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/header/package-info.java
@@ -0,0 +1,23 @@
+/*  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
+ *
+ */
+package org.apache.pluto.container.bean.processor.fixtures.header;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init1.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init1.java b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init1.java
new file mode 100644
index 0000000..d63836b
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/bean/processor/fixtures/init/Init1.java
@@ -0,0 +1,48 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.bean.processor.fixtures.init;
+
+import javax.inject.Inject;
+import javax.portlet.PortletConfig;
+import javax.portlet.annotations.InitMethod;
+
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+
+/**
+ * @author Scott
+ *
+ */
+public class Init1 {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @InitMethod("portlet1")
+   public void init1(PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init1");
+   }
+   
+   @InitMethod("portlet2")
+   public void init2(PortletConfig config) {
+      meths.addMethod(this.getClass().getSimpleName() + "#init2");
+   }
+   
+
+}


[09/35] portals-pluto git commit: Added configuration by annotation for V3 portlets. For v3 portlets, neither the web application deployment descriptor nor the portlet deployment descriptor are necessary. * Annotations provided for all portlet config

Posted by ms...@apache.org.
Added configuration by annotation for V3 portlets. For v3 portlets, neither
the web application deployment descriptor nor the portlet deployment
descriptor are necessary.
   * Annotations provided for all portlet config items
   * If portlet.xml supplied in addition, configuration is merged
   * Values from the portlet.xml file take precedence over annotated values
   * Added corresponding unit tests


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

Branch: refs/heads/V3Prototype
Commit: ab12285fb4689f153e4652f370f0361422968f02
Parents: a283cd0
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Dec 7 07:58:42 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Dec 7 07:58:42 2015 +0100

----------------------------------------------------------------------
 .../pluto/container/om/portlet/Dependency.java  |  25 +
 .../pluto/container/om/portlet/Description.java |  11 +-
 .../pluto/container/om/portlet/DisplayName.java |  48 +-
 .../pluto/container/om/portlet/Filter.java      |  23 +-
 .../pluto/container/om/portlet/Listener.java    |   3 +
 .../pluto/container/om/portlet/LocaleText.java  |  30 +
 .../container/om/portlet/PortletDefinition.java |   4 +
 .../pluto/container/om/portlet/PortletInfo.java |  71 +-
 .../om/portlet/PublicRenderParameter.java       |   4 +
 pluto-container/pom.xml                         |   2 +-
 .../impl/PortletAppDescriptorServiceImpl.java   |  32 +-
 .../om/portlet/impl/ConfigurationHolder.java    | 165 ++--
 .../om/portlet/impl/ConfigurationProcessor.java |  70 +-
 .../impl/ContainerRuntimeOptionImpl.java        |  36 +
 .../om/portlet/impl/CustomPortletModeImpl.java  |  36 +
 .../om/portlet/impl/CustomWindowStateImpl.java  |  36 +
 .../om/portlet/impl/DependencyImpl.java         | 118 +++
 .../om/portlet/impl/DescriptionImpl.java        |  51 +-
 .../om/portlet/impl/DisplayNameImpl.java        |  46 +-
 .../om/portlet/impl/EventDefinitionImpl.java    |  36 +
 .../impl/EventDefinitionReferenceImpl.java      |  36 +
 .../container/om/portlet/impl/FilterImpl.java   |  65 ++
 .../om/portlet/impl/FilterMappingImpl.java      |  36 +
 .../om/portlet/impl/InitParamImpl.java          |  36 +
 .../impl/JSR168ConfigurationProcessor.java      |  10 +-
 .../impl/JSR286ConfigurationProcessor.java      |  26 +-
 .../impl/JSR362ConfigurationProcessor.java      | 637 +++++++++----
 .../container/om/portlet/impl/ListenerImpl.java |  54 ++
 .../om/portlet/impl/LocaleTextImpl.java         | 136 +++
 .../impl/PortletApplicationDefinitionImpl.java  |  61 +-
 .../om/portlet/impl/PortletDefinitionImpl.java  | 140 ++-
 .../om/portlet/impl/PortletInfoImpl.java        | 195 +++-
 .../portlet/impl/PublicRenderParameterImpl.java |  71 ++
 .../om/portlet/impl/SecurityConstraintImpl.java |  36 +
 .../om/portlet/impl/SecurityRoleRefImpl.java    |  36 +
 .../container/om/portlet/impl/SupportsImpl.java |  36 +
 .../om/portlet/impl/UserAttributeImpl.java      |  36 +
 .../om/portlet/impl/UserDataConstraintImpl.java |  36 +
 .../container/impl/JaxbReadTest168Gen.java      |   1 -
 .../container/impl/JaxbReadTest286Gen.java      |   1 -
 .../pluto/container/impl/JaxbReadTest286NC.java |   1 -
 .../container/impl/JaxbReadTest362Gen.java      |   5 +-
 .../impl/fixtures/TestAnnotatedFilter.java      |  88 ++
 .../fixtures/TestAnnotatedGenericPortlet.java   |  60 ++
 .../impl/fixtures/TestAnnotatedPortlet.java     |  82 ++
 .../fixtures/TestMultiAnnotatedPortlet.java     |  74 ++
 .../fixtures/TestPortletAppAnnotatedClass.java  | 118 +++
 .../jsr168/CustomPortletMode168ImplTest.java    |   8 +-
 .../jsr168/CustomWindowState168ImplTest.java    |   8 +-
 ...PortletApplicationDefinition168ImplTest.java |   2 +-
 .../jsr168/PortletDefinition168ImplTest.java    |  22 +-
 .../jsr168/SecurityConstraint168ImplTest.java   |  10 +-
 .../impl/jsr168/UserAttribute168ImplTest.java   |  10 +-
 .../jsr168/UserDataConstraint168ImplTest.java   |  10 +-
 .../jsr286/CustomPortletMode286ImplTest.java    |   8 +-
 .../jsr286/CustomWindowState286ImplTest.java    |   8 +-
 ...PortletApplicationDefinition286ImplTest.java |  17 +-
 .../jsr286/PortletDefinition286ImplTest.java    |  22 +-
 .../jsr286/SecurityConstraint286ImplTest.java   |  10 +-
 .../impl/jsr286/UserAttribute286ImplTest.java   |  10 +-
 .../jsr286/UserDataConstraint286ImplTest.java   |  10 +-
 .../jsr362/CustomPortletMode362ImplTest.java    |   9 +-
 .../jsr362/CustomWindowState362ImplTest.java    |   8 +-
 ...ExtendingPortletInterfaceAnnotationTest.java | 266 ++++++
 .../jsr362/JSR362PortletAppAnnotationTest.java  | 385 ++++++++
 .../JSR362PortletFilterAnnotationTest.java      | 230 +++++
 .../impl/jsr362/MergePortletAppTest.java        | 819 +++++++++++++++++
 .../impl/jsr362/MergePortletDefinitionTest.java | 887 +++++++++++++++++++
 .../impl/jsr362/MultiAnnotatedPortletTest.java  | 346 ++++++++
 ...PortletApplicationDefinition362ImplTest.java | 249 +++++-
 .../PortletDefinition362AnnotationTest.java     | 815 +++++++++++++++++
 .../jsr362/PortletDefinition362ImplTest.java    | 364 +++++++-
 .../jsr362/SecurityConstraint362ImplTest.java   | 122 ---
 .../impl/jsr362/UserAttribute362ImplTest.java   |  10 +-
 .../jsr362/UserDataConstraint362ImplTest.java   | 105 ---
 .../om/portlet/AnotherBundle.properties         |   6 +
 .../om/portlet/portlet362Generated.xml          |  20 +-
 .../container/om/portlet/portlet362Merge.xml    | 185 ++++
 78 files changed, 7125 insertions(+), 816 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Dependency.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Dependency.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Dependency.java
new file mode 100644
index 0000000..0beff9c
--- /dev/null
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Dependency.java
@@ -0,0 +1,25 @@
+package org.apache.pluto.container.om.portlet;
+
+public interface Dependency {
+
+   /**
+    * @return the name
+    */
+   String getName();
+
+   /**
+    * @param name the name to set
+    */
+   void setName(String name);
+
+   /**
+    * @return the version
+    */
+   String getVersion();
+
+   /**
+    * @param version the version to set
+    */
+   void setVersion(String version);
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Description.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Description.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Description.java
index 9f3294c..f199bdd 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Description.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Description.java
@@ -16,15 +16,6 @@
  */
 package org.apache.pluto.container.om.portlet;
 
-import java.util.Locale;
 
-public interface Description {
-
-    String getLang();
-   void setLang(String lang);
-    
-	String getDescription();
-	void setDescription(String description);
-
-	Locale getLocale();
+public interface Description extends LocaleText {
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/DisplayName.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/DisplayName.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/DisplayName.java
index 52adaf6..55dee8d 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/DisplayName.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/DisplayName.java
@@ -1,29 +1,21 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.om.portlet;
-
-import java.util.Locale;
-
-public interface DisplayName {
-
-    String getLang();
-
-	String getDisplayName();
-	void setDisplayName(String displayName);
-	
-	Locale getLocale();
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.om.portlet;
+
+
+public interface DisplayName extends LocaleText {
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Filter.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Filter.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Filter.java
index d03f1be..346f091 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Filter.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Filter.java
@@ -21,23 +21,30 @@ import java.util.Locale;
 
 public interface Filter {
 
-    String getFilterName();
+   String getFilterName();
 
-    Description getDescription(Locale locale);
+   Description getDescription(Locale locale);
    List<Description> getDescriptions();
    void addDescription(Description desc);
 
-	DisplayName getDisplayName(Locale locale);
+   DisplayName getDisplayName(Locale locale);
    List<DisplayName> getDisplayNames();
    void addDisplayName(DisplayName dn);
 
-	String getFilterClass();
-	void setFilterClass(String filterClass);
+   String getFilterClass();
+   void setFilterClass(String filterClass);
 
-	InitParam getInitParam(String paramName);
+   InitParam getInitParam(String paramName);
    List<InitParam> getInitParams();
    void addInitParam(InitParam ip);
 
-	List<String> getLifecycles();
-	void addLifecycle(String lifecycle);
+   List<String> getLifecycles();
+   void addLifecycle(String lifecycle);
+
+   // establishes ordering for annotated filters
+   int getOrdinal();
+   void setOrdinal(int ordinal);
+
+   // marks if the ordinal was set (annotated filter only)
+   boolean isOrdinalSet();
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
index c1e7fdf..f507377 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/Listener.java
@@ -31,4 +31,7 @@ public interface Listener {
    DisplayName getDisplayName(Locale locale);
    List<DisplayName> getDisplayNames();
    void addDisplayName(DisplayName dispName);
+   
+   String getListenerName();
+   void setListenerName(String listenerName);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/LocaleText.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/LocaleText.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/LocaleText.java
new file mode 100644
index 0000000..9412905
--- /dev/null
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/LocaleText.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.om.portlet;
+
+import java.util.Locale;
+
+public interface LocaleText {
+
+   String getLang();
+   void setLang(String lang);
+    
+   String getText();
+   void setText(String text);
+
+   Locale getLocale();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
index 8d3250c..6de7da5 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
@@ -78,4 +78,8 @@ public interface PortletDefinition {
    ContainerRuntimeOption getContainerRuntimeOption(String name);
    List<ContainerRuntimeOption> getContainerRuntimeOptions();
    void addContainerRuntimeOption(ContainerRuntimeOption cro);
+
+   void addDependency(Dependency dep);
+   List<Dependency> getDependencies();
+   Dependency getDependency(String name);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletInfo.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletInfo.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletInfo.java
index 6c89bb8..131c92b 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletInfo.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletInfo.java
@@ -1,29 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.pluto.container.om.portlet;
-
-public interface PortletInfo {
-
-	String getTitle();
-	void setTitle(String title);
-
-	String getKeywords();
-	void setKeywords(String keywords);
-
-	String getShortTitle();
-	void setShortTitle(String shortTitle);
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.pluto.container.om.portlet;
+
+import java.util.List;
+import java.util.Locale;
+
+public interface PortletInfo {
+
+	String getTitle();
+	void setTitle(String title);
+
+   LocaleText getTitle(Locale locale);
+   List<LocaleText> getTitles();
+   void addTitle(LocaleText title);
+
+	String getKeywords();
+	void setKeywords(String keywords);
+
+   LocaleText getKeywords(Locale locale);
+   List<LocaleText> getKeywordsList();
+   void addKeywords(LocaleText kw);
+
+	String getShortTitle();
+	void setShortTitle(String shortTitle);
+
+   LocaleText getShortTitle(Locale locale);
+   List<LocaleText> getShortTitles();
+   void addShortTitle(LocaleText st);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PublicRenderParameter.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PublicRenderParameter.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PublicRenderParameter.java
index 7c0297e..3734e3c 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PublicRenderParameter.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PublicRenderParameter.java
@@ -30,6 +30,10 @@ public interface PublicRenderParameter {
    List<Description> getDescriptions();
    void addDescription(Description desc);
 
+   DisplayName getDisplayName(Locale locale);
+   List<DisplayName> getDisplayNames();
+   void addDisplayName(DisplayName desc);
+
    List<QName> getAliases();
    void addAlias(QName alias);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/pom.xml
----------------------------------------------------------------------
diff --git a/pluto-container/pom.xml b/pluto-container/pom.xml
index 1108ace..d05a50b 100644
--- a/pluto-container/pom.xml
+++ b/pluto-container/pom.xml
@@ -102,7 +102,7 @@
             <artifactId>maven-surefire-plugin</artifactId>
             <configuration>
                <includes>
-                  <include>**/*ImplTest.java</include>
+                  <include>**/*Test.java</include>
                   <include>**/*TestSuite.java</include>
                </includes>
                <excludes>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
index 48a9aab..c4e0354 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/impl/PortletAppDescriptorServiceImpl.java
@@ -103,22 +103,22 @@ public class PortletAppDescriptorServiceImpl implements PortletAppDescriptorServ
    public void mergeWebDescriptor(PortletApplicationDefinition pad,
          InputStream webDescriptor) throws Exception {
       
-      ConfigurationHolder confHolder = new ConfigurationHolder(pad);
-      confHolder.processWebDD(webDescriptor);
-      
-      if (isDebug) {
-         StringBuilder txt = new StringBuilder(128);
-         txt.append("Processed web DD for Portlet app: ").append(pad.getName());
-         txt.append(", context path: ").append(pad.getContextPath());
-         txt.append(", # portlets: ").append(pad.getPortlets().size());
-         txt.append(", names: ");
-         String sep = "";
-         for (PortletDefinition pd : pad.getPortlets()) {
-            txt.append(sep).append(pd.getPortletName());
-            sep = ", ";
-         }
-         LOG.debug(txt.toString());
-      }
+//       ConfigurationHolder confHolder = new ConfigurationHolder(pad);
+//       confHolder.processWebDD(webDescriptor);
+//       
+//       if (isDebug) {
+//          StringBuilder txt = new StringBuilder(128);
+//          txt.append("Processed web DD for Portlet app: ").append(pad.getName());
+//          txt.append(", context path: ").append(pad.getContextPath());
+//          txt.append(", # portlets: ").append(pad.getPortlets().size());
+//          txt.append(", names: ");
+//          String sep = "";
+//          for (PortletDefinition pd : pad.getPortlets()) {
+//             txt.append(sep).append(pd.getPortletName());
+//             sep = ", ";
+//          }
+//          LOG.debug(txt.toString());
+//       }
    }
 
    /**

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
index 8202fba..2595a95 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationHolder.java
@@ -20,7 +20,12 @@ package org.apache.pluto.container.om.portlet.impl;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Set;
 
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletRequestFilter;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBElement;
 import javax.xml.bind.JAXBException;
@@ -35,80 +40,53 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * This class processes the web app deployment descriptor and the portlet
- * deployment descriptor files.
+ * This class processes the web app deployment descriptor and the portlet deployment descriptor files.
  * 
  * 
  * @author Scott Nicklous
  * 
  */
 public class ConfigurationHolder {
-   
-   public static final String ATTRIB_NAME = "PortletAppConfig";
-
-   private PortletApplicationDefinition   pad = null;
-   private ConfigurationProcessor         jcp = null;
 
+   public static final String           ATTRIB_NAME  = "PortletAppConfig";
+   private PortletApplicationDefinition pad          = null;
+   private ConfigurationProcessor       jcp          = null;
 
    /** Logger. */
-   private static final Logger          LOG          = LoggerFactory
-                                                           .getLogger(ConfigurationHolder.class);
+   private static final Logger          LOG          = LoggerFactory.getLogger(ConfigurationHolder.class);
    private static final boolean         isDebug      = LOG.isDebugEnabled();
 
    private static final String          JAXB_CONTEXT = "org.apache.pluto.container.om.portlet10.impl:"
                                                            + "org.apache.pluto.container.om.portlet20.impl:"
                                                            + "org.apache.pluto.container.om.portlet30.impl";
 
-   
    /**
     * Default constructor
     */
    public ConfigurationHolder() {
       this.pad = new PortletApplicationDefinitionImpl();
    }
-   /**
-    * Constructor
-    * 
-    * @param pad
-    */
-   public ConfigurationHolder(PortletApplicationDefinition pad) {
-      this.pad = pad;
-   }
 
    /**
     * returns the finished portlet application definition
     * 
-    * @return  the portlet application definition
+    * @return the portlet application definition
     */
    public PortletApplicationDefinition getPad() {
       return pad;
    }
 
    /**
-    * Sets the portlet application definition to be processed
-    * 
-    * @param pad
-    */
-   public void setPad(PortletApplicationDefinition pad) {
-      this.pad = pad;
-   }
-
-   /**
-    * Processes the portlet deployment descriptor represented by the given input
-    * stream.
+    * Processes the portlet deployment descriptor represented by the given input stream.
     * <p>
-    * The data is merged into an existing configuration data structure if one is
-    * provided. This capability is used by version 3 portlets for merging config
-    * data from the files into config data that has been read from annotations.
+    * The data is merged into an existing configuration data structure if one is provided. This capability is used by
+    * version 3 portlets for merging config data from the files into config data that has been read from annotations.
     * <p>
-    * If no existing configuration data is provides, or if a version 1.0 or
-    * version 2.0 deployment descriptor is being processed, a new configuration
-    * data structure is created.
+    * If no existing configuration data is provides, or if a version 1.0 or version 2.0 deployment descriptor is being
+    * processed, a new configuration data structure is created.
     * <p>
-    * The class also performs validity checking and throws exceptions for
-    * invalid data. To maintain compatibility with the earlier Pluto
-    * implementation, an <code>IllegalArgumentException</code> is thrown in such
-    * cases.
+    * The class also performs validity checking and throws exceptions for invalid data. To maintain compatibility with
+    * the earlier Pluto implementation, an <code>IllegalArgumentException</code> is thrown in such cases.
     * 
     * 
     * @param stream
@@ -118,11 +96,11 @@ public class ConfigurationHolder {
     *            If an I/O error occurs
     * @throws IllegalArgumentException
     *            If data validation fails
-    * @throws XMLStreamException 
+    * @throws XMLStreamException
     */
-   public void processPortletDD(InputStream stream)
-         throws IOException, IllegalArgumentException, JAXBException, XMLStreamException {
-      
+   public void processPortletDD(InputStream stream) throws IOException, IllegalArgumentException, JAXBException,
+         XMLStreamException {
+
       ClassLoader mycl = this.getClass().getClassLoader();
       JAXBContext cntxt = JAXBContext.newInstance(JAXB_CONTEXT, mycl);
 
@@ -143,39 +121,31 @@ public class ConfigurationHolder {
          txt.append(jel.getValue().getClass().getCanonicalName());
          LOG.debug(txt.toString());
       }
-      
-      if (jel.getValue() instanceof 
-            org.apache.pluto.container.om.portlet10.impl.PortletAppType) {
 
-         // Ignore existing config data for 1.0 portlets 
+      if (jel.getValue() instanceof org.apache.pluto.container.om.portlet10.impl.PortletAppType) {
+
+         // Ignore existing config data for 1.0 portlets
          pad = new PortletApplicationDefinitionImpl();
-         jcp = new JSR168ConfigurationProcessor();
-         
-      } else if (jel.getValue() instanceof 
-            org.apache.pluto.container.om.portlet20.impl.PortletAppType) {
-         
+         jcp = new JSR168ConfigurationProcessor(pad);
+
+      } else if (jel.getValue() instanceof org.apache.pluto.container.om.portlet20.impl.PortletAppType) {
+
          // Ignore existing config data for 2.0 portlets
          pad = new PortletApplicationDefinitionImpl();
-         jcp = new JSR286ConfigurationProcessor();
-         
-      } else if (jel.getValue() instanceof 
-            org.apache.pluto.container.om.portlet30.impl.PortletAppType) {
-
-         // for v3, let config data from DD overwrite existing data from annotations
-         if (pad == null) {
-            pad = new PortletApplicationDefinitionImpl();
-         }
-         jcp = new JSR362ConfigurationProcessor();
-         
+         jcp = new JSR286ConfigurationProcessor(pad);
+
+      } else if (jel.getValue() instanceof org.apache.pluto.container.om.portlet30.impl.PortletAppType) {
+
+         jcp = new JSR362ConfigurationProcessor(pad);
+
       } else {
-         String warning = "Unknown application type: " + 
-               jel.getValue().getClass().getCanonicalName();
+         String warning = "Unknown application type: " + jel.getValue().getClass().getCanonicalName();
          LOG.warn(warning);
          throw new IOException(warning);
       }
 
-      pad = jcp.process(jel);
-      
+      jcp.process(jel);
+
       if (isDebug) {
          StringBuilder txt = new StringBuilder(128);
          txt.append("Parsed DD for Portlet app: ").append(pad.getName());
@@ -190,20 +160,67 @@ public class ConfigurationHolder {
       }
 
    }
-   
+
    /**
     * extracts the locale-encoding mapping from the web deployment descriptor
     * 
-    * @param in   Input stream for the web DD
-    * @throws Exception 
+    * @param in
+    *           Input stream for the web DD
+    * @throws Exception
     */
    public void processWebDD(InputStream in) throws Exception {
       if (jcp == null) {
-         jcp = new JSR286ConfigurationProcessor();
+         jcp = new JSR286ConfigurationProcessor(pad);
       }
-      jcp.processWebDD(in, pad);
+      jcp.processWebDD(in);
    }
-   
+
+   /**
+    * Accepts a list of classes that are annotated with portlet configuration and portlet application configuration
+    * annotations. Extracts the config data from the annotations to create a corresponding portlet application
+    * definition structure.
+    * <p>
+    * This method must be called before processing the portlet xml so that the data from the portlet DD may properly
+    * override the annotation configuration data.
+    * <p>
+    * This method is designed to be used within a ServletContainerInitializer onStartup() method. The SCI should be
+    * annotated as follows: <code>@HandlesTypes({PortletApplication.class, PortletConfiguration.class, #
+    * PortletConfigurations.class, PortletRequestFilter.class})</code>
+    * 
+    * @param classes
+    *           List of classes annotated with portlet config annotations
+    */
+   public void processConfigAnnotations(Set<Class<?>> classes) {
+      if (classes != null) {
+         jcp = new JSR362ConfigurationProcessor(pad);
+         for (Class<?> cls : classes) {
+            
+            PortletApplication pa = cls.getAnnotation(PortletApplication.class);
+            if (pa != null) {
+               jcp.processPortletAppAnnotation(pa);
+            }
+            
+            PortletConfiguration pc = cls.getAnnotation(PortletConfiguration.class);
+            if (pc != null) {
+               jcp.processPortletConfigAnnotation(pc, cls);
+            }
+            
+            PortletConfigurations pcs = cls.getAnnotation(PortletConfigurations.class);
+            if (pcs != null) {
+               for (PortletConfiguration config : pcs.value()) {
+                  jcp.processPortletConfigAnnotation(config, cls);
+               }
+            }
+            
+            PortletRequestFilter prf = cls.getAnnotation(PortletRequestFilter.class);
+            if (prf != null) {
+               jcp.processPortletFilterAnnotation(cls);
+            }
+            
+         }
+      }
+   }
+
    /**
     * validates the configuration. To be called after the configuration has been completely read.
     */

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
index 9ae6021..6ae4208 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ConfigurationProcessor.java
@@ -5,6 +5,8 @@ import java.util.Arrays;
 import java.util.Locale;
 import java.util.ResourceBundle;
 
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
 import javax.xml.bind.JAXBElement;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -27,10 +29,13 @@ public abstract class ConfigurationProcessor {
    /** Logger. */
    private static final Logger LOG = LoggerFactory
          .getLogger(ConfigurationProcessor.class);
-   
+
 
    protected PortletApplicationDefinition pad;
    
+   public ConfigurationProcessor(PortletApplicationDefinition pad) {
+      this.pad = pad;
+   }
 
    public PortletApplicationDefinition getPad() {
       return pad;
@@ -46,8 +51,7 @@ public abstract class ConfigurationProcessor {
     * @throws IllegalArgumentException
     *            If there is a data validation error
     */
-   public abstract PortletApplicationDefinition process(
-         JAXBElement<?> rootElement) throws IllegalArgumentException;
+   public abstract void process(JAXBElement<?> rootElement) throws IllegalArgumentException;
 
    /**
     * Validates the given portlet application definition. This method should only be called after 
@@ -144,11 +148,6 @@ public abstract class ConfigurationProcessor {
             txt.append(assignable.getCanonicalName());
             throw new Exception();
          }
-//       } catch (ClassNotFoundException e) {
-//          txt.append(", Exception: ").append(e.toString());
-//          LOG.warn(txt.toString());
-//          // can't throw exception if class not found, since the portlet
-//          // application definition is used by the assembly mojo
       } catch (Exception e) {
          LOG.warn(txt.toString());
          throw new IllegalArgumentException(txt.toString(), e);
@@ -189,10 +188,9 @@ public abstract class ConfigurationProcessor {
     * Reads web app deployment descriptor to extract the locale - encoding mappings 
     * 
     * @param in            Input stream for DD
-    * @param pad           Portlet application definition to be updated
     * @throws Exception    If there is a parsing problem
     */
-   public void processWebDD(InputStream in, PortletApplicationDefinition pad) throws Exception {
+   public void processWebDD(InputStream in) throws Exception {
 
       // set up document
       DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
@@ -220,5 +218,57 @@ public abstract class ConfigurationProcessor {
          pad.addLocaleEncodingMapping(locale, encstr);
       }
    }
+   
+   /**
+    * Extracts the data from the portlet application annotation and adds it to the 
+    * portlet application definition structure.
+    * <p>
+    * The default method implementation does nothing. The V3 implementation will
+    * override this method to provide function.  
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor
+    * is read so that data from the portlet DD can override that provided through annotations.
+    * 
+    * @param pa      The portlet application annotation
+    */
+   public void processPortletAppAnnotation(PortletApplication pa) {
+      // default impl = do nothing
+   }
+   
+   /**
+    * Extracts the data from the portlet annotation and adds it to a 
+    * portlet definition structure. The portlet definition will be created if it does not
+    * already exist.
+    * <p>
+    * The default method implementation does nothing. The V3 implementation will
+    * override this method to provide function.  
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor
+    * is read so that data from the portlet DD can override that provided through annotations.
+    * 
+    * @param pc   The portlet configuration annotation
+    * @param cls  The annotated class
+    */
+   public void processPortletConfigAnnotation(PortletConfiguration pc, Class<?> cls) {
+      // default impl = do nothing
+   }
+
+   
+   /**
+    * Extracts the data from the portlet annotation and adds it to a 
+    * portlet filter definition structure. The portlet filter definition will be created if it does not
+    * already exist.
+    * <p>
+    * The default method implementation does nothing. The V3 implementation will
+    * override this method to provide function.  
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor
+    * is read so that data from the portlet DD can override that provided through annotations.
+    * 
+    * @param cls     The annotated class. 
+    */
+   public void processPortletFilterAnnotation(Class<?> cls) {
+      // default impl = do nothing
+   }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ContainerRuntimeOptionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ContainerRuntimeOptionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ContainerRuntimeOptionImpl.java
index a99616f..dc516bf 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ContainerRuntimeOptionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ContainerRuntimeOptionImpl.java
@@ -78,4 +78,40 @@ public class ContainerRuntimeOptionImpl implements ContainerRuntimeOption {
       values.add(value);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((name == null) ? 0 : name.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      ContainerRuntimeOptionImpl other = (ContainerRuntimeOptionImpl) obj;
+      if (name == null) {
+         if (other.name != null) {
+            return false;
+         }
+      } else if (!name.equals(other.name)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomPortletModeImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomPortletModeImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomPortletModeImpl.java
index ad3a3ad..e635b86 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomPortletModeImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomPortletModeImpl.java
@@ -121,4 +121,40 @@ public class CustomPortletModeImpl implements CustomPortletMode {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((pm == null) ? 0 : pm.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      CustomPortletModeImpl other = (CustomPortletModeImpl) obj;
+      if (pm == null) {
+         if (other.pm != null) {
+            return false;
+         }
+      } else if (!pm.equals(other.pm)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomWindowStateImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomWindowStateImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomWindowStateImpl.java
index 0c6d311..26a783b 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomWindowStateImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/CustomWindowStateImpl.java
@@ -101,4 +101,40 @@ public class CustomWindowStateImpl implements CustomWindowState {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((ws == null) ? 0 : ws.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      CustomWindowStateImpl other = (CustomWindowStateImpl) obj;
+      if (ws == null) {
+         if (other.ws != null) {
+            return false;
+         }
+      } else if (!ws.equals(other.ws)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DependencyImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DependencyImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DependencyImpl.java
new file mode 100644
index 0000000..3a44d07
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DependencyImpl.java
@@ -0,0 +1,118 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl;
+
+import org.apache.pluto.container.om.portlet.Dependency;
+
+
+/**
+ * Encapsulates the dependency configuration data.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class DependencyImpl implements Dependency {
+
+   String   name = null;
+   String version = null;
+   
+   public DependencyImpl() {
+   }
+   
+   public DependencyImpl(String name, String version) {
+      this.name = name;
+      this.version = version;
+   }
+   
+   public DependencyImpl(Dependency di) {
+      this.name = di.getName();
+      this.version = di.getVersion();
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.impl.Dependency#getName()
+    */
+   @Override
+   public String getName() {
+      return name;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.impl.Dependency#setName(java.lang.String)
+    */
+   @Override
+   public void setName(String name) {
+      this.name = name;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.impl.Dependency#getVersion()
+    */
+   @Override
+   public String getVersion() {
+      return version;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.impl.Dependency#setVersion(java.lang.String)
+    */
+   @Override
+   public void setVersion(String version) {
+      this.version = version;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((name == null) ? 0 : name.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      DependencyImpl other = (DependencyImpl) obj;
+      if (name == null) {
+         if (other.name != null) {
+            return false;
+         }
+      } else if (!name.equals(other.name)) {
+         return false;
+      }
+      return true;
+   }
+   
+   
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DescriptionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DescriptionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DescriptionImpl.java
index dd7c258..63b87b3 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DescriptionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DescriptionImpl.java
@@ -29,17 +29,13 @@ import org.apache.pluto.container.om.portlet.Description;
  * @author Scott Nicklous
  *
  */
-public class DescriptionImpl implements Description {
-   
-   private Locale locale;
-   private String desc;
+public class DescriptionImpl extends LocaleTextImpl implements Description {
    
    /**
     * default: lang = english
     */
    public DescriptionImpl() {
-      locale = Locale.ENGLISH;
-      desc = "";
+      super();
    }
    
    /**
@@ -48,53 +44,14 @@ public class DescriptionImpl implements Description {
     * @param disp       description string
     */
    public DescriptionImpl(Locale locale, String desc) {
-      this.locale = locale;
-      this.desc = desc;
+      super(locale, desc);
    }
    
    /**
     * Copy constructor
     */
    public DescriptionImpl(Description di) {
-      this.locale = (Locale) di.getLocale().clone();
-      this.desc = di.getDescription();
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.Description#getLang()
-    */
-   @Override
-   public String getLang() {
-      return locale.toLanguageTag();
-   }
-   
-   @Override
-   public void setLang(String lang) {
-      this.locale = Locale.forLanguageTag(lang);
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.Description#getDescription()
-    */
-   @Override
-   public String getDescription() {
-      return desc;
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.Description#setDescription(java.lang.String)
-    */
-   @Override
-   public void setDescription(String description) {
-      desc = description;
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.Description#getLocale()
-    */
-   @Override
-   public Locale getLocale() {
-      return Locale.forLanguageTag(locale.toLanguageTag());
+      super(di);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DisplayNameImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DisplayNameImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DisplayNameImpl.java
index 89171a2..cd20cb1 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DisplayNameImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/DisplayNameImpl.java
@@ -29,17 +29,13 @@ import org.apache.pluto.container.om.portlet.DisplayName;
  * @author Scott Nicklous
  *
  */
-public class DisplayNameImpl implements DisplayName {
-   
-   private Locale locale;
-   private String disp;
+public class DisplayNameImpl extends LocaleTextImpl implements DisplayName {
    
    /**
     * default: lang = english
     */
    public DisplayNameImpl() {
-      locale = Locale.ENGLISH;
-      disp = "";
+      super();
    }
    
    /**
@@ -48,48 +44,14 @@ public class DisplayNameImpl implements DisplayName {
     * @param disp       description string
     */
    public DisplayNameImpl(Locale locale, String desc) {
-      this.locale = locale;
-      this.disp = desc;
+      super(locale, desc);
    }
    
    /**
     * Copy constructor
     */
    public DisplayNameImpl(DisplayName di) {
-      this.locale = (Locale) di.getLocale().clone();
-      this.disp = di.getDisplayName();
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.DisplayName#getLang()
-    */
-   @Override
-   public String getLang() {
-      return locale.toLanguageTag();
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.DisplayName#getDisplayName()
-    */
-   @Override
-   public String getDisplayName() {
-      return disp;
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.DisplayName#setDisplayName(java.lang.String)
-    */
-   @Override
-   public void setDisplayName(String description) {
-      disp = description;
-   }
-
-   /* (non-Javadoc)
-    * @see org.apache.pluto.container.om.portlet.DisplayName#getLocale()
-    */
-   @Override
-   public Locale getLocale() {
-      return (Locale) locale.clone();
+      super(di);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
index d932fbf..a4a70bd 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionImpl.java
@@ -176,4 +176,40 @@ public class EventDefinitionImpl implements EventDefinition {
       valType = valueType;
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((qn == null) ? 0 : qn.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      EventDefinitionImpl other = (EventDefinitionImpl) obj;
+      if (qn == null) {
+         if (other.qn != null) {
+            return false;
+         }
+      } else if (!qn.equals(other.qn)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionReferenceImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionReferenceImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionReferenceImpl.java
index bcdc4b3..9480c66 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionReferenceImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/EventDefinitionReferenceImpl.java
@@ -67,4 +67,40 @@ public class EventDefinitionReferenceImpl implements EventDefinitionReference {
       this.qname = qn;
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((qname == null) ? 0 : qname.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      EventDefinitionReferenceImpl other = (EventDefinitionReferenceImpl) obj;
+      if (qname == null) {
+         if (other.qname != null) {
+            return false;
+         }
+      } else if (!qname.equals(other.qname)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterImpl.java
index 6f3d53d..6598e84 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterImpl.java
@@ -43,6 +43,8 @@ public class FilterImpl implements Filter {
    private final List<DisplayName> dispNames = new ArrayList<DisplayName>();
    private final Map<String, InitParam> initParams = new HashMap<String, InitParam>();
    private String fclass = "";
+   private int ordinal;
+   private boolean ordinalSet = false;
    
    
    /**
@@ -65,6 +67,8 @@ public class FilterImpl implements Filter {
       for (InitParam ip : fi.getInitParams()) {
          this.initParams.put(ip.getParamName(), new InitParamImpl(ip));
       }
+      this.ordinal = fi.getOrdinal();
+      this.ordinalSet = fi.isOrdinalSet();
 
    }
 
@@ -191,4 +195,65 @@ public class FilterImpl implements Filter {
       initParams.put(ip.getParamName(),  ip);
    }
 
+   /**
+    * @return the ordinal
+    */
+   @Override
+   public int getOrdinal() {
+      return ordinal;
+   }
+
+   /**
+    * @param ordinal the ordinal to set
+    */
+   @Override
+   public void setOrdinal(int ordinal) {
+      this.ordinal = ordinal;
+      this.ordinalSet = true;
+   }
+
+   /**
+    * @return the ordinalSet
+    */
+   @Override
+   public boolean isOrdinalSet() {
+      return ordinalSet;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((filterName == null) ? 0 : filterName.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      FilterImpl other = (FilterImpl) obj;
+      if (filterName == null) {
+         if (other.filterName != null) {
+            return false;
+         }
+      } else if (!filterName.equals(other.filterName)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
index 2b46787..c727ebc 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/FilterMappingImpl.java
@@ -75,4 +75,40 @@ public class FilterMappingImpl implements FilterMapping {
       portletNames.add(portletName);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((filterName == null) ? 0 : filterName.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      FilterMappingImpl other = (FilterMappingImpl) obj;
+      if (filterName == null) {
+         if (other.filterName != null) {
+            return false;
+         }
+      } else if (!filterName.equals(other.filterName)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/InitParamImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/InitParamImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/InitParamImpl.java
index ab9b310..f7168b9 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/InitParamImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/InitParamImpl.java
@@ -115,4 +115,40 @@ public class InitParamImpl implements InitParam {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((name == null) ? 0 : name.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      InitParamImpl other = (InitParamImpl) obj;
+      if (name == null) {
+         if (other.name != null) {
+            return false;
+         }
+      } else if (!name.equals(other.name)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
index cc69cd1..6278314 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR168ConfigurationProcessor.java
@@ -77,15 +77,17 @@ public class JSR168ConfigurationProcessor extends ConfigurationProcessor {
                                                       .getLogger(JSR168ConfigurationProcessor.class);
    // private static final boolean         isDebug = LOG.isDebugEnabled();
    private static final boolean         isTrace = LOG.isTraceEnabled();
-
+   
+   public JSR168ConfigurationProcessor(PortletApplicationDefinition pad) {
+      super(pad);
+   }
 
    /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.impl.jsr168.ConfigurationProcessor#process(javax.xml.bind.JAXBElement)
     */
    @Override
-   public PortletApplicationDefinition process(JAXBElement<?> rootElement)
+   public void process(JAXBElement<?> rootElement)
          throws IllegalArgumentException {
-      pad = new PortletApplicationDefinitionImpl();
 
       // make sure we were called properly
       assert (rootElement != null);
@@ -120,7 +122,6 @@ public class JSR168ConfigurationProcessor extends ConfigurationProcessor {
       handleUA(app.getUserAttribute());
       handlePortlets(app.getPortlet());
 
-      return pad;
    }
 
    /**
@@ -559,6 +560,7 @@ public class JSR168ConfigurationProcessor extends ConfigurationProcessor {
 
       }
    }
+
    @Override
    public void validate() throws IllegalArgumentException {
       // For version 1.0, do nothing.

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
index 248633e..28df6f8 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Locale;
 
 import javax.portlet.Portlet;
-import javax.portlet.PortletPreferences;
 import javax.portlet.PortletURLGenerationListener;
 import javax.portlet.PreferencesValidator;
 import javax.portlet.filter.PortletFilter;
@@ -98,6 +97,10 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
    // private static final boolean isDebug = LOG.isDebugEnabled();
    private static final boolean         isTrace = LOG.isTraceEnabled();
 
+   public JSR286ConfigurationProcessor(PortletApplicationDefinition pad) {
+      super(pad);
+   }
+
    /*
     * (non-Javadoc)
     * 
@@ -106,9 +109,7 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
     * #process(javax.xml.bind.JAXBElement)
     */
    @Override
-   public PortletApplicationDefinition process(JAXBElement<?> rootElement)
-         throws IllegalArgumentException {
-      pad = new PortletApplicationDefinitionImpl();
+   public void process(JAXBElement<?> rootElement) throws IllegalArgumentException {
 
       // make sure we were called properly
       assert (rootElement != null);
@@ -172,7 +173,6 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
       handlePortlets(app.getPortlet());
       handleFilterMappings(app.getFilterMapping());
 
-      return pad;
    }
 
    /**
@@ -792,15 +792,15 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
             if (pit.getTitle() != null) {
                title = pit.getTitle().getValue();
             }
-               if (pit.getShortTitle() != null) {
-                  st = pit.getShortTitle().getValue();
-               }
-               if (pit.getKeywords() != null) {
-                  kw = pit.getKeywords().getValue();
-               }
-               PortletInfo info = new PortletInfoImpl(title, kw, st);
-               pd.setPortletInfo(info);
+            if (pit.getShortTitle() != null) {
+               st = pit.getShortTitle().getValue();
+            }
+            if (pit.getKeywords() != null) {
+               kw = pit.getKeywords().getValue();
             }
+            PortletInfo info = new PortletInfoImpl(title, kw, st);
+            pd.setPortletInfo(info);
+         }
 
          for (SupportedLocaleType slt : portlet.getSupportedLocale()) {
             pd.addSupportedLocale(slt.getValue());


[08/35] portals-pluto git commit: Added configuration by annotation for V3 portlets. For v3 portlets, neither the web application deployment descriptor nor the portlet deployment descriptor are necessary. * Annotations provided for all portlet config

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 03d6d50..6a961df 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -19,11 +19,26 @@
 package org.apache.pluto.container.om.portlet.impl;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
+import java.util.Random;
 
 import javax.portlet.Portlet;
-import javax.portlet.PreferencesValidator;
+import javax.portlet.PortletRequest;
+import javax.portlet.annotations.InitParameter;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletRequestFilter;
+import javax.portlet.annotations.PublicRenderParameterDefinition;
+import javax.portlet.annotations.RuntimeOption;
+import javax.portlet.annotations.UserAttribute;
+import javax.portlet.filter.ActionFilter;
+import javax.portlet.filter.EventFilter;
+import javax.portlet.filter.HeaderFilter;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
 import javax.xml.XMLConstants;
 import javax.xml.bind.JAXBElement;
 import javax.xml.namespace.QName;
@@ -33,6 +48,7 @@ import org.apache.pluto.container.om.portlet.CustomPortletMode;
 import org.apache.pluto.container.om.portlet.CustomWindowState;
 import org.apache.pluto.container.om.portlet.Description;
 import org.apache.pluto.container.om.portlet.DisplayName;
+import org.apache.pluto.container.om.portlet.Dependency;
 import org.apache.pluto.container.om.portlet.EventDefinition;
 import org.apache.pluto.container.om.portlet.EventDefinitionReference;
 import org.apache.pluto.container.om.portlet.Filter;
@@ -45,13 +61,12 @@ import org.apache.pluto.container.om.portlet.PortletInfo;
 import org.apache.pluto.container.om.portlet.Preference;
 import org.apache.pluto.container.om.portlet.Preferences;
 import org.apache.pluto.container.om.portlet.PublicRenderParameter;
-import org.apache.pluto.container.om.portlet.SecurityConstraint;
 import org.apache.pluto.container.om.portlet.SecurityRoleRef;
 import org.apache.pluto.container.om.portlet.Supports;
-import org.apache.pluto.container.om.portlet.UserDataConstraint;
 import org.apache.pluto.container.om.portlet30.impl.ContainerRuntimeOptionType;
 import org.apache.pluto.container.om.portlet30.impl.CustomPortletModeType;
 import org.apache.pluto.container.om.portlet30.impl.CustomWindowStateType;
+import org.apache.pluto.container.om.portlet30.impl.DependencyType;
 import org.apache.pluto.container.om.portlet30.impl.DescriptionType;
 import org.apache.pluto.container.om.portlet30.impl.DisplayNameType;
 import org.apache.pluto.container.om.portlet30.impl.EventDefinitionReferenceType;
@@ -59,10 +74,10 @@ import org.apache.pluto.container.om.portlet30.impl.EventDefinitionType;
 import org.apache.pluto.container.om.portlet30.impl.FilterMappingType;
 import org.apache.pluto.container.om.portlet30.impl.FilterType;
 import org.apache.pluto.container.om.portlet30.impl.InitParamType;
+import org.apache.pluto.container.om.portlet30.impl.KeywordsType;
 import org.apache.pluto.container.om.portlet30.impl.ListenerType;
 import org.apache.pluto.container.om.portlet30.impl.MimeTypeType;
 import org.apache.pluto.container.om.portlet30.impl.PortletAppType;
-import org.apache.pluto.container.om.portlet30.impl.PortletCollectionType;
 import org.apache.pluto.container.om.portlet30.impl.PortletInfoType;
 import org.apache.pluto.container.om.portlet30.impl.PortletModeType;
 import org.apache.pluto.container.om.portlet30.impl.PortletNameType;
@@ -70,12 +85,12 @@ import org.apache.pluto.container.om.portlet30.impl.PortletPreferencesType;
 import org.apache.pluto.container.om.portlet30.impl.PortletType;
 import org.apache.pluto.container.om.portlet30.impl.PreferenceType;
 import org.apache.pluto.container.om.portlet30.impl.PublicRenderParameterType;
-import org.apache.pluto.container.om.portlet30.impl.SecurityConstraintType;
 import org.apache.pluto.container.om.portlet30.impl.SecurityRoleRefType;
+import org.apache.pluto.container.om.portlet30.impl.ShortTitleType;
 import org.apache.pluto.container.om.portlet30.impl.SupportedLocaleType;
 import org.apache.pluto.container.om.portlet30.impl.SupportsType;
+import org.apache.pluto.container.om.portlet30.impl.TitleType;
 import org.apache.pluto.container.om.portlet30.impl.UserAttributeType;
-import org.apache.pluto.container.om.portlet30.impl.UserDataConstraintType;
 import org.apache.pluto.container.om.portlet30.impl.ValueType;
 import org.apache.pluto.container.om.portlet30.impl.WindowStateType;
 import org.slf4j.Logger;
@@ -90,22 +105,21 @@ import org.slf4j.LoggerFactory;
 public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
    /** Logger. */
-   private static final Logger          LOG     = LoggerFactory
-                                                      .getLogger(JSR362ConfigurationProcessor.class);
+   private static final Logger  LOG     = LoggerFactory.getLogger(JSR362ConfigurationProcessor.class);
    // private static final boolean isDebug = LOG.isDebugEnabled();
-   private static final boolean         isTrace = LOG.isTraceEnabled();
+   private static final boolean isTrace = LOG.isTraceEnabled();
+
+   public JSR362ConfigurationProcessor(PortletApplicationDefinition pad) {
+      super(pad);
+   }
 
    /*
     * (non-Javadoc)
     * 
-    * @see
-    * org.apache.pluto.container.om.portlet.impl.jsr362.ConfigurationProcessor
-    * #process(javax.xml.bind.JAXBElement)
+    * @see org.apache.pluto.container.om.portlet.impl.jsr362.ConfigurationProcessor #process(javax.xml.bind.JAXBElement)
     */
    @Override
-   public PortletApplicationDefinition process(JAXBElement<?> rootElement)
-         throws IllegalArgumentException {
-      pad = new PortletApplicationDefinitionImpl();
+   public void process(JAXBElement<?> rootElement) throws IllegalArgumentException {
 
       // make sure we were called properly
       assert (rootElement != null);
@@ -134,15 +148,13 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          LOG.trace(txt.toString());
       }
 
-      if (app.getDefaultNamespace() != null
-            && !app.getDefaultNamespace().equals("")) {
+      if (app.getDefaultNamespace() != null && !app.getDefaultNamespace().equals("")) {
          pad.setDefaultNamespace(app.getDefaultNamespace());
       } else {
          pad.setDefaultNamespace(XMLConstants.NULL_NS_URI);
       }
 
-      if (app.getResourceBundle() != null
-            && app.getResourceBundle().getValue() != null
+      if (app.getResourceBundle() != null && app.getResourceBundle().getValue() != null
             && !app.getResourceBundle().getValue().equals("")) {
          pad.setResourceBundle(app.getResourceBundle().getValue());
       }
@@ -151,25 +163,22 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          pad.addEventDefinition(ed);
       }
 
-      for (PublicRenderParameter prp : handlePRPs(app
-            .getPublicRenderParameter())) {
+      for (PublicRenderParameter prp : handlePRPs(app.getPublicRenderParameter())) {
          pad.addPublicRenderParameter(prp);
       }
-      
+
       for (ContainerRuntimeOption cro : handleRTOptions(app.getContainerRuntimeOption())) {
          pad.addContainerRuntimeOption(cro);
       }
 
       handleCPM(app.getCustomPortletMode());
       handleCWS(app.getCustomWindowState());
-      handleSC(app.getSecurityConstraint());
       handleUA(app.getUserAttribute());
       handleListeners(app.getListener());
       handleFilters(app.getFilter());
       handlePortlets(app.getPortlet());
       handleFilterMappings(app.getFilterMapping());
 
-      return pad;
    }
 
    /**
@@ -228,8 +237,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          }
 
          // set up the user attribute
-         UserAttributeImpl attr = new UserAttributeImpl(uat.getName()
-               .getValue());
+         UserAttributeImpl attr = new UserAttributeImpl(uat.getName().getValue());
          for (Description desc : handleDescriptions(uat.getDescription())) {
             attr.addDescription(desc);
          }
@@ -247,8 +255,8 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (FilterType item : args) {
 
          // validate data
-         if ((item.getFilterName() == null) || (item.getFilterName().length() == 0)
-               || (item.getFilterClass() == null) || (item.getFilterClass().length() == 0)) {
+         if ((item.getFilterName() == null) || (item.getFilterName().length() == 0) || (item.getFilterClass() == null)
+               || (item.getFilterClass().length() == 0)) {
             String warning = "Bad Filter definition. name or class was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -289,7 +297,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
-         
+
          // set up the filter mapping
          FilterMapping newitem = new FilterMappingImpl(fname);
          for (PortletNameType pnt : item.getPortletName()) {
@@ -314,16 +322,20 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
+         
 
          // set up the listener
          Listener newitem = new ListenerImpl(item.getListenerClass());
+         if (item.getListenerName() != null) {
+            newitem.setListenerName(item.getListenerName());
+         }
          for (Description desc : handleDescriptions(item.getDescription())) {
             newitem.addDescription(desc);
          }
          for (DisplayName dispName : handleDisplayNames(item.getDisplayName())) {
             newitem.addDisplayName(dispName);
          }
-         
+
          // add it to the model
          pad.addListener(newitem);
 
@@ -337,15 +349,13 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (CustomPortletModeType cpm : cpms) {
 
          // validate data
-         if ((cpm.getPortletMode() == null)
-               || (cpm.getPortletMode().getValue() == null)) {
+         if ((cpm.getPortletMode() == null) || (cpm.getPortletMode().getValue() == null)) {
             String warning = "Custom portlet mode cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          } else {
             String val = cpm.getPortletMode().getValue();
-            if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit")
-                  || val.equalsIgnoreCase("help")) {
+            if (val.equalsIgnoreCase("view") || val.equalsIgnoreCase("edit") || val.equalsIgnoreCase("help")) {
                String warning = "Bad custom portlet mode: " + val;
                LOG.warn(warning);
                throw new IllegalArgumentException(warning);
@@ -353,16 +363,13 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          }
 
          // set up the custom portlet mode
-         CustomPortletMode pm = new CustomPortletModeImpl(cpm.getPortletMode()
-               .getValue());
+         CustomPortletMode pm = new CustomPortletModeImpl(cpm.getPortletMode().getValue());
          for (Description desc : handleDescriptions(cpm.getDescription())) {
             pm.addDescription(desc);
          }
          boolean isPortalManaged = true; // default is true
-         if (cpm.getPortalManaged() != null
-               && cpm.getPortalManaged().value() != null) {
-            isPortalManaged = cpm.getPortalManaged().value()
-                  .equalsIgnoreCase("true");
+         if (cpm.getPortalManaged() != null && cpm.getPortalManaged().value() != null) {
+            isPortalManaged = cpm.getPortalManaged().value().equalsIgnoreCase("true");
          }
          pm.setPortalManaged(isPortalManaged);
 
@@ -379,8 +386,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (CustomWindowStateType cws : cwss) {
 
          // validate data
-         if ((cws.getWindowState() == null)
-               || (cws.getWindowState().getValue() == null)) {
+         if ((cws.getWindowState() == null) || (cws.getWindowState().getValue() == null)) {
             String warning = "Custom window state cannot be null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -395,8 +401,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          }
 
          // set up the custom portlet mode
-         CustomWindowState ws = new CustomWindowStateImpl(cws.getWindowState()
-               .getValue());
+         CustomWindowState ws = new CustomWindowStateImpl(cws.getWindowState().getValue());
          for (Description desc : handleDescriptions(cws.getDescription())) {
             ws.addDescription(desc);
          }
@@ -408,59 +413,6 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
    }
 
-   /**
-    * Security constraints
-    */
-   private void handleSC(List<SecurityConstraintType> scs) {
-      for (SecurityConstraintType sc : scs) {
-
-         // validate data
-         PortletCollectionType pct = sc.getPortletCollection();
-         if ((pct == null) || (pct.getPortletName() == null)
-               || (pct.getPortletName().size() == 0)) {
-            String warning = "Portlet collection is empty.";
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         } else {
-            for (PortletNameType pnt : pct.getPortletName()) {
-               if (pnt.getValue().length() == 0) {
-                  String warning = "Portlet name may not be null.";
-                  LOG.warn(warning);
-                  throw new IllegalArgumentException(warning);
-               }
-            }
-         }
-
-         UserDataConstraintType udc = sc.getUserDataConstraint();
-         if ((udc == null) || (udc.getTransportGuarantee() == null)
-               || (udc.getTransportGuarantee().value() == null)) {
-            String warning = "User data constraint contains null value.";
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
-
-         // set up the user data constraint
-         UserDataConstraint newudc = new UserDataConstraintImpl(udc
-               .getTransportGuarantee().value());
-         for (Description desc : handleDescriptions(udc.getDescription())) {
-            newudc.addDescription(desc);
-         }
-
-         // set up the security constraint
-         SecurityConstraint newsc = new SecurityConstraintImpl(newudc);
-         for (DisplayName dispName : handleDisplayNames(sc.getDisplayName())) {
-            newsc.addDisplayName(dispName);
-         }
-         for (PortletNameType portletName : pct.getPortletName()) {
-            newsc.addPortletName(portletName.getValue());
-         }
-
-         // add it to the model
-         pad.addSecurityConstraint(newsc);
-
-      }
-   }
-
    private List<Supports> handleSupports(List<SupportsType> sts) {
       ArrayList<Supports> newSupps = new ArrayList<Supports>();
       for (SupportsType st : sts) {
@@ -507,8 +459,8 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (InitParamType parm : parms) {
 
          // validate data
-         if ((parm.getName() == null) || (parm.getName().getValue() == null) ||
-               (parm.getName().getValue().length() == 0)) {
+         if ((parm.getName() == null) || (parm.getName().getValue() == null)
+               || (parm.getName().getValue().length() == 0)) {
             String warning = "Bad init parameter. Parameter name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -535,8 +487,8 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (PreferenceType item : args) {
 
          // validate data
-         if ((item.getName() == null) || (item.getName().getValue() == null) ||
-               (item.getName().getValue().length() == 0)) {
+         if ((item.getName() == null) || (item.getName().getValue() == null)
+               || (item.getName().getValue().length() == 0)) {
             String warning = "Bad portlet preference. Preference name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -549,7 +501,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          for (ValueType vt : vals) {
             lines.add(vt.getValue());
          }
-         boolean isRO = false;      // default if not specified
+         boolean isRO = false; // default if not specified
          if (item.getReadOnly() != null && item.getReadOnly().value() != null) {
             isRO = (item.getReadOnly().value().equalsIgnoreCase("true"));
          }
@@ -560,14 +512,12 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       return list;
    }
 
-   private List<ContainerRuntimeOption> handleRTOptions(
-         List<ContainerRuntimeOptionType> args) {
+   private List<ContainerRuntimeOption> handleRTOptions(List<ContainerRuntimeOptionType> args) {
       ArrayList<ContainerRuntimeOption> list = new ArrayList<ContainerRuntimeOption>();
       for (ContainerRuntimeOptionType arg : args) {
 
          // validate data
-         if ((arg.getName() == null) || (arg.getName().getValue() == null)
-               || arg.getName().getValue().equals("")) {
+         if ((arg.getName() == null) || (arg.getName().getValue() == null) || arg.getName().getValue().equals("")) {
             String warning = "Bad container runtime option. Name was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -581,8 +531,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             lines.add(vt.getValue());
          }
 
-         ContainerRuntimeOption item = new ContainerRuntimeOptionImpl(name,
-               lines);
+         ContainerRuntimeOption item = new ContainerRuntimeOptionImpl(name, lines);
          list.add(item);
 
       }
@@ -597,9 +546,8 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       for (SecurityRoleRefType item : args) {
 
          // validate data
-         if ((item.getRoleName() == null) || (item.getRoleName().length() == 0) || 
-               (item.getRoleLink() == null) || (item.getRoleLink().getValue() == null) ||
-               (item.getRoleLink().getValue().length() == 0)) {
+         if ((item.getRoleName() == null) || (item.getRoleName().length() == 0) || (item.getRoleLink() == null)
+               || (item.getRoleLink().getValue() == null) || (item.getRoleLink().getValue().length() == 0)) {
             String warning = "Bad security role reference. Name or link was null.";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
@@ -607,7 +555,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
          // set up the role ref
          String name = item.getRoleName();
-         String link = item.getRoleLink().getValue();
+         String link = (item.getRoleLink() != null) ? item.getRoleLink().getValue() : null;
          SecurityRoleRef srr = new SecurityRoleRefImpl(name);
          srr.setRoleLink(link);
          for (Description desc : handleDescriptions(item.getDescription())) {
@@ -620,11 +568,9 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
    }
 
    /**
-    * Event definition references - supported publishing events & supported
-    * processing events
+    * Event definition references - supported publishing events & supported processing events
     */
-   private List<EventDefinitionReference> handleEventDefRefs(
-         List<EventDefinitionReferenceType> args) {
+   private List<EventDefinitionReference> handleEventDefRefs(List<EventDefinitionReferenceType> args) {
       ArrayList<EventDefinitionReference> list = new ArrayList<EventDefinitionReference>();
       for (EventDefinitionReferenceType item : args) {
 
@@ -643,8 +589,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          }
 
          // set up the event def ref
-         EventDefinitionReference newedr = new EventDefinitionReferenceImpl(
-               qname);
+         EventDefinitionReference newedr = new EventDefinitionReferenceImpl(qname);
 
          list.add(newedr);
       }
@@ -690,8 +635,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
       return list;
    }
 
-   private List<PublicRenderParameter> handlePRPs(
-         List<PublicRenderParameterType> args) {
+   private List<PublicRenderParameter> handlePRPs(List<PublicRenderParameterType> args) {
       ArrayList<PublicRenderParameter> list = new ArrayList<PublicRenderParameter>();
       for (PublicRenderParameterType item : args) {
 
@@ -720,9 +664,6 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          for (Description desc : handleDescriptions(item.getDescription())) {
             newprp.addDescription(desc);
          }
-         for (QName qn : item.getAlias()) {
-            newprp.addAlias(qn);
-         }
 
          list.add(newprp);
       }
@@ -738,24 +679,28 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
          // validate portlet name & class
          String warning;
-         if (portlet.getPortletName() == null || portlet.getPortletName().getValue() == null ||
-               portlet.getPortletName().getValue().length() == 0) {
+         if (portlet.getPortletName() == null || portlet.getPortletName().getValue() == null
+               || portlet.getPortletName().getValue().length() == 0) {
             warning = "Portlet name may not be null";
             LOG.warn(warning);
             throw new IllegalArgumentException(warning);
          }
+         
          String pn = portlet.getPortletName().getValue();
-
          String clsName = portlet.getPortletClass();
-         if (clsName == null || clsName.length() == 0) {
-            warning = "Portlet class may not be null";
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
-         }
 
          // set up portlet definition
 
-         PortletDefinition pd = new PortletDefinitionImpl(pn, pad);
+         PortletDefinition pd = pad.getPortlet(pn);
+         if (pd == null) {
+            // If no annotated definition, the class name must be present
+            if (clsName == null || clsName.length() == 0) {
+               warning = "Portlet class may not be null";
+               LOG.warn(warning);
+               throw new IllegalArgumentException(warning);
+            }
+            pd = new PortletDefinitionImpl(pn, pad);
+         }
          pd.setPortletClass(portlet.getPortletClass());
 
          if (portlet.getResourceBundle() != null) {
@@ -770,8 +715,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             pd.setCacheScope(portlet.getCacheScope().getValue());
          }
 
-         for (DisplayName dispName : handleDisplayNames(portlet
-               .getDisplayName())) {
+         for (DisplayName dispName : handleDisplayNames(portlet.getDisplayName())) {
             pd.addDisplayName(dispName);
          }
 
@@ -783,22 +727,34 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             pd.addSupports(s);
          }
 
+         // handle portlet info
+
          PortletInfoType pit = portlet.getPortletInfo();
          if (pit != null) {
-               String title = null, st = null, kw = null;
-            if (pit.getTitle() != null) {
-               title = pit.getTitle().getValue();
+
+            PortletInfo info = pd.getPortletInfo();
+            if (info == null) {
+               info = new PortletInfoImpl();
             }
-               if (pit.getShortTitle() != null) {
-                  st = pit.getShortTitle().getValue();
-               }
-               if (pit.getKeywords() != null) {
-                  kw = pit.getKeywords().getValue();
-               }
-               PortletInfo info = new PortletInfoImpl(title, kw, st);
-               pd.setPortletInfo(info);
+
+            for (TitleType item : pit.getTitle()) {
+               Locale loc = (item.getLang() == null) ? Locale.ENGLISH : Locale.forLanguageTag(item.getLang());
+               info.addTitle(new LocaleTextImpl(loc, item.getValue()));
             }
 
+            for (ShortTitleType item : pit.getShortTitle()) {
+               Locale loc = (item.getLang() == null) ? Locale.ENGLISH : Locale.forLanguageTag(item.getLang());
+               info.addShortTitle(new LocaleTextImpl(loc, item.getValue()));
+            }
+
+            for (KeywordsType item : pit.getKeywords()) {
+               Locale loc = (item.getLang() == null) ? Locale.ENGLISH : Locale.forLanguageTag(item.getLang());
+               info.addKeywords(new LocaleTextImpl(loc, item.getValue()));
+            }
+
+            pd.setPortletInfo(info);
+         }
+
          for (SupportedLocaleType slt : portlet.getSupportedLocale()) {
             pd.addSupportedLocale(slt.getValue());
          }
@@ -809,7 +765,12 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
 
          PortletPreferencesType prefs = portlet.getPortletPreferences();
          if (prefs != null) {
-            Preferences newprefs = new PreferencesImpl();
+
+            // merge the new prefs with the old
+            Preferences newprefs = pd.getPortletPreferences();
+            if (newprefs == null) {
+               newprefs = new PreferencesImpl();
+            }
 
             clsName = prefs.getPreferencesValidator();
 
@@ -820,13 +781,11 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             pd.setPortletPreferences(newprefs);
          }
 
-         for (SecurityRoleRef srr : handleSecRoleRef(portlet
-               .getSecurityRoleRef())) {
+         for (SecurityRoleRef srr : handleSecRoleRef(portlet.getSecurityRoleRef())) {
             pd.addSecurityRoleRef(srr);
          }
 
-         for (ContainerRuntimeOption cro : handleRTOptions(portlet
-               .getContainerRuntimeOption())) {
+         for (ContainerRuntimeOption cro : handleRTOptions(portlet.getContainerRuntimeOption())) {
             pd.addContainerRuntimeOption(cro);
          }
 
@@ -840,27 +799,391 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          }
 
          // Supported processing events
-         for (EventDefinitionReference edr : handleEventDefRefs(portlet
-               .getSupportedProcessingEvent())) {
+         for (EventDefinitionReference edr : handleEventDefRefs(portlet.getSupportedProcessingEvent())) {
             pd.addSupportedProcessingEvent(edr);
          }
 
          // Supported publishing events
-         for (EventDefinitionReference edr : handleEventDefRefs(portlet
-               .getSupportedPublishingEvent())) {
+         for (EventDefinitionReference edr : handleEventDefRefs(portlet.getSupportedPublishingEvent())) {
             pd.addSupportedPublishingEvent(edr);
          }
+         
+         // dependencies
+         for (DependencyType dt : portlet.getDependency()) {
+            if (dt.getName() == null || dt.getName().getValue() == null || dt.getName().getValue().length() == 0) {
+               String warn = "Dependency name is empty, ignoring Dependency block.";
+               LOG.warn(warn);
+               continue;
+            }
+            if (dt.getMinVersion() == null || dt.getMinVersion().getValue() == null || dt.getMinVersion().getValue().length() == 0) {
+               String warn = "Dependency minimum version is empty, ignoring Dependency block.";
+               LOG.warn(warn);
+               continue;
+            }
+            Dependency dep = new DependencyImpl(dt.getName().getValue(), dt.getMinVersion().getValue());
+            pd.addDependency(dep);
+         }
 
          pad.addPortlet(pd);
 
       }
    }
-   
+
    /**
     * validate the v3.0 configuration
     */
-   public void validate () {
-      super.validate();             // reuse the 2.0 validation code
+   public void validate() {
+      super.validate(); // reuse the 2.0 validation code
+   }
+
+   /**
+    * Extracts the data from the portlet application annotation and adds it to the portlet application definition
+    * structure.
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor is read so that data from the
+    * portlet DD can override that provided through annotations.
+    * 
+    * @param app
+    *           The portlet application annotation
+    */
+   @Override
+   public void processPortletAppAnnotation(PortletApplication app) {
+
+      // version
+      if (!app.version().equals("3.0")) {
+         String warning = "Bad version in annotation. Expected 3.0, was: " + app.version();
+         LOG.warn(warning);
+         throw new IllegalArgumentException(warning);
+      }
+      pad.setVersion(app.version());
+
+      // default namespace & resource bundle
+      pad.setDefaultNamespace(app.defaultNamespaceURI());
+      pad.setResourceBundle(app.resourceBundle());
+
+      // runtime options
+      for (RuntimeOption ro : app.runtimeOptions()) {
+         ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(ro.name(), Arrays.asList(ro.values()));
+         pad.addContainerRuntimeOption(cro);
+      }
+
+      // User Attributes
+      for (UserAttribute ua : app.userAttributes()) {
+         org.apache.pluto.container.om.portlet.UserAttribute attrib = new UserAttributeImpl(ua.name());
+         for (LocaleString ls : ua.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            attrib.addDescription(d);
+         }
+         pad.addUserAttribute(attrib);
+      }
+
+      // Public render parameter defs
+      for (PublicRenderParameterDefinition prpd : app.publicParams()) {
+         QName qn = new QName(prpd.qname().namespaceURI(), prpd.qname().localPart());
+         PublicRenderParameter prp = new PublicRenderParameterImpl(qn, prpd.identifier());
+         for (LocaleString ls : prpd.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            prp.addDescription(d);
+         }
+         for (LocaleString ls : prpd.displayName()) {
+            DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            prp.addDisplayName(d);
+         }
+         pad.addPublicRenderParameter(prp);
+      }
+
+      // Event defs
+      for (javax.portlet.annotations.EventDefinition ed : app.events()) {
+         QName qn = new QName(ed.qname().namespaceURI(), ed.qname().localPart());
+         EventDefinition evt = new EventDefinitionImpl(qn);
+         for (LocaleString ls : ed.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            evt.addDescription(d);
+         }
+         for (LocaleString ls : ed.displayName()) {
+            DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            evt.addDisplayName(d);
+         }
+         pad.addEventDefinition(evt);
+      }
+
+      // Custom portlet mode
+      for (javax.portlet.annotations.CustomPortletMode cpm : app.customPortletModes()) {
+         org.apache.pluto.container.om.portlet.CustomPortletMode mode = new CustomPortletModeImpl(cpm.name());
+         for (LocaleString ls : cpm.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            mode.addDescription(d);
+         }
+         mode.setPortalManaged(cpm.portalManaged());
+         pad.addCustomPortletMode(mode);
+      }
+
+      // Custom window state
+      for (javax.portlet.annotations.CustomWindowState cpm : app.customWindowStates()) {
+         org.apache.pluto.container.om.portlet.CustomWindowState ws = new CustomWindowStateImpl(cpm.name());
+         for (LocaleString ls : cpm.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            ws.addDescription(d);
+         }
+         pad.addCustomWindowState(ws);
+      }
+
+   }
+
+   /**
+    * Extracts the data from the portlet annotation and adds it to a portlet filter definition structure. The portlet
+    * filter definition will be created if it does not already exist.
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor is read so that data from the
+    * portlet DD can override that provided through annotations.
+    * 
+    * @param cls
+    *           The annotated class.
+    */
+   @Override
+   public void processPortletFilterAnnotation(Class<?> cls) {
+
+      PortletRequestFilter prf = cls.getAnnotation(PortletRequestFilter.class);
+      if (prf != null) {
+
+         // determine the lifecycles based on the implemented filter interfaces
+         List<String> lc = new ArrayList<String>();
+         if (ActionFilter.class.isAssignableFrom(cls)) {
+            lc.add(PortletRequest.ACTION_PHASE);
+         }
+         if (RenderFilter.class.isAssignableFrom(cls)) {
+            lc.add(PortletRequest.RENDER_PHASE);
+         }
+         if (ResourceFilter.class.isAssignableFrom(cls)) {
+            lc.add(PortletRequest.RESOURCE_PHASE);
+         }
+         if (EventFilter.class.isAssignableFrom(cls)) {
+            lc.add(PortletRequest.EVENT_PHASE);
+         }
+         if (HeaderFilter.class.isAssignableFrom(cls)) {
+            lc.add(PortletRequest.HEADER_PHASE);
+         }
+
+         if (lc.size() == 0) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("@PortletRequestFilter annotated class must implement ActionFilter, RenderFilter, EventFilter, ResourceFilter, or HeaderFilter. ");
+            txt.append(", class: ").append(cls.getCanonicalName());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+
+         // prepare the filter definition
+         String clsName = cls.getCanonicalName();
+         String fn = prf.filterName();
+         if (fn.length() == 0) {
+            // create random name
+            final String chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZüÜäÄöÖß";
+            StringBuilder txt = new StringBuilder(128);
+            Random rand = new Random();
+            for (int ii = 0; ii < 32; ii++) {
+               txt.append(chars.charAt(rand.nextInt(chars.length())));
+            }
+            fn = "Generated " + txt.toString();
+         }
+         if (isTrace) {
+            LOG.trace("Adding filter named: " + fn);
+         }
+
+         if (pad.getFilter(fn) != null) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Duplicate filter annotation. FilterName: ").append(fn);
+            txt.append(", class: ").append(cls.getCanonicalName());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+
+         Filter filter = new FilterImpl(fn);
+         filter.setFilterClass(clsName);
+         for (String l : lc) {
+            filter.addLifecycle(l);
+         }
+         filter.setOrdinal(prf.ordinal());
+
+         for (LocaleString ls : prf.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            filter.addDescription(d);
+         }
+         for (LocaleString ls : prf.displayName()) {
+            DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            filter.addDisplayName(d);
+         }
+
+         for (InitParameter ip : prf.initParams()) {
+            InitParam plutoInitParam = new InitParamImpl(ip.name(), ip.value());
+            for (LocaleString ls : ip.description()) {
+               Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+               plutoInitParam.addDescription(d);
+            }
+            filter.addInitParam(plutoInitParam);
+         }
+
+         pad.addFilter(filter);
+
+         // now prepare and store the filter mapping
+
+         FilterMapping mapping = new FilterMappingImpl(fn);
+         for (String portletName : prf.portletNames()) {
+            mapping.addPortletName(portletName);
+         }
+         pad.addFilterMapping(mapping);
+
+      }
+   }
+
+   /**
+    * Extracts the data from the portlet annotation and adds it to a portlet definition structure. The portlet
+    * definition will be created if it does not already exist.
+    * <p>
+    * This method is designed to be called before the portlet deployment descriptor is read so that data from the
+    * portlet DD can override that provided through annotations.
+    * 
+    * @param pc   The portlet configuration annotation
+    * @param cls  The annotated class
+    */
+   @Override
+   public void processPortletConfigAnnotation(PortletConfiguration pc, Class<?> cls) {
+
+      if (pc != null) {
+
+         // Each portlet config annotation must have a unique portlet name
+         String portletName = pc.portletName();
+         if (pad.getPortlet(portletName) != null) {
+            StringBuilder txt = new StringBuilder(128);
+            txt.append("Duplicate portlet configuration annotation. Portlet name: ").append(portletName);
+            txt.append(", class: ").append(cls.getCanonicalName());
+            LOG.warn(txt.toString());
+            throw new IllegalArgumentException(txt.toString());
+         }
+
+         PortletDefinition pd = new PortletDefinitionImpl(portletName, pad);
+
+         // If the portlet config annotation is applied to a class that implements the
+         // Portlet interface, add the portlet class, otherwise, don't.
+         if (Portlet.class.isAssignableFrom(cls)) {
+            pd.setPortletClass(cls.getCanonicalName());
+         }
+
+         // handle descriptions, display names, and init params
+
+         for (LocaleString ls : pc.description()) {
+            Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            pd.addDescription(d);
+         }
+
+         for (LocaleString ls : pc.displayName()) {
+            DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+            pd.addDisplayName(d);
+         }
+
+         for (InitParameter ip : pc.initParams()) {
+            InitParam plutoInitParam = new InitParamImpl(ip.name(), ip.value());
+            for (LocaleString ls : ip.description()) {
+               Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+               plutoInitParam.addDescription(d);
+            }
+            pd.addInitParam(plutoInitParam);
+         }
+
+         // cache scope, expiration time, resource bundle
+
+         pd.setCacheScope(pc.cacheScopePublic() ? "public" : "private");
+         pd.setExpirationCache(pc.cacheExpirationTime());
+         pd.setResourceBundle(pc.resourceBundle());
+
+         // handle portlet info - title, short title, keywords
+
+         PortletInfo info = new PortletInfoImpl();
+         boolean infoAdded = false;
+
+         for (LocaleString item : pc.title()) {
+            Locale loc = (item.locale().length() == 0) ? Locale.ENGLISH : Locale.forLanguageTag(item.locale());
+            info.addTitle(new LocaleTextImpl(loc, item.value()));
+            infoAdded = true;
+         }
+
+         for (LocaleString item : pc.shortTitle()) {
+            Locale loc = (item.locale().length() == 0) ? Locale.ENGLISH : Locale.forLanguageTag(item.locale());
+            info.addShortTitle(new LocaleTextImpl(loc, item.value()));
+            infoAdded = true;
+         }
+
+         for (LocaleString item : pc.keywords()) {
+            Locale loc = (item.locale().length() == 0) ? Locale.ENGLISH : Locale.forLanguageTag(item.locale());
+            info.addKeywords(new LocaleTextImpl(loc, item.value()));
+            infoAdded = true;
+         }
+
+         if (infoAdded) {
+            pd.setPortletInfo(info);
+         }
+         
+         // public parameters, supported locales
+         
+         for (String prp : pc.publicParams()) {
+            pd.addSupportedPublicRenderParameter(prp);
+         }
+         
+         for (String loc : pc.supportedLocales()) {
+            pd.addSupportedLocale(loc);
+         }
+         
+         // Container runtime options
+         
+         for (RuntimeOption ro : pc.runtimeOptions()) {
+            ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(ro.name(), Arrays.asList(ro.values()));
+            pd.addContainerRuntimeOption(cro);
+         }
+         
+         // Portlet preferences
+         
+         Preferences prefs = new PreferencesImpl();
+         for (javax.portlet.annotations.Preference pa : pc.prefs()) {
+            Preference pref = new PreferenceImpl(pa.name(), pa.isReadOnly(), Arrays.asList(pa.values()));
+            prefs.addPreference(pref);
+         }
+         if (prefs.getPortletPreferences().size() > 0) {
+            pd.setPortletPreferences(prefs);
+         }
+         
+         // Supports
+         
+         for (javax.portlet.annotations.Supports sa : pc.supports()) {
+            Supports supps = new SupportsImpl(sa.mimeType());
+            for (String pm : sa.portletModes()) {
+               supps.addPortletMode(pm);
+            }
+            for (String ws : sa.windowStates()) {
+               supps.addWindowState(ws);
+            }
+            pd.addSupports(supps);
+         }
+         
+         // Security role refs
+         
+         for (javax.portlet.annotations.SecurityRoleRef srra : pc.roleRefs()) {
+            SecurityRoleRef ref = new SecurityRoleRefImpl(srra.roleName());
+            ref.setRoleLink(srra.roleLink());
+            for (LocaleString ls : srra.description()) {
+               Description d = new DescriptionImpl(Locale.forLanguageTag(ls.locale()), ls.value());
+               ref.addDescription(d);
+            }
+            pd.addSecurityRoleRef(ref);
+         }
+         
+         // dependencies
+
+         for (javax.portlet.annotations.Dependency da : pc.dependencies()) {
+            Dependency dep = new DependencyImpl(da.name(), da.minVersion());
+            pd.addDependency(dep);
+         }
+
+         pad.addPortlet(pd);
+      }
    }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
index 499979f..335fb1e 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/ListenerImpl.java
@@ -37,6 +37,7 @@ public class ListenerImpl implements Listener {
    private final List<Description> descs = new ArrayList<Description>();
    private final List<DisplayName> dispNames = new ArrayList<DisplayName>();
    private String listenerClass = "";
+   private String listenerName = "";
 
    
    /**
@@ -52,6 +53,7 @@ public class ListenerImpl implements Listener {
          dispNames.add(new DisplayNameImpl(disp));
       }
       listenerClass = lis.getListenerClass();
+      listenerName = lis.getListenerName();
    }
    
    /**
@@ -138,4 +140,56 @@ public class ListenerImpl implements Listener {
       listenerClass = filterClass;
    }
 
+   /**
+    * @return the listenerName
+    */
+   @Override
+   public String getListenerName() {
+      return listenerName;
+   }
+
+   /**
+    * @param listenerName the listenerName to set
+    */
+   @Override
+   public void setListenerName(String listenerName) {
+      this.listenerName = listenerName;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((listenerClass == null) ? 0 : listenerClass.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      ListenerImpl other = (ListenerImpl) obj;
+      if (listenerClass == null) {
+         if (other.listenerClass != null) {
+            return false;
+         }
+      } else if (!listenerClass.equals(other.listenerClass)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/LocaleTextImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/LocaleTextImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/LocaleTextImpl.java
new file mode 100644
index 0000000..a9e905b
--- /dev/null
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/LocaleTextImpl.java
@@ -0,0 +1,136 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl;
+
+import java.util.Locale;
+
+import org.apache.pluto.container.om.portlet.LocaleText;
+
+/**
+ * A single locale-specific text
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class LocaleTextImpl implements LocaleText {
+   
+   private Locale locale;
+   private String text;
+   
+   /**
+    * default: lang = english
+    */
+   public LocaleTextImpl() {
+      locale = Locale.ENGLISH;
+      text = "";
+   }
+   
+   /**
+    * Constructor
+    * @param locale     Locale language tag according to BCP 47
+    * @param disp       text string
+    */
+   public LocaleTextImpl(Locale locale, String text) {
+      this.locale = locale;
+      this.text = text;
+   }
+   
+   /**
+    * Copy constructor
+    */
+   public LocaleTextImpl(LocaleText lt) {
+      this.locale = (Locale) lt.getLocale().clone();
+      this.text = lt.getText();
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.Text#getLang()
+    */
+   @Override
+   public String getLang() {
+      return locale.toLanguageTag();
+   }
+   
+   @Override
+   public void setLang(String lang) {
+      this.locale = Locale.forLanguageTag(lang);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.Text#getText()
+    */
+   @Override
+   public String getText() {
+      return text;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.Text#setText(java.lang.String)
+    */
+   @Override
+   public void setText(String text) {
+      this.text = text;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.Text#getLocale()
+    */
+   @Override
+   public Locale getLocale() {
+      return Locale.forLanguageTag(locale.toLanguageTag());
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((locale == null) ? 0 : locale.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      LocaleTextImpl other = (LocaleTextImpl) obj;
+      if (locale == null) {
+         if (other.locale != null) {
+            return false;
+         }
+      } else if (!locale.equals(other.locale)) {
+         return false;
+      }
+      return true;
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
index 08cd166..382efcb 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
@@ -39,6 +39,8 @@ import org.apache.pluto.container.om.portlet.PortletDefinition;
 import org.apache.pluto.container.om.portlet.PublicRenderParameter;
 import org.apache.pluto.container.om.portlet.SecurityConstraint;
 import org.apache.pluto.container.om.portlet.UserAttribute;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Portlet application definition
@@ -47,6 +49,9 @@ import org.apache.pluto.container.om.portlet.UserAttribute;
  */
 public class PortletApplicationDefinitionImpl implements
       PortletApplicationDefinition {
+   
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletApplicationDefinitionImpl.class);
 
    private String id;
    private String name;
@@ -259,6 +264,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addPortlet(PortletDefinition pd) {
+      if (portlets.remove(pd)) {
+         LOG.debug("Removed duplicate portlet: " + pd.getPortletName());
+      }
       portlets.add( pd);
    }
 
@@ -284,6 +292,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addEventDefinition(EventDefinition ed) {
+      if (events.remove(ed)) {
+         LOG.debug("Removed duplicate event definition: " + ed.getQName());
+      }
       events.add(ed);
    }
 
@@ -309,6 +320,18 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addPublicRenderParameter(PublicRenderParameter prp) {
+      int ii = prps.indexOf(prp);
+      if (ii >= 0) {
+         
+         PublicRenderParameter tprp = prps.get(ii);
+         prps.remove(prp);
+         
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate public render parameter definition for QName: ");
+         txt.append(tprp.getQName());
+         txt.append(", id: ").append(tprp.getIdentifier());
+         LOG.debug(txt.toString());
+      }
       prps.add(prp);
    }
 
@@ -334,6 +357,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addCustomPortletMode(CustomPortletMode cpm) {
+      if (cpms.remove(cpm)) {
+         LOG.debug("Removed duplicate custom portlet mode: " + cpm.getPortletMode());
+      }
       cpms.add(cpm);
    }
 
@@ -359,6 +385,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addCustomWindowState(CustomWindowState cws) {
+      if (cwss.remove(cws)) {
+         LOG.debug("Removed duplicate custom window state: " + cws.getWindowState());
+      }
       cwss.add(cws);
    }
 
@@ -384,6 +413,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addUserAttribute(UserAttribute ua) {
+      if (uattrs.remove(ua)) {
+         LOG.debug("Removed duplicate user attribute: " + ua.getName());
+      }
       uattrs.add(ua);
    }
 
@@ -409,7 +441,15 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addFilter(Filter filter) {
-      filters.add(filter);
+      // If the filter class is null, remove the filter definition, otherwise replace it
+      if (filters.remove(filter)) {
+         LOG.debug("Removed duplicate filter definition: " + filter.getFilterName());
+      } 
+      if (filter.getFilterClass() != null && filter.getFilterClass().length() > 0) {
+         filters.add(filter);
+      } else {
+         LOG.debug("No filter class for filter: " + filter.getFilterName());
+      }
    }
 
    @Override
@@ -434,7 +474,15 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addFilterMapping(FilterMapping fm) {
-      fmaps.add(fm);
+      // If the filter mapping has no portlet names, remove the filter mapping definition, otherwise replace it
+      if (fmaps.remove(fm)) {
+         LOG.debug("Removed duplicate filter mapping: " + fm.getFilterName());
+      }
+      if (fm.getPortletNames().size() > 0) {
+         fmaps.add(fm);
+      } else {
+         LOG.debug("No portlet names for filter mapping. Filter name: " + fm.getFilterName());
+      }
    }
 
    @Override
@@ -459,6 +507,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addContainerRuntimeOption(ContainerRuntimeOption cro) {
+      if (cros.remove(cro)) {
+         LOG.debug("Removed duplicate container runtime option: " + cro.getName());
+      }
       cros.add(cro);
    }
 
@@ -473,6 +524,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addListener(Listener listener) {
+      if (listeners.remove(listener)) {
+         LOG.debug("Removed duplicate listener: " + listener.getListenerClass());
+      }
       listeners.add(listener);
    }
 
@@ -487,6 +541,9 @@ public class PortletApplicationDefinitionImpl implements
 
    @Override
    public void addSecurityConstraint(SecurityConstraint sc) {
+      if (constraints.remove(sc)) {
+         LOG.debug("Removed duplicate security constraint: " + sc.getUserDataConstraint().getTransportGuarantee());
+      }
       constraints.add(sc);
    }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
index 16b1c03..5437e62 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Locale;
 
 import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.Dependency;
 import org.apache.pluto.container.om.portlet.Description;
 import org.apache.pluto.container.om.portlet.DisplayName;
 import org.apache.pluto.container.om.portlet.EventDefinitionReference;
@@ -34,6 +35,8 @@ import org.apache.pluto.container.om.portlet.PortletInfo;
 import org.apache.pluto.container.om.portlet.Preferences;
 import org.apache.pluto.container.om.portlet.SecurityRoleRef;
 import org.apache.pluto.container.om.portlet.Supports;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * @author Scott Nicklous
@@ -41,6 +44,9 @@ import org.apache.pluto.container.om.portlet.Supports;
  */
 public class PortletDefinitionImpl implements PortletDefinition {
    
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletDefinitionImpl.class);
+   
    private PortletApplicationDefinition pad;
    
    private String portletName;
@@ -66,7 +72,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
    
    private final List<InitParam> iparms = new ArrayList<InitParam>(); 
    private final List<SecurityRoleRef> secRefs = new ArrayList<SecurityRoleRef>(); 
-   private final List<Supports> supps = new ArrayList<Supports>(); 
+   private final List<Supports> supps = new ArrayList<Supports>();
+   
+   private final List<Dependency> dependencies = new ArrayList<Dependency>(); 
 
    /**
     * Copy constructor
@@ -115,6 +123,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
       for (Supports s : pd.getSupports()) {
          this.supps.add(new SupportsImpl(s));
       }
+      for (Dependency dep : pd.getDependencies()) {
+         this.dependencies.add(dep);
+      }
    }
    
    /**
@@ -174,6 +185,17 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addInitParam(InitParam ip) {
+      int ii = iparms.indexOf(ip);
+      if (ii >= 0) {
+         
+         InitParam x = iparms.get(ii);
+         iparms.remove(ii);
+         
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate init parameter. name: ").append(x.getParamName());
+         txt.append(", value: ").append(x.getParamValue());
+         LOG.debug(txt.toString());
+      }
       iparms.add(ip);
    }
 
@@ -232,6 +254,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSupportedProcessingEvent(EventDefinitionReference edr) {
+      if (proEvtRefs.remove(edr)) {
+         LOG.debug("Removed duplicate supported processing event ref: " + edr.getQualifiedName());
+      }
       proEvtRefs.add(edr);
    }
 
@@ -248,6 +273,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSupportedPublishingEvent(EventDefinitionReference edr) {
+      if (pubEvtRefs.remove(edr)) {
+         LOG.debug("Removed duplicate supported publishing event ref: " + edr.getQualifiedName());
+      }
       pubEvtRefs.add(edr);
    }
 
@@ -264,6 +292,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSupportedPublicRenderParameter(String identifier) {
+      if (pubParms.remove(identifier)) {
+         LOG.debug("Removed duplicate supported render param: " + identifier);
+      }
       pubParms.add(identifier);
    }
 
@@ -310,6 +341,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSecurityRoleRef(SecurityRoleRef srr) {
+      if (secRefs.remove(srr)) {
+         LOG.debug("Removed duplicate security role ref: " + srr.getRoleName());
+      }
       secRefs.add(srr);
    }
 
@@ -340,7 +374,43 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSupports(Supports supp) {
-      supps.add(supp);
+      if (supps.remove(supp)) {
+         LOG.debug("Removed duplicate supports block for: " + supp.getMimeType());
+      }
+     supps.add(supp);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getDependency(java.lang.String)
+    */
+   @Override
+   public Dependency getDependency(String name) {
+      Dependency ret = null;
+      for (Dependency item : dependencies) {
+         if (item.getName().equals(name)) {
+            ret = new DependencyImpl(item);
+         }
+      }
+      return ret;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getDependency()
+    */
+   @Override
+   public List<Dependency> getDependencies() {
+      return new ArrayList<Dependency>(dependencies);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#addDependency(java.lang.String)
+    */
+   @Override
+   public void addDependency(Dependency dep) {
+      if (dependencies.remove(dep)) {
+         LOG.debug("Removed duplicate dependencies block for: " + dep.getName());
+      }
+     dependencies.add(dep);
    }
 
    /* (non-Javadoc)
@@ -370,6 +440,12 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addDescription(Description desc) {
+      if (descs.remove(desc)) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate description for locale: ").append(desc.getLocale().toString());
+         txt.append(", description: ").append(desc.getText());
+         LOG.debug(txt.toString());
+      }
       descs.add(desc);
    }
 
@@ -399,8 +475,14 @@ public class PortletDefinitionImpl implements PortletDefinition {
     * @see org.apache.pluto.container.om.portlet.PortletDefinition#addDisplayName(org.apache.pluto.container.om.portlet.DisplayName)
     */
    @Override
-   public void addDisplayName(DisplayName desc) {
-      dispNames.add(desc);
+   public void addDisplayName(DisplayName dispName) {
+      if (dispNames.remove(dispName)) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate description for locale: ").append(dispName.getLocale().toString());
+         txt.append(", description: ").append(dispName.getText());
+         LOG.debug(txt.toString());
+      }
+      dispNames.add(dispName);
    }
 
    /* (non-Javadoc)
@@ -416,6 +498,9 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addSupportedLocale(String lang) {
+      if (supportedLocales.remove(lang)) {
+         LOG.debug("Removed duplicate supported locale: " + lang);
+      }
       supportedLocales.add(lang);
    }
 
@@ -482,7 +567,54 @@ public class PortletDefinitionImpl implements PortletDefinition {
     */
    @Override
    public void addContainerRuntimeOption(ContainerRuntimeOption cro) {
+      int ii = crtOptions.indexOf(cro);
+      if (ii >= 0) {
+         
+         ContainerRuntimeOption x = crtOptions.get(ii);
+         crtOptions.remove(ii);
+         
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate portlet container runtime option: ").append(x.getName());
+         txt.append(", vals: ").append(x.getValues().toString());
+         LOG.debug(txt.toString());
+      }
       crtOptions.add(new ContainerRuntimeOptionImpl(cro));
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((portletName == null) ? 0 : portletName.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      PortletDefinitionImpl other = (PortletDefinitionImpl) obj;
+      if (portletName == null) {
+         if (other.portletName != null) {
+            return false;
+         }
+      } else if (!portletName.equals(other.portletName)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletInfoImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletInfoImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletInfoImpl.java
index 11e58e9..5a6a330 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletInfoImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletInfoImpl.java
@@ -19,7 +19,14 @@
 
 package org.apache.pluto.container.om.portlet.impl;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.pluto.container.om.portlet.LocaleText;
 import org.apache.pluto.container.om.portlet.PortletInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Portlet info
@@ -29,30 +36,52 @@ import org.apache.pluto.container.om.portlet.PortletInfo;
  */
 public class PortletInfoImpl implements PortletInfo {
    
-   private String title;
-   private String keywords;
-   private String sTitle;
+   /** Logger. */
+   private static final Logger LOG = LoggerFactory.getLogger(PortletInfoImpl.class);
    
+   private final List<LocaleText> titles = new ArrayList<LocaleText>();
+   private final List<LocaleText> keywords = new ArrayList<LocaleText>();
+   private final List<LocaleText> sTitles = new ArrayList<LocaleText>();
+
+   /**
+    * default constructor
+    */
+   public PortletInfoImpl() {
+   }
    
    /**
     * Copy constructor 
     */
    public PortletInfoImpl(PortletInfo pi) {
-      title = pi.getTitle();
-      keywords = pi.getKeywords();
-      sTitle = pi.getShortTitle();
-   }
+      
+      for (LocaleText lt : pi.getTitles()) {
+         this.titles.add(new LocaleTextImpl(lt));
+      }
+      
+      for (LocaleText lt : pi.getShortTitles()) {
+         this.sTitles.add(new LocaleTextImpl(lt));
+      }
+      
+      for (LocaleText lt : pi.getKeywordsList()) {
+         this.keywords.add(new LocaleTextImpl(lt));
+      }
+  }
    
    /**
-    * Constructor
+    * Constructor - JSR 286 compat
     * @param ti      title
     * @param kw      keywords
     * @param sti     short title
     */
    public PortletInfoImpl(String ti, String kw, String sti) {
-      title = ti;
-      keywords = kw;
-      sTitle = sti;
+      
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, ti);
+      titles.add(lt);
+      lt = new LocaleTextImpl(Locale.ENGLISH, sti);
+      sTitles.add(lt);
+      lt = new LocaleTextImpl(Locale.ENGLISH, kw);
+      keywords.add(lt);
+      
    }
 
    /* (non-Javadoc)
@@ -60,7 +89,14 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public String getTitle() {
-      return title;
+      LocaleText lt = null;
+      for (LocaleText title : titles) {
+         if (title.getLocale().equals(Locale.ENGLISH)) {
+            lt = title;
+            break;
+         }
+      }
+      return (lt == null) ? null : lt.getText();
    }
 
    /* (non-Javadoc)
@@ -68,7 +104,44 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public void setTitle(String title) {
-      this.title = title;
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, title);
+      titles.add(lt);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getTitle(java.util.Locale)
+    */
+   @Override
+   public LocaleText getTitle(Locale locale) {
+      LocaleText ret = null;
+      for (LocaleText item : titles) {
+         if (item.getLocale().equals(locale)) {
+            ret = new LocaleTextImpl(item);
+         }
+      }
+      return ret;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getTitles()
+    */
+   @Override
+   public List<LocaleText> getTitles() {
+      return new ArrayList<LocaleText>(titles);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#addTitle(org.apache.pluto.container.om.portlet.LocaleText)
+    */
+   @Override
+   public void addTitle(LocaleText title) {
+      if (titles.remove(title)) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate description for locale: ").append(title.getLocale().toString());
+         txt.append(", description: ").append(title.getText());
+         LOG.debug(txt.toString());
+      }
+      titles.add(title);
    }
 
    /* (non-Javadoc)
@@ -76,7 +149,14 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public String getKeywords() {
-      return keywords;
+      LocaleText lt = null;
+      for (LocaleText kw : keywords) {
+         if (kw.getLocale().equals(Locale.ENGLISH)) {
+            lt = kw;
+            break;
+         }
+      }
+      return (lt == null) ? null : lt.getText();
    }
 
    /* (non-Javadoc)
@@ -84,7 +164,44 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public void setKeywords(String keywords) {
-      this.keywords = keywords;
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, keywords);
+      this.keywords.add(lt);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getKeywordsList(java.util.Locale)
+    */
+   @Override
+   public LocaleText getKeywords(Locale locale) {
+      LocaleText ret = null;
+      for (LocaleText item : keywords) {
+         if (item.getLocale().equals(locale)) {
+            ret = new LocaleTextImpl(item);
+         }
+      }
+      return ret;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getKeywords()
+    */
+   @Override
+   public List<LocaleText> getKeywordsList() {
+      return new ArrayList<LocaleText>(keywords);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#addKeywords(org.apache.pluto.container.om.portlet.LocaleText)
+    */
+   @Override
+   public void addKeywords(LocaleText kw) {
+      if (keywords.remove(kw)) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate description for locale: ").append(kw.getLocale().toString());
+         txt.append(", description: ").append(kw.getText());
+         LOG.debug(txt.toString());
+      }
+      keywords.add(kw);
    }
 
    /* (non-Javadoc)
@@ -92,7 +209,14 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public String getShortTitle() {
-      return sTitle;
+      LocaleText lt = null;
+      for (LocaleText title : sTitles) {
+         if (title.getLocale().equals(Locale.ENGLISH)) {
+            lt = title;
+            break;
+         }
+      }
+      return (lt == null) ? null : lt.getText();
    }
 
    /* (non-Javadoc)
@@ -100,7 +224,44 @@ public class PortletInfoImpl implements PortletInfo {
     */
    @Override
    public void setShortTitle(String shortTitle) {
-      sTitle = shortTitle;
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, shortTitle);
+      sTitles.add(lt);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getShortTitle(java.util.Locale)
+    */
+   @Override
+   public LocaleText getShortTitle(Locale locale) {
+      LocaleText ret = null;
+      for (LocaleText item : sTitles) {
+         if (item.getLocale().equals(locale)) {
+            ret = new LocaleTextImpl(item);
+         }
+      }
+      return ret;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#getShortTitles()
+    */
+   @Override
+   public List<LocaleText> getShortTitles() {
+      return new ArrayList<LocaleText>(sTitles);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PortletDefinition#addShortTitle(org.apache.pluto.container.om.portlet.LocaleText)
+    */
+   @Override
+   public void addShortTitle(LocaleText st) {
+      if (sTitles.remove(st)) {
+         StringBuilder txt = new StringBuilder(128);
+         txt.append("Removed duplicate description for locale: ").append(st.getLocale().toString());
+         txt.append(", description: ").append(st.getText());
+         LOG.debug(txt.toString());
+      }
+      sTitles.add(st);
    }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PublicRenderParameterImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PublicRenderParameterImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PublicRenderParameterImpl.java
index 2f23354..1b15ce1 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PublicRenderParameterImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PublicRenderParameterImpl.java
@@ -26,6 +26,7 @@ import java.util.Locale;
 import javax.xml.namespace.QName;
 
 import org.apache.pluto.container.om.portlet.Description;
+import org.apache.pluto.container.om.portlet.DisplayName;
 import org.apache.pluto.container.om.portlet.PublicRenderParameter;
 
 /**
@@ -40,6 +41,7 @@ public class PublicRenderParameterImpl implements PublicRenderParameter {
    private String id;
    private final List<QName> aliases = new ArrayList<QName>();
    private final List<Description> descs = new ArrayList<Description>();
+   private final List<DisplayName> dispNames = new ArrayList<DisplayName>();
 
    /**
     * Copy constructor
@@ -55,6 +57,9 @@ public class PublicRenderParameterImpl implements PublicRenderParameter {
       for (Description desc : pri.getDescriptions()) {
          descs.add(new DescriptionImpl(desc));
       }
+      for (DisplayName dn : pri.getDisplayNames()) {
+         dispNames.add(new DisplayNameImpl(dn));
+      }
    }
    
    /**
@@ -112,6 +117,36 @@ public class PublicRenderParameterImpl implements PublicRenderParameter {
    }
 
    /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PublicRenderParameter#getDisplayName(java.util.Locale)
+    */
+   @Override
+   public DisplayName getDisplayName(Locale locale) {
+      DisplayName ret = null;
+      for (DisplayName dn : dispNames) {
+         if (dn.getLocale().equals(locale)) {
+            ret = dn;
+         }
+      }
+      return ret;
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PublicRenderParameter#getDisplayNames()
+    */
+   @Override
+   public List<DisplayName> getDisplayNames() {
+      return new ArrayList<DisplayName>(dispNames);
+   }
+
+   /* (non-Javadoc)
+    * @see org.apache.pluto.container.om.portlet.PublicRenderParameter#addDisplayName(org.apache.pluto.container.om.portlet.DisplayName)
+    */
+   @Override
+   public void addDisplayName(DisplayName dn) {
+      dispNames.add(dn);
+   }
+
+   /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.PublicRenderParameter#getAliases()
     */
    @Override
@@ -127,4 +162,40 @@ public class PublicRenderParameterImpl implements PublicRenderParameter {
       aliases.add(qName);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((id == null) ? 0 : id.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      PublicRenderParameterImpl other = (PublicRenderParameterImpl) obj;
+      if (id == null) {
+         if (other.id != null) {
+            return false;
+         }
+      } else if (!id.equals(other.id)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityConstraintImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityConstraintImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityConstraintImpl.java
index bc6f53a..c8a1686 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityConstraintImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityConstraintImpl.java
@@ -114,4 +114,40 @@ public class SecurityConstraintImpl implements SecurityConstraint {
       portletNames.add(portletName);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((udc == null) ? 0 : udc.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      SecurityConstraintImpl other = (SecurityConstraintImpl) obj;
+      if (udc == null) {
+         if (other.udc != null) {
+            return false;
+         }
+      } else if (!udc.equals(other.udc)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityRoleRefImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityRoleRefImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityRoleRefImpl.java
index 4a3e0ba..094921f 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityRoleRefImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SecurityRoleRefImpl.java
@@ -112,4 +112,40 @@ public class SecurityRoleRefImpl implements SecurityRoleRef {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((roleName == null) ? 0 : roleName.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      SecurityRoleRefImpl other = (SecurityRoleRefImpl) obj;
+      if (roleName == null) {
+         if (other.roleName != null) {
+            return false;
+         }
+      } else if (!roleName.equals(other.roleName)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SupportsImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SupportsImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SupportsImpl.java
index 366c103..1f8ebd2 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SupportsImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/SupportsImpl.java
@@ -102,4 +102,40 @@ public class SupportsImpl implements Supports {
       windowStates.add(windowState);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((mime == null) ? 0 : mime.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      SupportsImpl other = (SupportsImpl) obj;
+      if (mime == null) {
+         if (other.mime != null) {
+            return false;
+         }
+      } else if (!mime.equals(other.mime)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserAttributeImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserAttributeImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserAttributeImpl.java
index 8431028..46f99cc 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserAttributeImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserAttributeImpl.java
@@ -94,4 +94,40 @@ public class UserAttributeImpl implements UserAttribute {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((name == null) ? 0 : name.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      UserAttributeImpl other = (UserAttributeImpl) obj;
+      if (name == null) {
+         if (other.name != null) {
+            return false;
+         }
+      } else if (!name.equals(other.name)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserDataConstraintImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserDataConstraintImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserDataConstraintImpl.java
index 07aa5fd..2b013f4 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserDataConstraintImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/UserDataConstraintImpl.java
@@ -94,4 +94,40 @@ public class UserDataConstraintImpl implements UserDataConstraint {
       descs.add(desc);
    }
 
+   /* (non-Javadoc)
+    * @see java.lang.Object#hashCode()
+    */
+   @Override
+   public int hashCode() {
+      final int prime = 31;
+      int result = 1;
+      result = prime * result + ((transportGuarantee == null) ? 0 : transportGuarantee.hashCode());
+      return result;
+   }
+
+   /* (non-Javadoc)
+    * @see java.lang.Object#equals(java.lang.Object)
+    */
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) {
+         return true;
+      }
+      if (obj == null) {
+         return false;
+      }
+      if (getClass() != obj.getClass()) {
+         return false;
+      }
+      UserDataConstraintImpl other = (UserDataConstraintImpl) obj;
+      if (transportGuarantee == null) {
+         if (other.transportGuarantee != null) {
+            return false;
+         }
+      } else if (!transportGuarantee.equals(other.transportGuarantee)) {
+         return false;
+      }
+      return true;
+   }
+
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
index 3da7f6c..8f7ef42 100644
--- a/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
+++ b/pluto-container/src/test/java/org/apache/pluto/container/impl/JaxbReadTest168Gen.java
@@ -30,7 +30,6 @@ import org.apache.pluto.container.om.portlet10.impl.PortletAppType;
 import org.apache.pluto.container.om.portlet10.impl.PortletType;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Low-level test to read a deployment descriptor


[06/35] portals-pluto git commit: Added configuration by annotation for V3 portlets. For v3 portlets, neither the web application deployment descriptor nor the portlet deployment descriptor are necessary. * Annotations provided for all portlet config

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
new file mode 100644
index 0000000..5412191
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/JSR362PortletFilterAnnotationTest.java
@@ -0,0 +1,230 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.portlet.PortletRequest;
+
+import org.apache.pluto.container.om.portlet.Filter;
+import org.apache.pluto.container.om.portlet.FilterMapping;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.FilterImpl;
+import org.apache.pluto.container.om.portlet.impl.FilterMappingImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedFilter;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for JSR 362 portlet application definition.
+ * @author Scott Nicklous
+ *
+ */
+public class JSR362PortletFilterAnnotationTest {
+   
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestAnnotatedFilter.class;
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+      cfp = new ConfigurationHolder();
+      try {
+         cfp.processConfigAnnotations(classes);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilter() {
+      String newItem = "aFilter";
+      Filter item = cut.getFilter(newItem);
+      assertNotNull(item);
+      Filter filter = cut.getFilters().get(0);
+      assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedFilter", 
+            filter.getFilterClass());
+      assertEquals("true", filter.getInitParam("execute").getParamValue());
+   }
+   
+   @Test
+   public void testFilterLifecycle() {
+      String newItem = "aFilter";
+      Filter filter = cut.getFilter(newItem);
+      assertNotNull(filter);
+      List<String> lifecycles =  Arrays.asList(new String[] {PortletRequest.RENDER_PHASE, PortletRequest.RESOURCE_PHASE, PortletRequest.HEADER_PHASE});
+      for (String lc : filter.getLifecycles()) {
+         assertTrue(lifecycles.contains(lc));
+      }
+   }
+   
+   @Test
+   public void testFilterDescription() {
+      String newItem = "aFilter";
+      Filter filter = cut.getFilter(newItem);
+      assertNotNull(filter);
+      assertEquals(2, filter.getDescriptions().size());
+      assertEquals("Ein ordentlicher Filter", filter.getDescription(new Locale("de")).getText());
+      assertEquals("Quite the filter", filter.getDescription(Locale.ENGLISH).getText());
+   }
+
+   @Test
+   public void testFilterDisplayName() {
+      String newItem = "aFilter";
+      Filter filter = cut.getFilter(newItem);
+      assertNotNull(filter);
+      assertEquals(2, filter.getDisplayNames().size());
+      assertEquals("Ein Filter", filter.getDisplayName(Locale.GERMAN).getText());
+      assertEquals("A Filter", filter.getDisplayName(new Locale("en")).getText());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilters()}.
+    */
+   @Test
+   public void testGetFilters() {
+      String newItem = "aFilter";
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddFilter() {
+      String newItem = "newFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddDupFilter() {
+      String newItem = "aFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass("SomeClass");
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMapping(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilterMapping() {
+      String newItem = "aFilter";
+      FilterMapping item = cut.getFilterMapping(newItem);
+      assertNotNull(item);
+      assertEquals(1, item.getPortletNames().size());
+      assertEquals("portlet362", item.getPortletNames().get(0));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMappings()}.
+    */
+   @Test
+   public void testGetFilterMappings() {
+      String newItem = "aFilter";
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testAddFilterMapping() {
+      String newItem = "newFilter";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName("portlet 1");
+      fm.addPortletName("portlet 2");
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testAddDupFilterMapping() {
+      String newItem = "aFilter";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName("portlet 1");
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletAppTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletAppTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletAppTest.java
new file mode 100644
index 0000000..0db1c1f
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletAppTest.java
@@ -0,0 +1,819 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.CustomPortletMode;
+import org.apache.pluto.container.om.portlet.CustomWindowState;
+import org.apache.pluto.container.om.portlet.EventDefinition;
+import org.apache.pluto.container.om.portlet.Filter;
+import org.apache.pluto.container.om.portlet.FilterMapping;
+import org.apache.pluto.container.om.portlet.Listener;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PublicRenderParameter;
+import org.apache.pluto.container.om.portlet.SecurityConstraint;
+import org.apache.pluto.container.om.portlet.UserAttribute;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ContainerRuntimeOptionImpl;
+import org.apache.pluto.container.om.portlet.impl.CustomPortletModeImpl;
+import org.apache.pluto.container.om.portlet.impl.CustomWindowStateImpl;
+import org.apache.pluto.container.om.portlet.impl.EventDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.FilterImpl;
+import org.apache.pluto.container.om.portlet.impl.FilterMappingImpl;
+import org.apache.pluto.container.om.portlet.impl.ListenerImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PublicRenderParameterImpl;
+import org.apache.pluto.container.om.portlet.impl.SecurityConstraintImpl;
+import org.apache.pluto.container.om.portlet.impl.UserAttributeImpl;
+import org.apache.pluto.container.om.portlet.impl.UserDataConstraintImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortletAppAnnotatedClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Junit test cases for mer of portlet app definition from annotation
+ * with that from the portlet.xml file.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class MergePortletAppTest {
+
+   
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestPortletAppAnnotatedClass.class;
+   private static final String  WEBDDPKG         = "org/apache/pluto/container/om/portlet/";
+   private static final String  WEBDD31          = "webApp31simple.xml";
+
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Merge.xml";
+   
+   private static PortletApplicationDefinition pad;
+   private static ConfigurationHolder cfp;
+   
+   // class under test; cloned new for each test
+   private  PortletApplicationDefinition cut;
+
+   /**
+    * @throws java.lang.Exception
+    */
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+      cfp = new ConfigurationHolder();
+      try {
+         // portlet XML must be processed after annotations
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      cut = new PortletApplicationDefinitionImpl(pad);
+   }
+
+   /**
+    * Bundle from XML overrides bundle from annotation
+    */
+   @Test
+   public void testGetSetResourceBundle() {
+      String val = cut.getResourceBundle();
+      String txt = "com.ibm.portal.ResourceBundle";
+      assertNotNull(val);
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", val);
+      cut.setResourceBundle(txt);
+      val = cut.getResourceBundle();
+      assertNotNull(val);
+      assertEquals(txt, val);
+   }
+
+   /**
+    * Namespace from XML overrrides namespace from annotation
+    */
+   @Test
+   public void testGetSetDefaultNamespace() {
+      String val = cut.getDefaultNamespace();
+      String txt = "https://www.ibm.com/";
+      assertNotNull(val);
+      assertEquals("https://www.some.org/", val);
+      cut.setDefaultNamespace(txt);
+      val = cut.getDefaultNamespace();
+      assertNotNull(val);
+      assertEquals(txt, val);
+   }
+
+   /**
+    * Total event defs is uniion of annotation event defs & xml event defs
+    */
+   @Test
+   public void testGetEventDefinitions() {
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      QName qn = new QName("https://www.some.org/", "another-event");
+      EventDefinition evt = new EventDefinitionImpl(qn);
+      assertTrue(list.contains(evt));
+   }
+
+   /**
+    * Total event defs is uniion of annotation event defs & xml event defs
+    */
+   @Test
+   public void testGetEventDefinition() {
+      QName qn = new QName("https://www.some.org/", "another-event");
+      EventDefinition item = cut.getEventDefinition(qn);
+      assertNotNull(item);
+      qn = new QName("https://www.some.org/", "supported-event");
+      item = cut.getEventDefinition(qn);
+      assertNotNull(item);
+      qn = new QName("http://test.com", "supported-event");
+      item = cut.getEventDefinition(qn);
+      assertNotNull(item);
+   }
+
+   /**
+    * Total event defs is uniion of annotation event defs & xml event defs
+    */
+   @Test
+   public void testAddEventDefinition() {
+      QName qn = new QName("https://www.ibm.com/", "some-other-event");
+      EventDefinition ed = new EventDefinitionImpl(qn);
+      cut.addEventDefinition(ed);
+
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      EventDefinition evt = new EventDefinitionImpl(qn);
+      assertTrue(list.contains(evt));
+   }
+
+   /**
+    * Total event defs is uniion of annotation event defs & xml event defs
+    */
+   @Test
+   public void testAddDupEventDefinition() {
+      QName qn = new QName("https://www.some.org/", "different-event");
+      EventDefinition ed = new EventDefinitionImpl(qn);
+      cut.addEventDefinition(ed);
+
+      List<EventDefinition> list = cut.getEventDefinitions();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      boolean ok = false;
+      for (EventDefinition item : list) {
+         if (item.getQName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   /**
+    * Total prps are union of annotation prps & xml prps
+    */
+   @Test
+   public void testGetPublicRenderParameter() {
+      assertNotNull(cut.getPublicRenderParameter("color"));
+      assertNotNull(cut.getPublicRenderParameter("imgName"));
+      assertNotNull(cut.getPublicRenderParameter("link"));
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(3, prps.size());
+   }
+   
+   private boolean isPrpPresent(String prpid, List<PublicRenderParameter> prps) {
+      for (PublicRenderParameter prp : prps) {
+         if (prp.getIdentifier().equals(prpid)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Total prps are union of annotation prps & xml prps
+    */
+   @Test
+   public void testGetPublicRenderParameters() {
+      String prpid = "imgName";
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(3, prps.size());
+      assertTrue(isPrpPresent(prpid, prps));
+   }
+
+   /**
+    * Total prps are union of annotation prps & xml prps
+    */
+   @Test
+   public void testAddPublicRenderParameter() {
+      String prpid = "newprp";
+      QName qn = new QName("https://www.ibm.com/", "some-other-prp");
+      PublicRenderParameter prp = new PublicRenderParameterImpl(qn, prpid);
+      cut.addPublicRenderParameter(prp);
+      
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(4, prps.size());
+      assertTrue(isPrpPresent(prpid, prps));
+   }
+
+   /**
+    * Total prps are union of annotation prps & xml prps
+    */
+   @Test
+   public void testAddDupPublicRenderParameter() {
+      String prpid = "color";
+      QName qn = new QName("https://www.some.org/", "color");
+      PublicRenderParameter prp = new PublicRenderParameterImpl(qn, prpid);
+      cut.addPublicRenderParameter(prp);
+      
+      List<PublicRenderParameter> prps = cut.getPublicRenderParameters();
+      assertNotNull(prps);
+      assertEquals(3, prps.size());
+      assertTrue(isPrpPresent(prpid, prps));
+   }
+
+   /**
+    * Union of annotation modes & XML modes
+    */
+   @Test
+   public void testGetCustomPortletMode() {
+      assertNotNull(cut.getCustomPortletMode("portlet-mode"));
+      assertNotNull(cut.getCustomPortletMode("admin"));
+      assertNotNull(cut.getCustomPortletMode("aMode"));
+   }
+   
+   private boolean isPMPresent(String pm, List<CustomPortletMode> list) {
+      for (CustomPortletMode mode : list) {
+         if (mode.getPortletMode().equals(pm)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Total portlet modes is union of annotation modes & XML modes
+    */
+   @Test
+   public void testGetCustomPortletModes() {
+      String newItem = "portlet-mode";
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isPMPresent(newItem, list));
+   }
+
+   /**
+    * Total portlet modes is union of annotation modes & XML modes
+    */
+   @Test
+   public void testAddCustomPortletMode() {
+      String newItem = "newMode";
+      CustomPortletMode prp = new CustomPortletModeImpl(newItem);
+      cut.addCustomPortletMode(prp);
+      
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      assertTrue(isPMPresent(newItem, list));
+   }
+
+   /**
+    * Total portlet modes is union of annotation modes & XML modes
+    */
+   @Test
+   public void testAddDuplicateCustomPortletMode() {
+      String newItem = "portlet-mode";
+      CustomPortletMode prp = new CustomPortletModeImpl(newItem);
+      cut.addCustomPortletMode(prp);
+      
+      List<CustomPortletMode> list = cut.getCustomPortletModes();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isPMPresent(newItem, list));
+   }
+   
+   private boolean isWSPresent(String ws, List<CustomWindowState> list) {
+      for (CustomWindowState cws : list) {
+         if (cws.getWindowState().equals(ws)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Total custom window states is union of annotation states & XML states
+    */
+   @Test
+   public void testGetCustomWindowState() {
+      assertNotNull(cut.getCustomWindowState("window-state"));
+      assertNotNull(cut.getCustomWindowState("half_page"));
+      assertNotNull(cut.getCustomWindowState("quarter_page"));
+   }
+
+   /**
+    * Total custom window states is union of annotation states & XML states
+    */
+   @Test
+   public void testGetCustomWindowStates() {
+      String newItem = "window-state";
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isWSPresent(newItem, list));
+   }
+
+   /**
+    * Total custom window states is union of annotation states & XML states
+    */
+   @Test
+   public void testAddCustomWindowState() {
+      String newItem = "newState";
+      CustomWindowState prp = new CustomWindowStateImpl(newItem);
+      cut.addCustomWindowState(prp);
+      
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      assertTrue(isWSPresent(newItem, list));
+   }
+
+   /**
+    * Total custom window states is union of annotation states & XML states
+    */
+   @Test
+   public void testAddDupCustomWindowState() {
+      String newItem = "window-state";
+      CustomWindowState prp = new CustomWindowStateImpl(newItem);
+      cut.addCustomWindowState(prp);
+      
+      List<CustomWindowState> list = cut.getCustomWindowStates();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isWSPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getUserAttribute(java.lang.String)}.
+    */
+   @Test
+   public void testGetUserAttribute() {
+      assertNotNull(cut.getUserAttribute("user.name.given"));
+      assertNotNull(cut.getUserAttribute("user.name.family"));
+      assertNotNull(cut.getUserAttribute("dogs.name"));
+      assertNotNull(cut.getUserAttribute("user.home-info.online.email"));
+      assertNotNull(cut.getUserAttribute("user.business-info.postal.organization"));
+   }
+   
+   private boolean isUAPresent(String ua, List<UserAttribute> list) {
+      for (UserAttribute item : list) {
+         if (item.getName().equals(ua)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getUserAttributes()}.
+    */
+   @Test
+   public void testGetUserAttributes() {
+      String newItem = "user.name.family";
+      List<UserAttribute> list = cut.getUserAttributes();
+      assertNotNull(list);
+      assertEquals(5, list.size());
+      assertTrue(isUAPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addUserAttribute(org.apache.pluto.container.om.portlet.UserAttribute)}.
+    */
+   @Test
+   public void testAddUserAttribute() {
+      String newItem = "newAttr";
+      UserAttribute prp = new UserAttributeImpl(newItem);
+      cut.addUserAttribute(prp);
+      
+      List<UserAttribute> list = cut.getUserAttributes();
+      assertNotNull(list);
+      assertEquals(6, list.size());
+      assertTrue(isUAPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addUserAttribute(org.apache.pluto.container.om.portlet.UserAttribute)}.
+    */
+   @Test
+   public void testAddDupUserAttribute() {
+      String newItem = "user.name.family";
+      UserAttribute prp = new UserAttributeImpl(newItem);
+      cut.addUserAttribute(prp);
+      
+      List<UserAttribute> list = cut.getUserAttributes();
+      assertNotNull(list);
+      assertEquals(5, list.size());
+      assertTrue(isUAPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilter(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilter() {
+      String newItem = "filter-name";
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter item = cut.getFilter(newItem);
+      assertNotNull(item);
+      Filter filter = cut.getFilters().get(0);
+      assertEquals(filterClass, 
+            filter.getFilterClass());
+      assertEquals("description", filter.getDescription(new Locale("de")).getText());
+      assertEquals("display-name", filter.getDisplayName(new Locale("de")).getText());
+      assertEquals("lifecycle", filter.getLifecycles().get(0));
+      assertEquals("value", filter.getInitParam("name").getParamValue());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilters()}.
+    */
+   @Test
+   public void testGetFilters() {
+      String newItem = "filter-name";
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddFilter() {
+      String newItem = "newFilter";
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass(filterClass);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testRemoveFilter() {
+      // existing filter def is removed if filter class is null (= not set)
+      String newItem = "filter-name";
+      Filter fil = new FilterImpl(newItem);
+      assertNotNull(cut.getFilter(newItem));
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+      assertEquals(null, cut.getFilter(newItem));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilter(org.apache.pluto.container.om.portlet.Filter)}.
+    */
+   @Test
+   public void testAddDupFilter() {
+      String newItem = "filter-name";
+      String filterClass = "org.apache.pluto.container.om.portlet.impl.fixtures.TestFilter";
+      Filter fil = new FilterImpl(newItem);
+      fil.setFilterClass(filterClass);
+      cut.addFilter(fil);
+      
+      List<Filter> list = cut.getFilters();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMapping(java.lang.String)}.
+    */
+   @Test
+   public void testGetFilterMapping() {
+      String newItem = "filter-name";
+      FilterMapping item = cut.getFilterMapping(newItem);
+      assertNotNull(item);
+      assertEquals(1, item.getPortletNames().size());
+      assertEquals("AnnotatedPortlet", item.getPortletNames().get(0));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getFilterMappings()}.
+    */
+   @Test
+   public void testGetFilterMappings() {
+      String newItem = "filter-name";
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testAddFilterMapping() {
+      String newItem = "newFilter";
+      String portletName = "portlet362";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName(portletName);
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(newItem, list.get(1).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testRemoveFilterMapping() {
+      String newItem = "filter-name";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      assertNotNull(cut.getFilterMapping(newItem));
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(0, list.size());
+      assertEquals(null, cut.getFilterMapping(newItem));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addFilterMapping(org.apache.pluto.container.om.portlet.FilterMapping)}.
+    */
+   @Test
+   public void testAddDupFilterMapping() {
+      String newItem = "filter-name";
+      String portletName = "portlet362";
+      FilterMapping fm = new FilterMappingImpl(newItem);
+      fm.addPortletName(portletName);
+      cut.addFilterMapping(fm);
+      
+      List<FilterMapping> list = cut.getFilterMappings();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(newItem, list.get(0).getFilterName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getContainerRuntimeOption(java.lang.String)}.
+    */
+   @Test
+   public void testGetContainerRuntimeOption() {
+      assertNotNull(cut.getContainerRuntimeOption("javax.portlet.renderHeaders"));
+      assertNotNull(cut.getContainerRuntimeOption("Runtime-Option-Portlet-App"));
+      assertNotNull(cut.getContainerRuntimeOption("runtime.option"));
+   }
+   
+   private boolean isRTOPresent(String rt, List<ContainerRuntimeOption> list) {
+      for (ContainerRuntimeOption item : list) {
+         if (item.getName().equals(rt)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getContainerRuntimeOptions()}.
+    */
+   @Test
+   public void testGetContainerRuntimeOptions() {
+      String newItem = "Runtime-Option-Portlet-App";
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isRTOPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addContainerRuntimeOption(org.apache.pluto.container.om.portlet.ContainerRuntimeOption)}.
+    */
+   @Test
+   public void testAddContainerRuntimeOption() {
+      String newItem = "newRTO";
+      String[] newvals = {"v1", "v2"}; 
+      ContainerRuntimeOption item = new ContainerRuntimeOptionImpl(newItem, Arrays.asList(newvals));
+      cut.addContainerRuntimeOption(item);
+      
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(4, list.size());
+      assertTrue(isRTOPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addContainerRuntimeOption(org.apache.pluto.container.om.portlet.ContainerRuntimeOption)}.
+    */
+   @Test
+   public void testAddDupContainerRuntimeOption() {
+      String newItem = "Runtime-Option-Portlet-App";
+      String[] newvals = {"v1", "v2"}; 
+      ContainerRuntimeOption item = new ContainerRuntimeOptionImpl(newItem, Arrays.asList(newvals));
+      cut.addContainerRuntimeOption(item);
+      
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isRTOPresent(newItem, list));
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getListeners()}.
+    */
+   @Test
+   public void testGetListeners() {
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals("org.apache.pluto.container.om.portlet.impl.fixtures.TestListener", list.get(0).getListenerClass());
+      assertEquals("test listener", list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void testAddListener() {
+      String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.DifferentListener";
+      String lisName = "Different Listener";
+      Listener newitem = new ListenerImpl(clsName);
+      newitem.setListenerName(lisName);
+      
+      cut.addListener(newitem);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertEquals(clsName, list.get(1).getListenerClass());
+      assertEquals(lisName, list.get(1).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addListener(org.apache.pluto.container.om.portlet.Listener)}.
+    */
+   @Test
+   public void testAddDupListener() {
+      String clsName = "org.apache.pluto.container.om.portlet.impl.fixtures.TestListener";
+      String lisName = "test listener";
+      Listener newitem = new ListenerImpl(clsName);
+      newitem.setListenerName(lisName);
+      
+      cut.addListener(newitem);
+      
+      List<Listener> list = cut.getListeners();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals(clsName, list.get(0).getListenerClass());
+      assertEquals(lisName, list.get(0).getListenerName());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addSecurityConstraint(org.apache.pluto.container.om.portlet.SecurityConstraint)}.
+    */
+   @Test
+   public void testAddSecurityConstraint() {
+      SecurityConstraint seco = new SecurityConstraintImpl(new UserDataConstraintImpl("CONFIDENTIAL"));
+      cut.addSecurityConstraint(seco);
+      
+      List<SecurityConstraint> list = cut.getSecurityConstraints();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals("CONFIDENTIAL", list.get(0).getUserDataConstraint().getTransportGuarantee());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addSecurityConstraint(org.apache.pluto.container.om.portlet.SecurityConstraint)}.
+    */
+   @Test
+   public void testAddDupSecurityConstraint() {
+      SecurityConstraint seco = new SecurityConstraintImpl(new UserDataConstraintImpl("NONE"));
+      cut.addSecurityConstraint(seco);
+      
+      List<SecurityConstraint> list = cut.getSecurityConstraints();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      assertEquals("NONE", list.get(0).getUserDataConstraint().getTransportGuarantee());
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getLocaleEncodingMappings()}.
+    * @throws Exception 
+    */
+   @Test
+   public void testGetLocaleEncodingMappings() throws Exception {
+      String file = WEBDDPKG + WEBDD31;
+      InputStream in = this.getClass().getClassLoader().getResourceAsStream(file);
+      
+      try {
+         cfp.processWebDD(in);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+
+      Map<Locale, String> localemap = pad.getLocaleEncodingMappings();
+      assertEquals(2, localemap.size());
+      ArrayList<Locale> testlocs = new ArrayList<Locale>(Arrays.asList(new Locale[]{
+            Locale.forLanguageTag("de"), Locale.forLanguageTag("ja") }));
+      String[] testencs = {"UTF-8", "Shift_JIS"};
+      for (Locale loc : localemap.keySet()) {
+         assertTrue(testlocs.contains(loc));
+         int ind = testlocs.indexOf(loc);
+         assertEquals(testencs[ind], localemap.get(loc));
+      }
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#addLocaleEncodingMapping(java.util.Locale, java.lang.String)}.
+    */
+   @Test
+   public void testAddLocaleEncodingMapping() {
+      ArrayList<Locale> testlocs = new ArrayList<Locale>(Arrays.asList(new Locale[]{
+            Locale.forLanguageTag("de"), Locale.forLanguageTag("ja") }));
+      String[] testencs = {"UTF-8", "Shift_JIS"};
+      for (Locale loc : testlocs) {
+         int ind = testlocs.indexOf(loc);
+         cut.addLocaleEncodingMapping(loc, testencs[ind]);
+      }
+      
+      Map<Locale, String> localemap = cut.getLocaleEncodingMappings();
+      assertEquals(2, localemap.size());
+      for (Locale loc : localemap.keySet()) {
+         assertTrue(testlocs.contains(loc));
+         int ind = testlocs.indexOf(loc);
+         assertEquals(testencs[ind], localemap.get(loc));
+      }
+   }
+   
+   /**
+    * Make sure validate() throws no exceptions
+    */
+   @Test
+   public void testValidate() {
+         cfp.validate();
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
new file mode 100644
index 0000000..d949ca0
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MergePortletDefinitionTest.java
@@ -0,0 +1,887 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.om.portlet.ContainerRuntimeOption;
+import org.apache.pluto.container.om.portlet.Dependency;
+import org.apache.pluto.container.om.portlet.Description;
+import org.apache.pluto.container.om.portlet.DisplayName;
+import org.apache.pluto.container.om.portlet.EventDefinitionReference;
+import org.apache.pluto.container.om.portlet.InitParam;
+import org.apache.pluto.container.om.portlet.LocaleText;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.PortletInfo;
+import org.apache.pluto.container.om.portlet.Preference;
+import org.apache.pluto.container.om.portlet.Preferences;
+import org.apache.pluto.container.om.portlet.SecurityRoleRef;
+import org.apache.pluto.container.om.portlet.Supports;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.ContainerRuntimeOptionImpl;
+import org.apache.pluto.container.om.portlet.impl.DependencyImpl;
+import org.apache.pluto.container.om.portlet.impl.DescriptionImpl;
+import org.apache.pluto.container.om.portlet.impl.DisplayNameImpl;
+import org.apache.pluto.container.om.portlet.impl.EventDefinitionReferenceImpl;
+import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
+import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletInfoImpl;
+import org.apache.pluto.container.om.portlet.impl.PreferenceImpl;
+import org.apache.pluto.container.om.portlet.impl.PreferencesImpl;
+import org.apache.pluto.container.om.portlet.impl.SecurityRoleRefImpl;
+import org.apache.pluto.container.om.portlet.impl.SupportsImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestAnnotatedPortlet;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortlet;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPortletAppAnnotatedClass;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestPreferencesValidator;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+/**
+ * Test class for merging the portlet DD with the configuration from an
+ * annotation. For the individual items, the result should be the union of the
+ * annotation items with those from the portlet.xml. Forthe intersecting items, the
+ * value from the portlet.xml takes precedence.
+ * 
+ * @author Scott Nicklous
+ */
+public class MergePortletDefinitionTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestAnnotatedPortlet.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Merge.xml";
+   
+   private static PortletApplicationDefinition pad;
+   
+   // Class under test
+   private PortletDefinition cut;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletDefinitionTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+    
+      ConfigurationHolder cfp = new ConfigurationHolder();
+      try {
+         // portlet XML must be processed after annotations
+         cfp.processConfigAnnotations(classes);
+         cfp.processPortletDD(in);
+         pad = cfp.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+   
+   @Before
+   public void setUpBefore() throws Exception {
+      assertEquals(1, pad.getPortlets().size());
+      cut = new PortletDefinitionImpl(pad.getPortlets().get(0));
+   }
+
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(cut.getPortletName());
+      assertEquals("AnnotatedPortlet", cut.getPortletName());
+   }
+
+   @Test
+   public void testGetApplication() {
+      assertNotNull(cut.getApplication());
+      assertTrue(cut.getApplication() instanceof PortletApplicationDefinition);
+   }
+
+   @Test
+   public void testGetInitParam() {
+      InitParam ip = cut.getInitParam("name");
+      assertNotNull(ip);
+      assertEquals("name", ip.getParamName());
+      assertEquals("value", ip.getParamValue());
+      assertEquals(1, ip.getDescriptions().size());
+      Locale loc = new Locale("de");
+      Description d = ip.getDescription(loc);
+      assertNotNull(d);
+      assertEquals("description", d.getText());
+   }
+
+   @Test
+   public void testGetInitParamNullValue() {
+      InitParam ip = cut.getInitParam("nullValueParam");
+      assertNotNull(ip);
+      assertEquals("nullValueParam", ip.getParamName());
+      assertEquals("", ip.getParamValue());
+   }
+
+   @Test
+   public void testGetInitParams() {
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(4, ips.size());
+      boolean ok = false;
+      for (InitParam ip : ips) {
+         if (ip.getParamName().equals("name") && ip.getParamValue().equals("value")) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testAddInitParam() {
+      String name = "Fred", value = "bowling";
+      InitParam newip = new InitParamImpl(name, value);
+      cut.addInitParam(newip);
+      
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(5, ips.size());
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(value, ip.getParamValue());
+   }
+
+   @Test
+   public void testAddDupInitParam() {
+      String name = "name", value = "value";
+      InitParam newip = new InitParamImpl(name, value);
+      cut.addInitParam(newip);
+      
+      List<InitParam> ips = cut.getInitParams();
+      assertEquals(4, ips.size());
+      InitParam ip = cut.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(value, ip.getParamValue());
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNotNull(cut.getPortletClass());
+      assertEquals(TestPortlet.class.getCanonicalName(), cut.getPortletClass());
+   }
+
+   @Test
+   public void testGetPortletInfoJSR286Compat() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      assertEquals("Annotated Portlet", info.getTitle());
+      assertEquals("Anno Portlet", info.getShortTitle());
+      assertEquals("One, Two, Three", info.getKeywords());
+   }
+
+   @Test
+   public void testGetTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      for (LocaleText lt : list) {
+         System.out.println("title: " + lt.getText());
+      }
+      assertEquals(2, list.size());
+      assertEquals("Annotated Portlet", info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(3, list.size());
+      assertEquals("Annotated Portlet", info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("Titel", info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals("Anno Portlet", info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(3, list.size());
+      assertEquals("Anno Portlet", info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupShortTitle() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "Different Short Title";
+      LocaleText lt = new LocaleTextImpl(Locale.ENGLISH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals("Kurztitel", info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void testGetKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals("One, Two, Three", info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals("Schlagwörter", info.getKeywords(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(3, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals("One, Two, Three", info.getKeywords(Locale.ENGLISH).getText());
+      assertEquals("Schlagwörter", info.getKeywords(Locale.GERMAN).getText());
+   }
+   
+   @Test
+   public void testAddDupKeywords() {
+      PortletInfo info = cut.getPortletInfo();
+      assertNotNull(info);
+      String text = "andre Schlagwörter";
+      LocaleText lt = new LocaleTextImpl(Locale.GERMAN, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.GERMAN).getText());
+      assertEquals("One, Two, Three", info.getKeywords(Locale.ENGLISH).getText());
+   }
+
+   private boolean isPrefPresent(String pref, List<Preference> list) {
+      for (Preference item : list) {
+         if (item.getName().equals(pref)) {
+            return true;
+         }
+      }
+      return false;
+   }
+   
+   @Test
+   public void testGetPortletPreferences() {
+      Preferences prefs = cut.getPortletPreferences();
+      assertNotNull(prefs);
+      assertEquals(TestPreferencesValidator.class.getCanonicalName(), prefs.getPreferencesValidator());
+      List<Preference> list = prefs.getPortletPreferences();
+      assertEquals(3, list.size());
+      assertTrue(isPrefPresent("aPref", list));
+      assertTrue(isPrefPresent("bPref", list));
+      assertTrue(isPrefPresent("name", list));
+   }
+
+   @Test
+   public void testSetPortletPreferences() {
+      String validator = "validator";
+      String name = "prefName";
+      String[] vals = {"v1", "v2"};
+      Preferences prefs = new PreferencesImpl(cut.getPortletPreferences());
+      prefs.setPreferencesValidator(validator);
+      prefs.addPreference(new PreferenceImpl(name, true, Arrays.asList(vals)));
+      cut.setPortletPreferences(prefs);
+      
+      Preferences prefs2 = cut.getPortletPreferences();
+      assertNotNull(prefs2);
+      assertEquals(validator, prefs2.getPreferencesValidator());
+      List<Preference> list = prefs2.getPortletPreferences();
+      assertEquals(4, list.size());
+      Preference item = prefs2.getPortletPreference(name);
+      assertEquals(name, item.getName());
+      List<String> newvals = item.getValues();
+      assertEquals(2, newvals.size());
+      assertArrayEquals(vals, newvals.toArray());
+   }
+
+   @Test 
+   public void testGetSupportedProcessingEvents() {
+      List<EventDefinitionReference> list = cut.getSupportedProcessingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      QName qn = new QName("https://www.some.org/", "supported-event");
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testAddSupportedProcessingEvent() {
+      QName qn = new QName("https://www.ibm.com/", "some-other-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedProcessingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedProcessingEvents();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testAddDupSupportedProcessingEvent() {
+      QName qn = new QName("https://www.some.org/", "supported-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedProcessingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedProcessingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testGetSupportedPublishingEvents() {
+      List<EventDefinitionReference> list = cut.getSupportedPublishingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      QName qn = new QName("http://test.com", "supported-event");
+      for (EventDefinitionReference item : list) {
+         QName aqn = item.getQualifiedName();
+         if (aqn.equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testAddSupportedPublishingEvent() {
+      QName qn = new QName("https://www.ibm.com/", "some-other-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedPublishingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedPublishingEvents();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testAddDupSupportedPublishingEvent() {
+      QName qn = new QName("http://test.com", "supported-event");
+      EventDefinitionReference edr = new EventDefinitionReferenceImpl(qn);
+      cut.addSupportedPublishingEvent(edr);
+      
+      List<EventDefinitionReference> list = cut.getSupportedPublishingEvents();
+      assertNotNull(list);
+      assertEquals(1, list.size());
+      boolean ok = false;
+      for (EventDefinitionReference item : list) {
+         if (item.getQualifiedName().equals(qn)) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testGetSupportedPublicRenderParameters() {
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertTrue(list.contains("color"));
+      assertTrue(list.contains("aPrp"));
+   }
+
+   @Test  // JSR 286
+   public void testAddSupportedPublicRenderParameter() {
+      String newprp = "some-prp";
+      cut.addSupportedPublicRenderParameter(newprp);
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(list.contains(newprp));
+   }
+
+   @Test  // JSR 286
+   public void testAddDupSupportedPublicRenderParameter() {
+      String newprp = "color";
+      cut.addSupportedPublicRenderParameter(newprp);
+      List<String> list = cut.getSupportedPublicRenderParameters();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertTrue(list.contains(newprp));
+   }
+
+   @Test
+   public void testGetResourceBundle() {
+      assertNotNull(cut.getResourceBundle());
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", cut.getResourceBundle());
+   }
+
+   @Test
+   public void testSetResourceBundle() {
+      String text = "newBundle";
+      cut.setResourceBundle(text);
+      assertNotNull(cut.getResourceBundle());
+      assertEquals(text, cut.getResourceBundle());
+   }
+
+   @Test
+   public void testGetSecurityRoleRef() {
+      SecurityRoleRef srr = cut.getSecurityRoleRef("NMTOKEN");
+      assertNotNull(srr);
+      assertEquals("NMTOKEN", srr.getRoleName());
+      assertEquals("role-link", srr.getRoleLink());
+   }
+   
+   private boolean isSRPresent(String role, List<SecurityRoleRef> list) {
+      for (SecurityRoleRef item : list) {
+         if (item.getRoleName().equals(role)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   @Test
+   public void testGetSecurityRoleRefs() {
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(2, list.size());
+      assertTrue(isSRPresent("aRole", list));
+      assertTrue(isSRPresent("NMTOKEN", list));
+   }
+
+   @Test
+   public void testAddSecurityRoleRef() {
+      String name = "RoleName";
+      String link = "RoleLink";
+      SecurityRoleRef srr = new SecurityRoleRefImpl(name);
+      srr.setRoleLink(link);
+      cut.addSecurityRoleRef(srr);
+
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(3, list.size());
+      srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
+   public void testAddDupSecurityRoleRef() {
+      String name = "NMTOKEN";
+      String link = "role-link";
+      SecurityRoleRef srr = new SecurityRoleRefImpl(name);
+      srr.setRoleLink(link);
+      cut.addSecurityRoleRef(srr);
+
+      List<SecurityRoleRef> list = cut.getSecurityRoleRefs();
+      assertEquals(2, list.size());
+      srr = cut.getSecurityRoleRef(name);
+      assertNotNull(srr);
+      assertEquals(name, srr.getRoleName());
+      assertEquals(link, srr.getRoleLink());
+   }
+
+   @Test
+   public void testGetSupportsString() {
+      Supports s = cut.getSupports("mime-type2");
+      assertNotNull(s);
+      assertTrue(s.getPortletModes().contains("portlet-mode2"));
+   }
+
+   @Test
+   public void testGetSupportsMode() {
+      Supports s = cut.getSupports("mime-type2");
+      assertNotNull(s);
+      assertTrue(s.getPortletModes().contains("portlet-mode2"));
+   }
+
+   @Test
+   public void testGetSupportsState() {
+      Supports s = cut.getSupports("mime-type3");
+      assertNotNull(s);
+      assertTrue(s.getWindowStates().contains("window-state3"));
+   }
+
+   @Test
+   public void testGetSupports() {
+      List<Supports> list = cut.getSupports();
+      assertEquals(5, list.size());
+   }
+
+   @Test
+   public void testAddSupports() {
+      Supports s = new SupportsImpl("text/html");
+      cut.addSupports(s);
+      List<Supports> list = cut.getSupports();
+      assertEquals(6, list.size());
+      boolean ok = false;
+      for (Supports item : list) {
+         if (item.getMimeType().equals("text/html")) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testAddDupSupports() {
+      Supports s = new SupportsImpl("mime-type2");
+      cut.addSupports(s);
+      List<Supports> list = cut.getSupports();
+      assertEquals(5, list.size());
+      boolean ok = false;
+      for (Supports item : list) {
+         if (item.getMimeType().equals("mime-type2")) {
+            ok = true;
+            break;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test
+   public void testGetDescription() {
+      Locale loc = new Locale("DE");
+      Description desc = cut.getDescription(loc);
+      assertNotNull(desc);
+      assertEquals("multi line description", desc.getText());
+   }
+
+   @Test
+   public void testGetDescriptions() {
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+   }
+
+   @Test
+   public void testAddDescription() {
+      Locale loc = Locale.FRENCH;
+      String text = "Some description";
+      Description d = new DescriptionImpl(loc, text);
+      cut.addDescription(d);
+
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      for (Description desc : list) {
+         if (desc.getLocale().equals(loc)) {
+            assertEquals(text, desc.getText());
+         }
+      }
+   }
+
+   @Test
+   public void testAddDupDescription() {
+      Locale loc = Locale.GERMAN;
+      String text = "neue Beschreibung";
+      Description d = new DescriptionImpl(loc, text);
+      cut.addDescription(d);
+
+      List<Description> list = cut.getDescriptions();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      Description desc = cut.getDescription(loc);
+      assertEquals(text, desc.getText());
+   }
+
+   @Test
+   public void testGetDisplayName() {
+      Locale loc = new Locale("DE");
+      DisplayName name = cut.getDisplayName(loc);
+      assertNotNull(name);
+      assertEquals("display-name", name.getText());
+   }
+   
+   private boolean isDNPresent(String dn, List<DisplayName> list) {
+      for (DisplayName item : list) {
+         if (item.getText().equals(dn)) {
+            return true;
+         }
+      }
+      return false;
+   }
+
+   @Test
+   public void testGetDisplayNames() {
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+      assertEquals(2, list.size());
+      assertTrue(isDNPresent("Time Zone Clock Portlet", list));
+      assertTrue(isDNPresent("display-name", list));
+   }
+
+   @Test
+   public void testAddDisplayName() {
+      Locale loc = Locale.FRENCH;
+      String text = "Some display name";
+      DisplayName d = new DisplayNameImpl(loc, text);
+      cut.addDisplayName(d);
+
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      assertTrue(isDNPresent("Time Zone Clock Portlet", list));
+      assertTrue(isDNPresent("display-name", list));
+      assertTrue(isDNPresent(text, list));
+   }
+
+   @Test
+   public void testAddDupDisplayName() {
+      Locale loc = Locale.GERMAN;
+      String text = "Anzeigetext";
+      DisplayName d = new DisplayNameImpl(loc, text);
+      cut.addDisplayName(d);
+
+      List<DisplayName> list = cut.getDisplayNames();
+      assertNotNull(list);
+
+      assertEquals(2, list.size());
+      assertTrue(isDNPresent("Time Zone Clock Portlet", list));
+      assertTrue(isDNPresent(text, list));
+   }
+
+   @Test
+   public void testGetSupportedLocales() {
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(2, list.size());
+      assertTrue(list.contains("supported-locale"));
+      assertTrue(list.contains("Locale1"));
+   }
+
+   @Test
+   public void testAddSupportedLocale() {
+      String locname = "zh-cmn-Hans-CN";
+      cut.addSupportedLocale(locname);
+      
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(3, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
+   public void testAddDupSupportedLocale() {
+      String locname = "supported-locale";
+      cut.addSupportedLocale(locname);
+      
+      List<String> list = cut.getSupportedLocales();
+      assertEquals(2, list.size());
+      assertTrue(list.contains(locname));
+   }
+
+   @Test
+   public void testGetExpirationCache() {
+      assertNotNull(cut.getExpirationCache());
+      assertEquals(50, cut.getExpirationCache());
+   }
+
+   @Test
+   public void testSetExpirationCache() {
+      cut.setExpirationCache(100);
+      assertNotNull(cut.getExpirationCache());
+      assertEquals(100, cut.getExpirationCache());
+   }
+
+   @Test  // JSR 286
+   public void testGetCacheScope() {
+      assertNotNull(cut.getCacheScope());
+      assertEquals("private", cut.getCacheScope());
+   }
+
+   @Test  // JSR 286
+   public void testSetCacheScope() {
+      String cs = "whatever";
+      cut.setCacheScope(cs);
+      assertNotNull(cut.getCacheScope());
+      assertEquals(cs, cut.getCacheScope());
+   }
+
+   @Test  // JSR 286
+   public void testGetContainerRuntimeOption() {
+      ContainerRuntimeOption rto = cut.getContainerRuntimeOption("Runtime-Option1");
+      assertNotNull(rto);
+      assertEquals(1, rto.getValues().size());
+      assertTrue(rto.getValues().get(0).equalsIgnoreCase("true"));
+   }
+
+   @Test  // JSR 286
+   public void testGetContainerRuntimeOptions() {
+      List<ContainerRuntimeOption> list = cut.getContainerRuntimeOptions();
+      assertNotNull(list);
+      assertEquals(3, list.size());
+      boolean ok = false;
+      for (ContainerRuntimeOption item : list) {
+         if (item.getName().equalsIgnoreCase("Runtime-Option2") && 
+               item.getValues().size() == 1 && item.getValues().get(0).equalsIgnoreCase("value2")) {
+            ok = true;
+         }
+      }
+      assertTrue(ok);
+   }
+
+   @Test  // JSR 286
+   public void testAddContainerRuntimeOption() {
+      String name = "NewRTO";
+      String[] vals = {"v1", "v2", "v3"};
+      ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(name, Arrays.asList(vals));
+      cut.addContainerRuntimeOption(cro);
+      
+      ContainerRuntimeOption newcro = cut.getContainerRuntimeOption(name);
+      assertNotNull(newcro);
+      assertArrayEquals(vals, newcro.getValues().toArray());
+   }
+
+   @Test  // JSR 286
+   public void testAddDupContainerRuntimeOption() {
+      String name = "Runtime-Option1";
+      String[] vals = {"true"};
+      ContainerRuntimeOption cro = new ContainerRuntimeOptionImpl(name, Arrays.asList(vals));
+      cut.addContainerRuntimeOption(cro);
+      
+      ContainerRuntimeOption newcro = cut.getContainerRuntimeOption(name);
+      assertNotNull(newcro);
+      assertArrayEquals(vals, newcro.getValues().toArray());
+   }
+   
+   @Test
+   public void testGetDependency() {
+      String depName = "JQuery";
+      String depVers = "2.1.4";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+   
+   @Test
+   public void testGetDependency2() {
+      String depName = "AngularJS";
+      String depVers = "1.4.8";
+      Dependency dep = cut.getDependency(depName);
+      assertNotNull(dep);
+      assertEquals(depName, dep.getName());
+      assertEquals(depVers, dep.getVersion());
+   }
+   
+   @Test
+   public void testGetDependencies() {
+      String depName = "JQuery";
+      String depVers = "2.1.4";
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(3, deps.size());
+      Dependency dep = new DependencyImpl(depName, depVers);
+      assertTrue(deps.contains(dep));
+   }
+   
+   @Test
+   public void testAddDependency() {
+      String depName = "Bozo";
+      String depVers = "1.4";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+      
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(4, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+   
+   @Test
+   public void testAddDupDependency() {
+      String depName = "JQuery";
+      String depVers = "2.2.2";
+      Dependency dep = new DependencyImpl(depName, depVers);
+      cut.addDependency(dep);
+      
+      List<Dependency> deps = cut.getDependencies();
+      assertNotNull(deps);
+      assertEquals(3, deps.size());
+      assertTrue(deps.contains(dep));
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/ab12285f/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
new file mode 100644
index 0000000..762af95
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/om/portlet/impl/jsr362/MultiAnnotatedPortletTest.java
@@ -0,0 +1,346 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.om.portlet.impl.jsr362;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import org.apache.pluto.container.om.portlet.InitParam;
+import org.apache.pluto.container.om.portlet.LocaleText;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.PortletInfo;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.InitParamImpl;
+import org.apache.pluto.container.om.portlet.impl.LocaleTextImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.fixtures.TestMultiAnnotatedPortlet;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test class for a portlet configurations annotation containing multiple portlets along 
+ * with a portlet app annotation. 
+ * <p>
+ * Test Class: TestMultiAnnotatedPortlet
+ * 
+ * @author Scott Nicklous
+ */
+public class MultiAnnotatedPortletTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS = TestMultiAnnotatedPortlet.class;
+
+   private static PortletApplicationDefinition pad, app;
+
+   // Class under test
+   private PortletDefinition portlet1;
+   private PortletDefinition portlet2;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertEquals(2, pad.getPortlets().size());
+      assertNotNull(pad.getPortlet("Portlet1"));
+      assertNotNull(pad.getPortlet("Portlet2"));
+      app = new PortletApplicationDefinitionImpl(pad);
+      portlet1 = new PortletDefinitionImpl(pad.getPortlet("Portlet1"));
+      portlet2 = new PortletDefinitionImpl(pad.getPortlet("Portlet2"));
+   }
+
+   // Begin portlet app tests ==================================
+   
+
+   /**
+    * Test method for version from annotation
+    */
+   @Test
+   public void testGetVersion() {
+      String val = app.getVersion();
+      assertEquals("3.0", val);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getResourceBundle()}.
+    */
+   @Test
+   public void testGetResourceBundle() {
+      String val = app.getResourceBundle();
+      assertEquals("org.apache.pluto.container.om.portlet.GoodBundle", val);
+   }
+
+   /**
+    * Test method for {@link org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl#getDefaultNamespace()}.
+    */
+   @Test
+   public void testGetDefaultNamespace() {
+      String val = app.getDefaultNamespace();
+      assertEquals("https://www.apache.org/", val);
+   }
+
+   // Begin portlet 1 tests ================================== 
+   
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(portlet1.getPortletName());
+      assertEquals("Portlet1", portlet1.getPortletName());
+   }
+
+   @Test
+   public void testGetApplication() {
+      assertNotNull(portlet1.getApplication());
+      assertTrue(portlet1.getApplication() instanceof PortletApplicationDefinition);
+   }
+
+   @Test
+   public void testGetInitParam() {
+      String name = "color";
+      String val = "#cafeba";
+      InitParam ip = portlet1.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(val, ip.getParamValue());
+   }
+
+   @Test
+   public void testGetInitParams() {
+      String name = "color";
+      String val = "#cafeba";
+      List<InitParam> ips = portlet1.getInitParams();
+      assertEquals(1, ips.size());
+      
+      InitParam ip = new InitParamImpl(name, val);
+      assertTrue(ips.contains(ip));
+      
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNotNull(portlet1.getPortletClass());
+      assertEquals(TEST_ANNOTATED_CLASS.getCanonicalName(), portlet1.getPortletClass());
+   }
+
+   @Test
+   public void testGetTitle() {
+      String txt1 = "Annotated Portlet";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(1, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+   }
+
+   @Test
+   public void testAddTitle() {
+      String txt1 = "Annotated Portlet";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getTitle(Locale.ENGLISH).getText());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+   }
+
+   @Test
+   public void testGetShortTitle() {
+      String txt1 = "Anno Portlet";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(1, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+   }
+
+   @Test
+   public void testAddShortTitle() {
+      String txt1 = "Anno Portlet";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals(txt1, info.getShortTitle(Locale.ENGLISH).getText());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+   }
+
+   @Test
+   public void testGetKeywords() {
+      String txt1 = "One, Two, Three";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(1, list.size());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+   }
+
+   @Test
+   public void testAddKeywords() {
+      String txt1 = "One, Two, Three";
+      PortletInfo info = portlet1.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals(txt1, info.getKeywords(Locale.ENGLISH).getText());
+   }
+  
+   // Begin portlet 2 tests ================================== 
+   
+   @Test
+   public void test2GetPortletName() {
+      assertNotNull(portlet2.getPortletName());
+      assertEquals("Portlet2", portlet2.getPortletName());
+   }
+
+   @Test
+   public void test2GetApplication() {
+      assertNotNull(portlet2.getApplication());
+      assertTrue(portlet2.getApplication() instanceof PortletApplicationDefinition);
+   }
+
+   @Test
+   public void test2GetInitParam() {
+      String name = "color";
+      String val = "#def";
+      InitParam ip = portlet2.getInitParam(name);
+      assertNotNull(ip);
+      assertEquals(name, ip.getParamName());
+      assertEquals(val, ip.getParamValue());
+   }
+
+   @Test
+   public void test2GetInitParams() {
+      String name = "color";
+      String val = "#def";
+      List<InitParam> ips = portlet2.getInitParams();
+      assertEquals(1, ips.size());
+      
+      InitParam ip = new InitParamImpl(name, val);
+      assertTrue(ips.contains(ip));
+      
+   }
+
+   @Test
+   public void test2GetPortletClass() {
+      assertNotNull(portlet2.getPortletClass());
+      assertEquals(TEST_ANNOTATED_CLASS.getCanonicalName(), portlet2.getPortletClass());
+   }
+
+   @Test
+   public void test2GetTitle() {
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(1, list.size());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void test2AddTitle() {
+      String txt2 = "Annotiertes Portlet";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, "intitulé");
+      info.addTitle(lt);
+      List<LocaleText> list = info.getTitles();
+      assertEquals(2, list.size());
+      assertEquals("intitulé", info.getTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void test2GetShortTitle() {
+      String txt2 = "Ein Portlet";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(1, list.size());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void test2AddShortTitle() {
+      String txt2 = "Ein Portlet";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      String text = "intitulé en bref";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addShortTitle(lt);
+      List<LocaleText> list = info.getShortTitles();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getShortTitle(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getShortTitle(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void test2GetKeywords() {
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(1, list.size());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+   @Test
+   public void test2AddKeywords() {
+      String txt2 = "Eins, Zwei, Drei";
+      PortletInfo info = portlet2.getPortletInfo();
+      assertNotNull(info);
+      String text = "mot-clés";
+      LocaleText lt = new LocaleTextImpl(Locale.FRENCH, text);
+      info.addKeywords(lt);
+      List<LocaleText> list = info.getKeywordsList();
+      assertEquals(2, list.size());
+      assertEquals(text, info.getKeywords(Locale.FRENCH).getText());
+      assertEquals(txt2, info.getKeywords(Locale.GERMAN).getText());
+   }
+
+}


[19/35] portals-pluto git commit: Initial integration of bean processor code

Posted by ms...@apache.org.
http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ImpliedPortletTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ImpliedPortletTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ImpliedPortletTest.java
new file mode 100644
index 0000000..7b525ad
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ImpliedPortletTest.java
@@ -0,0 +1,168 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.om.portlet.EventDefinitionReference;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.EventDefinitionReferenceImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.jsr362.MergePortletAppTest;
+import org.apache.pluto.container.reconcile.fixtures.IncompletePortlet;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet2;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet3;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet4;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Adds a bean portlet that is defined implicitly through the portlet method annotations.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, TestPortlet1.class, 
+   TestPortlet2.class, TestPortlet3.class, TestPortlet4.class, IncompletePortlet.class})
+public class ImpliedPortletTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = TestPortlet2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Reconcile.xml";
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+
+   // Classes under test
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         ch.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+   }
+
+   // Begin portlet app tests ==================================
+   
+   @Test
+   public void testNumberPortlets() {
+      assertEquals(4, app.getPortlets().size());
+      assertNotNull(app.getPortlet("Portlet1"));
+      assertNotNull(app.getPortlet("Portlet2"));
+      assertNotNull(app.getPortlet("Portlet3"));
+      assertNotNull(app.getPortlet("Portlet4"));
+   }
+   
+   // tests that a portlet with not enough methods is thrown out.
+   @Test
+   public void incompletePortletTest() throws Exception {
+      assertNull(app.getPortlet("IncompletePortlet"));
+   }
+  
+   // Begin portlet 2 tests ================================== 
+   
+   @Test
+   public void test4GetPortletName() {
+      PortletDefinition portlet4 = app.getPortlet("Portlet4");
+      assertNotNull(portlet4.getPortletName());
+      assertEquals("Portlet4", portlet4.getPortletName());
+   }
+
+   @Test
+   public void test4GetPortletClass() {
+      PortletDefinition portlet4 = app.getPortlet("Portlet4");
+      assertNull(portlet4.getPortletClass());
+   }
+   
+   @Test
+   public void test4processingEvent() throws Exception {
+      PortletDefinition portlet4 = app.getPortlet("Portlet4");
+      List<EventDefinitionReference> events = portlet4.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(2, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event2"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event4"))));
+   }
+   
+   @Test
+   public void test4publishingEvent() throws Exception {
+      PortletDefinition portlet4 = app.getPortlet("Portlet4");
+      List<EventDefinitionReference> events = portlet4.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(3, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event1"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event3"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event4"))));
+   }
+   
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/InvokeHelper.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/InvokeHelper.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/InvokeHelper.java
new file mode 100644
index 0000000..fa77f54
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/InvokeHelper.java
@@ -0,0 +1,163 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.PortletInvoker;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockActionRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockActionResponse;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockEventRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockEventResponse;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockHeaderRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockHeaderResponse;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockPortletConfig;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockRenderRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockRenderResponse;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockResourceRequest;
+import org.apache.pluto.container.bean.processor.fixtures.mocks.MockResourceResponse;
+
+/**
+ * helper class for invoking portlet methods.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+public class InvokeHelper {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private static MockPortletConfig config = new MockPortletConfig();
+   
+   private static MockActionRequest  reqAction  = new MockActionRequest();
+   private static MockActionResponse respAction = new MockActionResponse();
+   
+   private static MockEventRequest  reqEvent  = new MockEventRequest();
+   private static MockEventResponse respEvent = new MockEventResponse();
+   
+   private static MockHeaderRequest  reqHeader  = new MockHeaderRequest();
+   private static MockHeaderResponse respHeader = new MockHeaderResponse();
+   
+   private static MockRenderRequest  reqRender  = new MockRenderRequest();
+   private static MockRenderResponse respRender = new MockRenderResponse();
+   
+   private static MockResourceRequest  reqResource  = new MockResourceRequest();
+   private static MockResourceResponse respResource = new MockResourceResponse();
+
+   
+   public void init(String portlet, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      i.init(config);
+      checkName(methName);
+   }
+   
+   public void destroy(String portlet, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      i.destroy();
+      checkName(methName);
+   }
+   
+   public void action(String portlet, String actName, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqAction.setActionName(actName);
+      i.processAction(reqAction, respAction);
+      checkName(methName);
+   }
+   
+   public void event(String portlet, QName qn, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqEvent.setQn(qn);
+      i.processEvent(reqEvent, respEvent);
+      checkName(methName);
+   }
+   
+   public void header(String portlet, PortletMode pm, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqHeader.setMode(pm);
+      i.renderHeaders(reqHeader, respHeader);
+      checkName(methName);
+   }
+   
+   public void render(String portlet, PortletMode pm, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqRender.setMode(pm);
+      i.render(reqRender, respRender);
+      checkName(methName);
+   }
+   
+   // used when a doHeaders call is expected (test portlet extends GenericPorlet)
+   public void renderWithHeaders(String portlet, PortletMode pm, List<String> methNames) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqRender.setMode(pm);
+      i.render(reqRender, respRender);
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      if (methNames != null) {
+         if (!names.containsAll(methNames)) {
+            System.out.println("checkName returned method names: " + names.toString());
+         }
+         assertEquals(methNames.size(), names.size());
+         assertArrayEquals(methNames.toArray(), names.toArray());
+      }
+   }
+   
+   public void resource(String portlet, String resid, String methName) throws Exception {
+      meths.reset();
+      PortletInvoker i = new PortletInvoker(acb, portlet);
+      reqResource.setResourceId(resid);
+      i.serveResource(reqResource, respResource);
+      checkName(methName);
+   }
+   
+   public void checkName(String methName) {
+      List<String> names = meths.getMethods();
+      assertNotNull(names);
+      if (methName != null) {
+         if (!names.contains(methName) || names.size() != 1) {
+            System.out.println("checkName returned method names: " + names.toString());
+         }
+         assertEquals(1, names.size());
+         assertTrue(names.contains(methName));
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/MergeEventDefsTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/MergeEventDefsTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/MergeEventDefsTest.java
new file mode 100644
index 0000000..0808400
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/MergeEventDefsTest.java
@@ -0,0 +1,210 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.om.portlet.EventDefinitionReference;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.jsr362.MergePortletAppTest;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet2;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet3;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Tests that event definitions and default namespaces from annotations and portlet DD
+ * are properly merged with one another.
+ * 
+ * @author Scott Nicklous
+ */
+public class MergeEventDefsTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = TestPortlet2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Reconcile.xml";
+
+   private static PortletApplicationDefinition pad, app;
+
+   // Class under test
+   private PortletDefinition portlet1;
+   private PortletDefinition portlet2;
+   private PortletDefinition portlet3;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         ch.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertEquals(3, pad.getPortlets().size());
+      assertNotNull(pad.getPortlet("Portlet1"));
+      assertNotNull(pad.getPortlet("Portlet2"));
+      assertNotNull(pad.getPortlet("Portlet3"));
+      app = new PortletApplicationDefinitionImpl(pad);
+      portlet1 = new PortletDefinitionImpl(pad.getPortlet("Portlet1"));
+      portlet2 = new PortletDefinitionImpl(pad.getPortlet("Portlet2"));
+      portlet3 = new PortletDefinitionImpl(pad.getPortlet("Portlet3"));
+   }
+
+   // Begin portlet app tests ==================================
+   
+   @Test
+   public void testGetVersion() {
+      String val = app.getVersion();
+      assertEquals("3.0", val);
+   }
+
+   @Test
+   public void testGetDefaultNamespace() {
+      String val = app.getDefaultNamespace();
+      assertEquals("https://www.java.net/", val);
+   }
+   
+   @Test
+   public void testEventDefinition() throws Exception {
+      assertNotNull(app.getEventDefinition(new QName("http://www.apache.org/", "event1")));  
+      assertNotNull(app.getEventDefinition(new QName("http://www.apache.org/", "event2")));   
+      assertNotNull(app.getEventDefinition(new QName("https://www.java.net/", "event3")));
+      assertNotNull(app.getEventDefinition(new QName("https://www.java.net/", "event4"))); 
+   }
+
+   // Begin portlet 1 tests ================================== 
+   
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(portlet1.getPortletName());
+      assertEquals("Portlet1", portlet1.getPortletName());
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNotNull(portlet1.getPortletClass());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), portlet1.getPortletClass());
+   }
+   
+   @Test
+   public void test1processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet1.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(0, events.size());
+   }
+   
+   @Test
+   public void test1publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet1.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(0, events.size());
+   }
+  
+   // Begin portlet 2 tests ================================== 
+   
+   @Test
+   public void test2GetPortletName() {
+      assertNotNull(portlet2.getPortletName());
+      assertEquals("Portlet2", portlet2.getPortletName());
+   }
+
+   @Test
+   public void test2GetPortletClass() {
+      assertNull(portlet2.getPortletClass());
+   }
+   
+   @Test
+   public void test2processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet2.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(0, events.size());
+   }
+   
+   @Test
+   public void test2publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet2.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(0, events.size());
+   }
+   
+   // Begin portlet 3 tests ================================== 
+   
+   @Test
+   public void test3GetPortletName() {
+      assertNotNull(portlet3.getPortletName());
+      assertEquals("Portlet3", portlet3.getPortletName());
+   }
+
+   @Test
+   public void test3GetPortletClass() {
+      assertNotNull(portlet3.getPortletClass());
+      assertEquals(TestPortlet3.class.getCanonicalName(), portlet3.getPortletClass());
+   }
+   
+   @Test
+   public void test3processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet3.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(1, events.size());
+      assertEquals(new QName("https://www.java.net/", "event3"), events.get(0).getQualifiedName());
+   }
+   
+   @Test
+   public void test3publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet3.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(1, events.size());
+      assertEquals(new QName("http://www.apache.org/", "event1"), events.get(0).getQualifiedName());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletInvokeTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletInvokeTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletInvokeTest.java
new file mode 100644
index 0000000..8fc461a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletInvokeTest.java
@@ -0,0 +1,323 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.jsr362.MergePortletAppTest;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1a;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet2;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet3;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet4;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that the expected portlet methods are present for a portlet app with several
+ * portlets, including bean portlets with no explicit configuration.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, InvokeHelper.class, TestPortlet1.class, TestPortlet1a.class, 
+   TestPortlet2.class, TestPortlet3.class, TestPortlet4.class})
+public class PortletInvokeTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   private InvokeHelper helper;
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = TestPortlet2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Reconcile.xml";
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   // Classes under test
+   private AnnotatedMethodStore ams = null;
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         ch.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+      assertNotNull(helper);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+      
+      helper.init("Portlet1", null);
+      helper.init("Portlet2", null);
+      helper.init("Portlet3", null);
+      helper.init("Portlet4", null);
+   }
+  
+   // Begin portlet 1 tests ================================== 
+
+   @Test
+   public void test1init() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#init";
+      helper.init("Portlet1", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1destroy() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#destroy";
+      helper.destroy("Portlet1", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1action() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#processAction";
+      helper.action("Portlet1", null, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1aaction() throws Exception {
+      String expectedMeth = TestPortlet1a.class.getSimpleName() + "#doAction";
+      helper.action("Portlet1", "Fred", expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1event1() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#processEvent";
+      QName qn = new QName("http://www.apache.org/", "event2");
+      helper.event("Portlet1", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1event2() throws Exception {
+      String expectedMeth = TestPortlet1a.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("http://www.apache.org/", "event1");
+      helper.event("Portlet1", qn, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1event3() throws Exception {
+      String expectedMeth = TestPortlet1a.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("https://www.java.net/", "event3");
+      helper.event("Portlet1", qn, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1header() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#renderHeaders";
+      PortletMode pm = PortletMode.VIEW;
+      helper.header("Portlet1", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1render() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#render";
+      PortletMode pm = PortletMode.VIEW;
+      helper.render("Portlet1", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test1res() throws Exception {
+      String expectedMeth = TestPortlet1.class.getSimpleName() + "#serveResource";
+      String resid = null;
+      helper.resource("Portlet1", resid, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+   
+   // Begin portlet 2 tests ================================== 
+
+   @Test
+   public void test2action() throws Exception {
+      String expectedMeth = TestPortlet2.class.getSimpleName() + "#doAction";
+      helper.action("Portlet2", null, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test2render() throws Exception {
+      String expectedMeth = TestPortlet2.class.getSimpleName() + "#myView";
+      PortletMode pm = PortletMode.VIEW;
+      helper.render("Portlet2", pm, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test2event1() throws Exception {
+      String expectedMeth = TestPortlet2.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("http://www.apache.org/", "event2");
+      helper.event("Portlet2", qn, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+
+   @Test
+   public void test2event2() throws Exception {
+      String expectedMeth = TestPortlet2.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("https://www.java.net/", "event4");
+      helper.event("Portlet2", qn, expectedMeth);
+      assertFalse(meths.isConfigExists());
+   }
+   
+   // Begin portlet 3 tests ================================== 
+
+   @Test
+   public void test3init() throws Exception {
+      String expectedMeth = TestPortlet3.class.getSimpleName() + "#init";
+      helper.init("Portlet3", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test3destroy() throws Exception {
+      String expectedMeth = TestPortlet3.class.getSimpleName() + "#destroy";
+      helper.destroy("Portlet3", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test3action() throws Exception {
+      String expectedMeth = TestPortlet3.class.getSimpleName() + "#processAction";
+      helper.action("Portlet3", null, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test3render() throws Exception {
+      String expectedMeth = TestPortlet3.class.getSimpleName() + "#render";
+      PortletMode pm = PortletMode.VIEW;
+      helper.render("Portlet3", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+   
+   // Begin portlet 4 tests ================================== 
+
+   @Test
+   public void test4init() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#init";
+      helper.init("Portlet4", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4destroy() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#destroy";
+      helper.destroy("Portlet4", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4action() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#doAction";
+      helper.action("Portlet4", null, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4event1() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("http://www.apache.org/", "event2");
+      helper.event("Portlet4", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4event2() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#doEvent";
+      QName qn = new QName("https://www.java.net/", "event4");
+      helper.event("Portlet4", qn, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4render() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#myView";
+      PortletMode pm = PortletMode.HELP;
+      helper.render("Portlet4", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4resource() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#res";
+      String resid = "something";
+      helper.resource("Portlet4", resid, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletMethodTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletMethodTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletMethodTest.java
new file mode 100644
index 0000000..b857f28
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/PortletMethodTest.java
@@ -0,0 +1,317 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.MethodIdentifier;
+import org.apache.pluto.container.bean.processor.MethodType;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.jsr362.MergePortletAppTest;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1a;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet2;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet3;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet4;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that the expected portlet methods are present for a portlet app with several
+ * portlets, including bean portlets with no explicit configuration.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, TestPortlet1.class, TestPortlet1a.class, 
+   TestPortlet2.class, TestPortlet3.class, TestPortlet4.class})
+public class PortletMethodTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = TestPortlet2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Reconcile.xml";
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   // Classes under test
+   private AnnotatedMethodStore ams = null;
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         ch.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+   }
+
+   // Begin portlet app tests ==================================
+   
+   @Test
+   public void testNumberPortlets() {
+      assertEquals(4, app.getPortlets().size());
+      assertNotNull(app.getPortlet("Portlet1"));
+      assertNotNull(app.getPortlet("Portlet2"));
+      assertNotNull(app.getPortlet("Portlet3"));
+      assertNotNull(app.getPortlet("Portlet4"));
+   }
+  
+   // Begin portlet 1 tests ================================== 
+
+   @Test
+   public void test1Contains() throws Exception {
+      Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet("Portlet1");
+      assertNotNull(meths);
+      assertEquals(10, meths.size());
+   }
+   
+   @Test
+   public void test1init() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.INIT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1destroy() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.DESTROY);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1action1() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.ACTION);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1action2() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "Fred", MethodType.ACTION);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1event1() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1event2() throws Exception {
+      QName qn = new QName("http://www.apache.org/", "event1");
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1event3() throws Exception {
+      QName qn = new QName("https://www.java.net/", "event3");
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test1render() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.RENDER);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   @Test
+   public void test1res() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.RESOURCE);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   @Test
+   public void test1headers() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet1", "", MethodType.HEADER);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   // Begin portlet 2 tests ================================== 
+
+   @Test
+   public void test2Contains() throws Exception {
+      Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet("Portlet2");
+      assertNotNull(meths);
+      assertEquals(4, meths.size());
+   }
+   
+   @Test
+   public void test2action1() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet2", "", MethodType.ACTION);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test2event1() throws Exception {
+      QName qn = new QName("http://www.apache.org/", "event2");
+      MethodIdentifier mi = new MethodIdentifier("Portlet2", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test2event2() throws Exception {
+      QName qn = new QName("https://www.java.net/", "event4");
+      MethodIdentifier mi = new MethodIdentifier("Portlet2", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test2render() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet2", "VIEW", MethodType.RENDER);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   // Begin portlet 3 tests ================================== 
+
+   @Test
+   public void test3Contains() throws Exception {
+      Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet("Portlet3");
+      assertNotNull(meths);
+      assertEquals(4, meths.size());
+   }
+   
+   @Test
+   public void test3init() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet3", "", MethodType.INIT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test3destroy() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet3", "", MethodType.DESTROY);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test3action1() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet3", "", MethodType.ACTION);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test3render() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet3", "", MethodType.RENDER);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   // Begin portlet 4 tests ================================== 
+
+   @Test
+   public void test4Contains() throws Exception {
+      Set<MethodIdentifier> meths = ams.getMethodIDsForPortlet("Portlet4");
+      assertNotNull(meths);
+      assertEquals(7, meths.size());
+   }
+   
+   @Test
+   public void test4init() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", "", MethodType.INIT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test4destroy() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", "", MethodType.DESTROY);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test4action1() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", "", MethodType.ACTION);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test4event2() throws Exception {
+      QName qn = new QName("http://www.apache.org/", "event2");
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test4event3() throws Exception {
+      QName qn = new QName("https://www.java.net/", "event4");
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", qn, MethodType.EVENT);
+      assertNotNull(ams.getMethod(mi));
+   }
+   
+   @Test
+   public void test4render() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", "", MethodType.RENDER);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+   
+   @Test
+   public void test4res() throws Exception {
+      MethodIdentifier mi = new MethodIdentifier("Portlet4", "", MethodType.RESOURCE);
+      assertTrue(ams.getMethods(mi).size() > 0);
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ReconcileAnnotatedTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ReconcileAnnotatedTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ReconcileAnnotatedTest.java
new file mode 100644
index 0000000..cc6755a
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/ReconcileAnnotatedTest.java
@@ -0,0 +1,246 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.xml.namespace.QName;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.om.portlet.EventDefinitionReference;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.PortletDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.om.portlet.impl.EventDefinitionReferenceImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletApplicationDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.PortletDefinitionImpl;
+import org.apache.pluto.container.om.portlet.impl.jsr362.MergePortletAppTest;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet1a;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet2;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet3;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Reconciles a bean portlet configuration with a portlet app definition
+ * and portlet application definition provided by annotation & portlet.xml.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, TestPortlet1.class, 
+   TestPortlet2.class, TestPortlet3.class, TestPortlet1a.class})
+public class ReconcileAnnotatedTest {
+
+   private static final Class<?> TEST_ANNOTATED_CLASS1 = TestPortlet1.class;
+   private static final Class<?> TEST_ANNOTATED_CLASS2 = TestPortlet2.class;
+   private static final String XML_FILE = 
+         "org/apache/pluto/container/om/portlet/portlet362Reconcile.xml";
+
+   private static PortletApplicationDefinition pad;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   private AnnotatedMethodStore ams = null;
+
+   // Classes under test
+   private PortletApplicationDefinition app;
+   private PortletDefinition portlet1;
+   private PortletDefinition portlet2;
+   private PortletDefinition portlet3;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+      
+      InputStream in = MergePortletAppTest.class
+            .getClassLoader().getResourceAsStream(XML_FILE);
+
+      Set<Class<?>> classes = new HashSet<Class<?>>();
+      classes.add(TEST_ANNOTATED_CLASS1);
+      classes.add(TEST_ANNOTATED_CLASS2);
+
+      ConfigurationHolder ch = new ConfigurationHolder();
+      try {
+         ch.processConfigAnnotations(classes);
+         ch.processPortletDD(in);     // process portlet xml after annotations
+         try {
+            ch.validate();         // validate and ignore any validation problems.
+         } catch (Exception e) {}   
+         pad = ch.getPad();
+      } catch (Exception e) {
+         e.printStackTrace();
+         throw e;
+      }
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+
+      app = new PortletApplicationDefinitionImpl(pad);
+      ConfigurationHolder coho = new ConfigurationHolder(app);
+      coho.reconcileBeanConfig(ams);
+
+      assertEquals(3, app.getPortlets().size());
+      assertNotNull(app.getPortlet("Portlet1"));
+      assertNotNull(app.getPortlet("Portlet2"));
+      assertNotNull(app.getPortlet("Portlet3"));
+      portlet1 = new PortletDefinitionImpl(app.getPortlet("Portlet1"));
+      portlet2 = new PortletDefinitionImpl(app.getPortlet("Portlet2"));
+      portlet3 = new PortletDefinitionImpl(app.getPortlet("Portlet3"));
+   }
+
+   // Begin portlet app tests ==================================
+   
+   @Test
+   public void testGetVersion() {
+      String val = app.getVersion();
+      assertEquals("3.0", val);
+   }
+
+   @Test
+   public void testGetDefaultNamespace() {
+      String val = app.getDefaultNamespace();
+      assertEquals("https://www.java.net/", val);
+   }
+   
+   @Test
+   public void testEventDefinition() throws Exception {
+      assertNotNull(app.getEventDefinition(new QName("http://www.apache.org/", "event1")));  
+      assertNotNull(app.getEventDefinition(new QName("http://www.apache.org/", "event2")));   
+      assertNotNull(app.getEventDefinition(new QName("https://www.java.net/", "event3")));
+      assertNotNull(app.getEventDefinition(new QName("https://www.java.net/", "event4"))); 
+   }
+
+   // Begin portlet 1 tests ================================== 
+   
+   @Test
+   public void testGetPortletName() {
+      assertNotNull(portlet1.getPortletName());
+      assertEquals("Portlet1", portlet1.getPortletName());
+   }
+
+   @Test
+   public void testGetPortletClass() {
+      assertNotNull(portlet1.getPortletClass());
+      assertEquals(TEST_ANNOTATED_CLASS1.getCanonicalName(), portlet1.getPortletClass());
+   }
+   
+   @Test
+   public void test1processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet1.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(2, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event1"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event3"))));
+   }
+   
+   @Test
+   public void test1publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet1.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(3, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event2"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event3"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event4"))));
+   }
+  
+   // Begin portlet 2 tests ================================== 
+   
+   @Test
+   public void test2GetPortletName() {
+      assertNotNull(portlet2.getPortletName());
+      assertEquals("Portlet2", portlet2.getPortletName());
+   }
+
+   @Test
+   public void test2GetPortletClass() {
+      assertNull(portlet2.getPortletClass());
+   }
+   
+   @Test
+   public void test2processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet2.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(2, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event2"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event4"))));
+   }
+   
+   @Test
+   public void test2publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet2.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(3, events.size());
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("http://www.apache.org/", "event1"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event3"))));
+      assertTrue(events.contains(new EventDefinitionReferenceImpl(new QName("https://www.java.net/", "event4"))));
+   }
+   
+   // Begin portlet 3 tests ================================== 
+   
+   @Test
+   public void test3GetPortletName() {
+      assertNotNull(portlet3.getPortletName());
+      assertEquals("Portlet3", portlet3.getPortletName());
+   }
+
+   @Test
+   public void test3GetPortletClass() {
+      assertNotNull(portlet3.getPortletClass());
+      assertEquals(TestPortlet3.class.getCanonicalName(), portlet3.getPortletClass());
+   }
+   
+   @Test
+   public void test3processingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet3.getSupportedProcessingEvents();
+      assertNotNull(events);
+      assertEquals(1, events.size());
+      assertEquals(new QName("https://www.java.net/", "event3"), events.get(0).getQualifiedName());
+   }
+   
+   @Test
+   public void test3publishingEvent() throws Exception {
+      List<EventDefinitionReference> events = portlet3.getSupportedPublishingEvents();
+      assertNotNull(events);
+      assertEquals(1, events.size());
+      assertEquals(new QName("http://www.apache.org/", "event1"), events.get(0).getQualifiedName());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/StandAloneBeanPortletInvokeTest.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/StandAloneBeanPortletInvokeTest.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/StandAloneBeanPortletInvokeTest.java
new file mode 100644
index 0000000..47af727
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/StandAloneBeanPortletInvokeTest.java
@@ -0,0 +1,131 @@
+/*  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+
+package org.apache.pluto.container.reconcile.tests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import javax.inject.Inject;
+import javax.portlet.PortletMode;
+
+import org.apache.pluto.container.bean.processor.AnnotatedConfigBean;
+import org.apache.pluto.container.bean.processor.AnnotatedMethodStore;
+import org.apache.pluto.container.bean.processor.PortletCDIExtension;
+import org.apache.pluto.container.bean.processor.fixtures.InvocationResults;
+import org.apache.pluto.container.om.portlet.PortletApplicationDefinition;
+import org.apache.pluto.container.om.portlet.impl.ConfigurationHolder;
+import org.apache.pluto.container.reconcile.fixtures.TestPortlet4;
+import org.jglue.cdiunit.AdditionalClasses;
+import org.jglue.cdiunit.CdiRunner;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests that a bean portlet without accompanying configuration data can
+ * be recognized and invoked.
+ * 
+ * @author Scott Nicklous
+ */
+@RunWith(CdiRunner.class)
+@AdditionalClasses({PortletCDIExtension.class, InvokeHelper.class, TestPortlet4.class})
+public class StandAloneBeanPortletInvokeTest {
+   
+   @Inject
+   private InvocationResults meths;
+   
+   @Inject
+   private InvokeHelper helper;
+   
+   @Inject
+   AnnotatedConfigBean acb;
+   
+   // Classes under test
+   private AnnotatedMethodStore ams = null;
+   private PortletApplicationDefinition app;
+
+   @BeforeClass
+   public static void setUpBeforeClass() throws Exception {
+   }
+
+   @Before
+   public void setUpBefore() throws Exception {
+      assertNotNull(acb);
+      ams = acb.getMethodStore();
+      assertNotNull(ams);
+      assertNotNull(helper);
+
+      ConfigurationHolder coho = new ConfigurationHolder();
+      coho.reconcileBeanConfig(ams);
+      app = coho.getPad();
+      
+      helper.init("Portlet4", null);
+   }
+  
+   // Begin portlet app tests ==================================
+   
+   @Test
+   public void testNumberPortlets() {
+      assertEquals(1, app.getPortlets().size());
+      assertNotNull(app.getPortlet("Portlet4"));
+   }
+   
+   // Begin portlet 4 tests ================================== 
+
+   @Test
+   public void test4init() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#init";
+      helper.init("Portlet4", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4destroy() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#destroy";
+      helper.destroy("Portlet4", expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4action() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#doAction";
+      helper.action("Portlet4", null, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4render() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#myView";
+      PortletMode pm = PortletMode.HELP;
+      helper.render("Portlet4", pm, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+   @Test
+   public void test4resource() throws Exception {
+      String expectedMeth = TestPortlet4.class.getSimpleName() + "#res";
+      String resid = "something";
+      helper.resource("Portlet4", resid, expectedMeth);
+      assertTrue(meths.isConfigExists());
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/package-info.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/package-info.java b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/package-info.java
new file mode 100644
index 0000000..a3e99b9
--- /dev/null
+++ b/pluto-container/src/test/java/org/apache/pluto/container/reconcile/tests/package-info.java
@@ -0,0 +1,27 @@
+/*  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 testing the reconciliation of a bean portlet configration
+ * with the servlet context portlet application definition and portlet
+ * definitions.
+ * 
+ * @author Scott Nicklous
+ *
+ */
+package org.apache.pluto.container.reconcile.tests;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Reconcile.xml
----------------------------------------------------------------------
diff --git a/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Reconcile.xml b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Reconcile.xml
new file mode 100644
index 0000000..938bffd
--- /dev/null
+++ b/pluto-container/src/test/resources/org/apache/pluto/container/om/portlet/portlet362Reconcile.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<portlet-app version="3.0"
+   xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:portlet="http://xmlns.jcp.org/xml/ns/portlet" 
+   xmlns:xml="http://www.w3.org/XML/1998/namespace"
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet portlet-app_3_0.xsd ">
+
+   <!-- JSR 362 portlet DD test file -->
+
+   <portlet>
+      <portlet-name>Portlet3</portlet-name>
+      <portlet-class>org.apache.pluto.container.reconcile.fixtures.TestPortlet3</portlet-class>
+      <supported-processing-event>
+         <name>event3</name>
+      </supported-processing-event>
+      <supported-publishing-event>
+         <qname xmlns:x="http://www.apache.org/">x:event1</qname>
+      </supported-publishing-event>
+   </portlet>
+   <event-definition>
+      <description xml:lang="de">description</description>
+      <name>event3</name>
+      <value-type>org.apache.pluto.container.om.portlet.impl.fixtures.TestEventType</value-type>
+   </event-definition>
+   <event-definition>
+      <description xml:lang="de">description</description>
+      <qname xmlns:x="http://www.apache.org/">x:event2</qname>
+      <value-type>java.lang.String</value-type>
+   </event-definition>
+</portlet-app>

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/2e60a313/pluto-portal-driver/src/main/java/org/apache/pluto/driver/container/PortletContextManager.java
----------------------------------------------------------------------
diff --git a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/container/PortletContextManager.java b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/container/PortletContextManager.java
index 8257f8a..be3263b 100644
--- a/pluto-portal-driver/src/main/java/org/apache/pluto/driver/container/PortletContextManager.java
+++ b/pluto-portal-driver/src/main/java/org/apache/pluto/driver/container/PortletContextManager.java
@@ -360,16 +360,15 @@ public class PortletContextManager implements PortletRegistryService, PortletCon
     }
 
 
-    @SuppressWarnings("unchecked")
     protected static String computeContextPath(ServletContext context) {
         if (APP_ID_RESOLVERS.size() < 1) {
-            List<Class> classes = null;
+            List<Class<?>> classes = null;
             try {
                 classes = ClasspathScanner.findConfiguredImplementations(ApplicationIdResolver.class);
             } catch (IOException e) {
                 throw new RuntimeException("Unable to find any ApplicationIdResolvers");
             }
-            for (Class c : classes) {
+            for (Class<?> c : classes) {
                 try {
                     APP_ID_RESOLVERS.add((ApplicationIdResolver)c.newInstance());
                 } catch (Exception e) {


[11/35] portals-pluto git commit: Adapted the portlet hub demo portlet to use annotation based configuration as much as possible (supported event config is not yet possible ... need the bean portlet functionality for that). Fixed several bugs in the conf

Posted by ms...@apache.org.
Adapted the portlet hub demo portlet to use annotation based configuration
as much as possible (supported event config is not yet possible ... need the
bean portlet functionality for that). Fixed several bugs in the config
reading impl.


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

Branch: refs/heads/V3Prototype
Commit: 0ceee24eb628552a07274448069563e755c3630a
Parents: df30f96
Author: Scott Nicklous <ms...@apache.org>
Authored: Mon Dec 7 15:49:20 2015 +0100
Committer: Scott Nicklous <ms...@apache.org>
Committed: Mon Dec 7 15:49:20 2015 +0100

----------------------------------------------------------------------
 .../java/basic/portlet/ImageSelPortlet.java     |   6 +-
 .../java/basic/portlet/MessageBoxPortlet.java   |   2 +-
 .../java/basic/portlet/ParamTestPortlet.java    |   4 +
 .../basic/portlet/PartialActionPortlet.java     |   6 +-
 .../java/basic/portlet/ResourcePortlet.java     |  35 +++++-
 .../src/main/webapp/WEB-INF/portlet.xml         |  97 +---------------
 .../portlet/PortletApplicationDefinition.java   |  12 ++
 .../container/om/portlet/PortletDefinition.java |   4 +
 .../driver/PortletContainerInitializer.java     |   9 +-
 .../impl/JSR286ConfigurationProcessor.java      | 113 ++++++++++++++-----
 .../impl/JSR362ConfigurationProcessor.java      |   5 +-
 .../impl/PortletApplicationDefinitionImpl.java  |  60 ++++++++++
 .../om/portlet/impl/PortletDefinitionImpl.java  |  15 +++
 13 files changed, 234 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
index 4475ebb..2221e84 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ImageSelPortlet.java
@@ -38,11 +38,15 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
 
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A demo portlet for selecting images
  */
+@PortletConfiguration(portletName = "ImageSelPortlet", publicParams = "imgName", 
+                      title = @LocaleString("PH Image Selection Portlet"))
 public class ImageSelPortlet extends GenericPortlet {
 
    // Set up logging

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
index 4fb730a..13cb517 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/MessageBoxPortlet.java
@@ -39,7 +39,7 @@ import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A demo portlet that displays messages sent via event
  */
 public class MessageBoxPortlet extends GenericPortlet {
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
index ab5b242..8d182ca 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ParamTestPortlet.java
@@ -38,6 +38,8 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
 
 
 /**
@@ -45,6 +47,8 @@ import javax.portlet.ResourceResponse;
  * 
  * @author Scott Nicklous
  */
+@PortletConfiguration(portletName = "ParamTestPortlet", publicParams = {"color", "imgName"},
+                        title = @LocaleString("PH Parameter Test Portlet"))
 public class ParamTestPortlet extends GenericPortlet {
 
    // Set up logging

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java b/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
index 185daea..4f6c365 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/PartialActionPortlet.java
@@ -39,10 +39,14 @@ import javax.portlet.ResourceRequest;
 import static javax.portlet.ResourceRequest.*;
 
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletConfiguration;
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A demo portlet exercising the partial action processing sequence
  */
+@PortletConfiguration(portletName = "PartialActionPortlet", publicParams = "color",
+                        title = @LocaleString("PH Partial Action Portlet"))
 public class PartialActionPortlet extends GenericPortlet {
 
    // Set up logging

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
index 7dac46f..eec1af5 100644
--- a/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
+++ b/PortletHubDemo/src/main/java/basic/portlet/ResourcePortlet.java
@@ -39,11 +39,44 @@ import javax.portlet.RenderRequest;
 import javax.portlet.RenderResponse;
 import javax.portlet.ResourceRequest;
 import javax.portlet.ResourceResponse;
+import javax.portlet.annotations.EventDefinition;
+import javax.portlet.annotations.LocaleString;
+import javax.portlet.annotations.PortletApplication;
+import javax.portlet.annotations.PortletConfiguration;
+import javax.portlet.annotations.PortletQName;
+import javax.portlet.annotations.PublicRenderParameterDefinition;
+import javax.portlet.annotations.Supports;
 
 
 /**
- * A management portlet that displays the current deep link configuraion
+ * A demo portlet that displays images
  */
+@PortletApplication(
+      events = {
+            @EventDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "http://www.apache.org/portals/pluto/ResourcePortlet", 
+                        localPart = "Message"),
+                  payloadType = String.class)},
+      publicParams = {
+            @PublicRenderParameterDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "http://www.apache.org/portals/pluto/ResourcePortlet", 
+                        localPart = "imgName"),
+                  identifier = "imgName"
+                  ),
+            @PublicRenderParameterDefinition(
+                  qname = @PortletQName(
+                        namespaceURI = "http://www.apache.org/portals/pluto/ResourcePortlet", 
+                        localPart = "color"),
+                  identifier = "color") }
+      )
+@PortletConfiguration(portletName = "PH-ResourcePortlet-PRP",
+      title={@LocaleString("PH Resource Portlet")},
+      supportedLocales = {"en"},
+      supports = @Supports(mimeType = "text/html", portletModes = "VIEW"),
+      publicParams = {"color", "imgName"}
+      )
 public class ResourcePortlet extends GenericPortlet {
 
    // Set up logging

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
----------------------------------------------------------------------
diff --git a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
index f5e8595..a79f959 100644
--- a/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
+++ b/PortletHubDemo/src/main/webapp/WEB-INF/portlet.xml
@@ -1,29 +1,9 @@
 <portlet-app xmlns="http://xmlns.jcp.org/xml/ns/portlet" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-             xmlns:rp="http://www.apache.org/portals/pluto/pub-render-params/ResourcePortlet"
+             xmlns:rp="http://www.apache.org/portals/pluto/ResourcePortlet"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/portlet http://xmlns.jcp.org/xml/ns/portlet/portlet-app_3_0.xsd" 
              version="3.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>MessageBoxPortlet</portlet-name>
@@ -50,26 +30,6 @@
    </portlet>
 
    <portlet>
-      <portlet-name>ImageSelPortlet</portlet-name>
-      <display-name>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>
       
@@ -92,59 +52,4 @@
       </supported-publishing-event>
       <supported-public-render-parameter>color</supported-public-render-parameter>
    </portlet>
-
-   <portlet>
-      <portlet-name>PartialActionPortlet</portlet-name>
-      <display-name>Partial Action Portlet</display-name>
-      
-      <portlet-class>basic.portlet.PartialActionPortlet</portlet-class>
-
-      <supports>
-         <mime-type>text/html</mime-type>
-         <portlet-mode>VIEW</portlet-mode>
-      </supports>
-
-      <supported-locale>en</supported-locale>        
-
-      <portlet-info>
-         <title>PH Partial Action Portlet</title>
-      </portlet-info>
-
-      <supported-public-render-parameter>color</supported-public-render-parameter>
-   </portlet>
-
-   <portlet>
-      <portlet-name>ParamTestPortlet</portlet-name>
-      <display-name>PH Parameter Test Portlet</display-name>
-      
-      <portlet-class>basic.portlet.ParamTestPortlet</portlet-class>
-
-      <supports>
-         <mime-type>text/html</mime-type>
-         <portlet-mode>VIEW</portlet-mode>
-      </supports>
-
-      <supported-locale>en</supported-locale>        
-
-      <portlet-info>
-         <title>PH Parameter Test Portlet</title>
-      </portlet-info>
-
-      <supported-public-render-parameter>imgName</supported-public-render-parameter>
-      <supported-public-render-parameter>color</supported-public-render-parameter>
-   </portlet>
-   
-   <event-definition>
-      <qname>rp:Message</qname>
-      <value-type>java.lang.String</value-type>
-   </event-definition>
-   
-   <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/0ceee24e/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
index b4698a7..6a76d15 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletApplicationDefinition.java
@@ -47,14 +47,17 @@ public interface PortletApplicationDefinition {
     */
    public List<PortletDefinition> getMatchingPortlets(String portletName);
    void addPortlet(PortletDefinition pd);
+   boolean removePortlet(PortletDefinition pd);
    
    List<EventDefinition> getEventDefinitions();
    EventDefinition getEventDefinition(QName qn);
    void addEventDefinition(EventDefinition ed);
+   boolean removeEventDefinition(EventDefinition ed);
 
    PublicRenderParameter getPublicRenderParameter(String identifier);
    List<PublicRenderParameter> getPublicRenderParameters();
    void addPublicRenderParameter(PublicRenderParameter prp);
+   boolean removePublicRenderParameter(PublicRenderParameter prp);
 
    String getVersion();
    void setVersion(String version);
@@ -62,17 +65,21 @@ public interface PortletApplicationDefinition {
    CustomPortletMode getCustomPortletMode(String name);
    List<CustomPortletMode> getCustomPortletModes();
    void addCustomPortletMode(CustomPortletMode cpm);
+   boolean removeCustomPortletMode(CustomPortletMode pm);
 
    CustomWindowState getCustomWindowState(String name);
    List<CustomWindowState> getCustomWindowStates();
    void addCustomWindowState(CustomWindowState cws);
+   boolean removeCustomWindowState(CustomWindowState ws);
 
    UserAttribute getUserAttribute(String name);
    List<UserAttribute> getUserAttributes();
    void addUserAttribute(UserAttribute ua);
+   boolean removeUserAttribute(UserAttribute ua);
 
    List<SecurityConstraint> getSecurityConstraints();
    void addSecurityConstraint(SecurityConstraint sc);
+   boolean removeSecurityCOnstraint(SecurityConstraint sc);
 
    String getResourceBundle();
    void setResourceBundle(String resourceBundle);
@@ -80,13 +87,16 @@ public interface PortletApplicationDefinition {
    Filter getFilter(String filterName);
    List<Filter> getFilters();
    void addFilter(Filter filter);
+   boolean removeFilter(Filter filter);
 
    FilterMapping getFilterMapping(String filterName);
    List<FilterMapping> getFilterMappings();
    void addFilterMapping(FilterMapping fm);
+   boolean removeFilterMapping(FilterMapping fm);
 
    List<Listener> getListeners();
    void addListener(Listener listener);
+   boolean removeListener(Listener listener);
 
    String getDefaultNamespace();
    void setDefaultNamespace(String defaultNamespace);
@@ -94,7 +104,9 @@ public interface PortletApplicationDefinition {
    ContainerRuntimeOption getContainerRuntimeOption(String name);
    List<ContainerRuntimeOption> getContainerRuntimeOptions();
    void addContainerRuntimeOption(ContainerRuntimeOption cro);
+   boolean removeRuntimeOption(ContainerRuntimeOption cro);
 
    Map<Locale, String> getLocaleEncodingMappings();
    void addLocaleEncodingMapping(Locale locale, String encoding);
+   String removeLocaleEncodingMapping(Locale locale);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
----------------------------------------------------------------------
diff --git a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
index 6de7da5..225844c 100644
--- a/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
+++ b/pluto-container-api/src/main/java/org/apache/pluto/container/om/portlet/PortletDefinition.java
@@ -40,12 +40,15 @@ public interface PortletDefinition {
 
    List<EventDefinitionReference> getSupportedProcessingEvents();
    void addSupportedProcessingEvent(EventDefinitionReference edr);
+   boolean removeSupportedProcessingEvent(EventDefinitionReference edr);
     
    List<EventDefinitionReference> getSupportedPublishingEvents();
    void addSupportedPublishingEvent(EventDefinitionReference edr);
+   boolean removeSupportedPublishingEvent(EventDefinitionReference edr);
 
    List<String> getSupportedPublicRenderParameters();
    void addSupportedPublicRenderParameter(String identifier);
+   boolean removeSupportedPublicRenderParameter(String identifier);
 
    String getResourceBundle();
    void setResourceBundle(String resourceBundle);
@@ -82,4 +85,5 @@ public interface PortletDefinition {
    void addDependency(Dependency dep);
    List<Dependency> getDependencies();
    Dependency getDependency(String name);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
----------------------------------------------------------------------
diff --git a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
index ff90207..9fb036b 100644
--- a/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
+++ b/pluto-container-driver-api/src/main/java/org/apache/pluto/container/driver/PortletContainerInitializer.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import javax.portlet.annotations.PortletApplication;
 import javax.portlet.annotations.PortletConfiguration;
 import javax.portlet.annotations.PortletConfigurations;
+import javax.portlet.annotations.PortletRequestFilter;
 import javax.portlet.filter.PortletFilter;
 import javax.servlet.ServletContainerInitializer;
 import javax.servlet.ServletContext;
@@ -45,7 +46,7 @@ import org.slf4j.LoggerFactory;
  * 
  */
 @HandlesTypes({PortletApplication.class, PortletConfiguration.class,
-               PortletFilter.class, PortletConfigurations.class})
+               PortletRequestFilter.class, PortletConfigurations.class})
 public class PortletContainerInitializer implements ServletContainerInitializer {
 
    private static final String WEB_XML     = "/WEB-INF/web.xml";
@@ -89,7 +90,7 @@ public class PortletContainerInitializer implements ServletContainerInitializer
             ConfigurationHolder holder = new ConfigurationHolder();
 
             if (classes != null) {
-               // digest any & all configuration annotations
+               holder.processConfigAnnotations(classes);
             }
 
             if (pin != null) {
@@ -129,7 +130,7 @@ public class PortletContainerInitializer implements ServletContainerInitializer
                ctx.setAttribute(ConfigurationHolder.ATTRIB_NAME, holder);
                
             } else {
-               LOG.error("Configuration problem - no portlet definitions");
+               LOG.debug("No portlet definitions for context: " + ctx.getServletContextName());
             }
 
          } catch (Exception e) {
@@ -138,7 +139,7 @@ public class PortletContainerInitializer implements ServletContainerInitializer
             txt.append(", Servlet ctx name: ").append(
                   ctx.getServletContextName());
             txt.append(", Exception: ").append(e.toString());
-            LOG.error(txt.toString());
+            LOG.info(txt.toString());
          }
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
index 28df6f8..b466e3d 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR286ConfigurationProcessor.java
@@ -478,12 +478,12 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          List<PortletModeType> pmlist = st.getPortletMode();
          if (pmlist.size() == 0) {
             String info = "No portlet modes found in Supports block.";
-            LOG.info(info);
+            LOG.debug(info);
          }
          List<WindowStateType> wslist = st.getWindowState();
          if (wslist.size() == 0) {
             String info = "No window states found in Supports block.";
-            LOG.info(info);
+            LOG.debug(info);
          }
 
          // set up Supports
@@ -865,30 +865,49 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
    public void validate () {
       super.validate();
       
+      StringBuilder txt = new StringBuilder(128);
+      
       // validate the resource bundle
       if (pad.getResourceBundle() != null) {
-         checkValidBundle(pad.getResourceBundle());
+         try {
+            checkValidBundle(pad.getResourceBundle());
+         } catch (Exception e) {
+            pad.setResourceBundle("");
+         }
       }
       
       // validate event definitions by making sure the payload classes, if provided, can be loaded.
       for (EventDefinition ed : pad.getEventDefinitions()) {
          String clsName = ed.getValueType();
          if (clsName != null && !clsName.equals("")) {
-            checkValidClass(clsName, null,
-                  "Bad Event definition. Payload type is invalid: ");
+            try {
+               checkValidClass(clsName, null, "Bad Event definition. Payload type is invalid: ");
+            } catch (Exception e) {
+               pad.removeEventDefinition(ed);
+            }
          }
       }
       
       // validate provided listener classes
       for (Listener l : pad.getListeners()) {
-         checkValidClass(l.getListenerClass(), PortletURLGenerationListener.class,
-               "Bad listener definition. Listener class is invalid: ");
+         try {
+            checkValidClass(l.getListenerClass(), PortletURLGenerationListener.class,
+                  "Bad listener definition. Listener class is invalid: ");
+         } catch(Exception e) {
+            pad.removeListener(l);
+         }
       }
       
       // Validate the filter classes
       for (Filter f : pad.getFilters()) {
-         checkValidClass(f.getFilterClass(), PortletFilter.class,
-               "Bad filter definition. Filter class is invalid: ");
+         try {
+            txt.setLength(0);
+            txt.append("Bad filter definition. Filter name: ").append(f.getFilterName());
+            txt.append(". Filter class is invalid: ");
+            checkValidClass(f.getFilterClass(), PortletFilter.class, txt.toString());
+         } catch(Exception e) {
+            pad.removeFilter(f);
+         }
       }
       
       // validate the filter mappings by making sure that the specified filters and 
@@ -896,15 +915,21 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
       for (FilterMapping fm : pad.getFilterMappings()) {
          String fname = fm.getFilterName();
          if (pad.getFilter(fname) == null) {
-            String warning = "Bad FilterMapping definition. Filter definition not found: " + fname;
-            LOG.warn(warning);
-            throw new IllegalArgumentException(warning);
+            txt.setLength(0);
+            txt.append("Bad filter mapping definition. Filter name: ").append(fm.getFilterName());
+            txt.append(", Portlet names: ").append(fm.getPortletNames().toString());
+            txt.append(", Filter definition not found: ").append(fname);
+            LOG.warn(txt.toString());
+            pad.removeFilterMapping(fm);
          }
          for (String pn : fm.getPortletNames()) {
             if (pad.getMatchingPortlets(pn).isEmpty()) {
-               String warning = "Bad FilterMapping definition. Portlet definition not found: " + pn;
-               LOG.warn(warning);
-               throw new IllegalArgumentException(warning);
+               txt.setLength(0);
+               txt.append("Bad filter mapping definition. Filter name: ").append(fm.getFilterName());
+               txt.append(", Portlet names: ").append(fm.getPortletNames().toString());
+               txt.append(", Portlet definition not found: ").append(pn);
+               LOG.warn(txt.toString());
+               pad.removeFilterMapping(fm);
             }
          }
       }
@@ -914,34 +939,52 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          
          // check the portlet class
          if (pad.getVersion().equals("2.0") || pad.getVersion().equals("1.0")) {
-            checkValidClass(portlet.getPortletClass(), Portlet.class, "Bad portlet class: ");
+            try {
+               checkValidClass(portlet.getPortletClass(), Portlet.class, "Bad portlet class: ");
+            } catch (Exception e) {
+               pad.removePortlet(portlet);
+               continue;
+            }
          }
          
          // check the resource bundle
          if (portlet.getResourceBundle() != null) {
-            checkValidBundle(portlet.getResourceBundle());
+            try {
+               checkValidBundle(portlet.getResourceBundle());
+            } catch (Exception e) {
+               pad.setResourceBundle("");
+            }
          }
          
          // check the portlet preferences validator class
          Preferences prefs = portlet.getPortletPreferences();
          if (prefs != null && prefs.getPreferencesValidator() != null) {
             String clsName = prefs.getPreferencesValidator();
+            try {
             checkValidClass(clsName, PreferencesValidator.class,
                   "Bad portlet preferences validator class: ");
+            } catch (Exception e) {
+               portlet.setPortletPreferences(null);
+            }
          }
          
          // Check the supported public render parameters
          for (String prp : portlet.getSupportedPublicRenderParameters()) {
             boolean ok = false;
+            txt.setLength(0);
+            txt.append("Valid PRP identifiers: ");
+            String sep = "";
             for (PublicRenderParameter prpdef : pad.getPublicRenderParameters()) {
+               txt.append(sep).append(prpdef.getIdentifier());
+               sep = ", ";
                if (prpdef.getIdentifier().equals(prp)) {
                   ok = true;
                }
             }
             if (!ok) {
-               String warning = "Public render parameter definition not found for: " + prp;
-               LOG.warn(warning);
-               throw new IllegalArgumentException(warning);
+               txt.append(". Public render parameter definition not found for: ").append(prp);
+               LOG.warn(txt.toString());
+               portlet.removeSupportedPublicRenderParameter(prp);
             }
          }
          
@@ -949,10 +992,17 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          for (EventDefinitionReference edr : portlet.getSupportedPublishingEvents()) {
             QName qname = edr.getQualifiedName();
             if (pad.getEventDefinition(qname) == null) {
-               String warning = "Bad publishing event definition reference. No event definition found for qname: "
-                     + qname;
-               LOG.warn(warning);
-               throw new IllegalArgumentException(warning);
+               txt.setLength(0);
+               txt.append("Bad publishing event definition reference. No event definition found for qname: ");
+               txt.append(qname);
+               txt.append(". Valid QNames: ");
+               String sep = "";
+               for (EventDefinition def : pad.getEventDefinitions()) {
+                  txt.append(sep).append(def.getQName());
+                  sep = ", ";
+               }
+               LOG.warn(txt.toString());
+               portlet.removeSupportedPublishingEvent(edr);
             }
          }
          
@@ -960,10 +1010,17 @@ public class JSR286ConfigurationProcessor extends JSR168ConfigurationProcessor {
          for (EventDefinitionReference edr : portlet.getSupportedProcessingEvents()) {
             QName qname = edr.getQualifiedName();
             if (pad.getEventDefinition(qname) == null) {
-               String warning = "Bad processing event definition reference. No event definition found for qname: "
-                     + qname;
-               LOG.warn(warning);
-               throw new IllegalArgumentException(warning);
+               txt.setLength(0);
+               txt.append("Bad publishing event definition reference. No event definition found for qname: ");
+               txt.append(qname);
+               txt.append(". Valid QNames: ");
+               String sep = "";
+               for (EventDefinition def : pad.getEventDefinitions()) {
+                  txt.append(sep).append(def.getQName());
+                  sep = ", ";
+               }
+               LOG.warn(txt.toString());
+               portlet.removeSupportedProcessingEvent(edr);
             }
          }
          

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
index 6a961df..a60a6f0 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/JSR362ConfigurationProcessor.java
@@ -427,12 +427,12 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
          List<PortletModeType> pmlist = st.getPortletMode();
          if (pmlist.size() == 0) {
             String info = "No portlet modes found in Supports block.";
-            LOG.info(info);
+            LOG.debug(info);
          }
          List<WindowStateType> wslist = st.getWindowState();
          if (wslist.size() == 0) {
             String info = "No window states found in Supports block.";
-            LOG.info(info);
+            LOG.debug(info);
          }
 
          // set up Supports
@@ -904,6 +904,7 @@ public class JSR362ConfigurationProcessor extends JSR286ConfigurationProcessor {
             DisplayName d = new DisplayNameImpl(Locale.forLanguageTag(ls.locale()), ls.value());
             evt.addDisplayName(d);
          }
+         evt.setValueType(ed.payloadType().getCanonicalName());
          pad.addEventDefinition(evt);
       }
 

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
index 382efcb..48fdb99 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletApplicationDefinitionImpl.java
@@ -269,6 +269,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       portlets.add( pd);
    }
+   
+   @Override
+   public boolean removePortlet(PortletDefinition pd) {
+      return portlets.remove(pd);
+   }
 
    @Override
    public List<EventDefinition> getEventDefinitions() {
@@ -297,6 +302,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       events.add(ed);
    }
+   
+   @Override
+   public boolean removeEventDefinition(EventDefinition ed) {
+      return events.remove(ed);
+   }
 
    @Override
    public PublicRenderParameter getPublicRenderParameter(String identifier) {
@@ -334,6 +344,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       prps.add(prp);
    }
+   
+   @Override
+   public boolean removePublicRenderParameter(PublicRenderParameter prp) {
+      return prps.remove(prp);
+   }
 
    @Override
    public CustomPortletMode getCustomPortletMode(String arg) {
@@ -362,6 +377,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       cpms.add(cpm);
    }
+   
+   @Override
+   public boolean removeCustomPortletMode(CustomPortletMode pm) {
+      return cpms.remove(pm);
+   }
 
    @Override
    public CustomWindowState getCustomWindowState(String arg) {
@@ -390,6 +410,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       cwss.add(cws);
    }
+   
+   @Override
+   public boolean removeCustomWindowState(CustomWindowState ws) {
+      return cwss.remove(ws);
+   }
 
    @Override
    public UserAttribute getUserAttribute(String arg) {
@@ -418,6 +443,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       uattrs.add(ua);
    }
+   
+   @Override
+   public boolean removeUserAttribute(UserAttribute ua) {
+      return uattrs.remove(ua);
+   }
 
    @Override
    public Filter getFilter(String arg) {
@@ -451,6 +481,11 @@ public class PortletApplicationDefinitionImpl implements
          LOG.debug("No filter class for filter: " + filter.getFilterName());
       }
    }
+   
+   @Override
+   public boolean removeFilter(Filter filter) {
+      return filters.remove(filter);
+   }
 
    @Override
    public FilterMapping getFilterMapping(String arg) {
@@ -484,6 +519,11 @@ public class PortletApplicationDefinitionImpl implements
          LOG.debug("No portlet names for filter mapping. Filter name: " + fm.getFilterName());
       }
    }
+   
+   @Override
+   public boolean removeFilterMapping(FilterMapping fm) {
+      return fmaps.remove(fm);
+   }
 
    @Override
    public ContainerRuntimeOption getContainerRuntimeOption(String arg) {
@@ -512,6 +552,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       cros.add(cro);
    }
+   
+   @Override
+   public boolean removeRuntimeOption(ContainerRuntimeOption cro) {
+      return cros.remove(cro);
+   }
 
    @Override
    public List<Listener> getListeners() {
@@ -529,6 +574,11 @@ public class PortletApplicationDefinitionImpl implements
       }
       listeners.add(listener);
    }
+   
+   @Override
+   public boolean removeListener(Listener listener) {
+      return listeners.remove(listener);
+   }
 
    @Override
    public List<SecurityConstraint> getSecurityConstraints() {
@@ -548,6 +598,11 @@ public class PortletApplicationDefinitionImpl implements
    }
 
    @Override
+   public boolean removeSecurityCOnstraint(SecurityConstraint sc) {
+      return constraints.remove(sc);
+   }
+
+   @Override
    public Map<Locale, String> getLocaleEncodingMappings() {
       Map<Locale, String> lem = new HashMap<Locale, String>();
       for (Locale l : localemap.keySet()) {
@@ -560,5 +615,10 @@ public class PortletApplicationDefinitionImpl implements
    public void addLocaleEncodingMapping(Locale locale, String encoding) {
       localemap.put(locale, encoding);
    }
+   
+   @Override
+   public String removeLocaleEncodingMapping(Locale locale) {
+      return localemap.remove(locale);
+   }
 
 }

http://git-wip-us.apache.org/repos/asf/portals-pluto/blob/0ceee24e/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
----------------------------------------------------------------------
diff --git a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
index 5437e62..7708180 100644
--- a/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
+++ b/pluto-container/src/main/java/org/apache/pluto/container/om/portlet/impl/PortletDefinitionImpl.java
@@ -259,6 +259,11 @@ public class PortletDefinitionImpl implements PortletDefinition {
       }
       proEvtRefs.add(edr);
    }
+   
+   @Override
+   public boolean removeSupportedProcessingEvent(EventDefinitionReference edr) {
+      return proEvtRefs.remove(edr);
+   }
 
    /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.PortletDefinition#getSupportedPublishingEvents()
@@ -278,6 +283,11 @@ public class PortletDefinitionImpl implements PortletDefinition {
       }
       pubEvtRefs.add(edr);
    }
+   
+   @Override
+   public boolean removeSupportedPublishingEvent(EventDefinitionReference edr) {
+      return pubEvtRefs.remove(edr);
+   }
 
    /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.PortletDefinition#getSupportedPublicRenderParameters()
@@ -297,6 +307,11 @@ public class PortletDefinitionImpl implements PortletDefinition {
       }
       pubParms.add(identifier);
    }
+   
+   @Override
+   public boolean removeSupportedPublicRenderParameter(String identifier) {
+      return pubParms.remove(identifier);
+   }
 
    /* (non-Javadoc)
     * @see org.apache.pluto.container.om.portlet.PortletDefinition#getResourceBundle()