[gatein-commits] gatein SVN: r4924 - in portal/trunk/component/wsrp: src/main/java/org/gatein/portal/wsrp and 3 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Wed Nov 3 16:48:20 EDT 2010


Author: chris.laprun at jboss.com
Date: 2010-11-03 16:48:19 -0400 (Wed, 03 Nov 2010)
New Revision: 4924

Added:
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProvider.java
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPPortalStructureAccess.java
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/PortalStructureAccess.java
   portal/trunk/component/wsrp/src/test/java/org/gatein/portal/wsrp/structure/
   portal/trunk/component/wsrp/src/test/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProviderTestCase.java
Removed:
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/MOPConsumerStructureProvider.java
Modified:
   portal/trunk/component/wsrp/pom.xml
   portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/WSRPServiceIntegration.java
Log:
- Re-factored MOPConsumerStructureProvider so that it's decoupled from MOP objects by introducing the PortalStructureAccess interface and its MOPPortalStructureAccess implementation. Made it easier to test.
- Added test case.

Modified: portal/trunk/component/wsrp/pom.xml
===================================================================
--- portal/trunk/component/wsrp/pom.xml	2010-11-03 20:28:48 UTC (rev 4923)
+++ portal/trunk/component/wsrp/pom.xml	2010-11-03 20:48:19 UTC (rev 4924)
@@ -104,6 +104,10 @@
          <groupId>org.chromattic</groupId>
          <artifactId>chromattic.spi</artifactId>
       </dependency>
+      <dependency>
+         <groupId>org.gatein.wci</groupId>
+         <artifactId>wci-wci</artifactId>
+      </dependency>
 
       <!-- Required to process Chromattic annotations -->
       <dependency>
@@ -119,8 +123,10 @@
          <scope>test</scope>
       </dependency>
       <dependency>
-         <groupId>org.gatein.wci</groupId>
-         <artifactId>wci-wci</artifactId>
+         <groupId>org.mockito</groupId>
+         <artifactId>mockito-core</artifactId>
+         <version>1.8.5</version>
+         <scope>test</scope>
       </dependency>
    </dependencies>
 

