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:10 UTC

[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

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