Author: chris.laprun(a)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@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@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@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@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@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";
+ }
+}