Deleted: portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/MOPConsumerStructureProvider.java
===================================================================
--- portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/MOPConsumerStructureProvider.java	2010-11-03 20:28:48 UTC (rev 4923)
+++ portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/MOPConsumerStructureProvider.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -1,312 +0,0 @@
-/*
- * JBoss, a division of Red Hat
- * Copyright 2010, Red Hat Middleware, LLC, and individual
- * contributors as indicated by the @authors tag. See the
- * copyright.txt in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.gatein.portal.wsrp;
-
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.portal.config.DataStorage;
-import org.exoplatform.portal.mop.Described;
-import org.exoplatform.portal.pom.config.POMSession;
-import org.exoplatform.portal.pom.config.POMSessionManager;
-import org.exoplatform.portal.pom.data.Mapper;
-import org.exoplatform.portal.pom.data.PageKey;
-import org.exoplatform.portal.pom.spi.wsrp.WSRP;
-import org.exoplatform.services.listener.Event;
-import org.exoplatform.services.listener.Listener;
-import org.gatein.common.util.ParameterValidation;
-import org.gatein.mop.api.content.Customization;
-import org.gatein.mop.api.workspace.ObjectType;
-import org.gatein.mop.api.workspace.Page;
-import org.gatein.mop.api.workspace.Site;
-import org.gatein.mop.api.workspace.Workspace;
-import org.gatein.mop.api.workspace.ui.UIComponent;
-import org.gatein.mop.api.workspace.ui.UIContainer;
-import org.gatein.mop.api.workspace.ui.UIWindow;
-import org.gatein.pc.api.PortletContext;
-import org.gatein.pc.api.PortletStateType;
-import org.gatein.pc.api.StatefulPortletContext;
-import org.gatein.wsrp.api.context.ConsumerStructureProvider;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author <a href="mailto:chris.laprun at jboss.com">Chris Laprun</a>
- * @version $Revision$
- */
-public class MOPConsumerStructureProvider extends Listener<DataStorage, org.exoplatform.portal.config.model.Page> implements ConsumerStructureProvider
-{
-   private static final String PAGES_CHILD_NAME = "pages";
-   private final POMSessionManager pomManager;
-   private Map<String, PageInfo> pageInfos;
-   private boolean pagesHaveBeenInitialized;
-
-   public MOPConsumerStructureProvider(ExoContainer container)
-   {
-      pomManager = (POMSessionManager)container.getComponentInstanceOfType(POMSessionManager.class);
-      pageInfos = new HashMap<String, PageInfo>();
-   }
-
-   public List<String> getPageIdentifiers()
-   {
-      if (!pagesHaveBeenInitialized)
-      {
-         // initialize page information
-         POMSession session = pomManager.getSession();
-         Workspace workspace = session.getWorkspace();
-         Collection<Site> sites = workspace.getSites(ObjectType.PORTAL_SITE);
-
-         for (Site site : sites)
-         {
-            Page page = getPagesFrom(site);
-            if (page != null)
-            {
-               addPage(page, true);
-            }
-         }
-
-         pagesHaveBeenInitialized = true;
-      }
-
-      LinkedList<String> identifiers = new LinkedList<String>(pageInfos.keySet());
-      Collections.sort(identifiers);
-      return identifiers;
-   }
-
-   private Page getPagesFrom(Site site)
-   {
-      // a site contains a root page with templates and pages
-      // more info at http://code.google.com/p/chromattic/wiki/MOPUseCases
-
-      return site.getRootPage().getChild(PAGES_CHILD_NAME);
-   }
-
-   private void addPage(Page page, boolean ignoreCurrent)
-   {
-      if (!ignoreCurrent)
-      {
-         Described described = page.adapt(Described.class);
-         PageInfo pageInfo = new PageInfo(page.getObjectId(), described.getName());
-         pageInfos.put(pageInfo.getName(), pageInfo);
-         UIContainer container = page.getRootComponent();
-         processContainer(container, pageInfo);
-      }
-
-      Collection<Page> children = page.getChildren();
-      if (ParameterValidation.existsAndIsNotEmpty(children))
-      {
-         for (Page child : children)
-         {
-            addPage(child, false);
-         }
-      }
-   }
-
-   public List<String> getWindowIdentifiersFor(String pageId)
-   {
-      PageInfo pageInfo = pageInfos.get(pageId);
-      ParameterValidation.throwIllegalArgExceptionIfNull(pageInfo, "PageInfo for " + pageId);
-
-      return pageInfo.getChildrenWindows();
-   }
-
-   private void processContainer(UIContainer container, PageInfo pageInfo)
-   {
-      List<UIComponent> components = container.getComponents();
-      for (UIComponent component : components)
-      {
-         ObjectType<? extends UIComponent> type = component.getObjectType();
-         if (ObjectType.WINDOW.equals(type))
-         {
-            Described described = component.adapt(Described.class);
-            String name = described.getName();
-
-            pageInfo.addWindow(name, component.getObjectId());
-         }
-         else if (ObjectType.CONTAINER.equals(type))
-         {
-            processContainer((UIContainer)component, pageInfo);
-         }
-         else
-         {
-            // ignore
-         }
-      }
-   }
-
-   public void assignPortletToWindow(PortletContext portletContext, String windowId, String pageId, String exportedPortletHandle)
-   {
-      PageInfo pageInfo = pageInfos.get(pageId);
-      String uuid = pageInfo.getWindowUUID(windowId);
-      ParameterValidation.throwIllegalArgExceptionIfNull(uuid, "UUID for " + windowId);
-
-      // get the window
-      POMSession session = pomManager.getSession();
-      UIWindow window = session.findObjectById(ObjectType.WINDOW, uuid);
-
-      // construct the new customization state
-      WSRP wsrp = new WSRP();
-      String portletId = portletContext.getId();
-      wsrp.setPortletId(portletId);
-      if (portletContext instanceof StatefulPortletContext)
-      {
-         StatefulPortletContext context = (StatefulPortletContext)portletContext;
-         if (PortletStateType.OPAQUE.equals(context.getType()))
-         {
-            wsrp.setState((byte[])context.getState());
-         }
-         else
-         {
-            throw new IllegalArgumentException("Don't know how to deal with state: " + context.getState());
-         }
-      }
-
-      // destroy existing customization as otherwise re-customizing will fail
-      Customization<?> customization = window.getCustomization();
-      customization.destroy();
-
-      // and re-customize
-      window.customize(WSRP.CONTENT_TYPE, portletId, wsrp);
-
-      // Change the window's name so that it's less confusing to users
-      Described described = window.adapt(Described.class);
-      String newName = exportedPortletHandle + " (remote)";
-      described.setName(newName); // should be the same as ApplicationRegistryService.REMOTE_DISPLAY_NAME_SUFFIX
-
-      // update window mappings
-      pageInfo.updateWindowName(windowId, newName);
-
-      // mark page for cache invalidation otherwise DataCache will use the previous customization id when trying to set
-      // the portlet state in UIPortlet.setState and will not find it resulting in an error
-      Page page = window.getPage();
-      session.scheduleForEviction(new PageKey("portal", page.getSite().getName(), page.getName()));
-
-      // save
-      session.close(true);
-   }
-
-   @Override
-   public void onEvent(Event<DataStorage, org.exoplatform.portal.config.model.Page> event) throws Exception
-   {
-      String eventName = event.getEventName();
-
-      // get the MOP page from the event data
-      org.exoplatform.portal.config.model.Page portalPage = event.getData();
-      Site site = pomManager.getSession().getWorkspace().getSite(Mapper.parseSiteType(portalPage.getOwnerType()), portalPage.getOwnerId());
-      Page page = getPagesFrom(site).getChild(portalPage.getName());
-
-      if (page != null)
-      {
-         if (DataStorage.PAGE_CREATED.equals(eventName))
-         {
-            // add information for new page
-            addPage(page, false);
-         }
-         else if (DataStorage.PAGE_REMOVED.equals(eventName))
-         {
-            removePage(page);
-         }
-         else if (DataStorage.PAGE_UPDATED.equals(eventName))
-         {
-            removePage(page);
-            addPage(page, false);
-         }
-      }
-   }
-
-   private void removePage(Page page)
-   {
-      Described described = page.adapt(Described.class);
-      String name = described.getName();
-
-      PageInfo pageInfo = pageInfos.get(name);
-      if (pageInfo != null)
-      {
-         // remove page info
-         pageInfos.remove(name);
-      }
-   }
-
-   private static class PageInfo
-   {
-      private final String uuid;
-      private final Map<String, String> childrenWindows = new HashMap<String, String>();
-      private final String name;
-
-      private PageInfo(String uuid, String name)
-      {
-         this.uuid = uuid;
-         this.name = name;
-      }
-
-      public String getUUID()
-      {
-         return uuid;
-      }
-
-      public List<String> getChildrenWindows()
-      {
-         return new ArrayList<String>(childrenWindows.keySet());
-      }
-
-      public void addWindow(String windowName, String uuid)
-      {
-         // add suffix in case we have several windows with the same name in the page
-         if (childrenWindows.containsKey(windowName))
-         {
-            if (windowName.endsWith("|"))
-            {
-               windowName += "|";
-            }
-            else
-            {
-               windowName += windowName + " |";
-            }
-         }
-
-         childrenWindows.put(windowName, uuid);
-      }
-
-      public void updateWindowName(String oldWindowName, String newWindowName)
-      {
-         String windowUUID = getWindowUUID(oldWindowName);
-         childrenWindows.remove(oldWindowName);
-         childrenWindows.put(newWindowName, windowUUID);
-      }
-
-      public String getName()
-      {
-         return name;
-      }
-
-      public String getWindowUUID(String windowId)
-      {
-         return childrenWindows.get(windowId);
-      }
-   }
-}

