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

[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

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());
+   }
+
+}