Modified: portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/WSRPServiceIntegration.java
===================================================================
--- portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/WSRPServiceIntegration.java	2010-11-03 20:28:48 UTC (rev 4923)
+++ portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/WSRPServiceIntegration.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -29,6 +29,7 @@
 import org.exoplatform.container.xml.InitParams;
 import org.exoplatform.portal.config.DataStorage;
 import org.exoplatform.portal.pc.ExoKernelIntegration;
+import org.exoplatform.portal.pom.config.POMSessionManager;
 import org.exoplatform.services.jcr.ext.hierarchy.NodeHierarchyCreator;
 import org.exoplatform.services.listener.ListenerService;
 import org.gatein.common.logging.Logger;
@@ -48,6 +49,9 @@
 import org.gatein.portal.wsrp.state.producer.configuration.JCRProducerConfigurationService;
 import org.gatein.portal.wsrp.state.producer.registrations.JCRRegistrationPersistenceManager;
 import org.gatein.portal.wsrp.state.producer.state.JCRPortletStatePersistenceManager;
+import org.gatein.portal.wsrp.structure.MOPConsumerStructureProvider;
+import org.gatein.portal.wsrp.structure.MOPPortalStructureAccess;
+import org.gatein.portal.wsrp.structure.PortalStructureAccess;
 import org.gatein.registration.RegistrationManager;
 import org.gatein.registration.RegistrationPersistenceManager;
 import org.gatein.registration.impl.RegistrationManagerImpl;
@@ -280,7 +284,9 @@
          consumerRegistry.setSessionEventBroadcaster(sessionEventBroadcaster);
 
          // create ConsumerStructureProvider and register it to listen to page events
-         MOPConsumerStructureProvider structureprovider = new MOPConsumerStructureProvider(container);
+         POMSessionManager sessionManager = (POMSessionManager)container.getComponentInstanceOfType(POMSessionManager.class);
+         PortalStructureAccess structureAccess = new MOPPortalStructureAccess(sessionManager);
+         MOPConsumerStructureProvider structureprovider = new MOPConsumerStructureProvider(structureAccess);
          listenerService.addListener(DataStorage.PAGE_CREATED, structureprovider);
          listenerService.addListener(DataStorage.PAGE_REMOVED, structureprovider);
          listenerService.addListener(DataStorage.PAGE_UPDATED, structureprovider);

Copied: portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProvider.java (from rev 4915, portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/MOPConsumerStructureProvider.java)
===================================================================
--- portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProvider.java	                        (rev 0)
+++ portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProvider.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -0,0 +1,283 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.gatein.portal.wsrp.structure;
+
+import org.exoplatform.portal.config.DataStorage;
+import org.exoplatform.portal.mop.Described;
+import org.exoplatform.portal.pom.spi.wsrp.WSRP;
+import org.exoplatform.services.listener.Event;
+import org.exoplatform.services.listener.Listener;
+import org.gatein.common.util.ParameterValidation;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+import org.gatein.pc.api.PortletContext;
+import org.gatein.pc.api.PortletStateType;
+import org.gatein.pc.api.StatefulPortletContext;
+import org.gatein.wsrp.api.context.ConsumerStructureProvider;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:chris.laprun at jboss.com">Chris Laprun</a>
+ * @version $Revision$
+ */
+public class MOPConsumerStructureProvider extends Listener<DataStorage, org.exoplatform.portal.config.model.Page> implements ConsumerStructureProvider
+{
+   private final PortalStructureAccess structureAccess;
+   private Map<String, PageInfo> pageInfos;
+   private boolean pagesHaveBeenInitialized;
+
+   public MOPConsumerStructureProvider(PortalStructureAccess structureAccess)
+   {
+      ParameterValidation.throwIllegalArgExceptionIfNull(structureAccess, "PortalStructureAccess");
+
+      this.structureAccess = structureAccess;
+      pageInfos = new HashMap<String, PageInfo>();
+   }
+
+   public List<String> getPageIdentifiers()
+   {
+      if (!pagesHaveBeenInitialized)
+      {
+         // initialize page information
+         Collection<Page> pages = structureAccess.getPages();
+         for (Page page : pages)
+         {
+            addPage(page);
+         }
+
+         pagesHaveBeenInitialized = true;
+      }
+
+      LinkedList<String> identifiers = new LinkedList<String>(pageInfos.keySet());
+      Collections.sort(identifiers);
+      return identifiers;
+   }
+
+   private void addPage(Page page)
+   {
+      Described described = page.adapt(Described.class);
+      PageInfo pageInfo = new PageInfo(page.getObjectId(), described.getName());
+      pageInfos.put(pageInfo.getName(), pageInfo);
+      UIContainer container = page.getRootComponent();
+      processContainer(container, pageInfo);
+
+      Collection<Page> children = page.getChildren();
+      if (ParameterValidation.existsAndIsNotEmpty(children))
+      {
+         for (Page child : children)
+         {
+            addPage(child);
+         }
+      }
+   }
+
+   public List<String> getWindowIdentifiersFor(String pageId)
+   {
+      PageInfo pageInfo = pageInfos.get(pageId);
+      ParameterValidation.throwIllegalArgExceptionIfNull(pageInfo, "PageInfo for " + pageId);
+
+      return pageInfo.getChildrenWindows();
+   }
+
+   private void processContainer(UIContainer container, PageInfo pageInfo)
+   {
+      if (container != null)
+      {
+         List<UIComponent> components = container.getComponents();
+         for (UIComponent component : components)
+         {
+            ObjectType<? extends UIComponent> type = component.getObjectType();
+            if (ObjectType.WINDOW.equals(type))
+            {
+               Described described = component.adapt(Described.class);
+               String name = described.getName();
+
+               pageInfo.addWindow(name, component.getObjectId());
+            }
+            else if (ObjectType.CONTAINER.equals(type))
+            {
+               processContainer((UIContainer)component, pageInfo);
+            }
+            else
+            {
+               // ignore
+            }
+         }
+      }
+   }
+
+   public void assignPortletToWindow(PortletContext portletContext, String windowId, String pageId, String exportedPortletHandle)
+   {
+      PageInfo pageInfo = pageInfos.get(pageId);
+      String uuid = pageInfo.getWindowUUID(windowId);
+      ParameterValidation.throwIllegalArgExceptionIfNull(uuid, "UUID for " + windowId);
+
+      // get the window
+      UIWindow window = structureAccess.getWindowFrom(uuid);
+
+      // construct the new customization state
+      WSRP wsrp = new WSRP();
+      String portletId = portletContext.getId();
+      wsrp.setPortletId(portletId);
+      if (portletContext instanceof StatefulPortletContext)
+      {
+         StatefulPortletContext context = (StatefulPortletContext)portletContext;
+         if (PortletStateType.OPAQUE.equals(context.getType()))
+         {
+            wsrp.setState((byte[])context.getState());
+         }
+         else
+         {
+            throw new IllegalArgumentException("Don't know how to deal with state: " + context.getState());
+         }
+      }
+
+      // destroy existing customization as otherwise re-customizing will fail
+      Customization<?> customization = window.getCustomization();
+      customization.destroy();
+
+      // and re-customize
+      window.customize(WSRP.CONTENT_TYPE, portletId, wsrp);
+
+      // Change the window's name so that it's less confusing to users
+      Described described = window.adapt(Described.class);
+      String newName = exportedPortletHandle + " (remote)";
+      described.setName(newName); // should be the same as ApplicationRegistryService.REMOTE_DISPLAY_NAME_SUFFIX
+
+      // update window mappings
+      pageInfo.updateWindowName(windowId, newName);
+
+      structureAccess.saveChangesTo(window);
+   }
+
+   @Override
+   public void onEvent(Event<DataStorage, org.exoplatform.portal.config.model.Page> event) throws Exception
+   {
+      String eventName = event.getEventName();
+
+      // get the MOP page from the event data
+      org.exoplatform.portal.config.model.Page portalPage = event.getData();
+      Page page = structureAccess.getPageFrom(portalPage);
+
+      if (page != null)
+      {
+         if (DataStorage.PAGE_CREATED.equals(eventName))
+         {
+            // add information for new page
+            addPage(page);
+         }
+         else if (DataStorage.PAGE_REMOVED.equals(eventName))
+         {
+            removePage(page);
+         }
+         else if (DataStorage.PAGE_UPDATED.equals(eventName))
+         {
+            removePage(page);
+            addPage(page);
+         }
+      }
+   }
+
+   private void removePage(Page page)
+   {
+      Described described = page.adapt(Described.class);
+      String name = described.getName();
+
+      PageInfo pageInfo = pageInfos.get(name);
+      if (pageInfo != null)
+      {
+         // remove page info
+         pageInfos.remove(name);
+      }
+   }
+
+   private static class PageInfo
+   {
+      private final String uuid;
+      private final Map<String, String> childrenWindows = new HashMap<String, String>();
+      private final String name;
+
+      private PageInfo(String uuid, String name)
+      {
+         this.uuid = uuid;
+         this.name = name;
+      }
+
+      public String getUUID()
+      {
+         return uuid;
+      }
+
+      public List<String> getChildrenWindows()
+      {
+         return new ArrayList<String>(childrenWindows.keySet());
+      }
+
+      public void addWindow(String windowName, String uuid)
+      {
+         // add suffix in case we have several windows with the same name in the page
+         if (childrenWindows.containsKey(windowName))
+         {
+            if (windowName.endsWith("|"))
+            {
+               windowName += "|";
+            }
+            else
+            {
+               windowName += windowName + " |";
+            }
+         }
+
+         childrenWindows.put(windowName, uuid);
+      }
+
+      public void updateWindowName(String oldWindowName, String newWindowName)
+      {
+         String windowUUID = getWindowUUID(oldWindowName);
+         childrenWindows.remove(oldWindowName);
+         childrenWindows.put(newWindowName, windowUUID);
+      }
+
+      public String getName()
+      {
+         return name;
+      }
+
+      public String getWindowUUID(String windowId)
+      {
+         return childrenWindows.get(windowId);
+      }
+   }
+}

Added: portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPPortalStructureAccess.java
===================================================================
--- portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPPortalStructureAccess.java	                        (rev 0)
+++ portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/MOPPortalStructureAccess.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -0,0 +1,111 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.gatein.portal.wsrp.structure;
+
+import org.exoplatform.portal.pom.config.POMSession;
+import org.exoplatform.portal.pom.config.POMSessionManager;
+import org.exoplatform.portal.pom.data.Mapper;
+import org.exoplatform.portal.pom.data.PageKey;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Workspace;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:chris.laprun at jboss.com">Chris Laprun</a>
+ * @version $Revision$
+ */
+public class MOPPortalStructureAccess implements PortalStructureAccess
+{
+   private static final String PAGES_CHILD_NAME = "pages";
+   private final POMSessionManager pomManager;
+
+   public MOPPortalStructureAccess(POMSessionManager pomManager)
+   {
+      this.pomManager = pomManager;
+   }
+
+   public Collection<Page> getPages()
+   {
+      POMSession session = pomManager.getSession();
+      Workspace workspace = session.getWorkspace();
+      Collection<Site> sites = workspace.getSites(ObjectType.PORTAL_SITE);
+
+      List<Page> pages = new ArrayList<Page>(sites.size() * 10);
+
+      for (Site site : sites)
+      {
+         Page pagesRoot = getPagesFrom(site);
+         if (pagesRoot != null)
+         {
+            Collection<Page> children = pagesRoot.getChildren();
+            for (Page child : children)
+            {
+               pages.add(child);
+            }
+         }
+      }
+
+      return pages;
+   }
+
+   public UIWindow getWindowFrom(String uuid)
+   {
+      POMSession session = pomManager.getSession();
+      return session.findObjectById(ObjectType.WINDOW, uuid);
+   }
+
+   public void saveChangesTo(UIWindow window)
+   {
+      POMSession session = pomManager.getSession();
+
+      // mark page for cache invalidation otherwise DataCache will use the previous customization id when trying to set
+      // the portlet state in UIPortlet.setState and will not find it resulting in an error
+      Page page = window.getPage();
+      session.scheduleForEviction(new PageKey("portal", page.getSite().getName(), page.getName()));
+
+      // save
+      session.close(true);
+   }
+
+   public Page getPageFrom(org.exoplatform.portal.config.model.Page portalPage)
+   {
+      POMSession session = pomManager.getSession();
+      Site site = session.getWorkspace().getSite(Mapper.parseSiteType(portalPage.getOwnerType()), portalPage.getOwnerId());
+      return getPagesFrom(site).getChild(portalPage.getName());
+   }
+
+   private Page getPagesFrom(Site site)
+   {
+      // a site contains a root page with templates and pages
+      // more info at http://code.google.com/p/chromattic/wiki/MOPUseCases
+
+      return site.getRootPage().getChild(PAGES_CHILD_NAME);
+   }
+}

Added: portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/PortalStructureAccess.java
===================================================================
--- portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/PortalStructureAccess.java	                        (rev 0)
+++ portal/trunk/component/wsrp/src/main/java/org/gatein/portal/wsrp/structure/PortalStructureAccess.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.gatein.portal.wsrp.structure;
+
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:chris.laprun at jboss.com">Chris Laprun</a>
+ * @version $Revision$
+ */
+public interface PortalStructureAccess
+{
+   Collection<Page> getPages();
+
+   UIWindow getWindowFrom(String uuid);
+
+   void saveChangesTo(UIWindow window);
+
+   Page getPageFrom(org.exoplatform.portal.config.model.Page portalPage);
+}

Added: portal/trunk/component/wsrp/src/test/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProviderTestCase.java
===================================================================
--- portal/trunk/component/wsrp/src/test/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProviderTestCase.java	                        (rev 0)
+++ portal/trunk/component/wsrp/src/test/java/org/gatein/portal/wsrp/structure/MOPConsumerStructureProviderTestCase.java	2010-11-03 20:48:19 UTC (rev 4924)
@@ -0,0 +1,289 @@
+/*
+ * JBoss, a division of Red Hat
+ * Copyright 2010, Red Hat Middleware, LLC, and individual
+ * contributors as indicated by the @authors tag. See the
+ * copyright.txt in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.gatein.portal.wsrp.structure;
+
+import junit.framework.TestCase;
+import org.exoplatform.portal.config.DataStorage;
+import org.exoplatform.portal.mop.Described;
+import org.exoplatform.portal.pom.spi.wsrp.WSRP;
+import org.exoplatform.services.listener.Event;
+import org.gatein.mop.api.content.Customization;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Page;
+import org.gatein.mop.api.workspace.ui.UIComponent;
+import org.gatein.mop.api.workspace.ui.UIContainer;
+import org.gatein.mop.api.workspace.ui.UIWindow;
+import org.gatein.pc.api.PortletContext;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * @author <a href="mailto:chris.laprun at jboss.com">Chris Laprun</a>
+ * @version $Revision$
+ */
+public class MOPConsumerStructureProviderTestCase extends TestCase
+{
+   private MOPConsumerStructureProvider provider;
+   private PortalStructureAccess structureAccess;
+   private Page page1;
+
+   public void testGetPageIdentifiers()
+   {
+      List<String> pageIdentifiers = provider.getPageIdentifiers();
+      assertEquals(5, pageIdentifiers.size());
+      assertTrue(pageIdentifiers.contains("page1"));
+      assertTrue(pageIdentifiers.contains("page11"));
+      assertTrue(pageIdentifiers.contains("page12"));
+      assertTrue(pageIdentifiers.contains("page2"));
+      assertTrue(pageIdentifiers.contains("page21"));
+   }
+
+   public void testGetWindowIdentifiersForInexistingPage()
+   {
+      List<String> windows = provider.getWindowIdentifiersFor("inexisting");
+      assertTrue(windows.isEmpty());
+   }
+
+   public void testGetWindowIdentifiersFor()
+   {
+      checkWindows("page1", "window11", "window12");
+      checkWindows("page2");
+      checkWindows("page11", "window111", "window112");
+      checkWindows("page12", "window121");
+      checkWindows("page21", "window211");
+   }
+
+   public void testAssignPortletToWindow()
+   {
+      String newCustomizationId = "new";
+      String newWindowName = "portlet";
+      provider.assignPortletToWindow(PortletContext.createPortletContext(newCustomizationId), "window11", "page1", newWindowName);
+      verify(structureAccess).getWindowFrom(getIdFor("window11"));
+
+      UIWindow window11 = structureAccess.getWindowFrom(getIdFor("window11"));
+      verify(structureAccess).saveChangesTo(window11);
+
+      Described described = window11.adapt(Described.class);
+      verify(described).setName(newWindowName + " (remote)");
+
+      WSRP state = new WSRP();
+      state.setPortletId(newCustomizationId);
+      verify(window11).customize(WSRP.CONTENT_TYPE, newCustomizationId, state);
+
+      Customization<?> customization = window11.getCustomization();
+      assertEquals(WSRP.CONTENT_TYPE, customization.getType());
+   }
+
+   public void testPageCreationEvent() throws Exception
+   {
+      Page foo = createPage("foo", new String[]{"foo1"}, new String[]{"windowfoo1"});
+      Page foo1 = foo.getChild("foo1");
+      addWindows(foo1, "windowfoo11");
+      org.exoplatform.portal.config.model.Page portalPage = mock(org.exoplatform.portal.config.model.Page.class);
+      when(structureAccess.getPageFrom(portalPage)).thenReturn(foo);
+
+      int pageNumber = provider.getPageIdentifiers().size();
+
+      provider.onEvent(new Event<DataStorage, org.exoplatform.portal.config.model.Page>(DataStorage.PAGE_CREATED, null, portalPage));
+
+      List<String> identifiers = provider.getPageIdentifiers();
+      assertEquals(pageNumber + 2, identifiers.size());
+      assertTrue(identifiers.contains("foo"));
+      assertTrue(identifiers.contains("foo1"));
+
+      checkWindows("foo", "windowfoo1");
+      checkWindows("foo1", "windowfoo11");
+
+      assertEquals(foo1.getRootComponent().get("windowfoo11"), structureAccess.getWindowFrom(getIdFor("windowfoo11")));
+   }
+
+   public void testPageDeletionEvent() throws Exception
+   {
+      org.exoplatform.portal.config.model.Page portalPage = mock(org.exoplatform.portal.config.model.Page.class);
+      when(structureAccess.getPageFrom(portalPage)).thenReturn(page1);
+
+      int pageNumber = provider.getPageIdentifiers().size();
+
+      provider.onEvent(new Event<DataStorage, org.exoplatform.portal.config.model.Page>(DataStorage.PAGE_REMOVED, null, portalPage));
+
+      List<String> identifiers = provider.getPageIdentifiers();
+      assertEquals(pageNumber - 3, identifiers.size());
+      assertFalse(identifiers.contains("page1"));
+      assertFalse(identifiers.contains("page11"));
+      assertFalse(identifiers.contains("page12"));
+
+      assertNull(structureAccess.getWindowFrom(getIdFor("window11")));
+      assertNull(structureAccess.getWindowFrom(getIdFor("window12")));
+      assertNull(structureAccess.getWindowFrom(getIdFor("window111")));
+      assertNull(structureAccess.getWindowFrom(getIdFor("window112")));
+      assertNull(structureAccess.getWindowFrom(getIdFor("window121")));
+   }
+
+   public void testPageUpdatedEvent() throws Exception
+   {
+      // todo!
+   }
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      structureAccess = mock(PortalStructureAccess.class);
+
+      page1 = createPage("page1", new String[]{"page11", "page12"}, new String[]{"window11", "window12"});
+      Page page2 = createPage("page2", new String[]{"page21"}, null);
+
+      Page page11 = page1.getChild("page11");
+      addWindows(page11, "window111", "window112");
+
+      Page page12 = page1.getChild("page12");
+      addWindows(page12, "window121");
+
+      Page page21 = page2.getChild("page21");
+      addWindows(page21, "window211");
+
+      ArrayList<Page> pages = new ArrayList<Page>();
+      pages.add(page1);
+      pages.add(page11);
+      pages.add(page12);
+      pages.add(page2);
+      pages.add(page21);
+      when(structureAccess.getPages()).thenReturn(pages);
+
+      provider = new MOPConsumerStructureProvider(structureAccess);
+
+      // needed to initialize state
+      provider.getPageIdentifiers();
+   }
+
+   private void checkWindows(final String pageName, String... windowNames)
+   {
+      List<String> windows = provider.getWindowIdentifiersFor(pageName);
+
+      if (windowNames != null)
+      {
+         assertEquals(windowNames.length, windows.size());
+         for (String windowName : windowNames)
+         {
+            assertTrue(windows.contains(windowName));
+         }
+      }
+   }
+
+   private Page createPage(String name, String[] childrenPages, String[] windowNames)
+   {
+      Page page = mock(Page.class);
+
+      when(page.getName()).thenThrow(new RuntimeException("Page.getName returns the internal name, not the human readable one"));
+
+      // mock call to adapt
+      Described described = mock(Described.class);
+      when(described.getName()).thenReturn(name);
+
+      when(page.adapt(Described.class)).thenReturn(described);
+
+      if (childrenPages != null)
+      {
+         List<Page> children = new ArrayList<Page>(childrenPages.length);
+         for (String pageId : childrenPages)
+         {
+            Page childPage = createPage(pageId, null, null);
+            when(page.getChild(pageId)).thenReturn(childPage);
+            children.add(childPage);
+         }
+
+         when(page.getChildren()).thenReturn(children);
+      }
+
+      addWindows(page, windowNames);
+
+      return page;
+   }
+
+   private void addWindows(Page page, String... windowNames)
+   {
+      if (windowNames != null)
+      {
+         // mock page container
+         UIContainer root = mock(UIContainer.class);
+         when(page.getRootComponent()).thenReturn(root);
+
+         // for each provided window name, create a mock UIWindow...
+         List<UIComponent> children = new ArrayList<UIComponent>(windowNames.length);
+         for (String windowName : windowNames)
+         {
+            UIWindow window = mock(UIWindow.class);
+            when(window.getName()).thenThrow(new RuntimeException("Window.getName returns the internal name, not the human readable one"));
+            when(window.getObjectId()).thenReturn(getIdFor(windowName));
+
+            // need to use thenAnswer instead of thenReturn here because it doesn't play well with generics
+            when(window.getObjectType()).thenAnswer(new Answer<Object>()
+            {
+               public Object answer(InvocationOnMock invocationOnMock) throws Throwable
+               {
+                  return ObjectType.WINDOW;
+               }
+            });
+
+            // mock call to adapt
+            Described described = mock(Described.class);
+            when(described.getName()).thenReturn(windowName);
+
+            when(window.adapt(Described.class)).thenReturn(described);
+
+            // mock Customization
+            final Customization<WSRP> customization = mock(Customization.class);
+            when(customization.getType()).thenReturn(WSRP.CONTENT_TYPE);
+            when(window.getCustomization()).thenAnswer(new Answer<Object>()
+            {
+               public Object answer(InvocationOnMock invocationOnMock) throws Throwable
+               {
+                  return customization;
+               }
+            });
+
+            // add it to the list of windows for this page
+            children.add(window);
+
+            // make sure that we return the window when we ask for it from its uuid
+            when(structureAccess.getWindowFrom(getIdFor(windowName))).thenReturn(window);
+
+            // make sure that we return the window if we ask the root component for it
+            when(root.get(windowName)).thenReturn(window);
+         }
+
+         // the container should return the list of windows when asked for its components
+         when(root.getComponents()).thenReturn(children);
+      }
+   }
+
+   private String getIdFor(String windowName)
+   {
+      return windowName + "Id";
+   }
+}



More information about the gatein-commits mailing list