gatein SVN: r6419 - in epp/portal/branches/EPP_5_1_RH_Branch: component/common/src/test/java/org/exoplatform/commons/utils and 29 other directories.
by do-not-reply@jboss.org
Author: theute
Date: 2011-05-01 15:34:54 -0400 (Sun, 01 May 2011)
New Revision: 6419
Added:
epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/main/java/org/exoplatform/commons/utils/Queues.java
epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/test/java/org/exoplatform/commons/utils/TestQueues.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/EventType.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Cache.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/CacheById.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationContext.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationError.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeChange.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/TreeContext.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Utils.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyAdapter.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeIterator.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeType.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyContext.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyDiff.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListAdapter.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeIterator.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeType.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListDiff.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/list/
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/list/ListTree.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/AbstractTestNavigationService.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceSave.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceUpdate.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceWrapper.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/list/
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/list/TestListTree.java
epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/webui/UISiteMap.js
Removed:
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/ListTree.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Navigation.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestListTree.java
Modified:
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/config/DataStorageImpl.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Invalidator.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationService.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceException.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceImpl.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceWrapper.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeContext.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeData.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeState.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Scope.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNavigation.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNode.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserPortalImpl.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/POMDataStorage.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/tasks/SearchTask.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestDataStorage.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestSearch.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestUserPortalConfigService.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/Node.java
epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationService.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/dashboard/src/main/java/org/exoplatform/dashboard/webui/component/UITabPaneDashboard.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UIGroupNavigationManagement.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UISiteManagement.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarDashboardPortlet.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarGroupPortlet.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarSitePortlet.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarDashboardPortlet.gtmpl
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarGroupPortlet.gtmpl
epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarSitePortlet.gtmpl
epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UINavigationPortlet.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UISitemapPortlet.java
epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/webapp/groovy/portal/webui/component/UIPortalNavigation.gtmpl
epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortal.js
epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortalNavigation.js
epp/portal/branches/EPP_5_1_RH_Branch/web/portal/src/main/webapp/groovy/webui/core/UISitemapTree.gtmpl
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/TreeNode.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIAddGroupNavigation.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UINavigationNodeSelector.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNavigationForm.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNodeSelector.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPortalNavigation.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/page/UIPageCreationWizard.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalComponentActionListener.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalForm.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplicationController.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java
epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/core/UIPortletApplication.java
Log:
JBEPP-853: Performance issues with the shipped-in applications when the portal has many nodes or pages
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/main/java/org/exoplatform/commons/utils/Queues.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/main/java/org/exoplatform/commons/utils/Queues.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/main/java/org/exoplatform/commons/utils/Queues.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.commons.utils;
+
+import java.util.AbstractQueue;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+/**
+ * A LIFO stack implementing the {@link java.util.Queue} interface backed by an array.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class Queues
+{
+
+ /** . */
+ private static final Queue<Object> EMPTY = new AbstractQueue<Object>()
+ {
+ @Override
+ public Iterator<Object> iterator()
+ {
+ return Collections.emptyList().iterator();
+ }
+
+ @Override
+ public int size()
+ {
+ return 0;
+ }
+
+ public boolean offer(Object o)
+ {
+ return false;
+ }
+
+ public Object poll()
+ {
+ return null;
+ }
+
+ public Object peek()
+ {
+ return null;
+ }
+ };
+
+ private static class LIFO<E> extends AbstractQueue<E>
+ {
+ /** . */
+ private Object[] elements;
+
+ /** . */
+ private int size;
+
+ public LIFO(int initialCapacity)
+ {
+ this.elements = new Object[initialCapacity];
+ this.size = 0;
+ }
+
+ @Override
+ public Iterator<E> iterator()
+ {
+ return new Iterator<E>()
+ {
+ int count = size;
+ public boolean hasNext()
+ {
+ return count > 0;
+ }
+ public E next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+ else
+ {
+ @SuppressWarnings("unchecked")
+ E element = (E)elements[--count];
+ return element;
+ }
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public int size()
+ {
+ return size;
+ }
+
+ public boolean offer(E e)
+ {
+ int length = elements.length;
+ if (size == length)
+ {
+ Object[] tmp = new Object[(length * 3) / 2 + 1];
+ System.arraycopy(elements, 0, tmp, 0, length);
+ elements = tmp;
+ }
+ elements[size++] = e;
+ return true;
+ }
+
+ public E poll()
+ {
+ if (size > 0)
+ {
+ int index = --size;
+ @SuppressWarnings("unchecked")
+ E element = (E)elements[index];
+ elements[index] = null;
+ return element;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public E peek()
+ {
+ if (size > 0)
+ {
+ @SuppressWarnings("unchecked")
+ E element = (E)elements[size - 1];
+ return element;
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ public static <E> Queue<E> empty()
+ {
+ @SuppressWarnings("unchecked")
+ Queue<E> queue = (Queue<E>)EMPTY;
+ return queue;
+ }
+
+ public static <E> Queue<E> lifo()
+ {
+ return lifo(10);
+ }
+
+ public static <E> Queue<E> lifo(int initialCapacity)
+ {
+ return new LIFO<E>(initialCapacity);
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/test/java/org/exoplatform/commons/utils/TestQueues.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/test/java/org/exoplatform/commons/utils/TestQueues.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/common/src/test/java/org/exoplatform/commons/utils/TestQueues.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.commons.utils;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class TestQueues extends TestCase
+{
+ public void testLIFO()
+ {
+ Queue<String> lifo = Queues.lifo();
+ assertEquals(0, lifo.size());
+ assertTrue(lifo.add("a"));
+ assertEquals(1, lifo.size());
+ assertTrue(lifo.add("b"));
+ assertEquals(2, lifo.size());
+ assertTrue(lifo.add("c"));
+ assertEquals(3, lifo.size());
+ Iterator<String> it = lifo.iterator();
+ assertEquals("c", it.next());
+ assertEquals("b", it.next());
+ assertEquals("a", it.next());
+ assertFalse(it.hasNext());
+ assertEquals("c", lifo.peek());
+ assertEquals(3, lifo.size());
+ assertEquals("c", lifo.poll());
+ assertEquals(2, lifo.size());
+ assertEquals("b", lifo.poll());
+ assertEquals(1, lifo.size());
+ assertEquals("a", lifo.poll());
+ assertEquals(0, lifo.size());
+ assertEquals(null, lifo.poll());
+ assertEquals(null, lifo.peek());
+ assertEquals(0, lifo.size());
+ assertEquals(null, lifo.poll());
+ assertEquals(null, lifo.peek());
+ assertEquals(0, lifo.size());
+ }
+
+ public void testLIFOResize()
+ {
+ Queue<String> lifo = Queues.lifo(0);
+ assertEquals(0, lifo.size());
+ lifo.add("a");
+ assertEquals(1, lifo.size());
+ assertEquals("a", lifo.peek());
+ assertEquals("a", lifo.poll());
+ assertEquals(0, lifo.size());
+ }
+
+ public void testEmpty()
+ {
+ Queue<String> lifo = Queues.empty();
+ assertFalse(lifo.offer(""));
+ try
+ {
+ lifo.add("");
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+ assertEquals(0, lifo.size());
+ assertNull(lifo.peek());
+ assertNull(lifo.poll());
+ try
+ {
+ lifo.element();
+ fail();
+ }
+ catch (NoSuchElementException ignore)
+ {
+ }
+ }
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/config/DataStorageImpl.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/config/DataStorageImpl.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/config/DataStorageImpl.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -36,6 +36,9 @@
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.config.model.PageNavigation;
import org.exoplatform.portal.config.model.PortalConfig;
+import org.exoplatform.portal.mop.EventType;
+import org.exoplatform.portal.mop.SiteKey;
+import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.pom.data.DashboardData;
import org.exoplatform.portal.pom.data.ModelChange;
import org.exoplatform.portal.pom.data.ModelData;
@@ -118,19 +121,19 @@
public void create(PageNavigation navigation) throws Exception
{
delegate.create(navigation.build());
- listenerServ_.broadcast(NAVIGATION_CREATED, this, navigation);
+ listenerServ_.broadcast(EventType.NAVIGATION_CREATED, this, new SiteKey(navigation.getOwnerType(), navigation.getOwnerId()));
}
public void save(PageNavigation navigation) throws Exception
{
delegate.save(navigation.build());
- listenerServ_.broadcast(NAVIGATION_UPDATED, this, navigation);
+ listenerServ_.broadcast(EventType.NAVIGATION_UPDATED, this, new SiteKey(navigation.getOwnerType(), navigation.getOwnerId()));
}
public void remove(PageNavigation navigation) throws Exception
{
delegate.remove(navigation.build());
- listenerServ_.broadcast(NAVIGATION_REMOVED, this, navigation);
+ listenerServ_.broadcast(EventType.NAVIGATION_DESTROYED, this, new SiteKey(navigation.getOwnerType(), navigation.getOwnerId()));
}
public <S> S load(ApplicationState<S> state, ApplicationType<S> type) throws Exception
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/EventType.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/EventType.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/EventType.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop;
+
+/**
+ * Group various event types.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class EventType
+{
+ /** . */
+ public final static String NAVIGATION_CREATED = "org.exoplatform.portal.mop.navigation.navigation_created";
+
+ /** . */
+ public final static String NAVIGATION_DESTROYED = "org.exoplatform.portal.mop.navigation.navigation_destroyed";
+
+ /** . */
+ public final static String NAVIGATION_UPDATED = "org.exoplatform.portal.mop.navigation.navigation_updated";
+
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Cache.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Cache.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Cache.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteKey;
+import org.exoplatform.portal.pom.config.POMSession;
+
+import javax.jcr.Session;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+abstract class Cache
+{
+
+ abstract NodeData getNodeData(POMSession session, String nodeId);
+
+ abstract NavigationContext getNavigation(POMSession session, SiteKey key);
+
+ abstract void start(Session session) throws Exception;
+
+ abstract void stop();
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/CacheById.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/CacheById.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/CacheById.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteKey;
+import org.exoplatform.portal.pom.config.POMSession;
+import org.exoplatform.portal.pom.data.MappedAttributes;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.api.workspace.Workspace;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.EventListenerIterator;
+import javax.jcr.observation.ObservationManager;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static org.exoplatform.portal.mop.navigation.Utils.objectType;
+
+/**
+ * Manages id.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+class CacheById extends Cache implements Invalidator
+{
+
+ /** . */
+ final String NAVIGATION_CONTAINER = "mop:navigationcontainer";
+
+ /** . */
+ final String NAVIGATION = "mop:navigation";
+
+ /** . */
+ final String ATTRIBUTES = "mop:attributes";
+
+ /** . */
+ private InvalidationManager invalidationManager;
+
+ /** . */
+ private Map<SiteKey, NavigationContext> navigationKeyCache;
+
+ /** . */
+ private Map<String, SiteKey> navigationPathCache;
+
+ /** . */
+ private Map<String, NodeData> nodeIdCache;
+
+ /** . */
+ private Map<String, String> nodePathCache;
+
+ /** . */
+ private Session bridgeSession;
+
+ CacheById()
+ {
+ this.nodeIdCache = new ConcurrentHashMap<String, NodeData>(1000);
+ this.nodePathCache = new ConcurrentHashMap<String, String>(1000);
+ this.navigationKeyCache = new ConcurrentHashMap<SiteKey, NavigationContext>(1000);
+ this.navigationPathCache = new ConcurrentHashMap<String, SiteKey>(1000);
+ }
+
+ NodeData getNodeData(POMSession session, String nodeId)
+ {
+ NodeData data;
+ if (session.isModified())
+ {
+ Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, nodeId);
+ if (navigation != null)
+ {
+ data = new NodeData(navigation);
+ }
+ else
+ {
+ data = null;
+ }
+ }
+ else
+ {
+ data = nodeIdCache.get(nodeId);
+ if (data == null)
+ {
+ Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, nodeId);
+ if (navigation != null)
+ {
+ data = new NodeData(navigation);
+ nodeIdCache.put(nodeId, data);
+ nodePathCache.put(session.pathOf(navigation), nodeId);
+ }
+ }
+ }
+ return data;
+ }
+
+ NavigationContext getNavigation(POMSession session, SiteKey key)
+ {
+ if (key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ //
+ NavigationContext data;
+ if (session.isModified())
+ {
+ data = findNavigation(session, key);
+ }
+ else
+ {
+ data = navigationKeyCache.get(key);
+ if (data == null)
+ {
+ data = findNavigation(session, key);
+ if (data != null)
+ {
+ navigationKeyCache.put(key, data);
+ navigationPathCache.put(data.path, key);
+ }
+ }
+ }
+
+ //
+ return data;
+ }
+
+ private NavigationContext findNavigation(POMSession session, SiteKey key)
+ {
+ Workspace workspace = session.getWorkspace();
+ ObjectType<Site> objectType = objectType(key.getType());
+ Site site = workspace.getSite(objectType, key.getName());
+ if (site != null)
+ {
+ Navigation root = site.getRootNavigation();
+ Navigation rootNode = root.getChild("default");
+ String path = session.pathOf(site);
+ if (rootNode != null)
+ {
+
+ Integer priority = rootNode.getAttributes().getValue(MappedAttributes.PRIORITY, 1);
+ String rootId = rootNode.getObjectId();
+ return new NavigationContext(path, key, new NavigationState(priority), rootId);
+ }
+ else
+ {
+ return new NavigationContext(path, key, null, null);
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ void start(Session session) throws Exception
+ {
+ ObservationManager observationManager = session.getWorkspace().getObservationManager();
+
+ //
+ InvalidationManager invalidationManager = new InvalidationManager(observationManager);
+ invalidationManager.register(NAVIGATION_CONTAINER, Event.NODE_REMOVED + Event.NODE_ADDED, this);
+ invalidationManager.register(NAVIGATION, Event.PROPERTY_ADDED + Event.PROPERTY_CHANGED + Event.PROPERTY_REMOVED, this);
+ invalidationManager.register(ATTRIBUTES, Event.NODE_ADDED + Event.NODE_REMOVED, this);
+
+ //
+ this.invalidationManager = invalidationManager;
+ this.bridgeSession = session;
+ }
+
+ void stop()
+ {
+ if (bridgeSession != null)
+ {
+ Session session = bridgeSession;
+ bridgeSession = null;
+
+ // Unregister
+ try
+ {
+ ObservationManager om = session.getWorkspace().getObservationManager();
+ EventListenerIterator i = om.getRegisteredEventListeners();
+ while (i.hasNext())
+ {
+ EventListener listener = i.nextEventListener();
+ om.removeEventListener(listener);
+ }
+ }
+ catch (RepositoryException e)
+ {
+ e.printStackTrace();
+ }
+
+ //
+ session.logout();
+ }
+ }
+
+ public void invalidate(int eventType, String nodeType, String itemPath)
+ {
+ if (nodeType.equals(NAVIGATION_CONTAINER))
+ {
+ switch (eventType)
+ {
+ case Event.NODE_REMOVED:
+ {
+ String nodeId = nodePathCache.remove(itemPath);
+ if (nodeId != null)
+ {
+ nodeIdCache.remove(nodeId);
+ }
+ String parentPath = parentPath(parentPath(itemPath));
+ String id = nodePathCache.remove(parentPath);
+ if (id != null)
+ {
+ nodeIdCache.remove(id);
+ }
+ String a = parentPath(parentPath(parentPath(itemPath)));
+ SiteKey sk = navigationPathCache.remove(a);
+ if (sk != null)
+ {
+ navigationKeyCache.remove(sk);
+ }
+ break;
+ }
+ case Event.NODE_ADDED:
+ {
+ String parentPath = parentPath(parentPath(itemPath));
+ String id = nodePathCache.remove(parentPath);
+ if (id != null)
+ {
+ nodeIdCache.remove(id);
+ }
+ String a = parentPath(parentPath(parentPath(itemPath)));
+ SiteKey sk = navigationPathCache.remove(a);
+ if (sk != null)
+ {
+ navigationKeyCache.remove(sk);
+ }
+ break;
+ }
+ }
+ }
+ else if (nodeType.equals(NAVIGATION))
+ {
+ // Look for node
+ String nodePath = parentPath(itemPath);
+ String id = nodePathCache.remove(nodePath);
+ if (id != null)
+ {
+ nodeIdCache.remove(id);
+ }
+ }
+ else if (nodeType.equals(ATTRIBUTES))
+ {
+ String nodePath = parentPath(parentPath(itemPath));
+
+ //
+ String id = nodePathCache.remove(nodePath);
+ if (id != null)
+ {
+ nodeIdCache.remove(id);
+ }
+
+ //
+ String navPath = parentPath(parentPath(parentPath(nodePath)));
+ SiteKey navigationKey = navigationPathCache.remove(navPath);
+ if (navigationKey != null)
+ {
+ navigationKeyCache.remove(navigationKey);
+ }
+ }
+ }
+
+ private String parentPath(String path)
+ {
+ int index = path.lastIndexOf('/');
+ return path.substring(0, index);
+ }
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Invalidator.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Invalidator.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Invalidator.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -23,9 +23,9 @@
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
-abstract class Invalidator
+interface Invalidator
{
- abstract void invalidate(int eventType, String nodeType, String itemPath);
+ void invalidate(int eventType, String nodeType, String itemPath);
}
Deleted: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/ListTree.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/ListTree.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/ListTree.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,699 +0,0 @@
-/*
- * Copyright (C) 2010 eXo Platform SAS.
- *
- * 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.exoplatform.portal.mop.navigation;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public abstract class ListTree<T extends ListTree<T, E>, E> implements Iterable<E>
-{
-
- /** . */
- private String name;
-
- /** . */
- private T parent;
-
- /** . */
- private Map<String, T> map;
-
- /** . */
- private T next;
-
- /** . */
- private T previous;
-
- /** . */
- private T head;
-
- /** . */
- private T tail;
-
- /** . */
- private boolean hidden;
-
- /** . */
- private int count;
-
- public ListTree(String name)
- {
- if (name == null)
- {
- throw new NullPointerException();
- }
-
- //
- this.name = name;
- this.next = null;
- this.previous = null;
- this.head = null;
- this.tail = null;
- this.hidden = false;
- this.count = -1;
- }
-
- public final int getSize()
- {
- return map == null ? -1 : map.size();
- }
-
- public final int getCount()
- {
- return count;
- }
-
- public final boolean isHidden()
- {
- return hidden;
- }
-
- public final T getNext()
- {
- return next;
- }
-
- public final T getPrevious()
- {
- return previous;
- }
-
- public final void setHidden(boolean hidden)
- {
- if (this.hidden != hidden)
- {
- if (parent != null)
- {
- if (hidden)
- {
- parent.count--;
- }
- else
- {
- parent.count++;
- }
- }
- this.hidden = hidden;
- }
- }
-
- public abstract E getElement();
-
- public final String getName()
- {
- return name;
- }
-
- public final T getParent()
- {
- return parent;
- }
-
- public final void rename(String from, String to) throws NullPointerException, IllegalStateException, IllegalArgumentException
- {
- if (from == null)
- {
- throw new NullPointerException();
- }
- if (to == null)
- {
- throw new NullPointerException();
- }
- if (map == null)
- {
- throw new IllegalStateException();
- }
-
- //
- if (!from.equals(to))
- {
- if (map.containsKey(to))
- {
- throw new IllegalArgumentException("the node " + to + " already exist");
- }
- T child = map.remove(from);
- if (child == null)
- {
- throw new IllegalArgumentException("the node " + from + " + does not exist");
- }
- if (child.hidden)
- {
- throw new IllegalArgumentException("the node " + from + " + is hidden");
- }
- child.name = to;
- map.put(to, child);
- }
- }
-
- public final T remove(String name) throws NullPointerException, IllegalStateException
- {
- T child = get(name);
- if (child != null)
- {
- child.remove();
- return child;
- }
- else
- {
- return null;
- }
- }
-
- public final boolean contains(String name) throws NullPointerException, IllegalStateException
- {
- return get(name) != null;
- }
-
- public final T get(String name) throws NullPointerException, IllegalStateException
- {
- if (name == null)
- {
- throw new NullPointerException();
- }
- if (map == null)
- {
- throw new IllegalStateException("No children relationship");
- }
-
- //
- T child = map.get(name);
- return child == null || child.hidden ? null : child;
- }
-
- public final T getFirst()
- {
- if (map == null)
- {
- throw new IllegalStateException("no children");
- }
- return head;
- }
-
- public final T getLast()
- {
- if (map == null)
- {
- throw new IllegalStateException("no children");
- }
- return tail;
- }
-
- public final T get(int index) throws IllegalStateException, IndexOutOfBoundsException
- {
- if (map == null)
- {
- throw new IllegalStateException("no children");
- }
- if (index < 0)
- {
- throw new IndexOutOfBoundsException("No negative index allowed");
- }
-
- //
- T current = head;
- while (true)
- {
- while (current != null && current.hidden)
- {
- current = current.next;
- }
- if (current == null)
- {
- throw new IndexOutOfBoundsException("index " + index + " is greater than the children size");
- }
- if (index == 0)
- {
- break;
- }
- else
- {
- current = current.next;
- index--;
- }
- }
- return current;
- }
-
- public final boolean hasTrees()
- {
- return map != null;
- }
-
- /**
- * Insert the specified tree.
- *
- * @param index the index
- * @param tree the tree
- * @throws NullPointerException if the context is null
- * @throws IllegalStateException if the children relationship does not exist
- * @throws IllegalArgumentException if an existing child with the same name already exist or if the context is hidden
- * @throws IndexOutOfBoundsException if the index is negative or is greater than the children size
- */
- public final void insert(Integer index, T tree) throws NullPointerException, IllegalStateException, IllegalArgumentException, IndexOutOfBoundsException
- {
- if (tree == null)
- {
- throw new NullPointerException("No null tree accepted");
- }
- if (tree.hidden)
- {
- throw new IllegalArgumentException("Cannot insert hidden tree");
- }
- if (map == null)
- {
- throw new IllegalStateException("No trees relationship");
- }
- if (index != null && index < 0)
- {
- throw new IndexOutOfBoundsException("No negative index permitted");
- }
-
- //
- T existing = map.get(tree.name);
- if (existing != null && existing != tree)
- {
- throw new IllegalArgumentException("Tree " + tree.name + " already in the map");
- }
-
- //
- if (index != null)
- {
- T a = head;
- if (index == 0)
- {
- insertFirst(tree);
- }
- else
- {
- while (index > 0)
- {
- while (a != null && a.hidden)
- {
- a = a.next;
- }
- if (a == null)
- {
- throw new IndexOutOfBoundsException();
- }
- index--;
- a = a.next;
- }
-
- //
- if (a == null)
- {
- insertLast(tree);
- }
- else if (a != tree)
- {
- a.insertBefore(tree);
- }
- }
- }
- else
- {
- T a = tail;
- while (a != null && a.hidden)
- {
- a = a.previous;
- }
- if (a == null)
- {
- insertFirst(tree);
- }
- else if (a != tree)
- {
- a.insertAfter(tree);
- }
- }
- }
-
- public final Iterator<E> iterator()
- {
- return new Iterator<E>()
- {
- T next = head;
- {
- while (next != null && next.hidden)
- {
- next = next.next;
- }
- }
- public boolean hasNext()
- {
- return next != null;
- }
- public E next()
- {
- if (next != null)
- {
- T tmp = next;
- do
- {
- next = next.next;
- }
- while (next != null && next.hidden);
- return tmp.getElement();
- }
- else
- {
- throw new NoSuchElementException();
- }
- }
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
- };
- }
-
- public final ListIterator<T> listIterator()
- {
- if (map == null)
- {
- return null;
- }
- return new ListIterator<T>()
- {
- T next = head;
- T current = null;
- T previous = null;
- int index = 0;
-
- public boolean hasNext()
- {
- return next != null;
- }
-
- public T next()
- {
- if (next != null)
- {
- current = next;
-
- //
- previous = next;
- next = next.next;
- index++;
- return current;
- }
- else
- {
- throw new NoSuchElementException();
- }
- }
-
- public boolean hasPrevious()
- {
- return previous != null;
- }
-
- public T previous()
- {
- if (previous != null)
- {
- current = previous;
-
- //
- next = previous;
- previous = previous.previous;
- index--;
- return current;
- }
- else
- {
- throw new NoSuchElementException();
- }
- }
-
- public int nextIndex()
- {
- return index;
- }
-
- public int previousIndex()
- {
- return index - 1;
- }
-
- public void remove()
- {
- if (current == null)
- {
- throw new IllegalStateException("no element to remove");
- }
- if (current == previous)
- {
- index--;
- }
- next = current.next;
- previous = current.previous;
- current.remove();
- current = null;
- }
-
- public void set(T tree)
- {
- throw new UnsupportedOperationException();
- }
-
- public void add(T tree)
- {
- if (previous == null)
- {
- insertFirst(tree);
- }
- else
- {
- previous.insertAfter(tree);
- }
- index++;
- previous = tree;
- next = tree.next;
- }
- };
- }
-
- protected final Iterable<T> getTrees()
- {
- if (map != null)
- {
- return new Iterable<T>()
- {
- public Iterator<T> iterator()
- {
- return listIterator();
- }
- };
- }
- else
- {
- return null;
- }
- }
-
- protected final void setTrees(Iterable<T> children)
- {
- if (children == null)
- {
- if (map == null)
- {
- throw new IllegalStateException();
- }
- else
- {
- while (head != null)
- {
- head.remove();
- }
- this.map = null;
- this.count = -1;
- }
- }
- else
- {
- if (map == null)
- {
- @SuppressWarnings("unchecked") Map<String, T> map = Collections.EMPTY_MAP;
- this.map = map;
- this.count = 0;
- for (T child : children)
- {
- insertLast(child);
- }
- }
- else
- {
- throw new IllegalStateException();
- }
- }
- }
-
- private void insertAfter(T tree)
- {
- if (this != tree)
- {
- if (tree.parent != null)
- {
- tree.remove();
- }
- tree.previous = (T)this;
- tree.next = next;
- if (next == null)
- {
- parent.tail = tree;
- }
- else
- {
- next.previous = tree;
- }
- next = tree;
- if (parent.map == Collections.EMPTY_MAP)
- {
- parent.map = new HashMap<String, T>();
- parent.count = 0;
- }
- if (!tree.hidden)
- {
- parent.count++;
- }
- parent.map.put(tree.name, tree);
- tree.parent = parent;
- }
- }
-
- private void insertBefore(T tree)
- {
- if (this != tree)
- {
- if (tree.parent != null)
- {
- tree.remove();
- }
- tree.previous = previous;
- tree.next = (T)this;
- if (previous == null)
- {
- parent.head = tree;
- }
- else
- {
- previous.next = tree;
- }
- previous = tree;
- if (parent.map == Collections.EMPTY_MAP)
- {
- parent.map = new HashMap<String, T>();
- parent.count = 0;
- }
- if (!tree.hidden)
- {
- parent.count++;
- }
- parent.map.put(tree.name, tree);
- tree.parent = parent;
- }
- }
-
- /**
- * Insert the specified context at the first position among the children of this context.
- *
- * @param tree the content to insert
- */
- private void insertFirst(T tree)
- {
- if (head == null)
- {
- if (tree.parent != null)
- {
- tree.remove();
- }
- head = tail = tree;
- if (map == Collections.EMPTY_MAP)
- {
- map = new HashMap<String, T>();
- count = 0;
- }
- if (!tree.hidden)
- {
- count++;
- }
- map.put(tree.name, tree);
- tree.parent = (T)this;
- }
- else
- {
- head.insertBefore(tree);
- }
- }
-
- private void insertLast(T context)
- {
- if (tail == null)
- {
- insertFirst(context);
- }
- else
- {
- tail.insertAfter(context);
- }
- }
-
- private void remove()
- {
- if (previous == null)
- {
- parent.head = next;
- }
- else
- {
- previous.next = next;
- }
- if (next == null)
- {
- parent.tail = previous;
- }
- else
- {
- next.previous = previous;
- }
- if (!hidden)
- {
- parent.count--;
- }
- parent.map.remove(name);
- parent = null;
- previous = null;
- next = null;
- }
-
- public String toString()
- {
- return getClass().getSimpleName() + "[name=" + getName() + ",element=" + getElement() + "]";
- }
-}
-
Deleted: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Navigation.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Navigation.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Navigation.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2010 eXo Platform SAS.
- *
- * 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.exoplatform.portal.mop.navigation;
-
-import org.exoplatform.portal.mop.SiteKey;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class Navigation
-{
-
- /** . */
- final String path;
-
- /** . */
- final SiteKey key;
-
- /** . */
- final NavigationState state;
-
- /** . */
- final String rootId;
-
- Navigation(String path, SiteKey key, NavigationState state, String rootId)
- {
- if (path == null)
- {
- throw new NullPointerException();
- }
- if (key == null)
- {
- throw new NullPointerException();
- }
-
- //
- this.path = path;
- this.key = key;
- this.state = state;
- this.rootId = rootId;
- }
-
- /**
- * Returns the navigation key.
- *
- * @return the navigation key
- */
- public SiteKey getKey()
- {
- return key;
- }
-
- /**
- * Returns the navigation state or null if the navigation is not entirely created yet.
- *
- * @return the navigation state
- */
- public NavigationState getState()
- {
- return state;
- }
-
- String getRootId()
- {
- return rootId;
- }
-}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationContext.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationContext.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationContext.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteKey;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class NavigationContext
+{
+
+ /** . */
+ final String path;
+
+ /** . */
+ final SiteKey key;
+
+ /** . */
+ final NavigationState state;
+
+ /** . */
+ final String rootId;
+
+ NavigationContext(String path, SiteKey key, NavigationState state, String rootId)
+ {
+ if (path == null)
+ {
+ throw new NullPointerException();
+ }
+ if (key == null)
+ {
+ throw new NullPointerException();
+ }
+
+ //
+ this.path = path;
+ this.key = key;
+ this.state = state;
+ this.rootId = rootId;
+ }
+
+ /**
+ * Returns the navigation key.
+ *
+ * @return the navigation key
+ */
+ public SiteKey getKey()
+ {
+ return key;
+ }
+
+ /**
+ * Returns the navigation state or null if the navigation is not entirely created yet.
+ *
+ * @return the navigation state
+ */
+ public NavigationState getState()
+ {
+ return state;
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationError.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationError.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationError.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public enum NavigationError
+{
+
+ MOVE_CONCURRENTLY_REMOVED_SRC_NODE,
+
+ MOVE_CONCURRENTLY_REMOVED_DST_NODE,
+
+ MOVE_CONCURRENTLY_REMOVED_MOVED_NODE,
+
+ MOVE_CONCURRENTLY_CHANGED_SRC_NODE,
+
+ MOVE_CONCURRENTLY_REMOVED_PREVIOUS_NODE,
+
+ ADD_CONCURRENTLY_REMOVED_PARENT_NODE,
+
+ ADD_CONCURRENTLY_ADDED_NODE,
+
+ ADD_CONCURRENTLY_REMOVED_PREVIOUS_NODE,
+
+ UPDATE_CONCURRENTLY_REMOVED_NODE,
+
+ RENAME_CONCURRENTLY_REMOVED_NODE,
+
+ RENAME_CONCURRENTLY_DUPLICATE_NAME,
+
+ NAVIGATION_CONCURRENCY_REMOVED
+
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationService.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationService.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationService.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -21,6 +21,8 @@
import org.exoplatform.portal.mop.SiteKey;
+import java.util.Iterator;
+
/**
* <p>The navigation service takes care of managing the various portal navigations and their nodes.</p>
*
@@ -44,9 +46,9 @@
* @param key the navigation key
* @return the matching navigation
* @throws NullPointerException if the key is null
- * @throws NavigationServiceException if the navigation could not be loaded
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
*/
- Navigation loadNavigation(SiteKey key) throws NullPointerException, NavigationServiceException;
+ NavigationContext loadNavigation(SiteKey key) throws NullPointerException, NavigationServiceException;
/**
* Create, update or destroy a navigation. When the navigation state is not null, the navigation
@@ -57,40 +59,53 @@
* @param state the navigation state
* @return true if the intent succeeded
* @throws NullPointerException if the key is null
- * @throws NavigationServiceException if the navigation could not be saved
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
*/
boolean saveNavigation(SiteKey key, NavigationState state) throws NullPointerException, NavigationServiceException;
/**
- * Load a navigation node from a specified navigation. The returned node will be the root node of the navigation.
+ * Load a navigation node from a specified navigation. The returned context will be the root node of the navigation.
*
* @param model the node model
* @param navigation the navigation
* @param scope the scope
- * @param <N> the node model generic type
* @return the loaded node
* @throws NullPointerException if any argument is null
- * @throws NavigationServiceException if the loading operation could not be performed
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
*/
- <N> N loadNode(NodeModel<N> model, Navigation navigation, Scope scope) throws NullPointerException, NavigationServiceException;
+ <N> NodeContext<N> loadNode(NodeModel<N> model, NavigationContext navigation, Scope scope) throws NullPointerException, NavigationServiceException;
/**
* Load a navigation node from a specified node. It will affect the node argument as well as all its descendants
* when they are loaded according to the specified scope. The returned node is either the same node or null
* if the node was skipped precisely.
*
- * @param model the node model
- * @param node the node
+ * @param context the context to load
* @param scope the scope
- * @param <N> the node model generic type
- * @return the loaded node
+ * @return the loaded node context
* @throws NullPointerException if any argument is null
- * @throws NavigationServiceException if the loading operation could not be performed
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
*/
- <N> N loadNode(NodeModel<N> model, N node, Scope scope) throws NullPointerException, NavigationServiceException;
+ <N> NodeContext<N> loadNode(NodeContext<N> context, Scope scope) throws NullPointerException, NavigationServiceException;
- <N> void refresh(NodeModel<N> model, N node, Scope scope) throws NullPointerException, NavigationServiceException;
+ /**
+ * Save the specified context state to the persistent storage.
+ *
+ * @param context the context to save
+ * @throws NullPointerException if the context argument is null
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
+ */
+ <N> void saveNode(NodeContext<N> context) throws NullPointerException, NavigationServiceException;
- <N> void saveNode(NodeModel<N> model, N node) throws NullPointerException, NavigationServiceException;
+ /**
+ * Update the specified content with the most recent state.
+ *
+ * @param context the context to update
+ * @param scope the optional scope
+ * @return an iterator over the changes that were applied to the context
+ * @throws NullPointerException if the context argument is null
+ * @throws NavigationServiceException anything that would prevent the operation to succeed
+ */
+ <N> Iterator<NodeChange<N>> updateNode(NodeContext<N> context, Scope scope) throws NullPointerException, NavigationServiceException;
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceException.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceException.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceException.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,28 +19,49 @@
package org.exoplatform.portal.mop.navigation;
+import java.util.regex.Pattern;
+
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
public class NavigationServiceException extends Exception
{
- public NavigationServiceException()
+
+ /** . */
+ private final NavigationError error;
+
+ public NavigationServiceException(NavigationError error)
{
+ this.error = error;
}
- public NavigationServiceException(String message)
+ public NavigationServiceException(NavigationError error, String message)
{
super(message);
+
+ //
+ this.error = error;
}
- public NavigationServiceException(String message, Throwable cause)
+ public NavigationServiceException(NavigationError error, String message, Throwable cause)
{
super(message, cause);
+
+ //
+ this.error = error;
}
- public NavigationServiceException(Throwable cause)
+ public NavigationServiceException(NavigationError error, Throwable cause)
{
super(cause);
+
+ //
+ this.error = error;
}
+
+ public NavigationError getError()
+ {
+ return error;
+ }
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceImpl.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceImpl.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceImpl.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -20,40 +20,32 @@
package org.exoplatform.portal.mop.navigation;
import org.chromattic.api.Chromattic;
+import org.exoplatform.commons.utils.Queues;
import org.exoplatform.portal.mop.Described;
import org.exoplatform.portal.mop.SiteKey;
-import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.mop.Visible;
import org.exoplatform.portal.pom.config.POMSession;
import org.exoplatform.portal.pom.config.POMSessionManager;
import org.exoplatform.portal.pom.data.MappedAttributes;
import org.exoplatform.portal.pom.data.Mapper;
+import static org.exoplatform.portal.mop.navigation.Utils.*;
+
+import org.exoplatform.portal.tree.diff.HierarchyAdapter;
+import org.exoplatform.portal.tree.diff.HierarchyChangeIterator;
+import org.exoplatform.portal.tree.diff.HierarchyChangeType;
+import org.exoplatform.portal.tree.diff.HierarchyDiff;
+import org.exoplatform.portal.tree.diff.ListAdapter;
import org.gatein.common.logging.Logger;
import org.gatein.common.logging.LoggerFactory;
import org.gatein.mop.api.Attributes;
+import org.gatein.mop.api.workspace.Navigation;
import org.gatein.mop.api.workspace.ObjectType;
import org.gatein.mop.api.workspace.Site;
import org.gatein.mop.api.workspace.Workspace;
import org.gatein.mop.api.workspace.link.PageLink;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventListener;
-import javax.jcr.observation.EventListenerIterator;
-import javax.jcr.observation.ObservationManager;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.*;
import static org.exoplatform.portal.pom.config.Utils.split;
@@ -65,39 +57,14 @@
{
/** . */
- private Map<SiteKey, Navigation> navigationKeyCache;
+ final POMSessionManager manager;
/** . */
- private Map<String, SiteKey> navigationPathCache;
+ private final Cache cache;
/** . */
- private Map<String, NodeData> nodeIdCache;
-
- /** . */
- private Map<String, String> nodePathCache;
-
- /** . */
- private final POMSessionManager manager;
-
- /** . */
- private Session bridgeSession;
-
- /** . */
- private InvalidationManager invalidationManager;
-
- /** . */
- private static final EnumMap<SiteType, ObjectType<Site>> a = new EnumMap<SiteType, ObjectType<Site>>(SiteType.class);
-
- /** . */
final Logger log = LoggerFactory.getLogger(NavigationServiceImpl.class);
- static
- {
- a.put(SiteType.PORTAL, ObjectType.PORTAL_SITE);
- a.put(SiteType.GROUP, ObjectType.GROUP_SITE);
- a.put(SiteType.USER, ObjectType.USER_SITE);
- }
-
public NavigationServiceImpl(POMSessionManager manager)
{
if (manager == null)
@@ -105,249 +72,34 @@
throw new NullPointerException("No null pom session manager allowed");
}
this.manager = manager;
- this.navigationKeyCache = new ConcurrentHashMap<SiteKey, Navigation>(1000);
- this.navigationPathCache = new ConcurrentHashMap<String, SiteKey>(1000);
- this.nodeIdCache = new ConcurrentHashMap<String, NodeData>(1000);
- this.nodePathCache = new ConcurrentHashMap<String, String>(1000);
- this.invalidationManager = null;
+ this.cache = new CacheById();
}
public void start() throws Exception
{
Chromattic chromattic = manager.getLifeCycle().getChromattic();
Session session = chromattic.openSession().getJCRSession();
- ObservationManager observationManager = session.getWorkspace().getObservationManager();
-
- invalidationManager = new InvalidationManager(observationManager);
-
- //
- final String NAVIGATION_CONTAINER = "mop:navigationcontainer";
- final String NAVIGATION = "mop:navigation";
- final String ATTRIBUTES = "mop:attributes";
-
- //
- invalidationManager.register(NAVIGATION_CONTAINER, Event.NODE_REMOVED + Event.NODE_ADDED, new Invalidator()
- {
- @Override
- void invalidate(int eventType, String nodeType, String itemPath)
- {
- if (nodeType.equals(NAVIGATION_CONTAINER))
- {
- switch (eventType)
- {
- case Event.NODE_REMOVED:
- {
- String nodeId = nodePathCache.remove(itemPath);
- if (nodeId != null)
- {
- nodeIdCache.remove(nodeId);
- }
- String parentPath = parentPath(parentPath(itemPath));
- String id = nodePathCache.remove(parentPath);
- if (id != null)
- {
- nodeIdCache.remove(id);
- }
- String a = parentPath(parentPath(parentPath(itemPath)));
- SiteKey sk = navigationPathCache.remove(a);
- if (sk != null)
- {
- navigationKeyCache.remove(sk);
- }
- break;
- }
- case Event.NODE_ADDED:
- {
- String parentPath = parentPath(parentPath(itemPath));
- String id = nodePathCache.remove(parentPath);
- if (id != null)
- {
- nodeIdCache.remove(id);
- }
- String a = parentPath(parentPath(parentPath(itemPath)));
- SiteKey sk = navigationPathCache.remove(a);
- if (sk != null)
- {
- navigationKeyCache.remove(sk);
- }
- break;
- }
- }
- }
- }
- });
-
- //
- invalidationManager.register(NAVIGATION, Event.PROPERTY_ADDED + Event.PROPERTY_CHANGED + Event.PROPERTY_REMOVED, new Invalidator()
- {
- @Override
- void invalidate(int eventType, String nodeType, String itemPath)
- {
- // Look for node
- String nodePath = parentPath(itemPath);
- String id = nodePathCache.remove(nodePath);
- if (id != null)
- {
- nodeIdCache.remove(id);
- }
- }
- });
-
- //
- invalidationManager.register(ATTRIBUTES, Event.NODE_ADDED + Event.NODE_REMOVED, new Invalidator()
- {
- @Override
- void invalidate(int eventType, String nodeType, String itemPath)
- {
- String nodePath = parentPath(parentPath(itemPath));
-
- //
- String id = nodePathCache.remove(nodePath);
- if (id != null)
- {
- nodeIdCache.remove(id);
- }
-
- //
- String navPath = parentPath(parentPath(parentPath(nodePath)));
- SiteKey navigationKey = navigationPathCache.remove(navPath);
- if (navigationKey != null)
- {
- navigationKeyCache.remove(navigationKey);
- }
- }
- });
-
- //
- this.bridgeSession = session;
+ cache.start(session);
}
- private String parentPath(String path)
- {
- int index = path.lastIndexOf('/');
- return path.substring(0, index);
- }
public void stop()
{
- if (bridgeSession != null)
- {
- Session session = bridgeSession;
- bridgeSession = null;
-
- // Unregister
- try
- {
- ObservationManager om = session.getWorkspace().getObservationManager();
- EventListenerIterator i = om.getRegisteredEventListeners();
- while (i.hasNext())
- {
- EventListener listener = i.nextEventListener();
- om.removeEventListener(listener);
- }
- }
- catch (RepositoryException e)
- {
- e.printStackTrace();
- }
-
- //
- session.logout();
- }
+ cache.stop();
}
- private NodeData getNodeData(POMSession session, String nodeId)
+ public NavigationContext loadNavigation(SiteKey key)
{
- NodeData data;
- if (session.isModified())
- {
- org.gatein.mop.api.workspace.Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, nodeId);
- if (navigation != null)
- {
- data = new NodeData(navigation);
- }
- else
- {
- data = null;
- }
- }
- else
- {
- data = nodeIdCache.get(nodeId);
- if (data == null)
- {
- org.gatein.mop.api.workspace.Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, nodeId);
- if (navigation != null)
- {
- data = new NodeData(navigation);
- nodeIdCache.put(nodeId, data);
- nodePathCache.put(session.pathOf(navigation), nodeId);
- }
- }
- }
- return data;
- }
-
- public Navigation loadNavigation(SiteKey key)
- {
if (key == null)
{
throw new NullPointerException();
}
//
- Navigation data;
POMSession session = manager.getSession();
- if (session.isModified())
- {
- data = findNavigation(session, key);
- }
- else
- {
- data = navigationKeyCache.get(key);
- if (data == null)
- {
- data = findNavigation(session, key);
- if (data != null)
- {
- navigationKeyCache.put(key, data);
- navigationPathCache.put(data.path, key);
- }
- }
- }
-
- //
- return data;
+ return cache.getNavigation(session, key);
}
- private Navigation findNavigation(POMSession session, SiteKey key)
- {
- Workspace workspace = session.getWorkspace();
- ObjectType<Site> objectType = a.get(key.getType());
- Site site = workspace.getSite(objectType, key.getName());
- if (site != null)
- {
- org.gatein.mop.api.workspace.Navigation root = site.getRootNavigation();
- org.gatein.mop.api.workspace.Navigation rootNode = root.getChild("default");
- String path = session.pathOf(site);
- if (rootNode != null)
- {
-
- Integer priority = rootNode.getAttributes().getValue(MappedAttributes.PRIORITY, 1);
- String rootId = rootNode.getObjectId();
- return new Navigation(path, key, new NavigationState(priority), rootId);
- }
- else
- {
- return new Navigation(path, key, null, null);
- }
- }
- else
- {
- return null;
- }
- }
-
public boolean saveNavigation(SiteKey key, NavigationState state) throws NavigationServiceException
{
if (key == null)
@@ -357,19 +109,19 @@
//
POMSession session = manager.getSession();
- ObjectType<Site> objectType = a.get(key.getType());
+ ObjectType<Site> objectType = objectType(key.getType());
Workspace workspace = session.getWorkspace();
Site site = workspace.getSite(objectType, key.getName());
if (site == null)
{
- throw new NavigationServiceException("The site " + key + " does not exist");
+ throw new NavigationServiceException(NavigationError.NAVIGATION_CONCURRENCY_REMOVED);
}
//
if (state != null)
{
- org.gatein.mop.api.workspace.Navigation root = site.getRootNavigation();
- org.gatein.mop.api.workspace.Navigation rootNode = root.getChild("default");
+ Navigation root = site.getRootNavigation();
+ Navigation rootNode = root.getChild("default");
boolean created = rootNode == null;
if (created)
{
@@ -380,8 +132,8 @@
}
else
{
- org.gatein.mop.api.workspace.Navigation root = site.getRootNavigation();
- org.gatein.mop.api.workspace.Navigation rootNode = root.getChild("default");
+ Navigation root = site.getRootNavigation();
+ Navigation rootNode = root.getChild("default");
boolean destroyed = rootNode != null;
if (destroyed)
{
@@ -391,7 +143,7 @@
}
}
- public <N> N loadNode(NodeModel<N> model, Navigation navigation, Scope scope)
+ public <N> NodeContext<N> loadNode(NodeModel<N> model, NavigationContext navigation, Scope scope)
{
if (model == null)
{
@@ -409,12 +161,13 @@
if (navigation.rootId != null)
{
POMSession session = manager.getSession();
- Scope.Visitor visitor = scope.get();
- NodeData data = getNodeData(session, nodeId);
+ NodeData data = cache.getNodeData(session, nodeId);
if (data != null)
{
- NodeContext<N> context = load(model, session, data, visitor, 0);
- return context.node;
+ NodeContext<N> context = new NodeContext<N>(new TreeContext<N>(model), data);
+ Scope.Visitor visitor = scope.get();
+ expand(session, context, visitor, 0);
+ return context;
}
else
{
@@ -427,577 +180,625 @@
}
}
- private <N> NodeContext<N> load(
- NodeModel<N> model,
- POMSession session,
- NodeData data,
- Scope.Visitor visitor,
- int depth)
+ public <N> Iterator<NodeChange<N>> updateNode(final NodeContext<N> root, Scope scope) throws NullPointerException, NavigationServiceException
{
- VisitMode visitMode = visitor.visit(depth, data.id, data.name, data.state);
- //
- NodeContext<N> context;
- if (visitMode == VisitMode.ALL_CHILDREN)
+ final POMSession session = manager.getSession();
+ TreeContext<N> tree = root.tree;
+
+ List<NodeChange<NodeContext<N>>> changes = tree.popChanges();
+ if (changes.size() > 0)
{
- ArrayList<NodeContext<N>> children = new ArrayList<NodeContext<N>>(data.children.size());
- for (String childId : data.children)
+ throw new IllegalArgumentException("For now we don't accept to update a context that has pending changes " + changes);
+ }
+
+ ListAdapter<String[], String> a1 = new ListAdapter<String[], String>()
+ {
+ public int size(String[] list)
{
- NodeData childData = getNodeData(session, childId);
- if (childData != null)
+ return list.length;
+ }
+ public Iterator<String> iterator(final String[] list, final boolean reverse)
+ {
+ return new Iterator<String>()
{
- NodeContext<N> childContext = load(model, session, childData, visitor, depth + 1);
- children.add(childContext);
- }
- else
- {
- throw new UnsupportedOperationException("Handle me gracefully");
- }
+ int count = 0;
+ public boolean hasNext()
+ {
+ return count < list.length;
+ }
+ public String next()
+ {
+ if (!hasNext())
+ {
+ throw new NoSuchElementException();
+ }
+ int index = count++;
+ if (reverse)
+ {
+ index = list.length - index - 1;
+ }
+ return list[index];
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
}
+ };
- //
- context = new NodeContext<N>(model, data);
- context.setContexts(children);
- }
- else if (visitMode == VisitMode.NO_CHILDREN)
- {
- context = new NodeContext<N>(model, data);
- }
- else
- {
- context = new NodeContext<N>(model, data);
- }
-
//
- return context;
- }
-
- public <N> N loadNode(NodeModel<N> model, N node, Scope scope)
- {
- POMSession session = manager.getSession();
- NodeContext<N> context = model.getContext(node);
- Scope.Visitor visitor = scope.get();
- return load(model, session, context, visitor, 0);
- }
-
- private <N> N load(NodeModel<N> model, POMSession session, NodeContext<N> context, Scope.Visitor visitor, int depth)
- {
- String nodeId = context.getId();
- NodeData data = getNodeData(session, nodeId);
-
- //
- if (data != null)
+ class M1 implements HierarchyAdapter<String[], NodeContext<N>, String>
{
- context.data = data;
- visit(model, session, context, visitor, depth);
- return context.node;
+ public String getHandle(NodeContext<N> node)
+ {
+ return node.data.id;
+ }
+ public String[] getChildren(NodeContext<N> node)
+ {
+ return node.hasContexts() ? node.data.children : new String[0];
+ }
+ public NodeContext<N> getDescendant(NodeContext<N> node, String handle)
+ {
+ return root.getDescendant(handle);
+ }
}
-
- return null;
- }
- private <N> void visit(
- NodeModel<N> model,
- POMSession session,
- NodeContext<N> context,
- Scope.Visitor visitor,
- int depth)
- {
- NodeData data = context.data;
-
//
- VisitMode visitMode;
- if (context.hasTrees())
+ class M2 implements HierarchyAdapter<String[], NodeData, String>
{
- visitMode = VisitMode.ALL_CHILDREN;
+ public String getHandle(NodeData node)
+ {
+ return node.id;
+ }
+ public String[] getChildren(NodeData node)
+ {
+ NodeContext<N> context = root.getDescendant(node.getId());
+ return context != null && context.hasContexts() ? node.children : new String[0];
+ }
+ public NodeData getDescendant(NodeData node, String handle)
+ {
+ return cache.getNodeData(session, handle);
+ }
}
- else
- {
- visitMode = visitor.visit(depth, data.id, data.name, data.state);
- }
//
- if (visitMode == VisitMode.ALL_CHILDREN)
- {
- Map<String, NodeContext<N>> previous = Collections.emptyMap();
- if (context.hasTrees())
- {
- previous = new HashMap<String, NodeContext<N>>();
- for (NodeContext<N> a : context.getContexts())
+ HierarchyDiff<String[], NodeContext<N>, String[], NodeData, String> diff =
+ new HierarchyDiff<String[], NodeContext<N>, String[], NodeData, String>(
+ a1,
+ new M1(),
+ a1,
+ new M2(),
+ new Comparator<String>()
{
- if (a.data != null)
+ public int compare(String s1, String s2)
{
- previous.put(a.getId(), a);
+ return s1.compareTo(s2);
}
}
- context.setContexts(null);
- }
+ );
- //
- ArrayList<NodeContext<N>> children = new ArrayList<NodeContext<N>>(data.children.size());
- for (String childId : data.children)
+ //
+ List<NodeChange<N>> list = Collections.emptyList();
+
+ // Switch to edit mode
+ tree.editMode = true;
+
+ // Apply diff changes to the model
+ try
+ {
+ NodeData dataRoot = cache.getNodeData(session, root.data.id);
+ HierarchyChangeIterator<String[], NodeContext<N>, String[], NodeData, String> it = diff.iterator(root, dataRoot);
+ Queue<NodeContext<N>> stack = Queues.lifo();
+ NodeContext<N> last = null;
+ while (it.hasNext())
{
- NodeData childData = getNodeData(session, childId);
- if (childData != null)
+ HierarchyChangeType change = it.next();
+ switch (change)
{
- NodeContext<N> childContext = previous.get(childId);
- if (childContext != null)
+ case ENTER:
+ stack.add(it.getSource());
+ break;
+ case LEAVE:
+ last = stack.poll();
+ break;
+ case MOVED_OUT:
+ break;
+ case MOVED_IN:
{
- childContext.data = childData;
- visit(model, session, childContext, visitor, depth + 1);
+ NodeContext<N> to = stack.peek();
+ NodeContext<N> moved = it.getSource();
+ NodeContext<N> from = moved.getParent();
+ NodeContext<N> previous;
+ if (last == null || last.getParent() != to)
+ {
+ previous = null;
+ to.insertAt(0, moved);
+ }
+ else
+ {
+ previous = last;
+ last.insertAfter(moved);
+ }
+
+ //
+ if (list.isEmpty()) {
+ list = new LinkedList<NodeChange<N>>();
+ }
+ list.add(new NodeChange.Moved<N>(
+ from.getNode(),
+ to.getNode(),
+ previous != null ? previous.getNode() : null,
+ moved.getNode()));
+
+ //
+ break;
}
- else
+ case ADDED:
{
- childContext = load(model, session, childData, visitor, depth + 1);
+ NodeContext<N> parent = stack.peek();
+ NodeContext<N> added = new NodeContext<N>(parent.tree, it.getDestination());
+ NodeContext<N> previous;
+ if (last == null || last.getParent() != parent)
+ {
+ previous = null;
+ parent.insertAt(0, added);
+ }
+ else
+ {
+ previous = last;
+ last.insertAfter(added);
+ }
+
+ //
+ if (list.isEmpty()) {
+ list = new LinkedList<NodeChange<N>>();
+ }
+ list.add(new NodeChange.Added<N>(
+ parent.getNode(),
+ previous != null ? previous.getNode() : null,
+ added.getNode(),
+ added.getName()));
+
+ //
+ break;
}
- children.add(childContext);
+ case REMOVED:
+ {
+ NodeContext<N> removed = it.getSource();
+ NodeContext<N> parent = removed.getParent();
+
+ //
+ removed.remove();
+
+ //
+ if (list.isEmpty()) {
+ list = new LinkedList<NodeChange<N>>();
+ }
+ list.add(new NodeChange.Removed<N>(
+ parent.getNode(),
+ removed.getNode()));
+
+ //
+ break;
+ }
+ default:
+ throw new UnsupportedOperationException("todo : " + change);
}
- else
- {
- throw new UnsupportedOperationException("Handle me gracefully");
- }
}
-
- //
- context.setContexts(children);
}
- else if (visitMode == VisitMode.NO_CHILDREN)
+ finally
{
- if (context.hasTrees())
- {
- context.setContexts(null);
- }
+ // Disable edit mode
+ tree.editMode = false;
}
- else
+
+ // Now update with scope
+ if (scope != null)
{
- throw new AssertionError();
+ expand(session, root, scope.get(), 0);
}
- }
-
- public <N> void refresh(NodeModel<N> model, N node, Scope scope) throws NullPointerException, NavigationServiceException
- {
- POMSession session = manager.getSession();
- NodeContext<N> context = model.getContext(node);
- refresh(model, session, context, scope.get(), 0);
+ //
+ return list.iterator();
}
- private <N> void refresh(
- NodeModel<N> model,
- POMSession session,
- NodeContext<N> context,
- Scope.Visitor visitor,
- int depth)
+ private <N> void expand(POMSession session, NodeContext<N> context, Scope.Visitor visitor, int depth)
{
-
- String id = context.data.getId();
-
- NodeData from = context.data;
-
- NodeData to = getNodeData(session, id);
-
- if (to == null)
+ if (context.hasContexts())
{
- throw new UnsupportedOperationException("Handle me gracefully");
+ for (NodeContext<N> current = context.getFirst();current != null;current = current.getNext())
+ {
+ expand(session, current, visitor, depth + 1);
+ }
}
-
- //
- if (context.hasTrees())
+ else
{
- Iterable<NodeContext<N>> children = context.getContexts();
-
- // Remove what we need
- for (Iterator<NodeContext<N>> it = children.iterator();it.hasNext();)
+ NodeData data = context.data;
+ VisitMode visitMode = visitor.visit(depth, data.id, data.name, data.state);
+ if (visitMode == VisitMode.ALL_CHILDREN)
{
- NodeContext<N> child = it.next();
- if (child.data == null || !to.children.contains(child.data.getId()))
+ ArrayList<NodeContext<N>> children = new ArrayList<NodeContext<N>>(data.children.length);
+ for (String childId : data.children)
{
- it.remove();
+ NodeData childData = cache.getNodeData(session, childId);
+ if (childData != null)
+ {
+ NodeContext<N> child = new NodeContext<N>(context.tree, childData);
+ expand(session, child, visitor, depth + 1);
+ children.add(child);
+ }
+ else
+ {
+ throw new UnsupportedOperationException("Handle me gracefully");
+ }
}
- else
- {
- // We do nothing for now
- }
+ context.setContexts(children);
}
+ else
+ {
+ // Do nothing
+ }
}
- else
- {
- throw new UnsupportedOperationException("Handle me gracefully");
- }
-
- // Update data now
- context.data = to;
}
- public <N> void saveNode(NodeModel<N> model, N node)
+ public <N> void saveNode(NodeContext<N> context) throws NullPointerException, NavigationServiceException
{
POMSession session = manager.getSession();
- NodeContext<N> context = model.getContext(node);
+ TreeContext<N> tree = context.tree;
//
- SaveContext<N> save = new SaveContext<N>(context);
+ List<NodeChange<NodeContext<N>>> changes = tree.popChanges();
- //
- save.phase0(session);
-
- //
- save.phase1(session);
-
- //
- save.phase2(session);
-
- //
- save.phase3(session);
-
- //
- save.phase4(session);
-
- //
- save.phase5(session);
-
- //
- save.phase6(session);
- }
-
- private static class SaveContext<N>
- {
-
- /** . */
- private final NodeContext<N> context;
-
- /** . */
- private final List<SaveContext<N>> children;
-
- /** The list of actual children ids, maintained during the phases. */
- private List<String> childrenIds;
-
- /** . */
- private SaveContext<N> parent;
-
- /** The related navigation object. */
- private org.gatein.mop.api.workspace.Navigation navigation;
-
- private SaveContext(NodeContext<N> context)
+ // First pass we update persistent store
+ for (NodeChange<NodeContext<N>> change : changes)
{
- List<SaveContext<N>> children;
- if (context.hasTrees())
+ if (change instanceof NodeChange.Added<?>)
{
- children = new ArrayList<SaveContext<N>>();
- for (NodeContext<N> childCtx : context.getContexts())
+ NodeChange.Added<NodeContext<N>> add = (NodeChange.Added<NodeContext<N>>)change;
+
+ //
+ Navigation parent = session.findObjectById(ObjectType.NAVIGATION, add.parent.data.id);
+ if (parent == null)
{
- SaveContext<N> child = new SaveContext<N>(childCtx);
- children.add(child);
- child.parent = this;
+ throw new NavigationServiceException(NavigationError.ADD_CONCURRENTLY_REMOVED_PARENT_NODE);
}
- }
- else
- {
- children = Collections.emptyList();
- }
- //
- ArrayList<String> bilto;
- if (context.data != null)
- {
- bilto = new ArrayList<String>(context.data.children);
+ //
+ Navigation added = parent.getChild(add.name);
+ if (added != null)
+ {
+ throw new NavigationServiceException(NavigationError.ADD_CONCURRENTLY_ADDED_NODE);
+ }
+ else
+ {
+ added = parent.addChild(add.name);
+ int index = 0;
+ if (add.previous != null)
+ {
+ Navigation previous = session.findObjectById(ObjectType.NAVIGATION, add.previous.data.id);
+ if (previous == null)
+ {
+ throw new NavigationServiceException(NavigationError.ADD_CONCURRENTLY_REMOVED_PREVIOUS_NODE);
+ }
+ index = parent.getChildren().indexOf(previous) + 1;
+ }
+ parent.getChildren().add(index, added);
+ add.node.data = new NodeData(added);
+ }
}
- else
+ else if (change instanceof NodeChange.Removed<?>)
{
- bilto = new ArrayList<String>();
+ NodeChange.Removed<NodeContext<N>> remove = (NodeChange.Removed<NodeContext<N>>)change;
+ Navigation removed = session.findObjectById(ObjectType.NAVIGATION, remove.node.data.id);
+ if (removed != null)
+ {
+ Navigation parent = removed.getParent();
+ removed.destroy();
+ remove.node.data = null;
+ }
+ else
+ {
+ // It was already removed concurrently
+ }
}
+ else if (change instanceof NodeChange.Moved<?>)
+ {
+ NodeChange.Moved<NodeContext<N>> move = (NodeChange.Moved<NodeContext<N>>)change;
+ Navigation src = session.findObjectById(ObjectType.NAVIGATION, move.from.data.id);
+ if (src == null)
+ {
+ throw new NavigationServiceException(NavigationError.MOVE_CONCURRENTLY_REMOVED_SRC_NODE);
+ }
- //
- this.context = context;
- this.children = children;
- this.childrenIds = bilto;
- this.navigation = null;
- }
+ //
+ Navigation dst = session.findObjectById(ObjectType.NAVIGATION, move.to.data.id);
+ if (dst == null)
+ {
+ throw new NavigationServiceException(NavigationError.MOVE_CONCURRENTLY_REMOVED_DST_NODE);
+ }
- static abstract class Finder<N>
- {
-
- final SaveContext<N> any(SaveContext<N> context)
- {
- SaveContext<N> root = context;
- while (root.parent != null)
+ //
+ Navigation moved = session.findObjectById(ObjectType.NAVIGATION, move.node.data.id);
+ if (moved == null)
{
- root = root.parent;
+ throw new NavigationServiceException(NavigationError.MOVE_CONCURRENTLY_REMOVED_MOVED_NODE);
}
- return descendants(root);
- }
- final SaveContext<N> descendants(SaveContext<N> context)
- {
- SaveContext<N> found = null;
- if (accept(context))
+ //
+ if (src != moved.getParent())
{
- found = context;
+ throw new NavigationServiceException(NavigationError.MOVE_CONCURRENTLY_CHANGED_SRC_NODE);
}
- else
+
+ //
+ int index = 0;
+ if (move.previous != null)
{
- int size = context.children.size();
- for (int i = 0;i < size;i++)
+ Navigation previous = session.findObjectById(ObjectType.NAVIGATION, move.previous.data.id);
+ if (previous == null)
{
- found = descendants(context.children.get(i));
- if (found != null)
- {
- break;
- }
+ throw new NavigationServiceException(NavigationError.MOVE_CONCURRENTLY_REMOVED_PREVIOUS_NODE);
}
+ index = dst.getChildren().indexOf(previous) + 1;
}
- return found;
+ dst.getChildren().add(index, moved);
}
-
- abstract boolean accept(SaveContext<N> context);
- }
-
- // Remove orphans
- void phase0(POMSession session)
- {
- if (context.hasTrees())
+ else if (change instanceof NodeChange.Renamed)
{
- if (context.data != null)
+ NodeChange.Renamed<NodeContext<N>> rename = (NodeChange.Renamed<NodeContext<N>>)change;
+ Navigation renamed = session.findObjectById(ObjectType.NAVIGATION, rename.node.data.id);
+ if (renamed == null)
{
- for (final String childId : context.data.children)
- {
- // Is it still here ?
- boolean found = false;
- for (NodeContext<N> childContext : context.getContexts())
- {
- if (childContext.data != null && childContext.data.id.equals(childId))
- {
- found = true;
- }
- }
+ throw new NavigationServiceException(NavigationError.RENAME_CONCURRENTLY_REMOVED_NODE);
+ }
- //
- if (!found)
- {
- Finder<N> finder = new Finder<N>()
- {
- boolean accept(SaveContext<N> context)
- {
- return context.context.data != null && context.context.data.getId().equals(childId);
- }
- };
- if (finder.any(this) == null)
- {
- org.gatein.mop.api.workspace.Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, childId);
- navigation.destroy();
- }
- else
- {
- // It's a move operation
- }
- childrenIds.remove(childId);
- }
- }
+ //
+ Navigation parent = renamed.getParent();
+ if (parent.getChild(rename.name) != null)
+ {
+ throw new NavigationServiceException(NavigationError.RENAME_CONCURRENTLY_DUPLICATE_NAME);
}
- }
- //
- for (SaveContext<N> child : children)
+ // We rename and reorder to compensate the move from the rename
+ List<Navigation> children = parent.getChildren();
+ int index = children.indexOf(renamed);
+ renamed.setName(rename.name);
+ children.add(index, renamed);
+ }
+ else
{
- child.phase0(session);
+ throw new AssertionError("Cannot execute " + change);
}
}
- // Create new nodes and associates with navigation object
- void phase1(POMSession session)
+ // Update state
+ saveState(session, context);
+ }
+
+ private <N> void saveState(POMSession session, NodeContext<N> context) throws NavigationServiceException
+ {
+ NodeState state = context.state;
+
+ // For now we just do a reference comparison but it would make sense
+ // to use an equals instead
+ if (state != null && !state.equals(context.data.state))
{
- if (context.data == null)
+ Navigation navigation = session.findObjectById(ObjectType.NAVIGATION, context.data.id);
+
+ //
+ if (navigation == null)
{
- throw new IllegalArgumentException();
+ throw new NavigationServiceException(NavigationError.UPDATE_CONCURRENTLY_REMOVED_NODE);
}
+
+ //
+ Workspace workspace = navigation.getSite().getWorkspace();
+ String reference = state.getPageRef();
+ if (reference != null)
+ {
+ String[] pageChunks = split("::", reference);
+ ObjectType<? extends Site> siteType = Mapper.parseSiteType(pageChunks[0]);
+ Site site = workspace.getSite(siteType, pageChunks[1]);
+ org.gatein.mop.api.workspace.Page target = site.getRootPage().getChild("pages").getChild(pageChunks[2]);
+ PageLink link = navigation.linkTo(ObjectType.PAGE_LINK);
+ link.setPage(target);
+ }
else
{
- navigation = session.findObjectById(ObjectType.NAVIGATION, context.getId());
-
- //
- for (SaveContext<N> child : children)
- {
- if (child.context.data == null)
- {
- org.gatein.mop.api.workspace.Navigation added = navigation.addChild(child.context.getName());
- child.context.data = new NodeData(added);
- childrenIds.add(added.getObjectId());
- }
- }
+ PageLink link = navigation.linkTo(ObjectType.PAGE_LINK);
+ link.setPage(null);
}
//
- for (SaveContext<N> child : children)
- {
- child.phase1(session);
- }
+ Described described = navigation.adapt(Described.class);
+ described.setName(state.getLabel());
+
+ //
+ Visible visible = navigation.adapt(Visible.class);
+ visible.setVisibility(state.getVisibility());
+
+ //
+ visible.setStartPublicationDate(state.getStartPublicationDate());
+ visible.setEndPublicationDate(state.getEndPublicationDate());
+
+ //
+ Attributes attrs = navigation.getAttributes();
+ attrs.setValue(MappedAttributes.URI, state.getURI());
+ attrs.setValue(MappedAttributes.ICON, state.getIcon());
}
- // Rename nodes
- void phase2(POMSession session)
+ //
+ context.data = context.toData();
+
+ //
+ context.state = null;
+
+ //
+ if (context.hasContexts())
{
- if (!context.data.name.equals(context.getName()))
+ for (NodeContext<N> child : context.getContexts())
{
- navigation.setName(context.getName());
+ saveState(session, child);
}
-
- //
- for (SaveContext<N> child : children)
- {
- child.phase2(session);
- }
}
+ }
- // Update state
- void phase3(POMSession session)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // Code to remove soon below
+
+ private <N> NodeContext<N> load(
+ TreeContext<N> tree,
+ POMSession session,
+ NodeData data,
+ Scope.Visitor visitor,
+ int depth)
+ {
+ VisitMode visitMode = visitor.visit(depth, data.id, data.name, data.state);
+
+ //
+ NodeContext<N> context;
+ if (visitMode == VisitMode.ALL_CHILDREN)
{
- NodeState state = context.state;
- if (state != null)
+ ArrayList<NodeContext<N>> children = new ArrayList<NodeContext<N>>(data.children.length);
+ for (String childId : data.children)
{
- Workspace workspace = navigation.getSite().getWorkspace();
- String reference = state.getPageRef();
- if (reference != null)
+ NodeData childData = cache.getNodeData(session, childId);
+ if (childData != null)
{
- String[] pageChunks = split("::", reference);
- ObjectType<? extends Site> siteType = Mapper.parseSiteType(pageChunks[0]);
- Site site = workspace.getSite(siteType, pageChunks[1]);
- org.gatein.mop.api.workspace.Page target = site.getRootPage().getChild("pages").getChild(pageChunks[2]);
- PageLink link = navigation.linkTo(ObjectType.PAGE_LINK);
- link.setPage(target);
+ NodeContext<N> childContext = load(tree, session, childData, visitor, depth + 1);
+ children.add(childContext);
}
else
{
- PageLink link = navigation.linkTo(ObjectType.PAGE_LINK);
- link.setPage(null);
+ throw new UnsupportedOperationException("Handle me gracefully");
}
+ }
- //
- Described described = navigation.adapt(Described.class);
- described.setName(state.getLabel());
+ //
+ context = new NodeContext<N>(tree, data);
+ context.setContexts(children);
+ }
+ else if (visitMode == VisitMode.NO_CHILDREN)
+ {
+ context = new NodeContext<N>(tree, data);
+ }
+ else
+ {
+ context = new NodeContext<N>(tree, data);
+ }
- //
- Visible visible = navigation.adapt(Visible.class);
- visible.setVisibility(state.getVisibility());
+ //
+ return context;
+ }
- //
- visible.setStartPublicationDate(state.getStartPublicationDate());
- visible.setEndPublicationDate(state.getEndPublicationDate());
+ public <N> NodeContext<N> loadNode(NodeContext<N> context, Scope scope)
+ {
+ POMSession session = manager.getSession();
+ Scope.Visitor visitor = scope.get();
- //
- Attributes attrs = navigation.getAttributes();
- attrs.setValue(MappedAttributes.URI, state.getURI());
- attrs.setValue(MappedAttributes.ICON, state.getIcon());
- }
+ //
+ String nodeId = context.getId();
+ NodeData data = cache.getNodeData(session, nodeId);
- //
- for (SaveContext<N> child : children)
- {
- child.phase3(session);
- }
+ //
+ if (data != null)
+ {
+ context.data = data;
+ visit(session, context, visitor, 0);
+ return context;
}
+ return null;
+ }
- // Move nodes
- void phase4(POMSession session)
+ private <N> void visit(
+ POMSession session,
+ NodeContext<N> context,
+ Scope.Visitor visitor,
+ int depth)
+ {
+ NodeData data = context.data;
+
+ //
+ VisitMode visitMode;
+ if (context.hasContexts())
{
+ visitMode = VisitMode.ALL_CHILDREN;
+ }
+ else
+ {
+ visitMode = visitor.visit(depth, data.id, data.name, data.state);
+ }
- if (context.hasTrees())
+ //
+ if (visitMode == VisitMode.ALL_CHILDREN)
+ {
+ Map<String, NodeContext<N>> previous = Collections.emptyMap();
+ if (context.hasContexts())
{
- for (NodeContext<N> childCtx : context.getContexts())
+ previous = new HashMap<String, NodeContext<N>>();
+ for (NodeContext<N> a : context.getContexts())
{
- final String childId = childCtx.data.id;
- if (!context.data.children.contains(childId))
+ if (a.data != null)
{
- if (!childrenIds.contains(childId))
- {
- Finder<N> finder = new Finder<N>()
- {
- boolean accept(SaveContext<N> context)
- {
- return context.context.data.getId().equals(childId);
- }
- };
- SaveContext<N> movedCtx = finder.any(this);
- org.gatein.mop.api.workspace.Navigation moved = movedCtx.navigation;
- navigation.getChildren().add(moved);
- childrenIds.add(childId);
- }
+ previous.put(a.getId(), a);
}
}
+ context.setContexts(null);
}
//
- for (SaveContext<N> child : children)
+ ArrayList<NodeContext<N>> children = new ArrayList<NodeContext<N>>(data.children.length);
+ for (String childId : data.children)
{
- child.phase4(session);
- }
- }
-
- // Reorder nodes
- void phase5(POMSession session)
- {
- if (context.hasTrees())
- {
- final ArrayList<String> orders = new ArrayList<String>();
- for (NodeContext<N> foo : context.getContexts())
+ NodeData childData = cache.getNodeData(session, childId);
+ if (childData != null)
{
- orders.add(foo.data.id);
- }
-
- //
- if (!childrenIds.equals(orders))
- {
- // Now sort children according to the order provided by the container
- // need to replace that with Collections.sort once the set(int index, E element) is implemented in Chromattic lists
- org.gatein.mop.api.workspace.Navigation[] a = navigation.getChildren().toArray(new org.gatein.mop.api.workspace.Navigation[navigation.getChildren().size()]);
- Arrays.sort(a, new Comparator<org.gatein.mop.api.workspace.Navigation>()
+ NodeContext<N> childContext = previous.get(childId);
+ if (childContext != null)
{
- public int compare(org.gatein.mop.api.workspace.Navigation o1, org.gatein.mop.api.workspace.Navigation o2)
- {
- int i1 = orders.indexOf(o1.getObjectId());
- int i2 = orders.indexOf(o2.getObjectId());
- return i1 - i2;
- }
- });
- for (int j = 0; j < a.length; j++)
+ childContext.data = childData;
+ visit(session, childContext, visitor, depth + 1);
+ }
+ else
{
- navigation.getChildren().add(j, a[j]);
+ childContext = load(context.tree, session, childData, visitor, depth + 1);
}
+ children.add(childContext);
}
+ else
+ {
+ throw new UnsupportedOperationException("Handle me gracefully");
+ }
}
//
- for (SaveContext<N> child : children)
- {
- child.phase5(session);
- }
+ context.setContexts(children);
}
-
- // Update model
- void phase6(POMSession session)
+ else if (visitMode == VisitMode.NO_CHILDREN)
{
- Set<String> childMap;
- if (context.hasTrees())
+ if (context.hasContexts())
{
- // todo : I think we have a bug here :-)
- childMap = new LinkedHashSet<String>();
+ context.setContexts(null);
}
- else
- {
- childMap = context.data.children;
- }
-
- //
- String id = context.data.id;
- String name = context.getName();
- NodeState state = context.getState();
-
- //
- context.data = new NodeData(id, name, state, childMap);
-
- //
- for (SaveContext<N> child : children)
- {
- child.phase6(session);
- }
}
+ else
+ {
+ throw new AssertionError();
+ }
}
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceWrapper.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceWrapper.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NavigationServiceWrapper.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -21,11 +21,20 @@
import org.exoplatform.container.PortalContainer;
import org.exoplatform.container.component.RequestLifeCycle;
+import org.exoplatform.portal.mop.EventType;
import org.exoplatform.portal.mop.SiteKey;
+import static org.exoplatform.portal.mop.navigation.Utils.*;
import org.exoplatform.portal.pom.config.POMSessionManager;
+import org.exoplatform.services.listener.ListenerService;
import org.exoplatform.services.organization.OrganizationService;
+import org.gatein.common.logging.Logger;
+import org.gatein.common.logging.LoggerFactory;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
import org.picocontainer.Startable;
+import java.util.Iterator;
+
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
@@ -34,11 +43,18 @@
{
/** . */
+ private static final Logger log = LoggerFactory.getLogger(NavigationServiceWrapper.class);
+
+ /** . */
private final NavigationServiceImpl service;
- public NavigationServiceWrapper(POMSessionManager manager, OrganizationService organization)
+ /** . */
+ private ListenerService listenerService;
+
+ public NavigationServiceWrapper(POMSessionManager manager, OrganizationService organization, ListenerService listenerService)
{
this.service = new NavigationServiceImpl(manager);
+ this.listenerService = listenerService;
}
public void start()
@@ -71,33 +87,55 @@
}
}
- public Navigation loadNavigation(SiteKey key)
+ public NavigationContext loadNavigation(SiteKey key)
{
return service.loadNavigation(key);
}
public boolean saveNavigation(SiteKey key, NavigationState state) throws NavigationServiceException
{
- return service.saveNavigation(key, state);
+ boolean changed = service.saveNavigation(key, state);
+ String name = state != null ? (changed ? EventType.NAVIGATION_CREATED : EventType.NAVIGATION_UPDATED) : (changed ? EventType.NAVIGATION_DESTROYED : null);
+ if (name != null)
+ {
+ notify(name, key);
+ }
+ return changed;
}
- public <N> N loadNode(NodeModel<N> model, Navigation navigation, Scope scope)
+ public <N> NodeContext<N> loadNode(NodeModel<N> model, NavigationContext navigation, Scope scope)
{
return service.loadNode(model, navigation, scope);
}
- public <N> N loadNode(NodeModel<N> model, N node, Scope scope)
+ public <N> NodeContext<N> loadNode(NodeContext<N> context, Scope scope)
{
- return service.loadNode(model, node, scope);
+ return service.loadNode(context, scope);
}
- public <N> void refresh(NodeModel<N> model, N node, Scope scope) throws NullPointerException, NavigationServiceException
+ public <N> void saveNode(NodeContext<N> context) throws NavigationServiceException
{
- service.refresh(model, node, scope);
+ service.saveNode(context);
+ org.gatein.mop.api.workspace.Navigation nav = service.manager.getSession().findObjectById(ObjectType.NAVIGATION, context.data.id);
+ Site site = nav.getSite();
+ SiteKey key = new SiteKey(siteType(site.getObjectType()), site.getName());
+ notify(EventType.NAVIGATION_UPDATED, key);
}
- public <N> void saveNode(NodeModel<N> model, N node)
+ public <N> Iterator<NodeChange<N>> updateNode(NodeContext<N> context, Scope scope) throws NullPointerException, NavigationServiceException
{
- service.saveNode(model, node);
+ return service.updateNode(context, scope);
}
+
+ private void notify(String name, SiteKey key)
+ {
+ try
+ {
+ listenerService.broadcast(name, this, key);
+ }
+ catch (Exception e)
+ {
+ log.error("Error when delivering notification " + name + " for navigation " + key, e);
+ }
+ }
}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeChange.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeChange.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeChange.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+/**
+ * Describe a node change.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class NodeChange<N>
+{
+
+ private NodeChange()
+ {
+ }
+
+ public static class Removed<N> extends NodeChange<N>
+ {
+
+ /** . */
+ final N parent;
+
+ /** . */
+ final N node;
+
+ public Removed(N parent, N node)
+ {
+ this.parent = parent;
+ this.node = node;
+ }
+ }
+
+ public static class Added<N> extends NodeChange<N>
+ {
+
+ /** . */
+ final N parent;
+
+ /** . */
+ final N previous;
+
+ /** . */
+ final N node;
+
+ /** . */
+ final String name;
+
+ public Added(N parent, N previous, N node, String name)
+ {
+ this.parent = parent;
+ this.previous = previous;
+ this.node = node;
+ this.name = name;
+ }
+ }
+
+ public static class Moved<N> extends NodeChange<N>
+ {
+
+ /** . */
+ final N from;
+
+ /** . */
+ final N to;
+
+ /** . */
+ final N previous;
+
+ /** . */
+ final N node;
+
+ public Moved(N from, N to, N previous, N node)
+ {
+ this.from = from;
+ this.to = to;
+ this.previous = previous;
+ this.node = node;
+ }
+ }
+
+ public static class Renamed<N> extends NodeChange<N>
+ {
+
+ /** . */
+ final N node;
+
+ /** . */
+ final String name;
+
+ public Renamed(N node, String name)
+ {
+ this.node = node;
+ this.name = name;
+ }
+ }
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeContext.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeContext.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeContext.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 eXo Platform SAS.
+ * Copyright (C) 2011 eXo Platform SAS.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
@@ -19,18 +19,24 @@
package org.exoplatform.portal.mop.navigation;
+import org.exoplatform.portal.tree.list.ListTree;
+
import java.util.AbstractCollection;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.NoSuchElementException;
/**
* The context of a node.
*/
-public final class NodeContext<N> extends ListTree<NodeContext<N>, N>
+public final class NodeContext<N> extends ListTree<NodeContext<N>>
{
/** . */
+ final TreeContext<N> tree;
+
+ /** . */
final N node;
/** node data representing persistent state. */
@@ -39,61 +45,203 @@
/** The new state if any. */
NodeState state;
- NodeContext(NodeModel<N> model, NodeData data)
+ /** . */
+ private boolean hidden;
+
+ /** . */
+ private int hiddenCount;
+
+ /** . */
+ private String name;
+
+ /** . */
+ private boolean hasContexts;
+
+ NodeContext(TreeContext<N> tree, NodeData data)
{
- super(data.getName());
-
- //
- this.node = model.create(this);
+ this.name = data.getName();
+ this.tree = tree;
+ this.node = tree.model.create(this);
this.data = data;
- this.state = data.getState();
+ this.state = null;
+ this.hidden = false;
+ this.hiddenCount = 0;
+ this.hasContexts = false;
}
- NodeContext(NodeModel<N> model, String name, NodeState state)
+ private NodeContext(TreeContext<N> tree, String name, NodeState state)
{
- super(name);
-
- //
- this.node = model.create(this);
+ this.name = name;
+ this.tree = tree;
+ this.node = tree.model.create(this);
this.data = null;
this.state = state;
+ this.hidden = false;
+ this.hiddenCount = 0;
+ this.hasContexts = false;
}
+ NodeData toData()
+ {
+ String id = data.id;
+ String name = getName();
+ NodeState state = this.state != null ? this.state : data.state;
+ String[] children;
+ if (hasContexts)
+ {
+ children = new String[getSize()];
+ int index = 0;
+ for (NodeContext<N> current = getFirst();current != null;current = current.getNext())
+ {
+ children[index++] = current.data.id;
+ }
+ }
+ else
+ {
+ children = data.children;
+ }
+ return new NodeData(id, name, state, children);
+ }
+
+ public NodeContext<N> getDescendant(String id) throws NullPointerException
+ {
+ if (id == null)
+ {
+ throw new NullPointerException();
+ }
+
+ //
+ NodeContext<N> found = null;
+ if (data != null && data.id.equals(id))
+ {
+ found = this;
+ }
+ else
+ {
+ if (hasContexts)
+ {
+ for (NodeContext<N> current = getFirst();current != null;current = current.getNext())
+ {
+ found = current.getDescendant(id);
+ if (found != null)
+ {
+ break;
+ }
+ }
+ }
+ }
+ return found;
+ }
+
/**
- * Applies a filter recursively.
+ * Returns true if the context is currently hidden.
*
+ * @return the hidden value
+ */
+ public boolean isHidden()
+ {
+ return hidden;
+ }
+
+ /**
+ * Updates the hiddent value.
+ *
+ * @param hidden the hidden value
+ */
+ public void setHidden(boolean hidden)
+ {
+ if (this.hidden != hidden)
+ {
+ NodeContext<N> parent = getParent();
+ if (parent != null)
+ {
+ if (hidden)
+ {
+ parent.hiddenCount++;
+ }
+ else
+ {
+ parent.hiddenCount--;
+ }
+ }
+ this.hidden = hidden;
+ }
+ }
+
+ /**
+ * Applies a filter recursively, the filter will update the hiddent status of the
+ * fragment.
+ *
* @param filter the filter to apply
*/
public void filter(NodeFilter filter)
{
- filter(0, filter);
+ doFilter(0, filter);
}
- private void filter(int depth, NodeFilter filter)
+ private void doFilter(int depth, NodeFilter filter)
{
- boolean accept = filter.accept(depth, getId(), getName(), state);
+ boolean accept = filter.accept(depth, getId(), name, getState());
setHidden(!accept);
- if (hasTrees())
+ if (hasContexts)
{
- for (NodeContext<N> node : getTrees())
+ for (NodeContext<N> node = getFirst();node != null;node = node.getNext())
{
- node.filter(depth + 1, filter);
+ node.doFilter(depth + 1, filter);
}
}
}
- public N getElement()
+ /**
+ * Returns the associated node with this context
+ *
+ * @return the node
+ */
+ public N getNode()
{
return node;
}
+ /**
+ * Reutrns the context id or null if the context is not associated with a persistent navigation node.
+ *
+ * @return the id
+ */
public String getId()
{
return data != null ? data.getId() : null;
}
- public void setName(String name)
+ /**
+ * Returns the context index among its parent.
+ *
+ * @return the index value
+ */
+ public int getIndex()
{
+ int count = 0;
+ for (NodeContext<N> node = getPrevious();node != null;node = node.getPrevious())
+ {
+ count++;
+ }
+ return count;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Rename this context.
+ *
+ * @param name the new name
+ * @throws NullPointerException if the name is null
+ * @throws IllegalStateException if the parent is null
+ * @throws IllegalArgumentException if the parent already have a child with the specified name
+ */
+ public void setName(String name) throws NullPointerException, IllegalStateException, IllegalArgumentException
+ {
NodeContext<N> parent = getParent();
if (parent == null)
{
@@ -101,10 +249,50 @@
}
else
{
- parent.rename(getName(), name);
+ NodeContext<N> blah = parent.get(name);
+ if (blah != null)
+ {
+ if (blah == this)
+ {
+ // We do nothing
+ }
+ else
+ {
+ throw new IllegalArgumentException("the node " + name + " already exist");
+ }
+ }
+ else
+ {
+ this.name = name;
+ tree.addChange(new NodeChange.Renamed<NodeContext<N>>(this, name));
+ }
}
}
+ public NodeContext<N> get(String name) throws NullPointerException, IllegalStateException
+ {
+ if (name == null)
+ {
+ throw new NullPointerException();
+ }
+ if (!hasContexts)
+ {
+ throw new IllegalStateException("No children relationship");
+ }
+
+ //
+ for (NodeContext<N> node = getFirst();node != null;node = node.getNext())
+ {
+ if (node.name.equals(name))
+ {
+ return node;
+ }
+ }
+
+ //
+ return null;
+ }
+
/**
* Returns the total number of nodes.
*
@@ -112,13 +300,13 @@
*/
public int getNodeSize()
{
- if (hasTrees())
+ if (hasContexts)
{
return getSize();
}
else
{
- return data.children.size();
+ return data.children.length;
}
}
@@ -133,13 +321,13 @@
*/
public int getNodeCount()
{
- if (hasTrees())
+ if (hasContexts)
{
- return getCount();
+ return getSize() - hiddenCount;
}
else
{
- return data.children.size();
+ return data.children.length;
}
}
@@ -159,8 +347,18 @@
}
}
- public void setState(NodeState state)
+ /**
+ * Update the context state
+ *
+ * @param state the new state
+ * @throws NullPointerException if the state is null
+ */
+ public void setState(NodeState state) throws NullPointerException
{
+ if (state == null)
+ {
+ throw new NullPointerException("No null state accepted");
+ }
this.state = state;
}
@@ -173,21 +371,79 @@
public N getNode(String name) throws NullPointerException
{
NodeContext<N> child = get(name);
- return child != null ? child.node: null;
+ return child != null && !child.hidden ? child.node: null;
}
public N getNode(int index)
{
- NodeContext<N> child = get(index);
- return child != null ? child.node: null;
+ if (index < 0)
+ {
+ throw new IndexOutOfBoundsException("Index " + index + " cannot be negative");
+ }
+ if (!hasContexts)
+ {
+ throw new IllegalStateException("No children relationship");
+ }
+ NodeContext<N> context = getFirst();
+ while (context != null && (context.hidden || index-- > 0))
+ {
+ context = context.getNext();
+ }
+ if (context == null)
+ {
+ throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
+ }
+ else
+ {
+ return context.node;
+ }
}
+ public final Iterator<N> iterator()
+ {
+ return new Iterator<N>()
+ {
+ NodeContext<N> next = getFirst();
+ {
+ while (next != null && next.isHidden())
+ {
+ next = next.getNext();
+ }
+ }
+ public boolean hasNext()
+ {
+ return next != null;
+ }
+ public N next()
+ {
+ if (next != null)
+ {
+ NodeContext<N> tmp = next;
+ do
+ {
+ next = next.getNext();
+ }
+ while (next != null && next.isHidden());
+ return tmp.getNode();
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
/** . */
private Collection<N> nodes;
public Collection<N> getNodes()
{
- if (hasTrees())
+ if (hasContexts)
{
if (nodes == null)
{
@@ -211,61 +467,251 @@
}
}
- public N addNode(NodeModel<N> model, String name)
+ /**
+ * Add a child node at the specified index with the specified name. If the index argument
+ * is null then the node is added at the last position among the children otherwise
+ * the node is added at the specified index.
+ *
+ * @param index the index
+ * @param name the node name
+ * @return the created node
+ * @throws NullPointerException if the model or the name is null
+ * @throws IndexOutOfBoundsException if the index is negative or greater than the children size
+ * @throws IllegalStateException if the children relationship does not exist
+ */
+ public N addNode(Integer index, String name) throws NullPointerException, IndexOutOfBoundsException, IllegalStateException
{
- if (model == null)
+ if (name == null)
{
- throw new NullPointerException();
+ throw new NullPointerException("No null name accepted");
}
//
- NodeContext<N> nodeContext = new NodeContext<N>(model, name, new NodeState.Builder().capture());
+ NodeContext<N> nodeContext = new NodeContext<N>(tree, name, new NodeState.Builder().capture());
nodeContext.setContexts(Collections.<NodeContext<N>>emptyList());
- insert(null, nodeContext);
+ addNode(index, nodeContext);
return nodeContext.node;
}
- public void addNode(NodeModel<N> model, Integer index, N child)
+ /**
+ * Move a node as a child node of this node at the specified index. If the index argument
+ * is null then the node is added at the last position among the children otherwise
+ * the node is added at the specified index.
+ *
+ * @param index the index
+ * @param node the node to move
+ * @throws NullPointerException if the model or the node is null
+ * @throws IndexOutOfBoundsException if the index is negative or greater than the children size
+ * @throws IllegalStateException if the children relationship does not exist
+ */
+ public void addNode(Integer index, N node) throws NullPointerException, IndexOutOfBoundsException, IllegalStateException
{
- if (model == null)
+ if (node == null)
{
- throw new NullPointerException();
+ throw new NullPointerException("No null node argument accepted");
}
//
- NodeContext<N> nodeContext = model.getContext(child);
- insert(index, nodeContext);
+ NodeContext<N> nodeContext = tree.model.getContext(node);
+
+ //
+ addNode(index, nodeContext);
}
- public boolean removeNode(NodeModel<N> model, String name)
+ private void addNode(final Integer index, NodeContext<N> child)
{
- if (model == null)
+ NodeContext<N> previousParent = child.getParent();
+
+ //
+ if (index == null)
{
- throw new NullPointerException();
+ NodeContext<N> before = getLast();
+ while (before != null && before.isHidden())
+ {
+ before = before.getPrevious();
+ }
+ if (before == null)
+ {
+ insertAt(0, child);
+ }
+ else
+ {
+ before.insertAfter(child);
+ }
}
+ else if (index < 0)
+ {
+ throw new IndexOutOfBoundsException("No negative index accepted");
+ }
+ else if (index == 0)
+ {
+ insertAt(0, child);
+ }
+ else
+ {
+ NodeContext<N> before = getFirst();
+ if (before == null)
+ {
+ throw new IndexOutOfBoundsException("Index " + index + " is greater than 0");
+ }
+ for (int count = index;count > 1;count -= before.isHidden() ? 0 : 1)
+ {
+ before = before.getNext();
+ if (before == null)
+ {
+ throw new IndexOutOfBoundsException("Index " + index + " is greater than the number of children " + (index - count));
+ }
+ }
+ before.insertAfter(child);
+ }
//
- return remove(name) != null;
+ if (previousParent != null)
+ {
+ tree.addChange(new NodeChange.Moved<NodeContext<N>>(previousParent, this, child.getPrevious(), child));
+ }
+ else
+ {
+ tree.addChange(new NodeChange.Added<NodeContext<N>>(this, child.getPrevious(), child, child.name));
+ }
}
- NodeContext<N> getRoot()
+ /**
+ * Remove a specified context.
+ *
+ * @param name the name of the context to remove
+ * @return true if the context was removed
+ * @throws NullPointerException if the name argument is null
+ * @throws IllegalArgumentException if the named context does not exist
+ * @throws IllegalStateException if the children relationship does not exist
+ */
+ public boolean removeNode(String name) throws NullPointerException, IllegalArgumentException, IllegalStateException
{
- NodeContext<N> root = this;
- while (root.getParent() != null)
+ NodeContext<N> node = get(name);
+ if (node == null)
{
- root = root.getParent();
+ throw new IllegalArgumentException("Cannot remove non existent " + name + " child");
}
- return root;
+
+ //
+ if (node.hidden)
+ {
+ return false;
+ }
+ else
+ {
+ node.remove();
+
+ //
+ tree.addChange(new NodeChange.Removed<NodeContext<N>>(this, node));
+
+ //
+ return true;
+ }
}
+ public boolean hasContexts()
+ {
+ return hasContexts;
+ }
+
Iterable<NodeContext<N>> getContexts()
{
- return getTrees();
+ if (hasContexts)
+ {
+ return new Iterable<NodeContext<N>>()
+ {
+ public Iterator<NodeContext<N>> iterator()
+ {
+ return listIterator();
+ }
+ };
+ }
+ else
+ {
+ return null;
+ }
}
void setContexts(Iterable<NodeContext<N>> contexts)
{
- setTrees(contexts);
+ if (contexts == null)
+ {
+ if (!hasContexts)
+ {
+ throw new IllegalStateException();
+ }
+ else
+ {
+ while (getFirst() != null)
+ {
+ getFirst().remove();
+ }
+ this.hasContexts = false;
+ }
+ }
+ else
+ {
+ if (!hasContexts)
+ {
+ this.hasContexts = true;
+ for (NodeContext<N> context : contexts)
+ {
+ insertLast(context);
+ }
+ }
+ else
+ {
+ throw new IllegalStateException();
+ }
+ }
}
+ protected void beforeRemove(NodeContext<N> context)
+ {
+ if (!hasContexts)
+ {
+ throw new IllegalStateException();
+ }
+ }
+
+ protected void beforeInsert(NodeContext<N> context)
+ {
+ if (!hasContexts)
+ {
+ throw new IllegalStateException("No children relationship");
+ }
+
+ //
+ if (!tree.editMode)
+ {
+ NodeContext<N> existing = get(context.name);
+ if (existing != null && existing != context)
+ {
+ throw new IllegalArgumentException("Tree " + context.name + " already in the map");
+ }
+ }
+ }
+
+ protected void afterInsert(NodeContext<N> context)
+ {
+ super.afterInsert(context);
+
+ //
+ if (context.hidden)
+ {
+ hiddenCount++;
+ }
+ }
+
+ protected void afterRemove(NodeContext<N> context)
+ {
+ if (context.hidden)
+ {
+ hiddenCount--;
+ }
+
+ //
+ super.afterRemove(context);
+ }
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeData.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeData.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeData.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -32,11 +32,7 @@
import org.gatein.mop.api.workspace.link.PageLink;
import java.io.Serializable;
-import java.util.Collections;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
-import java.util.Set;
+import java.util.*;
/**
* An immutable node data class.
@@ -57,29 +53,39 @@
final NodeState state;
/** . */
- final Set<String> children;
+ final String[] children;
- NodeData(String id, String name, NodeState state, Set<String> children)
+ NodeData(String id, String name, NodeState state, String[] children)
{
this.id = id;
this.name = name;
this.state = state;
- this.children = Collections.unmodifiableSet(children);
+ this.children = children;
}
- NodeData(Navigation nav)
+ NodeData(Navigation navigation)
{
- LinkedHashSet<String> children = new LinkedHashSet<String>();
- for (Navigation child : nav.getChildren())
+ String[] children;
+ List<Navigation> _children = navigation.getChildren();
+ if (_children == null)
{
- children.add(child.getObjectId());
+ children = new String[0];
}
+ else
+ {
+ children = new String[_children.size()];
+ int index = 0;
+ for (Navigation child : _children)
+ {
+ children[index++] = child.getObjectId();
+ }
+ }
//
String label = null;
- if (nav.isAdapted(Described.class))
+ if (navigation.isAdapted(Described.class))
{
- Described described = nav.adapt(Described.class);
+ Described described = navigation.adapt(Described.class);
label = described.getName();
}
@@ -87,9 +93,9 @@
Visibility visibility = Visibility.DISPLAYED;
Date startPublicationDate = null;
Date endPublicationDate = null;
- if (nav.isAdapted(Visible.class))
+ if (navigation.isAdapted(Visible.class))
{
- Visible visible = nav.adapt(Visible.class);
+ Visible visible = navigation.adapt(Visible.class);
visibility = visible.getVisibility();
startPublicationDate = visible.getStartPublicationDate();
endPublicationDate = visible.getEndPublicationDate();
@@ -97,7 +103,7 @@
//
String pageRef = null;
- Link link = nav.getLink();
+ Link link = navigation.getLink();
if (link instanceof PageLink)
{
PageLink pageLink = (PageLink)link;
@@ -111,7 +117,7 @@
}
//
- Attributes attrs = nav.getAttributes();
+ Attributes attrs = navigation.getAttributes();
//
NodeState state = new NodeState(
@@ -125,12 +131,68 @@
);
//
- this.id = nav.getObjectId();
- this.name = nav.getName();
+ this.id = navigation.getObjectId();
+ this.name = navigation.getName();
this.state = state;
- this.children = Collections.unmodifiableSet(children);
+ this.children = children;
}
+ public Iterator<String> iterator(boolean reverse)
+ {
+ if (reverse)
+ {
+ return new Iterator<String>()
+ {
+ int index = children.length;
+ public boolean hasNext()
+ {
+ return index > 0;
+ }
+ public String next()
+ {
+ if (index > 0)
+ {
+ return children[--index];
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ else
+ {
+ return new Iterator<String>()
+ {
+ int index = 0;
+ public boolean hasNext()
+ {
+ return index < children.length;
+ }
+ public String next()
+ {
+ if (index < children.length)
+ {
+ return children[index++];
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+ public void remove()
+ {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
public String getId()
{
return id;
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeState.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeState.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/NodeState.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,6 +19,7 @@
package org.exoplatform.portal.mop.navigation;
+import org.exoplatform.commons.utils.Safe;
import org.exoplatform.portal.mop.Visibility;
import java.util.Date;
@@ -29,7 +30,7 @@
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
-public class NodeState
+public final class NodeState
{
public static class Builder
@@ -63,7 +64,7 @@
this.label = null;
this.startPublicationTime = -1;
this.endPublicationTime = -1;
- this.visibility = null;
+ this.visibility = Visibility.DISPLAYED;
this.pageRef = null;
}
@@ -262,4 +263,37 @@
{
return pageRef;
}
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ {
+ return true;
+ }
+ if (o instanceof NodeState)
+ {
+ NodeState that = (NodeState)o;
+ return Safe.equals(uri, that.uri)
+ && Safe.equals(label, that.label)
+ && Safe.equals(icon, that.icon)
+ && Safe.equals(startPublicationTime, that.startPublicationTime)
+ && Safe.equals(endPublicationTime, that.endPublicationTime)
+ && Safe.equals(visibility, that.visibility)
+ && Safe.equals(pageRef, that.pageRef);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "NodeState[uri=" + uri + ",label=" + label + ",icon=" + icon + ",startPublicationTime=" + startPublicationTime +
+ ",endPublicationTime=" + endPublicationTime + ",visibility=" + visibility + ",pageRef=" + pageRef + "]";
+ }
+
+ public Builder builder()
+ {
+ return new Builder(this);
+ }
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Scope.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Scope.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Scope.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,8 +19,6 @@
package org.exoplatform.portal.mop.navigation;
-import org.exoplatform.portal.mop.Visibility;
-
/**
* <p>The scope describes a set of nodes, the scope implementation should be stateless and should be shared
* between many threads.</p>
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/TreeContext.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/TreeContext.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/TreeContext.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * The context of a tree.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+class TreeContext<N>
+{
+
+ /** . */
+ private LinkedList<NodeChange<NodeContext<N>>> changes;
+
+ /** . */
+ final NodeModel<N> model;
+
+ /** . */
+ boolean editMode;
+
+ TreeContext(NodeModel<N> model)
+ {
+ this.model = model;
+ this.editMode = false;
+ }
+
+ void addChange(NodeChange<NodeContext<N>> change)
+ {
+ if (editMode)
+ {
+ throw new AssertionError();
+ }
+ if (changes == null)
+ {
+ changes = new LinkedList<NodeChange<NodeContext<N>>>();
+ }
+ changes.addLast(change);
+ }
+
+ List<NodeChange<NodeContext<N>>> popChanges()
+ {
+ if (changes == null || changes.size() == 0)
+ {
+ return Collections.emptyList();
+ }
+ else
+ {
+ LinkedList<NodeChange<NodeContext<N>>> tmp = changes;
+ changes = null;
+ return tmp;
+ }
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Utils.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Utils.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/navigation/Utils.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteType;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+class Utils
+{
+
+ /** . */
+ private static final EnumMap<SiteType, ObjectType<Site>> a = new EnumMap<SiteType, ObjectType<Site>>(SiteType.class);
+
+ /** . */
+ private static final Map<ObjectType<Site>, SiteType> b = new HashMap<ObjectType<Site>, SiteType>(3);
+
+ static
+ {
+ a.put(SiteType.PORTAL, ObjectType.PORTAL_SITE);
+ a.put(SiteType.GROUP, ObjectType.GROUP_SITE);
+ a.put(SiteType.USER, ObjectType.USER_SITE);
+ b.put(ObjectType.PORTAL_SITE, SiteType.PORTAL);
+ b.put(ObjectType.GROUP_SITE, SiteType.GROUP);
+ b.put(ObjectType.USER_SITE, SiteType.USER);
+ }
+
+ static ObjectType<Site> objectType(SiteType siteType)
+ {
+ return a.get(siteType);
+ }
+
+ static SiteType siteType(ObjectType objectType)
+ {
+ return b.get(objectType);
+ }
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNavigation.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNavigation.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNavigation.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -20,7 +20,7 @@
package org.exoplatform.portal.mop.user;
import org.exoplatform.portal.mop.SiteKey;
-import org.exoplatform.portal.mop.navigation.Navigation;
+import org.exoplatform.portal.mop.navigation.NavigationContext;
import org.exoplatform.portal.mop.navigation.NavigationState;
import org.exoplatform.portal.mop.navigation.NodeContext;
import org.exoplatform.portal.mop.navigation.NodeModel;
@@ -39,7 +39,7 @@
final UserPortalImpl portal;
/** . */
- final Navigation navigation;
+ final NavigationContext navigation;
/** . */
private final boolean modifiable;
@@ -68,7 +68,7 @@
}
};
- UserNavigation(UserPortalImpl portal, Navigation navigation, boolean modifiable)
+ UserNavigation(UserPortalImpl portal, NavigationContext navigation, boolean modifiable)
{
if (navigation == null)
{
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNode.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNode.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserNode.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -222,7 +222,7 @@
*/
public boolean hasChildrenRelationship()
{
- return context.getNodes() != null;
+ return context.hasContexts();
}
/**
@@ -242,8 +242,7 @@
public Collection<UserNode> getChildren()
{
- Collection<UserNode> children = context.getNodes();
- return children != null ? children : Collections.<UserNode>emptyList();
+ return context.hasContexts() ? context.getNodes() : Collections.<UserNode>emptyList();
}
/**
@@ -255,7 +254,7 @@
*/
public UserNode getChild(String childName) throws NullPointerException
{
- if (context.getNodes() != null)
+ if (context.hasContexts())
{
return context.getNode(childName);
}
@@ -274,7 +273,7 @@
*/
public UserNode getChild(int childIndex) throws IndexOutOfBoundsException
{
- if (context.getNodes() != null)
+ if (context.hasContexts())
{
return context.getNode(childIndex);
}
@@ -286,53 +285,33 @@
public void addChild(UserNode child)
{
- context.addNode(navigation.model, null, child);
+ context.addNode(null, child);
}
public void addChild(int index, UserNode child)
{
- context.addNode(navigation.model, index, child);
+ context.addNode(index, child);
}
public UserNode addChild(String childName)
{
- return context.addNode(navigation.model, childName);
+ return context.addNode(null, childName);
}
public boolean removeChild(String childName)
{
- return context.removeNode(navigation.model, childName);
+ return context.removeNode(childName);
}
public void save() throws NavigationServiceException
{
- navigation.portal.navigationService.saveNode(navigation.model, this);
+ navigation.portal.navigationService.saveNode(context);
}
// Keep this internal for now
UserNode find(String nodeId)
{
- UserNode found = null;
- if (context.getId().equals(nodeId))
- {
- found = this;
- }
- else
- {
- Collection<UserNode> children = context.getNodes();
- if (children != null)
- {
- for (UserNode child : children)
- {
- UserNode a = child.find(nodeId);
- if (a != null)
- {
- found = a;
- break;
- }
- }
- }
- }
- return found;
+ NodeContext<UserNode> found = context.getDescendant(nodeId);
+ return found != null ? found.getNode() : null;
}
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserPortalImpl.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserPortalImpl.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/mop/user/UserPortalImpl.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -24,7 +24,7 @@
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.SiteType;
-import org.exoplatform.portal.mop.navigation.Navigation;
+import org.exoplatform.portal.mop.navigation.NavigationContext;
import org.exoplatform.portal.mop.navigation.NavigationServiceException;
import org.exoplatform.portal.mop.navigation.NavigationService;
import org.exoplatform.portal.mop.navigation.NodeFilter;
@@ -120,7 +120,7 @@
if (navigations == null)
{
List<UserNavigation> navigations = new ArrayList<UserNavigation>(userName == null ? 1 : 10);
- Navigation portalNav = navigationService.loadNavigation(new SiteKey(SiteType.PORTAL, portalName));
+ NavigationContext portalNav = navigationService.loadNavigation(new SiteKey(SiteType.PORTAL, portalName));
navigations.add(new UserNavigation(
this,
portalNav,
@@ -130,7 +130,7 @@
if (userName != null)
{
// Add user nav if any
- Navigation userNavigation = navigationService.loadNavigation(SiteKey.user(userName));
+ NavigationContext userNavigation = navigationService.loadNavigation(SiteKey.user(userName));
if (userNavigation != null && userNavigation.getState() != null)
{
navigations.add(new UserNavigation(this, userNavigation, true));
@@ -152,7 +152,7 @@
String groupId = m.getId().trim();
if (!groupId.equals(acl.getGuestsGroup()))
{
- Navigation groupNavigation = navigationService.loadNavigation(SiteKey.group(groupId));
+ NavigationContext groupNavigation = navigationService.loadNavigation(SiteKey.group(groupId));
if (groupNavigation != null && groupNavigation.getState() != null)
{
navigations.add(new UserNavigation(
@@ -195,13 +195,12 @@
public UserNode getNode(UserNavigation userNavigation, Scope scope) throws Exception
{
- return navigationService.loadNode(userNavigation.model, userNavigation.navigation, scope);
+ return navigationService.loadNode(userNavigation.model, userNavigation.navigation, scope).getNode();
}
public UserNode getNode(UserNode node, Scope scope) throws Exception
{
- UserNavigation navigation = node.navigation;
- return navigationService.loadNode(navigation.model, node, scope);
+ return navigationService.loadNode(node.context, scope).getNode();
}
private class MatchingScope implements Scope
@@ -221,7 +220,7 @@
void resolve() throws NavigationServiceException
{
- UserNode node = navigationService.loadNode(userNavigation.model, userNavigation.navigation, this);
+ UserNode node = navigationService.loadNode(userNavigation.model, userNavigation.navigation, this).getNode();
if (score > 0)
{
userNode = node.find(id);
@@ -264,10 +263,10 @@
{
for (UserNavigation userNavigation : getNavigations())
{
- Navigation navigation = userNavigation.navigation;
+ NavigationContext navigation = userNavigation.navigation;
if (navigation.getState() != null)
{
- UserNode root = navigationService.loadNode(userNavigation.model, navigation, Scope.CHILDREN);
+ UserNode root = navigationService.loadNode(userNavigation.model, navigation, Scope.CHILDREN).getNode();
for (UserNode node : root.getChildren())
{
return new NavigationPath(userNavigation, node);
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/POMDataStorage.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/POMDataStorage.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/POMDataStorage.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -27,6 +27,7 @@
import org.chromattic.api.ChromatticSession;
import org.exoplatform.commons.utils.IOUtil;
import org.exoplatform.commons.utils.LazyPageList;
+import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.portal.application.PortletPreferences;
import org.exoplatform.portal.config.Query;
@@ -251,7 +252,30 @@
Class<T> type = q.getClassType();
if (PageData.class.equals(type))
{
- return (LazyPageList<T>)new LazyPageList<PageData>(new MOPAccess.PageAccess(pomMgr, (Query<PageData>)q), 10);
+ ListAccess<PageData> pageAccess;
+ try
+ {
+ pageAccess = new MOPAccess.PageAccess(pomMgr, (Query<PageData>)q);
+ }
+ catch (IllegalArgumentException e)
+ {
+ pageAccess = new ListAccess<PageData>()
+ {
+ @Override
+ public PageData[] load(int index, int length) throws Exception, IllegalArgumentException
+ {
+ return new PageData[0];
+ }
+
+ @Override
+ public int getSize() throws Exception
+ {
+ return 0;
+ }
+
+ };
+ }
+ return (LazyPageList<T>)new LazyPageList<PageData>(pageAccess, 10);
}
else if (NavigationData.class.equals(type))
{
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/tasks/SearchTask.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/tasks/SearchTask.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/pom/config/tasks/SearchTask.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -32,6 +32,7 @@
import org.gatein.mop.api.workspace.Site;
import org.gatein.mop.api.workspace.Workspace;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@@ -126,24 +127,27 @@
public LazyPageList<PortalKey> run(final POMSession session) throws Exception
{
Workspace workspace = session.getWorkspace();
- final Collection<? extends Site> portals = workspace.getSites(ObjectType.PORTAL_SITE);
+ Collection<Site> sites = workspace.getSites(ObjectType.PORTAL_SITE);
+ final ArrayList<PortalKey> keys = new ArrayList<PortalKey>(sites.size());
+ for (Site site : sites)
+ {
+ keys.add(new PortalKey("portal", site.getName()));
+ }
ListAccess<PortalKey> la = new ListAccess<PortalKey>()
{
public PortalKey[] load(int index, int length) throws Exception, IllegalArgumentException
{
- Iterator<? extends Site> iterator = portals.iterator();
PortalKey[] result = new PortalKey[length];
for (int i = 0; i < length; i++)
{
- Site site = iterator.next();
- result[i] = new PortalKey("portal", site.getName());
+ result[i] = keys.get(index++);
}
return result;
}
public int getSize() throws Exception
{
- return portals.size();
+ return keys.size();
}
};
return new LazyPageList<PortalKey>(la, 10);
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyAdapter.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyAdapter.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyAdapter.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public interface HierarchyAdapter<L, N, H> {
+
+ H getHandle(N node);
+
+ L getChildren(N node);
+
+ N getDescendant(N node, H handle);
+
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeIterator.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeIterator.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeIterator.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class HierarchyChangeIterator<L1, N1, L2, N2, H> implements Iterator<HierarchyChangeType>
+{
+
+ /** . */
+ private final HierarchyDiff<L1, N1, L2, N2, H> diff;
+
+ /** . */
+ private Frame frame;
+
+ /** . */
+ private final HierarchyContext<L1, N1, H> context1;
+
+ /** . */
+ private final HierarchyContext<L2, N2, H> context2;
+
+ /** . */
+ private final ListDiff<L1, L2, H> listDiff;
+
+ HierarchyChangeIterator(HierarchyDiff<L1, N1, L2, N2, H> diff, HierarchyContext<L1, N1, H> context1, HierarchyContext<L2, N2, H> context2) {
+ this.diff = diff;
+ this.context1 = context1;
+ this.context2 = context2;
+ this.frame = new Frame(null, context1.getRoot(), context2.getRoot());
+ this.listDiff = new ListDiff<L1, L2, H>(
+ diff.listAdapter1,
+ diff.listAdapter2,
+ diff.comparator);
+ }
+
+ /**
+ * The internal status.
+ */
+ private enum Status {
+
+ INIT(null),
+
+ ENTER(HierarchyChangeType.ENTER),
+
+ ADDED(HierarchyChangeType.ADDED),
+
+ REMOVED(HierarchyChangeType.REMOVED),
+
+ MOVED_IN(HierarchyChangeType.MOVED_IN),
+
+ MOVED_OUT(HierarchyChangeType.MOVED_OUT),
+
+ LEAVE(HierarchyChangeType.LEAVE),
+
+ ERROR(HierarchyChangeType.ERROR),
+
+ RESUME(null);
+
+ /** The associated change type. */
+ final HierarchyChangeType changeType;
+
+ private Status(HierarchyChangeType changeType) {
+ this.changeType = changeType;
+ }
+ }
+
+ private class Frame {
+
+ /** . */
+ private final Frame parent;
+
+ /** . */
+ private final N1 srcRoot;
+
+ /** . */
+ private final N2 dstRoot;
+
+ /** . */
+ private ListChangeIterator<L1, L2, H> it;
+
+ /** . */
+ private Status previous;
+
+ /** . */
+ private Status next;
+
+ /** . */
+ private Iterator<H> srcIt;
+
+ /** . */
+ private Iterator<H> dstIt;
+
+ /** . */
+ private N1 src;
+
+ /** . */
+ private N2 dst;
+
+ private Frame(Frame parent, N1 srcRoot, N2 dstRoot) {
+ this.parent = parent;
+ this.srcRoot = srcRoot;
+ this.dstRoot = dstRoot;
+ this.previous = Status.INIT;
+ }
+ }
+
+ public boolean hasNext() {
+ if (frame != null && frame.next == null) {
+ while (true) {
+
+ if (frame.previous == Status.INIT) {
+ H id2 = context2.getHierarchyAdapter().getHandle(frame.dstRoot);
+ if (frame.srcRoot == null)
+ {
+ frame.next = Status.ENTER;
+ frame.src = null;
+ frame.dst = frame.dstRoot;
+ }
+ else
+ {
+ H id1 = context1.getHierarchyAdapter().getHandle(frame.srcRoot);
+ if (diff.comparator.compare(id1, id2) != 0) {
+ frame.next = Status.ERROR;
+ frame.src = frame.srcRoot;
+ frame.dst = frame.dstRoot;
+ } else {
+ frame.next = Status.ENTER;
+ frame.src = frame.srcRoot;
+ frame.dst = frame.dstRoot;
+ }
+ }
+ break;
+ } else if (frame.previous == Status.ERROR) {
+ break;
+ } else if (frame.previous == Status.LEAVE) {
+ frame = frame.parent;
+ if (frame != null) {
+ frame.previous = Status.RESUME;
+ continue;
+ } else {
+ break;
+ }
+ } else if (frame.previous == Status.MOVED_IN) {
+ frame = new Frame(frame, frame.src, frame.dst);
+ continue;
+ } else if (frame.previous == Status.ADDED) {
+ frame = new Frame(frame, frame.src, frame.dst);
+ continue;
+ } else if (frame.previous == Status.ENTER) {
+ L1 children1;
+ if (frame.src != null) {
+ children1 = context1.getHierarchyAdapter().getChildren(frame.srcRoot);
+ frame.srcIt = diff.listAdapter1.iterator(children1, false);
+ }
+ else {
+ children1 = null;
+ frame.srcIt = null;
+ }
+ L2 children2 = context2.getHierarchyAdapter().getChildren(frame.dstRoot);
+ frame.dstIt = diff.listAdapter2.iterator(children2, false);
+ frame.it = listDiff.iterator(children1, children2);
+ } else {
+ // Nothing
+ }
+
+ //
+ if (frame.it.hasNext()) {
+ switch (frame.it.next()) {
+ case SAME:
+ N1 next1 = context1.findByHandle(frame.srcIt.next());
+ N2 next2 = context2.findByHandle(frame.dstIt.next());
+ frame = new Frame(frame, next1, next2);
+ continue;
+ case ADD:
+ frame.dstIt.next();
+ H addedHandle = frame.it.getElement();
+ N2 added = context2.findByHandle(addedHandle);
+ H addedId = context2.getHierarchyAdapter().getHandle(added);
+ N1 a = context1.findByHandle(addedId);
+ if (a != null) {
+ frame.next = Status.MOVED_IN;
+ frame.src = a;
+ frame.dst = added;
+ } else {
+ frame.next = Status.ADDED;
+ frame.src = null;
+ frame.dst = added;
+ }
+ break;
+ case REMOVE:
+ frame.srcIt.next();
+ H removedHandle = frame.it.getElement();
+ N1 removed = context1.findByHandle(removedHandle);
+ H removedId = context1.getHierarchyAdapter().getHandle(removed);
+ N2 b = context2.findByHandle(removedId);
+ if (b != null) {
+ frame.next = Status.MOVED_OUT;
+ frame.src = removed;
+ frame.dst = b;
+ } else {
+ frame.next = Status.REMOVED;
+ frame.src = removed;
+ frame.dst = null;
+ }
+ break;
+ default:
+ throw new AssertionError();
+ }
+ } else {
+ frame.next = Status.LEAVE;
+ frame.src = frame.srcRoot;
+ frame.dst = frame.dstRoot;
+ }
+
+ //
+ break;
+ }
+ }
+ return frame != null && frame.next != null;
+ }
+
+ public HierarchyChangeType next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ } else {
+ frame.previous = frame.next;
+ frame.next = null;
+ return frame.previous.changeType;
+ }
+ }
+
+ public N1 getSource() {
+ return frame.src;
+ }
+
+ public N2 getDestination() {
+ return frame.dst;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeType.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeType.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyChangeType.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public enum HierarchyChangeType {
+
+ ENTER,
+
+ ADDED,
+
+ REMOVED,
+
+ MOVED_IN,
+
+ MOVED_OUT,
+
+ LEAVE,
+
+ ERROR
+
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyContext.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyContext.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyContext.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class HierarchyContext<L, N, H> {
+
+ /** . */
+ final ListAdapter<L, H> listAdapter;
+
+ /** . */
+ final HierarchyAdapter<L, N, H> hierarchyAdapter;
+
+ /** . */
+ final N root;
+
+ public HierarchyContext(ListAdapter<L, H> listAdapter, HierarchyAdapter<L, N, H> hierarchyAdapter, N root) throws NullPointerException {
+ if (listAdapter == null) {
+ throw new NullPointerException();
+ }
+ if (hierarchyAdapter == null) {
+ throw new NullPointerException();
+ }
+ if (root == null) {
+ throw new NullPointerException();
+ }
+
+ //
+ this.listAdapter = listAdapter;
+ this.hierarchyAdapter = hierarchyAdapter;
+ this.root = root;
+ }
+
+ public HierarchyAdapter<L, N, H> getHierarchyAdapter() {
+ return hierarchyAdapter;
+ }
+
+ public N getRoot() {
+ return root;
+ }
+
+ public N findByHandle(H handle) {
+ return hierarchyAdapter.getDescendant(root, handle);
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyDiff.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyDiff.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/HierarchyDiff.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+import java.util.Comparator;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class HierarchyDiff<L1, N1, L2, N2, H> {
+
+ /** . */
+ final ListAdapter<L1, H> listAdapter1;
+
+ /** . */
+ final HierarchyAdapter<L1, N1, H> hierarchyAdapter1;
+
+ /** . */
+ final ListAdapter<L2, H> listAdapter2;
+
+ /** . */
+ final HierarchyAdapter<L2, N2, H> hierarchyAdapter2;
+
+ /** . */
+ final Comparator<H> comparator;
+
+ public HierarchyDiff(ListAdapter<L1, H> listAdapter1, HierarchyAdapter<L1, N1, H> hierarchyAdapter1, ListAdapter<L2, H> listAdapter2, HierarchyAdapter<L2, N2, H> hierarchyAdapter2, Comparator<H> comparator) {
+ this.listAdapter1 = listAdapter1;
+ this.hierarchyAdapter1 = hierarchyAdapter1;
+ this.listAdapter2 = listAdapter2;
+ this.hierarchyAdapter2 = hierarchyAdapter2;
+ this.comparator = comparator;
+ }
+
+ public HierarchyChangeIterator<L1, N1, L2, N2, H> iterator(N1 node1, N2 node2) {
+ return new HierarchyChangeIterator<L1, N1, L2, N2, H>(this, new HierarchyContext<L1, N1, H>(listAdapter1, hierarchyAdapter1, node1), new HierarchyContext<L2, N2, H>(listAdapter2, hierarchyAdapter2, node2));
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListAdapter.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListAdapter.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListAdapter.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+import java.util.Iterator;
+
+/**
+ * An adapter for a list of elements.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public interface ListAdapter<L, E> {
+
+ /**
+ * Returns the number of list elements.
+ *
+ * @param list the list
+ * @return the list size
+ */
+ int size(L list);
+
+ /**
+ * Returns an iterator over the list elements.
+ *
+ *
+ * @param list the list
+ * @param reverse the iteration direction
+ * @return the iterator
+ */
+ Iterator<E> iterator(L list, boolean reverse);
+
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeIterator.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeIterator.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeIterator.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Iterates over a list of {@link ListChangeType} computed from two list of objects. The implementation
+ * is optimized to use the LCS algorithm only when needed, for trivial list no LCS computation should be
+ * required.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class ListChangeIterator<L1, L2, E> implements Iterator<ListChangeType>
+{
+
+ /** . */
+ private static final int[] EMPTY = new int[0];
+
+ /** . */
+ private static final int TRIVIAL_MODE = 0;
+
+ /** . */
+ private static final int LCS_MODE = 1;
+
+ /** . */
+ ListDiff<L1, L2, E> diff;
+
+ /** . */
+ private final L1 elements1;
+
+ /** . */
+ private final L2 elements2;
+
+ /** . */
+ private final Iterator<E> it1;
+
+ /** . */
+ private final Iterator<E> it2;
+
+ /** . */
+ private int index1;
+
+ /** . */
+ private int index2;
+
+ /** . */
+ private E next1;
+
+ /** . */
+ private E next2;
+
+ /** . */
+ private E element;
+
+ /** . */
+ private ListChangeType type;
+
+ /** . */
+ private int mode;
+
+ /** . */
+ private boolean buffered;
+
+ // LCS state
+
+ /** . */
+ private int[] matrix;
+
+ /** . */
+ private int m;
+
+ /** . */
+ private int n;
+
+ ListChangeIterator(ListDiff<L1, L2, E> diff, L1 elements1, L2 elements2) {
+ this.diff = diff;
+ this.elements1 = elements1;
+ this.elements2 = elements2;
+ this.it1 = elements1 != null ? diff.adapter1.iterator(elements1, false) : null;
+ this.it2 = elements2 != null ? diff.adapter2.iterator(elements2, false) : null;
+ this.mode = TRIVIAL_MODE;
+
+ //
+ this.index1 = 0;
+ this.index2 = 0;
+ this.buffered = false;
+ this.next1 = null;
+ this.next2 = null;
+ this.type = null;
+ this.element = null;
+
+ //
+ if (it1 != null && it1.hasNext()) {
+ next1 = it1.next();
+ }
+ if (it2 != null && it2.hasNext()) {
+ next2 = it2.next();
+ }
+
+ //
+ this.m = 0;
+ this.n = 0;
+ this.matrix = EMPTY;
+ }
+
+ private void next1() {
+ index1++;
+ if (it1 != null && it1.hasNext()) {
+ next1 = it1.next();
+ } else {
+ next1 = null;
+ }
+ }
+
+ private void next2() {
+ index2++;
+ if (it2 != null && it2.hasNext()) {
+ next2 = it2.next();
+ } else {
+ next2 = null;
+ }
+ }
+
+ public boolean hasNext() {
+
+ while (!buffered) {
+ if (mode == TRIVIAL_MODE) {
+ if (next1 != null) {
+ if (next2 != null) {
+ if (diff.equals(next1, next2)) {
+ type = ListChangeType.SAME;
+ element = next1;
+ buffered = true;
+ next1();
+ next2();
+ } else {
+ lcs(index1, elements1, elements2);
+ mode = LCS_MODE;
+ }
+ } else {
+ type = ListChangeType.REMOVE;
+ element = next1;
+ buffered = true;
+ next1();
+ }
+ } else {
+ if (next2 != null) {
+ type = ListChangeType.ADD;
+ element = next2;
+ buffered = true;
+ next2();
+ } else {
+ // Force a break with buffered to false
+ break;
+ }
+ }
+ } else if (mode == LCS_MODE) {
+ E elt1 = null;
+ E elt2 = null;
+ int i = diff.adapter1.size(elements1) - index1;
+ int j = diff.adapter2.size(elements2) - index2;
+ if (i > 0 && j > 0 && diff.equals(elt1 = next1, elt2 = next2)) {
+ type = ListChangeType.SAME;
+ element = elt1;
+ next1();
+ next2();
+ buffered = true;
+ } else {
+ int index1 = i + (j - 1) * m;
+ int index2 = i - 1 + j * m;
+ if (j > 0 && (i == 0 || matrix[index1] >= matrix[index2])) {
+ type = ListChangeType.ADD;
+ element = elt2 == null ? next2 : elt2;
+ next2();
+ buffered = true;
+ } else if (i > 0 && (j == 0 || matrix[index1] < matrix[index2])) {
+ type = ListChangeType.REMOVE;
+ element = elt1 == null ? next1 : elt1;
+ next1();
+ buffered = true;
+ } else {
+ // Force a break with buffered to false
+ break;
+ }
+ }
+ } else {
+ throw new AssertionError();
+ }
+ }
+
+ //
+ return buffered;
+ }
+
+ public ListChangeType next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ } else {
+ buffered = false;
+ return type;
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public E getElement() {
+ return element;
+ }
+
+ public int getIndex1() {
+ return index1;
+ }
+
+ public int getIndex2() {
+ return index2;
+ }
+
+ /**
+ * Compute the LCS matrix from the specified offset. It updates the state of this object
+ * with the relevant state. The LCS matrix is computed using the LCS algorithm
+ * (see http://en.wikipedia.org/wiki/Longest_common_subsequence_problem).
+ *
+ * @param offset the offset
+ * @param elements1 the elements 1
+ * @param elements2 the elements 2
+ */
+ private void lcs(int offset, L1 elements1, L2 elements2) {
+ m = 1 + diff.adapter1.size(elements1) - offset;
+ n = 1 + diff.adapter2.size(elements2) - offset;
+
+ //
+ int s = m * n;
+ matrix = new int[s];
+
+ // Compute the lcs matrix
+ Iterator<E> itI = diff.adapter1.iterator(elements1, true);
+ for (int i = 1; i < m; i++) {
+ E abc = itI.next();
+ Iterator<E> itJ = diff.adapter2.iterator(elements2, true);
+ for (int j = 1; j < n; j++) {
+ int index = i + j * m;
+ int v;
+ E def = itJ.next();
+ if (diff.equals(abc, def)) {
+ v = matrix[index - m - 1] + 1;
+ } else {
+ int v1 = matrix[index - 1];
+ int v2 = matrix[index - m];
+ v = v1 < v2 ? v2 : v1;
+ }
+ matrix[index] = v;
+ }
+ }
+ }
+
+ // For unit testing purpose
+ String getMatrix() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < m; i++) {
+ sb.append('[');
+ for (int j = 0; j < n; j++) {
+ if (j > 0) {
+ sb.append(',');
+ }
+ sb.append(matrix[i + j * m]);
+ }
+ sb.append("]\n");
+ }
+ return sb.toString();
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeType.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeType.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListChangeType.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public enum ListChangeType {
+
+ REMOVE,
+
+ SAME,
+
+ ADD
+
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListDiff.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListDiff.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/diff/ListDiff.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.diff;
+
+import java.util.Comparator;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class ListDiff<L1, L2, E> {
+
+ /** . */
+ final Comparator<E> comparator;
+
+ /** . */
+ final ListAdapter<L1, E> adapter1;
+
+ /** . */
+ final ListAdapter<L2, E> adapter2;
+
+ public ListDiff(ListAdapter<L1, E> adapter1, ListAdapter<L2, E> adapter2, Comparator<E> comparator) {
+ this.adapter1 = adapter1;
+ this.adapter2 = adapter2;
+ this.comparator = comparator;
+ }
+
+ public ListDiff(ListAdapter<L1, E> adapter1, ListAdapter<L2, E> adapter2) {
+ this(adapter1, adapter2, null);
+ }
+
+ boolean equals(E e1, E e2) {
+ if (comparator == null) {
+ return e1.equals(e2);
+ } else {
+ return comparator.compare(e1, e2) == 0;
+ }
+ }
+
+ public final ListChangeIterator<L1, L2, E> iterator(L1 elements1, L2 elements2) {
+ return new ListChangeIterator<L1, L2, E>(this, elements1, elements2);
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/list/ListTree.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/list/ListTree.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/main/java/org/exoplatform/portal/tree/list/ListTree.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.list;
+
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * <p>A tree structure where the children in which the children are organized as a linked list. The children of a
+ * tree is a linked list and can be iterated with an iterator or thanks to the {@link #getFirst()}, {@link #getLast()},
+ * {@link #getNext()} and {@link #getPrevious()} methods.</p>
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ * @param <T> the self bounding tree type
+ */
+public class ListTree<T extends ListTree<T>>
+{
+
+ /** . */
+ private T parent;
+
+ /** . */
+ private T next;
+
+ /** . */
+ private T previous;
+
+ /** . */
+ private T head;
+
+ /** . */
+ private T tail;
+
+ /** . */
+ private int size;
+
+ public ListTree()
+ {
+ this.next = null;
+ this.previous = null;
+ this.head = null;
+ this.tail = null;
+ this.size = 0;
+ }
+
+ /**
+ * Returns the tree.
+ *
+ * @return the tree
+ */
+ public final T getNext()
+ {
+ return next;
+ }
+
+ /**
+ * Returns the previous.
+ *
+ * @return the previous
+ */
+ public final T getPrevious()
+ {
+ return previous;
+ }
+
+ /**
+ * Returns the parent.
+ *
+ * @return the parent
+ */
+ public final T getParent()
+ {
+ return parent;
+ }
+
+ /**
+ * Returns the size.
+ *
+ * @return the size
+ */
+ public final int getSize()
+ {
+ return size;
+ }
+
+ /**
+ * Returns the first tree.
+ *
+ * @return the first tree
+ */
+ public final T getFirst()
+ {
+ return head;
+ }
+
+ /**
+ * Returns the last tree.
+ *
+ * @return the last tree
+ */
+ public final T getLast()
+ {
+ return tail;
+ }
+
+ /**
+ * Returns a tree specified by its index.
+ *
+ * @param index the index
+ * @return the corresponding tree
+ * @throws IndexOutOfBoundsException if the index is incorrect
+ */
+ public final T get(int index) throws IndexOutOfBoundsException
+ {
+ if (index < 0)
+ {
+ throw new IndexOutOfBoundsException("No negative index allowed");
+ }
+
+ //
+ T current = head;
+ while (true)
+ {
+ if (current == null)
+ {
+ throw new IndexOutOfBoundsException("index " + index + " is greater than the children size");
+ }
+ if (index == 0)
+ {
+ break;
+ }
+ else
+ {
+ current = current.next;
+ index--;
+ }
+ }
+ return current;
+ }
+
+ /**
+ * Insert the specified tree.
+ *
+ * @param index the index
+ * @param tree the tree
+ * @throws NullPointerException if the context is null
+ * @throws IllegalArgumentException if an existing child with the same name already exist
+ * @throws IndexOutOfBoundsException if the index is negative or is greater than the children size
+ */
+ public final void insertAt(Integer index, T tree) throws NullPointerException, IllegalArgumentException, IndexOutOfBoundsException
+ {
+ if (tree == null)
+ {
+ throw new NullPointerException("No null tree accepted");
+ }
+ if (index != null && index < 0)
+ {
+ throw new IndexOutOfBoundsException("No negative index permitted");
+ }
+
+ //
+ if (index != null)
+ {
+ T a = head;
+ if (index == 0)
+ {
+ insertFirst(tree);
+ }
+ else
+ {
+ while (index > 0)
+ {
+ if (a == null)
+ {
+ throw new IndexOutOfBoundsException();
+ }
+ index--;
+ a = a.next;
+ }
+
+ //
+ if (a == null)
+ {
+ insertLast(tree);
+ }
+ else if (a != tree)
+ {
+ a.insertBefore(tree);
+ }
+ }
+ }
+ else
+ {
+ T a = tail;
+ if (a == null)
+ {
+ insertFirst(tree);
+ }
+ else if (a != tree)
+ {
+ a.insertAfter(tree);
+ }
+ }
+ }
+
+ /**
+ * Insert the specified context at the last position among the children of this context.
+ *
+ * @param tree the content to insert
+ * @throws NullPointerException if the tree argument is null
+ */
+ public final void insertLast(T tree)
+ {
+ if (tail == null)
+ {
+ insertFirst(tree);
+ }
+ else
+ {
+ tail.insertAfter(tree);
+ }
+ }
+
+ /**
+ * Insert the specified context at the first position among the children of this context.
+ *
+ * @param tree the content to insert
+ * @throws NullPointerException if the tree argument is null
+ */
+ public void insertFirst(T tree) throws NullPointerException
+ {
+ if (tree == null)
+ {
+ throw new NullPointerException();
+ }
+ if (head == null)
+ {
+ beforeInsert(tree);
+ if (tree.parent != null)
+ {
+ tree.remove();
+ }
+ head = tail = tree;
+ tree.parent = (T)this;
+ size++;
+ afterInsert(tree);
+ }
+ else
+ {
+ head.insertBefore(tree);
+ }
+ }
+
+ /**
+ * Insert the specified tree after this tree
+ *
+ * @param tree the tree to insert after
+ * @throws NullPointerException if the specified tree argument is null
+ * @throws IllegalStateException if this tree does not have a parent
+ */
+ public final void insertAfter(T tree)
+ {
+ if (tree == null)
+ {
+ throw new NullPointerException("No null tree argument accepted");
+ }
+ if (parent == null)
+ {
+ throw new IllegalStateException();
+ }
+ if (this != tree)
+ {
+ parent.beforeInsert(tree);
+ if (tree.parent != null)
+ {
+ tree.remove();
+ }
+ tree.previous = (T)this;
+ tree.next = next;
+ if (next == null)
+ {
+ parent.tail = tree;
+ }
+ else
+ {
+ next.previous = tree;
+ }
+ next = tree;
+ tree.parent = parent;
+ parent.size++;
+ parent.afterInsert(tree);
+ }
+ }
+
+ /**
+ * Insert the specified tree before this tree
+ *
+ * @param tree the tree to insert before
+ * @throws NullPointerException if the specified tree argument is null
+ * @throws IllegalStateException if this tree does not have a parent
+ */
+ public final void insertBefore(T tree) throws NullPointerException, IllegalStateException
+ {
+ if (tree == null)
+ {
+ throw new NullPointerException("No null tree argument accepted");
+ }
+ if (parent == null)
+ {
+ throw new IllegalStateException();
+ }
+ if (this != tree)
+ {
+ parent.beforeInsert(tree);
+ if (tree.parent != null)
+ {
+ tree.remove();
+ }
+ tree.previous = previous;
+ tree.next = (T)this;
+ if (previous == null)
+ {
+ parent.head = tree;
+ }
+ else
+ {
+ previous.next = tree;
+ }
+ previous = tree;
+ tree.parent = parent;
+ parent.size++;
+ parent.afterInsert(tree);
+ }
+ }
+
+ /**
+ * Removes this tree from its parent
+ *
+ * @throws IllegalStateException if this tree does not have a parent
+ */
+ public final void remove() throws IllegalStateException
+ {
+ if (parent == null)
+ {
+ throw new IllegalStateException();
+ }
+ parent.beforeRemove((T)this);
+ if (previous == null)
+ {
+ parent.head = next;
+ }
+ else
+ {
+ previous.next = next;
+ }
+ if (next == null)
+ {
+ parent.tail = previous;
+ }
+ else
+ {
+ next.previous = previous;
+ }
+ T _parent = parent;
+ parent = null;
+ previous = null;
+ next = null;
+ _parent.size--;
+ _parent.afterRemove((T)this);
+ }
+
+ public final ListIterator<T> listIterator()
+ {
+/*
+ if (map == null)
+ {
+ return null;
+ }
+*/
+ return new ListIterator<T>()
+ {
+ T next = head;
+ T current = null;
+ T previous = null;
+ int index = 0;
+
+ public boolean hasNext()
+ {
+ return next != null;
+ }
+
+ public T next()
+ {
+ if (next != null)
+ {
+ current = next;
+
+ //
+ previous = next;
+ next = next.next;
+ index++;
+ return current;
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public boolean hasPrevious()
+ {
+ return previous != null;
+ }
+
+ public T previous()
+ {
+ if (previous != null)
+ {
+ current = previous;
+
+ //
+ next = previous;
+ previous = previous.previous;
+ index--;
+ return current;
+ }
+ else
+ {
+ throw new NoSuchElementException();
+ }
+ }
+
+ public int nextIndex()
+ {
+ return index;
+ }
+
+ public int previousIndex()
+ {
+ return index - 1;
+ }
+
+ public void remove()
+ {
+ if (current == null)
+ {
+ throw new IllegalStateException("no element to remove");
+ }
+ if (current == previous)
+ {
+ index--;
+ }
+ next = current.next;
+ previous = current.previous;
+ current.remove();
+ current = null;
+ }
+
+ public void set(T tree)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void add(T tree)
+ {
+ if (previous == null)
+ {
+ insertFirst(tree);
+ }
+ else
+ {
+ previous.insertAfter(tree);
+ }
+ index++;
+ previous = tree;
+ next = tree.next;
+ }
+ };
+ }
+
+ /**
+ * Callback to signal insertion occured.
+ *
+ * @param tree the child inserted
+ */
+ protected void beforeInsert(T tree)
+ {
+ }
+
+ /**
+ * Callback to signal insertion occured.
+ *
+ * @param tree the child inserted
+ */
+ protected void afterInsert(T tree)
+ {
+ }
+
+ /**
+ * Callback to signal insertion occured.
+ *
+ * @param tree the child inserted
+ */
+ protected void beforeRemove(T tree)
+ {
+ }
+
+ /**
+ * Callback to signal insertion occured.
+ *
+ * @param tree the child inserted
+ */
+ protected void afterRemove(T tree)
+ {
+ }
+}
+
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestDataStorage.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestDataStorage.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestDataStorage.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -36,6 +36,7 @@
import org.exoplatform.portal.config.model.PageNode;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.config.model.TransientApplicationState;
+import org.exoplatform.portal.mop.EventType;
import org.exoplatform.portal.pom.config.POMSessionManager;
import org.exoplatform.portal.pom.data.ModelChange;
import org.exoplatform.portal.pom.spi.gadget.Gadget;
@@ -105,9 +106,9 @@
listenerService.addListener(DataStorage.PAGE_CREATED, listener);
listenerService.addListener(DataStorage.PAGE_REMOVED, listener);
listenerService.addListener(DataStorage.PAGE_UPDATED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_CREATED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_REMOVED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_UPDATED, listener);
+ listenerService.addListener(EventType.NAVIGATION_CREATED, listener);
+ listenerService.addListener(EventType.NAVIGATION_DESTROYED, listener);
+ listenerService.addListener(EventType.NAVIGATION_UPDATED, listener);
listenerService.addListener(DataStorage.PORTAL_CONFIG_CREATED, listener);
listenerService.addListener(DataStorage.PORTAL_CONFIG_UPDATED, listener);
listenerService.addListener(DataStorage.PORTAL_CONFIG_REMOVED, listener);
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestSearch.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestSearch.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestSearch.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -59,22 +59,20 @@
super.tearDown();
}
- private void assertFound(String searchTitle, String expectedPage) throws Exception
+ private void assertPageFound(Query<Page> q, String expectedPage) throws Exception
{
- Query<Page> q = new Query<Page>(null, null, null, searchTitle, Page.class);
List<Page> res = storage.find(q).getAll();
assertEquals(1, res.size());
assertEquals(expectedPage, res.get(0).getPageId());
}
- private void assertNotFound(String searchTitle) throws Exception
+ private void assertPageNotFound(Query<Page> q) throws Exception
{
- Query<Page> q = new Query<Page>(null, null, null, searchTitle, Page.class);
List<Page> res = storage.find(q).getAll();
assertEquals(0, res.size());
}
- public void testFoo() throws Exception
+ public void testSearchPage() throws Exception
{
Page page = new Page();
page.setPageId("portal::test::searchedpage");
@@ -83,18 +81,19 @@
session.save();
//
- assertFound("Juuu Ziii", "portal::test::searchedpage");
- assertFound("Juuu", "portal::test::searchedpage");
- assertFound("Ziii", "portal::test::searchedpage");
- assertFound("juuu ziii", "portal::test::searchedpage");
- assertFound("juuu", "portal::test::searchedpage");
- assertFound("ziii", "portal::test::searchedpage");
- assertFound("juu", "portal::test::searchedpage");
- assertFound("zii", "portal::test::searchedpage");
- assertFound("ju", "portal::test::searchedpage");
- assertFound("zi", "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "Juuu Ziii", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "Juuu", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "Ziii", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "juuu ziii", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "juuu", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "ziii", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "juu", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "zii", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "ju", Page.class), "portal::test::searchedpage");
+ assertPageFound(new Query<Page>(null, null, null, "zi", Page.class), "portal::test::searchedpage");
- assertNotFound("foo");
- assertNotFound("foo bar");
+ assertPageNotFound(new Query<Page>(null, null, null, "foo", Page.class));
+ assertPageNotFound(new Query<Page>(null, null, null, "foo bar", Page.class));
+ assertPageNotFound(new Query<Page>("test", null, null, null, Page.class));
}
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestUserPortalConfigService.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestUserPortalConfigService.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/config/TestUserPortalConfigService.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -32,6 +32,8 @@
import org.exoplatform.portal.config.model.PageNavigation;
import org.exoplatform.portal.config.model.PageNode;
import org.exoplatform.portal.config.model.PortalConfig;
+import org.exoplatform.portal.mop.EventType;
+import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.pom.config.POMDataStorage;
import org.exoplatform.portal.pom.config.POMSession;
import org.exoplatform.portal.pom.config.POMSessionManager;
@@ -131,9 +133,9 @@
listenerService.addListener(DataStorage.PAGE_CREATED, listener);
listenerService.addListener(DataStorage.PAGE_REMOVED, listener);
listenerService.addListener(DataStorage.PAGE_UPDATED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_CREATED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_REMOVED, listener);
- listenerService.addListener(DataStorage.NAVIGATION_UPDATED, listener);
+ listenerService.addListener(EventType.NAVIGATION_CREATED, listener);
+ listenerService.addListener(EventType.NAVIGATION_DESTROYED, listener);
+ listenerService.addListener(EventType.NAVIGATION_UPDATED, listener);
}
}
@@ -583,10 +585,9 @@
storage_.remove(navigation);
assertEquals(1, events.size());
Event event = events.removeFirst();
- assertEquals(DataStorage.NAVIGATION_REMOVED, event.getEventName());
- PageNavigation n = ((PageNavigation)event.getData());
- assertEquals("group", n.getOwnerType());
- assertEquals("/platform/administrators", n.getOwnerId());
+ assertEquals(EventType.NAVIGATION_DESTROYED, event.getEventName());
+ SiteKey n = ((SiteKey)event.getData());
+ assertEquals(SiteKey.group("/platform/administrators"), n);
assertEquals(null, storage_.getPageNavigation("group", "/platform/administrators"));
}
}.execute(null);
@@ -607,10 +608,9 @@
storage_.create(navigation);
assertEquals(1, events.size());
Event event = events.removeFirst();
- assertEquals(DataStorage.NAVIGATION_CREATED, event.getEventName());
- PageNavigation n = ((PageNavigation)event.getData());
- assertEquals("group", n.getOwnerType());
- assertEquals("/platform/administrators", n.getOwnerId());
+ assertEquals(EventType.NAVIGATION_CREATED, event.getEventName());
+ SiteKey n = ((SiteKey)event.getData());
+ assertEquals(SiteKey.group("/platform/administrators"), n);
PageNavigation n2 = storage_.getPageNavigation("group", "/platform/administrators");
assertEquals("group", n2.getOwnerType());
assertEquals("/platform/administrators", n2.getOwnerId());
@@ -692,11 +692,9 @@
storage_.save(navigation);
assertEquals(1, events.size());
Event event = events.removeFirst();
- assertEquals(DataStorage.NAVIGATION_UPDATED, event.getEventName());
- PageNavigation n = ((PageNavigation)event.getData());
- assertEquals("group", n.getOwnerType());
- assertEquals("/platform/administrators", n.getOwnerId());
- assertEquals(3, n.getPriority());
+ assertEquals(EventType.NAVIGATION_UPDATED, event.getEventName());
+ SiteKey n = ((SiteKey)event.getData());
+ assertEquals(SiteKey.group("/platform/administrators"), n);
PageNavigation n2 = storage_.getPageNavigation("group", "/platform/administrators");
assertEquals("group", n2.getOwnerType());
assertEquals("/platform/administrators", n2.getOwnerId());
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/AbstractTestNavigationService.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/AbstractTestNavigationService.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/AbstractTestNavigationService.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import junit.framework.AssertionFailedError;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.portal.config.AbstractPortalTest;
+import org.exoplatform.portal.config.DataStorage;
+import org.exoplatform.portal.pom.config.POMSessionManager;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public abstract class AbstractTestNavigationService extends AbstractPortalTest
+{
+
+ /** . */
+ protected POMSessionManager mgr;
+
+ /** . */
+ protected NavigationServiceImpl service;
+
+ /** . */
+ protected DataStorage dataStorage;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ //
+ PortalContainer container = PortalContainer.getInstance();
+ mgr = (POMSessionManager)container.getComponentInstanceOfType(POMSessionManager.class);
+ service = new NavigationServiceImpl(mgr);
+ dataStorage = (DataStorage)container.getComponentInstanceOfType(DataStorage.class);
+ //
+ begin();
+ }
+
+ protected void sync()
+ {
+ end();
+ begin();
+ }
+
+ protected void sync(boolean save)
+ {
+ end(save);
+ begin();
+ }
+
+ @Override
+ protected void end(boolean save)
+ {
+ if (save)
+ {
+ try
+ {
+ startService();
+ super.end(save);
+ }
+ finally
+ {
+ stopService();
+ }
+ }
+ else
+ {
+ super.end(save);
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception
+ {
+ end();
+ super.tearDown();
+ }
+
+ private void startService()
+ {
+ try
+ {
+ begin();
+ service.start();
+ end();
+ }
+ catch (Exception e)
+ {
+ AssertionFailedError afe = new AssertionFailedError();
+ afe.initCause(e);
+ throw afe;
+ }
+ }
+
+ private void stopService()
+ {
+ begin();
+ service.stop();
+ end();
+ }
+}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/Node.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/Node.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/Node.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,7 +19,12 @@
package org.exoplatform.portal.mop.navigation;
+import junit.framework.Assert;
+
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
/**
* Represents a navigation node.
@@ -104,37 +109,139 @@
public void addChild(Node child)
{
- context.addNode(MODEL, null, child);
+ context.addNode(null, child);
}
public void addChild(int index, Node child)
{
- context.addNode(MODEL, index, child);
+ context.addNode(index, child);
}
public Node addChild(String childName)
{
- return context.addNode(MODEL, childName);
+ return context.addNode(null, childName);
}
+ public Node addChild(int index, String childName)
+ {
+ return context.addNode(index, childName);
+ }
+
public boolean removeChild(String childName)
{
- return context.removeNode(MODEL, childName);
+ return context.removeNode(childName);
}
- public int getChildrenCount()
+ public int getNodeCount()
{
return context.getNodeCount();
}
+ public int getSize()
+ {
+ return context.getSize();
+ }
+
+ public void setHidden(boolean hidden)
+ {
+ context.setHidden(hidden);
+ }
+
+ public boolean isHidden()
+ {
+ return context.isHidden();
+ }
+
public void filter(NodeFilter filter)
{
context.filter(filter);
}
+ public void assertConsistent()
+ {
+ if (context.hasContexts())
+ {
+ List<String> a = new ArrayList<String>();
+ for (NodeContext<Node> b = context.getFirst();b != null;b = b.getNext()) {
+ Assert.assertNotNull(b.data);
+ a.add(b.data.getId());
+ }
+ List<String> b = Arrays.asList(context.data.children);
+ Assert.assertEquals(a, b);
+ for (NodeContext<Node> c = context.getFirst();c != null;c = c.getNext()) {
+ c.getNode().assertConsistent();
+ }
+ }
+ }
+
+ public void assertEquals(Node node) {
+
+ // First check state
+ if (context.data != null) {
+ Assert.assertNotNull(node.context.data);
+ Assert.assertEquals(context.data.id, node.context.data.id);
+ Assert.assertEquals(context.data.name, node.context.data.name);
+ Assert.assertEquals(context.data.state, node.context.data.state);
+ Assert.assertEquals(context.state, node.context.state);
+ } else {
+ Assert.assertNull(node.context.data);
+ Assert.assertEquals(context.getName(), node.context.getName());
+ Assert.assertEquals(context.state, node.context.state);
+ }
+
+ //
+ List<Node> nodes1 = new ArrayList<Node>();
+ for (NodeContext<Node> current = context.getFirst();current != null;current = current.getNext()) {
+ nodes1.add(current.getNode());
+ }
+
+ //
+ List<Node> nodes2 = new ArrayList<Node>();
+ for (NodeContext<Node> current = node.context.getFirst();current != null;current = current.getNext()) {
+ nodes2.add(current.getNode());
+ }
+
+ //
+ Assert.assertEquals("Was expecting to have the same children for node " + toString(1) + " " + node.toString(1), nodes1.size(), nodes2.size());
+
+ //
+ for (int i = 0;i < nodes1.size();i++) {
+ nodes1.get(i).assertEquals(nodes2.get(i));
+ }
+ }
+
@Override
public String toString()
{
- return "Node[" + context.getName() + "]";
+ StringBuilder sb = new StringBuilder();
+ toString(1, sb);
+ return sb.toString();
}
+
+ public String toString(int depth)
+ {
+ StringBuilder sb = new StringBuilder();
+ toString(depth, sb);
+ return sb.toString();
+ }
+
+ private void toString(int depth, StringBuilder sb)
+ {
+ if (depth < 0) {
+ throw new IllegalArgumentException("Depth cannot be negative " + depth);
+ }
+ sb.append("Node[id=").append(getId()).append(",name=").append(getName());
+ if (context.hasContexts() && depth > 0) {
+ sb.append(",children={");
+ for (Node node : context.getNodes()) {
+ if (node.context.getPrevious() != null) {
+ sb.append(',');
+ }
+ node.toString(depth - 1, sb);
+ }
+ sb.append("}");
+ } else {
+ sb.append("]");
+ }
+ }
}
Deleted: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestListTree.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestListTree.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestListTree.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,896 +0,0 @@
-/*
- * Copyright (C) 2010 eXo Platform SAS.
- *
- * 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.exoplatform.portal.mop.navigation;
-
-import junit.framework.TestCase;
-import org.exoplatform.portal.mop.navigation.ListTree;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
- * @version $Revision$
- */
-public class TestListTree extends TestCase
-{
-
- public static class IntegerTree extends ListTree<IntegerTree, Integer>
- {
-
- /** . */
- private final int value;
-
- public IntegerTree(int value, String name)
- {
- super(name);
-
- //
- this.value = value;
- }
-
- @Override
- public Integer getElement()
- {
- return value;
- }
- }
-
- private static IntegerTree hidden(String name, int value, IntegerTree... trees)
- {
- IntegerTree tree = shown(name, value, trees);
- tree.setHidden(true);
- return tree;
- }
-
- private static IntegerTree shown(String name, int value, IntegerTree... trees)
- {
- IntegerTree tree = new IntegerTree(value, name);
- if (trees != null)
- {
- tree.setTrees(Arrays.asList(trees));
- }
- return tree;
- }
-
- private void assertChildren(IntegerTree tree, Integer... expected)
- {
- List<Integer> children = new ArrayList<Integer>();
- for (int child : tree)
- {
- children.add(child);
- }
- assertEquals(Arrays.asList(expected), children);
- }
-
- private void assertAllChildren(IntegerTree tree, Integer... expected)
- {
- List<Integer> children = new ArrayList<Integer>();
- for (IntegerTree child : tree.getTrees())
- {
- children.add(child.getElement());
- }
- assertEquals(Arrays.asList(expected), children);
- }
-
- private void assertAllChildren(IntegerTree tree)
- {
- assertAllChildren(tree, new Integer[0]);
- assertAllChildren(tree, new String[0]);
- }
-
- private void assertAllChildren(IntegerTree tree, String... expected)
- {
- List<String> children = new ArrayList<String>();
- for (IntegerTree child : tree.getTrees())
- {
- children.add(child.getName());
- }
- assertEquals(Arrays.asList(expected), children);
- }
-
- public void testInsert1()
- {
- IntegerTree root = shown("", 0);
- assertChildren(root);
- assertAllChildren(root);
-
- //
- root = shown("", 0);
- root.insert(0, shown("a", 1));
- assertChildren(root, 1);
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
-
- //
- root = shown("", 0);
- root.insert(null, shown("a", 1));
- assertChildren(root, 1);
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
- }
-
- public void testInsert2()
- {
- IntegerTree root = shown("", 0, hidden("a", 1));
- assertChildren(root);
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
-
- //
- root = shown("", 0, hidden("a", 1));
- root.insert(0, shown("b", 2));
- assertChildren(root, 2);
- assertAllChildren(root, 2, 1);
- assertAllChildren(root, "b", "a");
-
- //
- root = shown("", 0, hidden("a", 1));
- root.insert(null, shown("b", 2));
- assertChildren(root, 2);
- assertAllChildren(root, 2, 1);
- assertAllChildren(root, "b", "a");
- }
-
- public void testInsert3()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2));
- assertChildren(root, 1);
- assertAllChildren(root, 1, 2);
- assertAllChildren(root, "a", "b");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2));
- root.insert(0, shown("c", 3));
- assertChildren(root, 3, 1);
- assertAllChildren(root, 3, 1, 2);
- assertAllChildren(root, "c", "a", "b");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2));
- root.insert(1, shown("c", 3));
- assertChildren(root, 1, 3);
- assertAllChildren(root, 1, 3, 2);
- assertAllChildren(root, "a", "c", "b");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2));
- root.insert(null, shown("c", 3));
- assertChildren(root, 1, 3);
- assertAllChildren(root, 1, 3, 2);
- assertAllChildren(root, "a", "c", "b");
- }
-
- public void testInsert4()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertChildren(root, 1, 3);
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- root.insert(0, shown("d", 4));
- assertChildren(root, 4, 1, 3);
- assertAllChildren(root, 4, 1, 2, 3);
- assertAllChildren(root, "d", "a", "b", "c");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- root.insert(1, shown("d", 4));
- assertChildren(root, 1, 4, 3);
- assertAllChildren(root, 1, 4, 2, 3);
- assertAllChildren(root, "a", "d", "b", "c");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- root.insert(2, shown("d", 4));
- assertChildren(root, 1, 3, 4);
- assertAllChildren(root, 1, 2, 3, 4);
- assertAllChildren(root, "a", "b", "c", "d");
-
- //
- root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- root.insert(null, shown("d", 4));
- assertChildren(root, 1, 3, 4);
- assertAllChildren(root, 1, 2, 3, 4);
- assertAllChildren(root, "a", "b", "c", "d");
- }
-
- public void testInsertDuplicate()
- {
- IntegerTree root = shown("", 0, shown("a", 1));
- assertChildren(root, 1);
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
-
- //
- try
- {
- root.insert(0, shown("a", 2));
- fail();
- }
- catch (IllegalArgumentException ignore)
- {
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
- }
- }
-
- public void testInsertWithNoChildren()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
- assertFalse(root.hasTrees());
-
- //
- try
- {
- root.insert(0, shown("a", 1));
- fail();
- }
- catch (IllegalStateException ignore)
- {
- assertFalse(root.hasTrees());
- }
- }
-
- public void testInsertMove1()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree b = shown("b", 2);
- IntegerTree root1 = shown("", 0, a, b);
-
- //
- root1.insert(0, b);
- assertAllChildren(root1, 2, 1);
- }
-
- public void testInsertMove2()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree root1 = shown("", 0, a);
-
- //
- root1.insert(null, a);
- assertAllChildren(root1, 1);
-
- //
- root1.insert(0, a);
- assertAllChildren(root1, 1);
- }
-
- public void testInsertMove3()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree root1 = shown("", 0, a);
- IntegerTree root2 = shown("", 0);
-
- //
- root2.insert(0, a);
- assertAllChildren(root1);
- assertAllChildren(root2, 1);
- assertAllChildren(root2, "a");
- assertSame(root2, a.getParent());
- }
-
- public void testInsertReorder1()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree root1 = shown("", 0, a);
-
- //
- root1.insert(0, a);
- assertAllChildren(root1, 1);
- assertAllChildren(root1, "a");
- assertSame(root1, a.getParent());
- }
-
- public void testInsertReorder2()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree root1 = shown("", 0, a, shown("b", 2));
-
- //
- root1.insert(2, a);
- assertAllChildren(root1, 2, 1);
- assertAllChildren(root1, "b", "a");
- assertSame(root1, a.getParent());
-
- //
- root1.insert(0, a);
- assertAllChildren(root1, 1, 2);
- assertAllChildren(root1, "a", "b");
- assertSame(root1, a.getParent());
- }
-
- public void testGetByKey()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- assertEquals(1, (int)root.get("a").getElement());
- assertNull(root.get("b"));
- assertNull(root.get("d"));
- }
-
- public void testGetByKeyWithNoChildren()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
- assertFalse(root.hasTrees());
-
- //
- try
- {
- root.get("a");
- fail();
- }
- catch (IllegalStateException ignore)
- {
- assertFalse(root.hasTrees());
- }
- }
-
- public void testRemove()
- {
- IntegerTree root = shown("", 0, hidden("a", 1), shown("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- assertNull(root.remove("a"));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- IntegerTree b = root.remove("b");
- assertNull(b.getParent());
- assertNull(b.getPrevious());
- assertNull(b.getNext());
- assertEquals(2, (int)b.getElement());
- assertAllChildren(root, 1, 3);
- assertAllChildren(root, "a", "c");
- }
-
- public void testRemoveLast()
- {
- IntegerTree root = shown("", 0, shown("a", 1), shown("b", 2));
- assertAllChildren(root, 1, 2);
- assertAllChildren(root, "a", "b");
-
- //
- assertEquals(2, (int)root.remove("b").getElement());
- assertAllChildren(root, 1);
- assertAllChildren(root, "a");
- assertEquals(1, (int)root.getLast().getElement());
- }
-
- public void testRemoveWithNoChildren()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
- assertFalse(root.hasTrees());
-
- //
- try
- {
- root.remove("a");
- fail();
- }
- catch (IllegalStateException ignore)
- {
- assertFalse(root.hasTrees());
- }
- }
-
- public void testRename()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- root.rename("a", "a");
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- root.rename("a", "d");
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "d", "b", "c");
- }
-
- public void testRenameWithNoChildren()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
- assertFalse(root.hasTrees());
-
- //
- try
- {
- root.rename("a", "b");
- fail();
- }
- catch (IllegalStateException e)
- {
- assertFalse(root.hasTrees());
- }
- }
-
- public void testRenameWithNonExisting()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- try
- {
- root.rename("d", "e");
- fail();
- }
- catch (IllegalArgumentException e)
- {
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
- }
- }
-
- public void testRenameWithExisting()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- try
- {
- root.rename("a", "c");
- fail();
- }
- catch (IllegalArgumentException e)
- {
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
- }
- }
-
- public void testRenameHidden()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
-
- //
- try
- {
- root.rename("b", "d");
- fail();
- }
- catch (IllegalArgumentException e)
- {
- assertAllChildren(root, 1, 2, 3);
- assertAllChildren(root, "a", "b", "c");
- }
- }
-
- public void testGetByIndex1()
- {
- IntegerTree root = shown("", 0, shown("a", 1), hidden("b", 2), shown("c", 3));
-
- //
- assertEquals(1, (int)root.get(0).getElement());
- assertEquals(3, (int)root.get(1).getElement());
- try
- {
- root.get(2);
- fail();
- }
- catch (IndexOutOfBoundsException e)
- {
- }
- }
-
- public void testGetByIndex2()
- {
- IntegerTree root = shown("", 0, hidden("a", 1), shown("b", 2), hidden("c", 3));
-
- //
- assertEquals(2, (int)root.get(0).getElement());
- try
- {
- root.get(1);
- fail();
- }
- catch (IndexOutOfBoundsException e)
- {
- }
- }
-
- public void testGetByIndexWithNoChildren()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
-
- //
- try
- {
- root.get(0);
- fail();
- }
- catch (IllegalStateException e)
- {
- }
- }
-
- public void testIteratorRemove()
- {
- IntegerTree root = shown("", 0, shown("a", 1));
- Iterator<IntegerTree> it = root.getTrees().iterator();
-
- //
- try
- {
- it.remove();
- fail();
- }
- catch (IllegalStateException e)
- {
- }
-
- //
- IntegerTree a = it.next();
- it.remove();
- assertNull(a.getParent());
- assertFalse(it.hasNext());
- assertAllChildren(root);
- }
-
- public void testListIterator1()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree root = shown("", 0, a);
-
- //
- ListIterator<IntegerTree> i = root.listIterator();
- assertTrue(i.hasNext());
- assertEquals(0, i.nextIndex());
- assertFalse(i.hasPrevious());
- assertEquals(-1, i.previousIndex());
-
- //
- assertSame(a, i.next());
- assertFalse(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
-
- //
- assertSame(a, i.previous());
- assertTrue(i.hasNext());
- assertEquals(0, i.nextIndex());
- assertFalse(i.hasPrevious());
- assertEquals(-1, i.previousIndex());
- }
-
- public void testListIterator2()
- {
- IntegerTree a = shown("a", 1);
- IntegerTree b = shown("b", 2);
- IntegerTree root = shown("", 0, a, b);
-
- //
- ListIterator<IntegerTree> i = root.listIterator();
- assertTrue(i.hasNext());
- assertEquals(0, i.nextIndex());
- assertFalse(i.hasPrevious());
- assertEquals(-1, i.previousIndex());
- assertSame(a, i.next());
- assertTrue(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- assertSame(b, i.next());
- assertFalse(i.hasNext());
- assertEquals(2, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(1, i.previousIndex());
- i.remove();
- assertFalse(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- }
-
- public void testListIterator3()
- {
- // Remove middle
- IntegerTree a = shown("a", 1);
- IntegerTree b = shown("b", 2);
- IntegerTree c = shown("c", 3);
- IntegerTree root = shown("", 0, a, b, c);
- ListIterator<IntegerTree> i = root.listIterator();
- i.next();
- i.next();
- i.remove();
- assertTrue(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- assertSame(c, i.next());
-
- // Remove middle
- root = shown("", 0, a = shown("a", 1), b = shown("b", 2), c = shown("c", 3));
- i = root.listIterator();
- i.next();
- i.next();
- i.next();
- i.previous();
- i.previous();
- i.remove();
- assertTrue(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- assertSame(c, i.next());
-
- // Remove middle
- root = shown("", 0, a = shown("a", 1), b = shown("b", 2), c = shown("c", 3));
- i = root.listIterator();
- i.next();
- i.next();
- i.remove();
- assertTrue(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- assertSame(a, i.previous());
-
- // Remove middle
- root = shown("", 0, a = shown("a", 1), b = shown("b", 2), c = shown("c", 3));
- i = root.listIterator();
- i.next();
- i.next();
- i.next();
- i.previous();
- i.previous();
- i.remove();
- assertTrue(i.hasNext());
- assertEquals(1, i.nextIndex());
- assertTrue(i.hasPrevious());
- assertEquals(0, i.previousIndex());
- assertSame(a, i.previous());
- }
-
- public void testCount()
- {
- IntegerTree root = shown("", 0, (IntegerTree[])null);
- assertEquals(-1, root.getCount());
- IntegerTree a = shown("a", 1);
- root.setTrees(Collections.singleton(a));
- assertEquals(1, root.getCount());
- a.setHidden(true);
- assertEquals(0, root.getCount());
- a.remove("a");
- assertEquals(0, root.getCount());
- root.setTrees(null);
- assertEquals(-1, root.getCount());
- }
-
-
- @SuppressWarnings("unchecked")
- public void testListIteratorNavigation()
- {
- IntegerTree root = shown("", 0, shown("1", 1), shown("2", 2), shown("3", 3), shown("4", 4), shown("5", 5));
- ListIterator<IntegerTree> it = root.listIterator();
- assertTrue(it.hasNext());
- assertTrue(!it.hasPrevious());
- assertEquals(-1, it.previousIndex());
- assertEquals(0, it.nextIndex());
- assertEquals(1, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- assertEquals(1, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(!it.hasPrevious());
- assertEquals(-1, it.previousIndex());
- assertEquals(0, it.nextIndex());
- assertEquals(1, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- assertEquals(2, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertEquals(2, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- assertEquals(2, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertEquals(3, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(2, it.previousIndex());
- assertEquals(3, it.nextIndex());
- assertEquals(4, it.next().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(3, it.previousIndex());
- assertEquals(4, it.nextIndex());
- assertEquals(5, it.next().value);
- assertTrue(!it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(4, it.previousIndex());
- assertEquals(5, it.nextIndex());
- assertEquals(5, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(3, it.previousIndex());
- assertEquals(4, it.nextIndex());
- assertEquals(4, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(2, it.previousIndex());
- assertEquals(3, it.nextIndex());
- assertEquals(3, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertEquals(2, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(it.hasPrevious());
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- assertEquals(1, it.previous().value);
- assertTrue(it.hasNext());
- assertTrue(!it.hasPrevious());
- assertEquals(-1, it.previousIndex());
- assertEquals(0, it.nextIndex());
- }
-
- /*
- @Override
- @SuppressWarnings("unchecked")
- public void testListIteratorSet() {
- list.add((E) "1");
- list.add((E) "2");
- list.add((E) "3");
- list.add((E) "4");
- list.add((E) "5");
-
- ListIterator<E> it = list.listIterator();
- assertEquals("1", it.next());
- it.set((E) "a");
- assertEquals("a", it.previous());
- it.set((E) "A");
- assertEquals("A", it.next());
- assertEquals("2", it.next());
- it.set((E) "B");
- assertEquals("3", it.next());
- assertEquals("4", it.next());
- it.set((E) "D");
- assertEquals("5", it.next());
- it.set((E) "E");
- assertEquals("[A, B, 3, D, E]", list.toString());
- }
- */
-
- public void testListIteratorRemove()
- {
- IntegerTree root = shown("", 0, shown("1", 1), shown("2", 2), shown("3", 3), shown("4", 4), shown("5", 5));
- ListIterator<IntegerTree> it = root.listIterator();
- try
- {
- it.remove();
- fail();
- }
- catch (IllegalStateException e)
- {
- // expected
- }
- assertEquals(1, it.next().value);
- assertEquals(2, it.next().value);
- assertAllChildren(root, 1, 2, 3, 4, 5);
- it.remove();
- assertAllChildren(root, 1, 3, 4, 5);
- assertEquals(3, it.next().value);
- assertEquals(3, it.previous().value);
- assertEquals(1, it.previous().value);
- it.remove();
- assertAllChildren(root, 3, 4, 5);
- assertTrue(!it.hasPrevious());
- assertEquals(3, it.next().value);
- it.remove();
- assertAllChildren(root, 4, 5);
- try
- {
- it.remove();
- fail();
- }
- catch (IllegalStateException e)
- {
- // expected
- }
- assertEquals(4, it.next().value);
- assertEquals(5, it.next().value);
- it.remove();
- assertAllChildren(root, 4);
- assertEquals(4, it.previous().value);
- it.remove();
- assertAllChildren(root);
- }
-
- public void testListIteratorAdd()
- {
- IntegerTree root = shown("", 0);
- ListIterator<IntegerTree> it = root.listIterator();
- it.add(shown("a", 1));
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- assertAllChildren(root, 1);
- it.add(shown("c", 3));
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertAllChildren(root, 1, 3);
- it.add(shown("e", 5));
- assertEquals(2, it.previousIndex());
- assertEquals(3, it.nextIndex());
- assertAllChildren(root, 1, 3, 5);
- assertEquals(5, it.previous().value);
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- it.add(shown("d", 4));
- assertEquals(2, it.previousIndex());
- assertEquals(3, it.nextIndex());
- assertAllChildren(root, 1, 3, 4, 5);
- assertEquals(4, it.previous().value);
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertEquals(3, it.previous().value);
- assertEquals(0, it.previousIndex());
- assertEquals(1, it.nextIndex());
- it.add(shown("b", 2));
- assertEquals(1, it.previousIndex());
- assertEquals(2, it.nextIndex());
- assertAllChildren(root, 1, 2, 3, 4, 5);
- }
-
- public void testListIteratorMove()
- {
- IntegerTree root = shown("", 0, shown("a", 1), shown("b", 2), shown("c", 3));
- ListIterator<IntegerTree> it = root.listIterator();
- it.add(root.get(2));
- assertAllChildren(root, 3, 1, 2);
- }
-}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationService.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationService.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationService.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,18 +19,14 @@
package org.exoplatform.portal.mop.navigation;
-import junit.framework.AssertionFailedError;
-import org.exoplatform.container.PortalContainer;
-import org.exoplatform.portal.config.AbstractPortalTest;
-import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.model.PageNavigation;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.Described;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.mop.Visibility;
-import org.exoplatform.portal.pom.config.POMSessionManager;
import org.exoplatform.portal.pom.data.MappedAttributes;
+import org.gatein.mop.api.workspace.Navigation;
import org.gatein.mop.api.workspace.ObjectType;
import org.gatein.mop.api.workspace.Site;
import org.gatein.mop.core.api.MOPService;
@@ -43,83 +39,9 @@
* @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
* @version $Revision$
*/
-public class TestNavigationService extends AbstractPortalTest
+public class TestNavigationService extends AbstractTestNavigationService
{
- /** . */
- private POMSessionManager mgr;
-
- /** . */
- private NavigationServiceImpl service;
-
- private DataStorage dataStorage;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
-
- //
- PortalContainer container = PortalContainer.getInstance();
- mgr = (POMSessionManager)container.getComponentInstanceOfType(POMSessionManager.class);
- service = new NavigationServiceImpl(mgr);
- dataStorage = (DataStorage)container.getComponentInstanceOfType(DataStorage.class);
- //
- begin();
- }
-
-
- @Override
- protected void end(boolean save)
- {
- if (save)
- {
- try
- {
- startService();
- super.end(save);
- }
- finally
- {
- stopService();
- }
- }
- else
- {
- super.end(save);
- }
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- end();
- super.tearDown();
- }
-
- private void startService()
- {
- try
- {
- begin();
- service.start();
- end();
- }
- catch (Exception e)
- {
- AssertionFailedError afe = new AssertionFailedError();
- afe.initCause(e);
- throw afe;
- }
- }
-
- private void stopService()
- {
- begin();
- service.stop();
- end();
- }
-
public void testNonExistingSite() throws Exception
{
assertNull(service.loadNavigation(SiteKey.portal("non_existing")));
@@ -128,147 +50,107 @@
public void testNavigationInvalidationByRootId() throws Exception
{
mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "get_navigation");
- end(true);
//
- begin();
+ sync(true);
+
+ //
SiteKey key = new SiteKey(SiteType.PORTAL, "get_navigation");
- Navigation nav = service.loadNavigation(key);
+ NavigationContext nav = service.loadNavigation(key);
assertNotNull(nav);
assertEquals(key, nav.getKey());
- assertNull(nav.getState());
- end();
+ assertNull(nav.state);
//
- begin();
+ sync();
+
+ //
mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "get_navigation").getRootNavigation().addChild("default");
- end(true);
//
- begin();
+ sync(true);
+
nav = service.loadNavigation(key);
assertNotNull(nav);
- assertEquals(1, (int)nav.getState().getPriority());
+ assertEquals(1, (int)nav.state.getPriority());
assertEquals(key, nav.getKey());
- assertNotNull(nav.getRootId());
- end();
+ assertNotNull(nav.rootId);
//
- begin();
+ sync();
+
+ //
mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "get_navigation").getRootNavigation().getChild("default").destroy();
- end(true);
//
- begin();
+ sync(true);
+
+ //
nav = service.loadNavigation(key);
assertNotNull(nav);
assertEquals(key, nav.getKey());
- assertNull(nav.getState());
+ assertNull(nav.state);
}
public void testNavigationInvalidationByPriority()
{
mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "invalidation_by_priority_change").getRootNavigation().addChild("default");
- end(true);
//
- begin();
+ sync(true);
+
+ //
SiteKey key = new SiteKey(SiteType.PORTAL, "invalidation_by_priority_change");
- Navigation nav = service.loadNavigation(key);
- assertEquals(1, (int)nav.getState().getPriority());
- end();
+ NavigationContext nav = service.loadNavigation(key);
+ assertEquals(1, (int)nav.state.getPriority());
//
- begin();
+ sync();
+
+ //
Site site = mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_priority_change");
site.getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.PRIORITY, 2);
- end(true);
//
- begin();
- nav = service.loadNavigation(key);
- assertEquals(2, (int)nav.getState().getPriority());
- end();
+ sync(true);
//
- begin();
- site = mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_priority_change");
- site.getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.PRIORITY, 4);
- end(true);
+ nav = service.loadNavigation(key);
+ assertEquals(2, (int)nav.state.getPriority());
//
- begin();
- nav = service.loadNavigation(key);
- assertEquals(4, (int)nav.getState().getPriority());
- end();
+ sync();
//
- begin();
site = mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_priority_change");
- site.getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.PRIORITY, null);
- end(true);
+ site.getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.PRIORITY, 4);
//
- begin();
- nav = service.loadNavigation(key);
- assertEquals(1, (int)nav.getState().getPriority());
- }
+ sync(true);
- public void testSaveNavigation() throws Exception
- {
- Navigation nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNull(nav);
-
//
- mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_navigation");
- end(true);
+ nav = service.loadNavigation(key);
+ assertEquals(4, (int)nav.state.getPriority());
//
- begin();
- nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNotNull(nav);
- assertEquals(SiteKey.portal("save_navigation"), nav.getKey());
- assertNull(nav.getState());
- assertNull(nav.getRootId());
+ sync();
//
- assertTrue(service.saveNavigation(nav.getKey(), new NavigationState(5)));
- nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNotNull(nav.getState());
- assertEquals(5, nav.getState().getPriority().intValue());
- end(true);
-
- //
- begin();
- nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNotNull(nav);
- assertEquals(SiteKey.portal("save_navigation"), nav.getKey());
- assertEquals(5, (int)nav.getState().getPriority());
- assertNotNull(nav.getRootId());
+ site = mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_priority_change");
+ site.getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.PRIORITY, null);
//
- assertTrue(service.saveNavigation(nav.getKey(), null));
- nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNull(nav.getState());
- assertNull(nav.getRootId());
- end(true);
+ sync(true);
//
- begin();
- nav = service.loadNavigation(SiteKey.portal("save_navigation"));
- assertNotNull(nav);
- assertNull(nav.getState());
- assertNull(nav.getRootId());
-
- //
- assertFalse(service.saveNavigation(nav.getKey(), null));
+ nav = service.loadNavigation(key);
+ assertEquals(1, (int)nav.state.getPriority());
}
-
public void testLoadSingleScope() throws Exception
{
- Navigation nav = service.loadNavigation(SiteKey.portal("classic"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("classic"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertNull(root.getChildren());
assertEquals("default", root.getName());
try
@@ -279,12 +161,36 @@
catch (IllegalStateException ignore)
{
}
+ try
+ {
+ root.addChild("a");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ try
+ {
+ root.addChild(0, "a");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ try
+ {
+ root.removeChild("a");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
}
public void testLoadChildrenScope() throws Exception
{
- Navigation nav = service.loadNavigation(SiteKey.portal("classic"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("classic"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
assertEquals("default", root.getName());
Iterator<? extends Node> i = root.getChildren().iterator();
assertTrue(i.hasNext());
@@ -302,7 +208,7 @@
public void testLoadCustomScope() throws Exception
{
- Navigation nav = service.loadNavigation(SiteKey.portal("large"));
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("large"));
Node root = service.loadNode(Node.MODEL, nav, new Scope()
{
public Visitor get()
@@ -328,7 +234,7 @@
}
};
}
- });
+ }).getNode();
assertNull(root.getChild("a").getChildren());
Node b = root.getChild("b");
Node d = b.getChild("d");
@@ -337,18 +243,18 @@
public void testLoadNode() throws Exception
{
- Navigation nav = service.loadNavigation(SiteKey.portal("large"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("large"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
Node a = root.getChild("a");
assertNotNull(a);
assertNull(a.getChildren());
- assertSame(a, service.loadNode(Node.MODEL, a, Scope.CHILDREN));
+ service.updateNode(a.context, Scope.CHILDREN);
assertNotNull(a.getChildren());
assertEquals(1, a.getChildren().size());
Node c = a.getChild("c");
assertEquals("c", c.getName());
assertSame(a, c.getParent());
- assertSame(a, service.loadNode(Node.MODEL, a, Scope.SINGLE));
+ service.loadNode(a.context, Scope.SINGLE);
assertNotNull(a.getChildren());
assertEquals(1, a.getChildren().size());
assertSame(c, a.getChild("c"));
@@ -357,9 +263,9 @@
public void testState() throws Exception
{
- Navigation nav = service.loadNavigation(SiteKey.portal("test"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- assertEquals(5, root.getChildrenCount());
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("test"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ assertEquals(5, root.getNodeCount());
Node child1 = root.getChild("node_name");
Node child2 = root.getChild("node_name4");
assertEquals("node_name", child1.getName());
@@ -380,61 +286,317 @@
{
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "hidden_node");
- org.gatein.mop.api.workspace.Navigation defaultNav = portal.getRootNavigation().addChild("default");
+ Navigation defaultNav = portal.getRootNavigation().addChild("default");
defaultNav.addChild("a");
defaultNav.addChild("b");
- end(true);
+ defaultNav.addChild("c");
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("hidden_node"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- root.filter(new NodeFilter()
- {
- public boolean accept(int depth, String id, String name, NodeState state)
- {
- return !(depth == 1 && "a".equals(name));
- }
- });
+ sync(true);
//
- assertEquals(1, root.getChildren().size());
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("hidden_node"));
+
+ //
+ Node root;
+ Node a;
+ Node b;
+ Node c;
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.GRANDCHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ a.setHidden(true);
+ assertEquals(2, root.getChildren().size());
assertNull(root.getChild("a"));
assertEquals("b", root.getChild(0).getName());
try
{
- root.getChild(1);
+ root.getChild(2);
fail();
}
catch (IndexOutOfBoundsException ignore)
{
}
+ assertFalse(root.removeChild("a"));
+ try
+ {
+ b.setName("a");
+ fail();
+ }
+ catch (IllegalArgumentException ignore)
+ {
+ }
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ b.setHidden(true);
+ assertSame(a, root.getChild(0));
+ assertSame(c, root.getChild(1));
+ try
+ {
+ root.getChild(2);
+ fail();
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ }
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ a.setHidden(true);
+ c.setHidden(true);
+ assertSame(b, root.getChild(0));
+ try
+ {
+ root.getChild(1);
+ fail();
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ }
}
+ public void testHiddenInsert1() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "hidden_insert_1");
+ Navigation defaultNav = portal.getRootNavigation().addChild("default");
+ defaultNav.addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("hidden_insert_1"));
+
+ //
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node a = root.getChild("a");
+ a.setHidden(true);
+ Node b = root.addChild("b");
+ assertEquals(1, root.getChildren().size());
+ assertSame(b, root.getChildren().iterator().next());
+ a.setHidden(false);
+ assertEquals(2, root.getChildren().size());
+ Iterator<Node> it = root.getChildren().iterator();
+ assertSame(b, it.next());
+ assertSame(a, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ a.setHidden(true);
+ b = root.addChild(0, "b");
+ assertEquals(1, root.getChildren().size());
+ assertSame(b, root.getChildren().iterator().next());
+ a.setHidden(false);
+ assertEquals(2, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(b, it.next());
+ assertSame(a, it.next());
+ }
+
+ public void testHiddenInsert2() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "hidden_insert_2");
+ Navigation defaultNav = portal.getRootNavigation().addChild("default");
+ defaultNav.addChild("a");
+ defaultNav.addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("hidden_insert_2"));
+
+ //
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node a = root.getChild("a");
+ Node b = root.getChild("b");
+ b.setHidden(true);
+ Node c = root.addChild(0, "c");
+ assertEquals(2, root.getChildren().size());
+ Iterator<Node> it = root.getChildren().iterator();
+ assertSame(c, it.next());
+ assertSame(a, it.next());
+ b.setHidden(false);
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(c, it.next());
+ assertSame(a, it.next());
+ assertSame(b, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ b.setHidden(true);
+ c = root.addChild(1, "c");
+ assertEquals(2, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ b.setHidden(false);
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ assertSame(b, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ b.setHidden(true);
+ c = root.addChild("c");
+ assertEquals(2, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ b.setHidden(false);
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ assertSame(b, it.next());
+ }
+
+ public void testHiddenInsert3() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "hidden_insert_3");
+ Navigation defaultNav = portal.getRootNavigation().addChild("default");
+ defaultNav.addChild("a");
+ defaultNav.addChild("b");
+ defaultNav.addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("hidden_insert_3"));
+
+ //
+ Node root,a,b,c,d;
+ Iterator<Node> it;
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ b.setHidden(true);
+ d = root.addChild(0, "d");
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(d, it.next());
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ b.setHidden(false);
+ assertEquals(4, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(d, it.next());
+ assertSame(a, it.next());
+ assertSame(b, it.next());
+ assertSame(c, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ b.setHidden(true);
+ d = root.addChild(1, "d");
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(d, it.next());
+ assertSame(c, it.next());
+ b.setHidden(false);
+ assertEquals(4, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(d, it.next());
+ assertSame(b, it.next());
+ assertSame(c, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ b.setHidden(true);
+ d = root.addChild(2, "d");
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ assertSame(d, it.next());
+ b.setHidden(false);
+ assertEquals(4, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(b, it.next());
+ assertSame(c, it.next());
+ assertSame(d, it.next());
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ a = root.getChild("a");
+ b = root.getChild("b");
+ c = root.getChild("c");
+ b.setHidden(true);
+ d = root.addChild("d");
+ assertEquals(3, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(c, it.next());
+ assertSame(d, it.next());
+ b.setHidden(false);
+ assertEquals(4, root.getChildren().size());
+ it = root.getChildren().iterator();
+ assertSame(a, it.next());
+ assertSame(b, it.next());
+ assertSame(c, it.next());
+ assertSame(d, it.next());
+ }
+
public void testNodeInvalidationByRemoval() throws Exception
{
//
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "invalidation_by_removal");
portal.getRootNavigation().addChild("default");
- end(true);
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("invalidation_by_removal"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("invalidation_by_removal"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertNotNull(root);
- end();
//
- begin();
+ sync();
+
+ //
mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_removal").getRootNavigation().getChild("default").destroy();
- end(true);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
- assertNull(root);
+ sync(true);
+
+ //
+ NodeContext<Node> rootCtx = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ assertNull(rootCtx);
}
public void testNodeInvalidationByChild() throws Exception
@@ -443,37 +605,42 @@
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "invalidation_by_child");
portal.getRootNavigation().addChild("default");
- end(true);
+ //
+ sync(true);
+
// Put the navigation in the cache
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("invalidation_by_child"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("invalidation_by_child"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
Iterator<? extends Node> iterator = root.getChildren().iterator();
assertFalse(iterator.hasNext());
- end();
//
- begin();
+ sync();
+
+ //
mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_child").getRootNavigation().getChild("default").addChild("new");
- end(true);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
+ sync(true);
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
iterator = root.getChildren().iterator();
iterator.next();
assertFalse(iterator.hasNext());
- end();
//
- begin();
+ sync();
+
+ //
mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_child").getRootNavigation().getChild("default").getChild("new").destroy();
- end(true);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
+ sync(true);
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
iterator = root.getChildren().iterator();
assertFalse(iterator.hasNext());
}
@@ -484,48 +651,55 @@
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "invalidation_by_propertychange");
portal.getRootNavigation().addChild("default");
- end(true);
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("invalidation_by_propertychange"));
- Node defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("invalidation_by_propertychange"));
+ Node defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertNull(defaultNode.getContext().getState().getLabel());
- end();
//
- begin();
+ sync();
+
+ //
Described defaultDescribed = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_propertychange").getRootNavigation().getChild("default").adapt(Described.class);
defaultDescribed.setName("bilto");
- end(true);
//
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ sync(true);
+
+ //
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertEquals("bilto", defaultNode.getContext().getState().getLabel());
- end();
//
- begin();
+ sync();
+
+ //
defaultDescribed = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_propertychange").getRootNavigation().getChild("default").adapt(Described.class);
defaultDescribed.setName("bilta");
- end(true);
//
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ sync(true);
+
+ //
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertEquals("bilta", defaultNode.getContext().getState().getLabel());
- end();
//
- begin();
+ sync();
+
+ //
defaultDescribed = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_propertychange").getRootNavigation().getChild("default").adapt(Described.class);
defaultDescribed.setName(null);
- end(true);
//
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ sync(true);
+
+ //
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertNull(defaultNode.getContext().getState().getLabel());
}
@@ -535,247 +709,87 @@
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute");
portal.getRootNavigation().addChild("default");
- end(true);
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("invalidation_by_attribute"));
- Node defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
- assertNull(defaultNode.getContext().getState().getURI());
- end();
+ sync(true);
//
- begin();
- mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, "foo_uri");
- end(true);
-
- //
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
- assertEquals("foo_uri", defaultNode.getContext().getState().getURI());
- end();
-
- //
- begin();
- mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, "bar_uri");
- end(true);
-
- //
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
- assertEquals("bar_uri", defaultNode.getContext().getState().getURI());
- end();
-
- //
- begin();
- mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, null);
- end(true);
-
- //
- begin();
- defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("invalidation_by_attribute"));
+ Node defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
assertNull(defaultNode.getContext().getState().getURI());
- }
- public void testPendingChangesBypassCache() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "pending_changes_bypass_cache");
- portal.getRootNavigation().addChild("default");
- end(true);
-
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("pending_changes_bypass_cache"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- root.addChild("foo");
- service.saveNode(Node.MODEL, root);
+ sync();
//
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- assertNotNull(root.getChild("foo"));
- }
+ mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, "foo_uri");
- public void testAddChild() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "add_child");
- portal.getRootNavigation().addChild("default");
- end(true);
-
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("add_child"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- assertEquals(0, root.getChildrenCount());
+ sync(true);
//
- Node foo = root.addChild("foo");
- assertNull(foo.getId());
- assertEquals("foo", foo.getName());
- assertSame(foo, root.getChild("foo"));
- assertEquals(1, root.getChildrenCount());
- service.saveNode(Node.MODEL, root);
- end(true);
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
+ assertEquals("foo_uri", defaultNode.getContext().getState().getURI());
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- foo = root.getChild("foo");
- assertNotNull(foo);
- assertEquals(1, root.getChildrenCount());
- assertEquals("foo", foo.getName());
- }
+ sync();
- public void testRemoveChild() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "remove_child");
- portal.getRootNavigation().addChild("default").addChild("foo");
- end(true);
-
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("remove_child"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- Node foo = root.getChild("foo");
- assertNotNull(foo.getId());
- assertEquals("foo", foo.getName());
- assertSame(foo, root.getChild("foo"));
+ mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, "bar_uri");
//
- assertTrue(root.removeChild("foo"));
- assertNull(root.getChild("foo"));
- service.saveNode(Node.MODEL, root);
- end(true);
+ sync(true);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- foo = root.getChild("foo");
- assertNull(foo);
- }
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
+ assertEquals("bar_uri", defaultNode.getContext().getState().getURI());
- public void testReorderChild() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("foo");
- rootNavigation.addChild("bar");
- end(true);
-
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("reorder_child"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- Iterator<Node> i = root.getChildren().iterator();
- Node foo = i.next();
- assertNotNull(foo.getId());
- assertEquals("foo", foo.getName());
- assertSame(foo, root.getChild("foo"));
- Node bar = i.next();
- assertNotNull(bar.getId());
- assertEquals("bar", bar.getName());
- assertSame(bar, root.getChild("bar"));
- assertFalse(i.hasNext());
+ sync();
//
- root.addChild(foo);
- service.saveNode(Node.MODEL, root);
- end(true);
+ mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "invalidation_by_attribute").getRootNavigation().getChild("default").getAttributes().setValue(MappedAttributes.URI, null);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- i = root.getChildren().iterator();
- bar = i.next();
- assertNotNull(bar.getId());
- assertEquals("bar", bar.getName());
- assertSame(bar, root.getChild("bar"));
- foo = i.next();
- assertNotNull(foo.getId());
- assertEquals("foo", foo.getName());
- assertSame(foo, root.getChild("foo"));
- assertFalse(i.hasNext());
- }
+ sync(true);
- public void _testReorderChild2() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child_2");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("foo");
- rootNavigation.addChild("bar");
- rootNavigation.addChild("juu");
- end(true);
-
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("reorder_child_2"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- assertEquals("bar", root.getChild(1).getName());
- assertTrue(root.removeChild("bar"));
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- root.addChild("daa");
- Node tab3 = root.getChild(2);
- assertEquals("daa", tab3.getName());
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root = new NavigationServiceImpl(mgr).loadNode(Node.MODEL, nav, Scope.CHILDREN);
- for (Node child : root.getChildren())
- {
- System.out.println("child : " + child.getId());
- }
- tab3 = root.getChild(2);
- assertEquals("daa", tab3.getName());
-
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- for (Node child : root.getChildren())
- {
- System.out.println("child : " + child.getId());
- }
- tab3 = root.getChild(2);
- assertEquals("daa", tab3.getName());
+ defaultNode = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
+ assertNull(defaultNode.getContext().getState().getURI());
}
public void _testWeirdBug() throws Exception
{
MOPService mop = mgr.getPOMService();
Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child_2");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
rootNavigation.addChild("foo");
rootNavigation.addChild("bar");
rootNavigation.addChild("juu");
- end(true);
//
- begin();
+ sync(true);
+
+ //
portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
rootNavigation = portal.getRootNavigation().getChild("default");
rootNavigation.getChild("bar").destroy();
- end(true);
//
- begin();
+ sync(true);
+
+ //
portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
rootNavigation = portal.getRootNavigation().getChild("default");
rootNavigation.addChild("daa");
- end(true);
//
- begin();
+ sync(true);
+
+ //
portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
rootNavigation = portal.getRootNavigation().getChild("default");
- org.gatein.mop.api.workspace.Navigation daa = rootNavigation.getChildren().get(2);
+ Navigation daa = rootNavigation.getChildren().get(2);
assertEquals("daa", daa.getName());
}
@@ -792,25 +806,28 @@
container.addNode("mop:foo");
container.addNode("mop:bar");
container.addNode("mop:juu");
- end(true);
//
- begin();
+ sync(true);
+
+ //
session = mop.getModel().getSession().getJCRSession();
container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
container.getNode("mop:bar").remove();
- end(true);
//
- begin();
+ sync(true);
+
+ //
session = mop.getModel().getSession().getJCRSession();
container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
container.addNode("mop:daa");
container.orderBefore("mop:daa", null);
- end(true);
//
- begin();
+ sync(true);
+
+ //
container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
NodeIterator it = container.getNodes();
assertEquals("mop:foo", it.nextNode().getName());
@@ -819,214 +836,6 @@
assertFalse(it.hasNext());
}
- public void testMoveChild() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_child");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("foo").addChild("juu");
- rootNavigation.addChild("bar");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("move_child"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- Node foo = root.getChild("foo");
- Node bar = root.getChild("bar");
- Node juu = foo.getChild("juu");
- bar.addChild(juu);
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- foo = root.getChild("foo");
- juu = foo.getChild("juu");
- assertNull(juu);
- bar = root.getChild("bar");
- juu = bar.getChild("juu");
- assertNotNull(juu);
- }
-
- public void testRenameNode() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "rename_node");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("foo");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("rename_node"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- Node foo = root.getChild("foo");
- foo.setName("foo");
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- nav = service.loadNavigation(SiteKey.portal("rename_node"));
- root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- foo = root.getChild("foo");
- foo.setName("bar");
- assertEquals("bar", foo.getName());
- assertSame(foo, root.getChild("bar"));
- service.saveNode(Node.MODEL, root);
- assertEquals("bar", foo.getName());
- assertSame(foo, root.getChild("bar"));
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- Node bar = root.getChild("bar");
- assertNotNull(bar);
- assertSame(bar, root.getChild("bar"));
-
- //
- root.addChild("foo");
- try
- {
- bar.setName("foo");
- fail();
- }
- catch (IllegalArgumentException ignore)
- {
- }
- }
-
- public void testSaveChildren() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_children");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("1");
- rootNavigation.addChild("2");
- rootNavigation.addChild("3");
- rootNavigation.addChild("4");
- rootNavigation.addChild("5");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("save_children"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- root.removeChild("5");
- root.removeChild("2");
- root.addChild(0, root.getChild("3"));
- root.addChild(1, root.addChild("."));
- service.saveNode(Node.MODEL, root);
- Iterator<Node> i = root.getChildren().iterator();
- assertEquals("3", i.next().getName());
- assertEquals(".", i.next().getName());
- assertEquals("1", i.next().getName());
- assertEquals("4", i.next().getName());
- assertFalse(i.hasNext());
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- i = root.getChildren().iterator();
- assertEquals("3", i.next().getName());
- assertEquals(".", i.next().getName());
- assertEquals("1", i.next().getName());
- assertEquals("4", i.next().getName());
- assertFalse(i.hasNext());
- }
-
- public void testSaveRecursive() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_recursive");
- org.gatein.mop.api.workspace.Navigation rootNavigation = portal.getRootNavigation().addChild("default");
- rootNavigation.addChild("foo");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("save_recursive"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- Node foo = root.getChild("foo");
- Node bar = foo.addChild("bar");
- bar.addChild("juu");
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- foo = root.getChild("foo");
- bar = foo.getChild("bar");
- assertNotNull(bar.getId());
- Node juu = bar.getChild("juu");
- assertNotNull(juu.getId());
- }
-
- public void testSaveState() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_state");
- portal.getRootNavigation().addChild("default");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("save_state"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.SINGLE);
- NodeState state = root.getState();
- assertNull(state.getURI());
- assertNull(state.getLabel());
- assertEquals(-1, state.getStartPublicationTime());
- assertEquals(-1, state.getEndPublicationTime());
- long now = System.currentTimeMillis();
- root.setState(new NodeState.Builder().setURI("foo").setEndPublicationTime(now).setLabel("bar").capture());
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.ALL);
- state = root.getState();
- assertEquals("foo", state.getURI());
- assertEquals("bar", state.getLabel());
- assertEquals(-1, state.getStartPublicationTime());
- assertEquals(now, state.getEndPublicationTime());
- assertNull(state.getVisibility());
- }
-
- public void testSaveStateOverwrite() throws Exception
- {
- MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_state_overwrite");
- portal.getRootNavigation().addChild("default");
- end(true);
-
- //
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("save_state_overwrite"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- root.addChild("foo");
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- root.addChild("bar");
- service.saveNode(Node.MODEL, root);
- end(true);
-
- //
- begin();
- nav = service.loadNavigation(SiteKey.portal("save_state_overwrite"));
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- assertEquals(2, root.getChildren().size());
- }
-
public void testDelayBetweenServices() throws Exception
{
PortalConfig portalConfig = new PortalConfig();
@@ -1044,34 +853,62 @@
assertEquals("portal", pageNav.getOwnerType());
assertEquals("testPortalNavigation", pageNav.getOwnerId());
- Navigation navigation = service.loadNavigation(SiteKey.portal("testPortalNavigation"));
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("testPortalNavigation"));
assertNotNull(navigation);
assertEquals(SiteType.PORTAL, navigation.getKey().getType());
assertEquals("testPortalNavigation", navigation.getKey().getName());
}
- public void testRecreateNode() throws Exception
+ public void testCount()
{
MOPService mop = mgr.getPOMService();
- Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "recreate_node");
- portal.getRootNavigation().addChild("default").addChild("foo");
- end(true);
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "count");
+ portal.getRootNavigation().addChild("default");
//
- begin();
- Navigation nav = service.loadNavigation(SiteKey.portal("recreate_node"));
- Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- String fooId = root.getChild("foo").getId();
- assertTrue(root.removeChild("foo"));
- assertNull(root.addChild("foo").getId());
- service.saveNode(Node.MODEL, root);
- end(true);
+ sync(true);
//
- begin();
- root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN);
- assertNotNull(root.getChild("foo").getId());
- assertNotSame(fooId, root.getChild("foo").getId());
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("count"));
+ Node root;
+
+ //
+ root = service.loadNode(Node.MODEL, navigation, Scope.SINGLE).getNode();
+ assertEquals(0, root.getNodeCount());
+// assertEquals(-1, root.getSize());
+
+ //
+ root = service.loadNode(Node.MODEL, navigation, Scope.CHILDREN).getNode();
+ assertEquals(0, root.getNodeCount());
+ assertEquals(0, root.getSize());
+ Node a = root.addChild("a");
+ assertEquals(1, root.getNodeCount());
+ assertEquals(1, root.getSize());
+ a.setHidden(true);
+ assertEquals(0, root.getNodeCount());
+ assertEquals(1, root.getSize());
}
+
+ public void testInsertDuplicate()
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "insert_duplicate");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("insert_duplicate"));
+ Node root = service.loadNode(Node.MODEL, navigation, Scope.CHILDREN).getNode();
+ try
+ {
+ root.addChild("a");
+ fail();
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ }
}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceSave.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceSave.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceSave.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,1427 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteKey;
+import org.exoplatform.portal.mop.Visibility;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.core.api.MOPService;
+
+import javax.jcr.NodeIterator;
+import javax.jcr.Session;
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestNavigationServiceSave extends AbstractTestNavigationService
+{
+
+ public void testNonExistingSite() throws Exception
+ {
+ assertNull(service.loadNavigation(SiteKey.portal("non_existing")));
+ }
+
+ public void testSaveNavigation() throws Exception
+ {
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNull(nav);
+
+ //
+ mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_navigation");
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNotNull(nav);
+ assertEquals(SiteKey.portal("save_navigation"), nav.getKey());
+ assertNull(nav.state);
+ assertNull(nav.rootId);
+
+ //
+ assertTrue(service.saveNavigation(nav.getKey(), new NavigationState(5)));
+ nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNotNull(nav.state);
+ assertEquals(5, nav.state.getPriority().intValue());
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNotNull(nav);
+ assertEquals(SiteKey.portal("save_navigation"), nav.getKey());
+ assertEquals(5, (int)nav.state.getPriority());
+ assertNotNull(nav.rootId);
+
+ //
+ assertTrue(service.saveNavigation(nav.getKey(), null));
+ nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNull(nav.state);
+ assertNull(nav.rootId);
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("save_navigation"));
+ assertNotNull(nav);
+ assertNull(nav.state);
+ assertNull(nav.rootId);
+
+ //
+ assertFalse(service.saveNavigation(nav.getKey(), null));
+ }
+
+
+ public void testPendingChangesBypassCache() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "pending_changes_bypass_cache");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("pending_changes_bypass_cache"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ root.addChild("foo");
+ service.saveNode(root.context);
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ assertNotNull(root.getChild("foo"));
+ }
+
+ public void testAddChild() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "add_child");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("add_child"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ assertEquals(0, root1.getNodeCount());
+
+ // Test what happens when null is added
+ try
+ {
+ root1.addChild((String)null);
+ fail();
+ }
+ catch (NullPointerException ignore)
+ {
+ }
+
+ // Test what happens when an illegal index is added
+ try
+ {
+ root1.addChild(-1, "foo");
+ fail();
+ }
+ catch (IndexOutOfBoundsException ignore)
+ {
+ }
+ try
+ {
+ root1.addChild(1, "foo");
+ fail();
+ }
+ catch (IndexOutOfBoundsException ignore)
+ {
+ }
+
+ //
+ Node foo = root1.addChild("foo");
+ assertNull(foo.getId());
+ assertEquals("foo", foo.getName());
+ assertSame(foo, root1.getChild("foo"));
+ assertEquals(1, root1.getNodeCount());
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node foo2 = root2.getChild("foo");
+ assertNotNull(foo2);
+ assertEquals(1, root2.getNodeCount());
+ assertEquals("foo", foo2.getName());
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testRemoveChild() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "remove_child");
+ portal.getRootNavigation().addChild("default").addChild("foo");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("remove_child"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+
+ //
+ try
+ {
+ root1.removeChild(null);
+ fail();
+ }
+ catch (NullPointerException e)
+ {
+ }
+ try
+ {
+ root1.removeChild("bar");
+ fail();
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+
+ //
+ Node foo1 = root1.getChild("foo");
+ assertNotNull(foo1.getId());
+ assertEquals("foo", foo1.getName());
+ assertSame(foo1, root1.getChild("foo"));
+
+ //
+ assertTrue(root1.removeChild("foo"));
+ assertNull(root1.getChild("foo"));
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node foo2 = root2.getChild("foo");
+ assertNull(foo2);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testRemoveTransientChild() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "remove_transient_child");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("remove_transient_child"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node foo1 = root1.addChild("foo");
+ assertNull(foo1.getId());
+ assertEquals("foo", foo1.getName());
+ assertSame(foo1, root1.getChild("foo"));
+
+ //
+ assertTrue(root1.removeChild("foo"));
+ assertNull(root1.getChild("foo"));
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node foo2 = root2.getChild("foo");
+ assertNull(foo2);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testRename() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "rename");
+ Navigation def = portal.getRootNavigation().addChild("default");
+ def.addChild("a");
+ def.addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("rename"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.GRANDCHILDREN).getNode();
+ try
+ {
+ root1.setName("something");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+
+ //
+ Node a1 = root1.getChild("a");
+ assertEquals(0, a1.context.getIndex());
+ try
+ {
+ a1.setName(null);
+ fail();
+ }
+ catch (NullPointerException e)
+ {
+ }
+ try
+ {
+ a1.setName("b");
+ fail();
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+
+ //
+ a1.setName("c");
+ assertEquals("c", a1.getName());
+ assertEquals(0, a1.context.getIndex());
+ service.saveNode(a1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("rename"));
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Node a2 = root2.getChild("c");
+ assertNotNull(a2);
+ // assertEquals(0, a2.context.getIndex());
+
+ // Does not pass randomly because of JCR bugs
+ // root1.assertEquals(root2);
+ }
+
+ public void testReorderChild() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo");
+ rootNavigation.addChild("bar");
+ rootNavigation.addChild("juu");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("reorder_child"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ Iterator<Node> i = root1.getChildren().iterator();
+ Node foo1 = i.next();
+ assertEquals("foo", foo1.getName());
+ Node bar1 = i.next();
+ assertEquals("bar", bar1.getName());
+ Node juu1 = i.next();
+ assertEquals("juu", juu1.getName());
+ assertFalse(i.hasNext());
+
+ // Test what happens when null is added
+ try
+ {
+ root1.addChild(1, (Node)null);
+ fail();
+ }
+ catch (NullPointerException expected)
+ {
+ }
+
+ // Test what happens when an illegal index is added
+ try
+ {
+ root1.addChild(-1, juu1);
+ fail();
+ }
+ catch (IndexOutOfBoundsException expected)
+ {
+ }
+ try
+ {
+ root1.addChild(4, juu1);
+ fail();
+ }
+ catch (IndexOutOfBoundsException expected)
+ {
+ }
+
+ //
+ root1.addChild(1, juu1);
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ i = root2.getChildren().iterator();
+ Node foo2 = i.next();
+ assertEquals("foo", foo2.getName());
+ Node juu2 = i.next();
+ assertEquals("juu", juu2.getName());
+ Node bar2 = i.next();
+ assertEquals("bar", bar2.getName());
+ assertFalse(i.hasNext());
+
+ //
+ root1.assertEquals(root2);
+
+ //
+ root2.addChild(0, bar2);
+
+ //
+ service.saveNode(root2.context);
+
+ //
+ root2.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root3 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ i = root3.getChildren().iterator();
+ Node bar3 = i.next();
+ assertEquals("bar", bar3.getName());
+ Node foo3 = i.next();
+ assertEquals("foo", foo3.getName());
+ Node juu3 = i.next();
+ assertEquals("juu", juu3.getName());
+ assertFalse(i.hasNext());
+
+ //
+ root2.assertEquals(root3);
+ }
+
+ public void _testReorderChild2() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child_2");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo");
+ rootNavigation.addChild("bar");
+ rootNavigation.addChild("juu");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("reorder_child_2"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ assertEquals("bar", root.getChild(1).getName());
+ assertTrue(root.removeChild("bar"));
+ service.saveNode(root.context);
+
+ //
+ sync(true);
+
+ //
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ root.addChild("daa");
+ Node tab3 = root.getChild(2);
+ assertEquals("daa", tab3.getName());
+ service.saveNode(root.context);
+
+ //
+ sync(true);
+
+ //
+ root = new NavigationServiceImpl(mgr).loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ for (Node child : root.getChildren())
+ {
+ System.out.println("child : " + child.getId());
+ }
+ tab3 = root.getChild(2);
+ assertEquals("daa", tab3.getName());
+
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ for (Node child : root.getChildren())
+ {
+ System.out.println("child : " + child.getId());
+ }
+ tab3 = root.getChild(2);
+ assertEquals("daa", tab3.getName());
+ }
+
+ public void _testWeirdBug() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "reorder_child_2");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo");
+ rootNavigation.addChild("bar");
+ rootNavigation.addChild("juu");
+
+ //
+ sync(true);
+
+ //
+ portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
+ rootNavigation = portal.getRootNavigation().getChild("default");
+ rootNavigation.getChild("bar").destroy();
+
+ //
+ sync(true);
+
+ //
+ portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
+ rootNavigation = portal.getRootNavigation().getChild("default");
+ rootNavigation.addChild("daa");
+
+ //
+ sync(true);
+
+ //
+ portal = mop.getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "reorder_child_2");
+ rootNavigation = portal.getRootNavigation().getChild("default");
+ Navigation daa = rootNavigation.getChildren().get(2);
+ assertEquals("daa", daa.getName());
+ }
+
+ public void _testWeirdBug2() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Session session = mop.getModel().getSession().getJCRSession();
+ javax.jcr.Node container = session.getRootNode().
+ getNode("mop:workspace/mop:portalsites").
+ addNode("mop:reorder_child_2").
+ getNode("mop:rootnavigation/mop:children").
+ addNode("mop:default").
+ getNode("mop:children");
+ container.addNode("mop:foo");
+ container.addNode("mop:bar");
+ container.addNode("mop:juu");
+
+ //
+ sync(true);
+
+ //
+ session = mop.getModel().getSession().getJCRSession();
+ container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
+ container.getNode("mop:bar").remove();
+
+ //
+ sync(true);
+
+ //
+ session = mop.getModel().getSession().getJCRSession();
+ container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
+ container.addNode("mop:daa");
+ container.orderBefore("mop:daa", null);
+
+ //
+ sync(true);
+
+ //
+ container = session.getRootNode().getNode("mop:workspace/mop:portalsites/mop:reorder_child_2/mop:rootnavigation/mop:children/mop:default/mop:children");
+ NodeIterator it = container.getNodes();
+ assertEquals("mop:foo", it.nextNode().getName());
+ assertEquals("mop:juu", it.nextNode().getName());
+ assertEquals("mop:daa", it.nextNode().getName());
+ assertFalse(it.hasNext());
+ }
+
+ public void testMoveChild() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_child");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo").addChild("juu");
+ rootNavigation.addChild("bar");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("move_child"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node foo1 = root1.getChild("foo");
+ Node bar1 = root1.getChild("bar");
+ Node juu1 = foo1.getChild("juu");
+ bar1.addChild(juu1);
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node foo2 = root2.getChild("foo");
+ Node juu2 = foo2.getChild("juu");
+ assertNull(juu2);
+ Node bar2 = root2.getChild("bar");
+ juu2 = bar2.getChild("juu");
+ assertNotNull(juu2);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testRenameNode() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "rename_node");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("rename_node"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node foo1 = root1.getChild("foo");
+ foo1.setName("foo");
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("rename_node"));
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+
+ //
+ root1.assertEquals(root2);
+
+ //
+ Node foo2 = root2.getChild("foo");
+ foo2.setName("bar");
+ assertEquals("bar", foo2.getName());
+ assertSame(foo2, root2.getChild("bar"));
+ service.saveNode(root2.context);
+ assertEquals("bar", foo2.getName());
+ assertSame(foo2, root2.getChild("bar"));
+
+ //
+ root2.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root3 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node bar3 = root3.getChild("bar");
+ assertNotNull(bar3);
+ assertSame(bar3, root3.getChild("bar"));
+
+ //
+ root2.assertEquals(root3);
+
+ //
+ root3.addChild("foo");
+ try
+ {
+ bar3.setName("foo");
+ fail();
+ }
+ catch (IllegalArgumentException ignore)
+ {
+ }
+ }
+
+ public void testSaveChildren() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_children");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("1");
+ rootNavigation.addChild("2");
+ rootNavigation.addChild("3");
+ rootNavigation.addChild("4");
+ rootNavigation.addChild("5");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("save_children"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ root1.removeChild("5");
+ root1.removeChild("2");
+ root1.addChild(0, root1.getChild("3"));
+ root1.addChild(1, root1.addChild("."));
+ service.saveNode(root1.context);
+ Iterator<Node> i = root1.getChildren().iterator();
+ assertEquals("3", i.next().getName());
+ assertEquals(".", i.next().getName());
+ assertEquals("1", i.next().getName());
+ assertEquals("4", i.next().getName());
+ assertFalse(i.hasNext());
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ i = root2.getChildren().iterator();
+ assertEquals("3", i.next().getName());
+ assertEquals(".", i.next().getName());
+ assertEquals("1", i.next().getName());
+ assertEquals("4", i.next().getName());
+ assertFalse(i.hasNext());
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testSaveRecursive() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_recursive");
+ Navigation rootNavigation = portal.getRootNavigation().addChild("default");
+ rootNavigation.addChild("foo");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("save_recursive"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node foo1 = root1.getChild("foo");
+ Node bar1 = foo1.addChild("bar");
+ bar1.addChild("juu");
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ Node foo2 = root2.getChild("foo");
+ Node bar2 = foo2.getChild("bar");
+ assertNotNull(bar2.getId());
+ Node juu2 = bar2.getChild("juu");
+ assertNotNull(juu2.getId());
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testSaveState() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_state");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("save_state"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.SINGLE).getNode();
+ NodeState state = root1.getState();
+ assertNull(state.getURI());
+ assertNull(state.getLabel());
+ assertEquals(-1, state.getStartPublicationTime());
+ assertEquals(-1, state.getEndPublicationTime());
+ long now = System.currentTimeMillis();
+ root1.setState(new NodeState.Builder().setURI("foo").setEndPublicationTime(now).setLabel("bar").capture());
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.ALL).getNode();
+ state = root2.getState();
+ assertEquals("foo", state.getURI());
+ assertEquals("bar", state.getLabel());
+ assertEquals(-1, state.getStartPublicationTime());
+ assertEquals(now, state.getEndPublicationTime());
+ assertEquals(Visibility.DISPLAYED, state.getVisibility());
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void _testSaveStateOverwrite() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_state_overwrite");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("save_state_overwrite"));
+ Node root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ root.addChild("foo");
+ service.saveNode(root.context);
+
+ //
+ sync(true);
+
+ //
+ root.addChild("bar");
+ service.saveNode(root.context);
+
+ //
+ sync(true);
+
+ //
+ nav = service.loadNavigation(SiteKey.portal("save_state_overwrite"));
+ root = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ assertEquals(2, root.getChildren().size());
+ }
+
+ public void testRecreateNode() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "recreate_node");
+ portal.getRootNavigation().addChild("default").addChild("foo");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext nav = service.loadNavigation(SiteKey.portal("recreate_node"));
+ Node root1 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ String fooId = root1.getChild("foo").getId();
+ assertTrue(root1.removeChild("foo"));
+ assertNull(root1.addChild("foo").getId());
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, nav, Scope.CHILDREN).getNode();
+ assertNotNull(root2.getChild("foo").getId());
+ assertNotSame(fooId, root2.getChild("foo").getId());
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testMoveToAdded() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_to_added");
+ Navigation nav = portal.getRootNavigation().addChild("default");
+ nav.addChild("a").addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("move_to_added"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.GRANDCHILDREN).getNode();
+ Node a1 = root1.getChild("a");
+ Node b1 = a1.getChild("b");
+ Node c1 = root1.addChild("c");
+ c1.addChild(b1);
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ navigation = service.loadNavigation(SiteKey.portal("move_to_added"));
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.GRANDCHILDREN).getNode();
+ Node a2 = root2.getChild("a");
+ assertNotNull(a2);
+ Node c2 = root2.getChild("c");
+ assertNotNull(c2);
+ Node b2 = c2.getChild("b");
+ assertNotNull(b2);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testMoveFromRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "moved_from_removed");
+ Navigation nav = portal.getRootNavigation().addChild("default");
+ nav.addChild("a").addChild("c");
+ nav.addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("moved_from_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.GRANDCHILDREN).getNode();
+ Node a1 = root1.getChild("a");
+ Node b1 = root1.getChild("b");
+ Node c1 = a1.getChild("c");
+ b1.addChild(c1);
+ root1.removeChild("a");
+ service.saveNode(root1.context);
+
+ //
+ root1.assertConsistent();
+
+ //
+ sync(true);
+
+ //
+ navigation = service.loadNavigation(SiteKey.portal("moved_from_removed"));
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.GRANDCHILDREN).getNode();
+ assertNull(root2.getChild("a"));
+ Node b2 = root2.getChild("b");
+ assertNotNull(b2);
+ Node c2 = b2.getChild("c");
+ assertNotNull(c2);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testConcurrentAddToRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "add_to_removed");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("add_to_removed"));
+ Node root = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root.getChild("a").addChild("b");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.ADD_CONCURRENTLY_REMOVED_PARENT_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentMerge() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "save_merge");
+ Navigation nav = portal.getRootNavigation().addChild("default");
+ nav.addChild("a");
+ nav.addChild("b");
+ nav.addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("save_merge"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.CHILDREN).getNode();
+
+ //
+ sync();
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.CHILDREN).getNode();
+ root2.addChild(1, root2.addChild("2"));
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ service.saveNode(root1.context);
+ root1.assertConsistent();
+
+ //
+ root1.addChild(1, root1.addChild("1"));
+ service.saveNode(root1.context);
+ root1.assertConsistent();
+ }
+
+ public void testConcurrentRemoveRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "remove_removed");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("remove_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.removeChild("a");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ service.saveNode(root1.context);
+
+ //
+ root1.assertEquals(root2);
+ }
+
+ public void testConcurrentMoveRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_removed");
+ portal.getRootNavigation().addChild("default").addChild("a").addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("move_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.addChild(root1.getChild("a").getChild("b"));
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.getChild("a").removeChild("b");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.MOVE_CONCURRENTLY_REMOVED_MOVED_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentMoveToRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_to_removed");
+ portal.getRootNavigation().addChild("default").addChild("a");
+ portal.getRootNavigation().getChild("default").addChild("b");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("move_to_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("b").addChild(root1.getChild("a"));
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("b");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.MOVE_CONCURRENTLY_REMOVED_DST_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentMoveMoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "move_moved");
+ portal.getRootNavigation().addChild("default").addChild("a");
+ portal.getRootNavigation().getChild("default").addChild("b");
+ portal.getRootNavigation().getChild("default").addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("move_moved"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("b").addChild(root1.getChild("a"));
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.getChild("c").addChild(root2.getChild("a"));
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.MOVE_CONCURRENTLY_CHANGED_SRC_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentAddDuplicate() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_add_duplicate");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_add_duplicate"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.addChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ root1.addChild("a");
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.ADD_CONCURRENTLY_ADDED_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentAddAfterRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_add_after_removed");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_add_after_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.addChild(1, "b");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.ADD_CONCURRENTLY_REMOVED_PREVIOUS_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentMoveAfterRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_move_after_removed");
+ Navigation def = portal.getRootNavigation().addChild("default");
+ def.addChild("a").addChild("b");
+ def.addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_move_after_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.addChild(2, root1.getChild("a").getChild("b"));
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("c");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.MOVE_CONCURRENTLY_REMOVED_PREVIOUS_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentMoveFromRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_move_from_removed");
+ portal.getRootNavigation().addChild("default").addChild("a").addChild("b");
+ portal.getRootNavigation().getChild("default").addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_move_from_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("c").addChild(root1.getChild("a").getChild("b"));
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.MOVE_CONCURRENTLY_REMOVED_SRC_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentRenameRemoved() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_rename_removed");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_rename_removed"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("a").setName("b");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.RENAME_CONCURRENTLY_REMOVED_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentDuplicateRename() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_duplicate_rename");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_duplicate_rename"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("a").setName("b");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.addChild("b");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.RENAME_CONCURRENTLY_DUPLICATE_NAME, e.getError());
+ }
+ }
+
+ public void testSavePhantomNode() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "concurrent_save");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("concurrent_save"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.addChild("a");
+ service.saveNode(root1.context);
+
+ //
+ sync(true);
+
+ // Reload the root node and modify it
+ root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.getChild("a").setState(root1.getState().builder().setLabel("foo").capture());
+
+ //
+ sync(true);
+
+ // Edit navigation in another browser
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ // Now click Save button in the first browser
+ try
+ {
+ service.saveNode(root1.context);
+ fail();
+ }
+ catch (NavigationServiceException e)
+ {
+ assertEquals(NavigationError.UPDATE_CONCURRENTLY_REMOVED_NODE, e.getError());
+ }
+ }
+
+ public void testConcurrentRemovalDoesNotPreventSave() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "removal_does_not_prevent_save");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("removal_does_not_prevent_save"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ service.saveNode(root1.context);
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceUpdate.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceUpdate.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceUpdate.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2011 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.portal.mop.SiteKey;
+import org.gatein.mop.api.workspace.Navigation;
+import org.gatein.mop.api.workspace.ObjectType;
+import org.gatein.mop.api.workspace.Site;
+import org.gatein.mop.core.api.MOPService;
+
+import java.util.Iterator;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ */
+public class TestNavigationServiceUpdate extends AbstractTestNavigationService
+{
+
+ public void testNoop() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_no_op");
+ Navigation def = portal.getRootNavigation().addChild("default");
+ def.addChild("a");
+ def.addChild("b");
+ def.addChild("c");
+ def.addChild("d");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_no_op"));
+ NodeContext<Node> root = service.loadNode(Node.MODEL, navigation, Scope.ALL);
+ Iterator<NodeChange<Node>> it = service.updateNode(root, null);
+ assertFalse(it.hasNext());
+ }
+
+ public void testAddFirst() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_add_first");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_add_first"));
+ NodeContext<Node> root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL);
+ assertEquals(0, root1.getNodeSize());
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.addChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ service.updateNode(root1, null);
+ assertEquals(1, root1.getNodeSize());
+ Node a = root1.getNode(0);
+ assertEquals("a", a.getName());
+
+ }
+
+ public void testAddSecond() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_add_second");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_add_second"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ Node a = root1.getChild("a");
+ assertEquals(1, root1.getSize());
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.addChild("b");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ Iterator<NodeChange<Node>> changes = service.updateNode(root1.context, null);
+ NodeChange.Added<Node> added = (NodeChange.Added<Node>)changes.next();
+ assertSame(root1, added.parent);
+ assertSame(root1.getChild("b"), added.node);
+ assertSame(a, added.previous);
+ assertFalse(changes.hasNext());
+ assertEquals(2, root1.getSize());
+ assertEquals("a", root1.getChild(0).getName());
+ assertEquals("b", root1.getChild(1).getName());
+ }
+
+ public void testRemove() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_remove");
+ portal.getRootNavigation().addChild("default").addChild("a");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_remove"));
+ NodeContext<Node> root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL);
+ assertEquals(1, root1.getNodeSize());
+ Node a = root1.getNode("a");
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.removeChild("a");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ Iterator<NodeChange<Node>> changes = service.updateNode(root1, null);
+ NodeChange.Removed<Node> removed = (NodeChange.Removed<Node>)changes.next();
+ assertSame(root1.node, removed.parent);
+ assertSame(a, removed.node);
+ assertFalse(changes.hasNext());
+ assertEquals(0, root1.getNodeSize());
+ }
+
+ public void testMove() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_move");
+ portal.getRootNavigation().addChild("default").addChild("a").addChild("b");
+ portal.getRootNavigation().getChild("default").addChild("c");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_move"));
+ NodeContext<Node> root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL);
+ assertEquals(2, root1.getNodeSize());
+ Node a = root1.getNode("a");
+ Node b = a.getChild("b");
+ Node c = root1.getNode("c");
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.getChild("c").addChild(root2.getChild("a").getChild("b"));
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ Iterator<NodeChange<Node>> changes = service.updateNode(root1, null);
+ NodeChange.Moved<Node> moved = (NodeChange.Moved<Node>)changes.next();
+ assertSame(a, moved.from);
+ assertSame(c, moved.to);
+ assertSame(b, moved.node);
+ assertSame(null, moved.previous);
+ assertFalse(changes.hasNext());
+ assertEquals(0, root1.getNode("a").getSize());
+ assertEquals(1, root1.getNode("c").getSize());
+ }
+
+ public void testAddWithSameName() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_add_with_same_name");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_add_with_same_name"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root1.addChild("a").addChild("b");
+ root1.addChild("c");
+ service.saveNode(root1.context);
+
+ //
+ sync(true);
+
+ //
+ root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ Node a = root1.getChild("a");
+ Node b = a.getChild("b");
+ Node c = root1.getChild("c");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ root2.getChild("c").addChild(root2.getChild("a").getChild("b"));
+ Node b2 = root2.getChild("a").addChild("b");
+ service.saveNode(root2.context);
+
+ //
+ Iterator<NodeChange<Node>> changes = service.updateNode(root1.context, null);
+ NodeChange.Added<Node> added = (NodeChange.Added<Node>)changes.next();
+ assertNull(added.previous);
+ assertSame(a, added.parent);
+ NodeChange.Moved<Node> moved = (NodeChange.Moved<Node>)changes.next();
+ assertNull(moved.previous);
+ assertSame(a, moved.from);
+ assertSame(c, moved.to);
+ assertSame(b, moved.node);
+ assertFalse(changes.hasNext());
+
+ //
+ assertSame(a, root1.getChild("a"));
+ assertSame(c, root1.getChild("c"));
+ assertSame(b, c.getChild("b"));
+ assertEquals(b2.getId(), a.getChild("b").getId());
+ assertSame(a.getChild("b"), added.node);
+ }
+
+ public void testComplex() throws Exception
+ {
+ MOPService mop = mgr.getPOMService();
+ Site portal = mop.getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "update_complex");
+ portal.getRootNavigation().addChild("default");
+
+ //
+ sync(true);
+
+ //
+ NavigationContext navigation = service.loadNavigation(SiteKey.portal("update_complex"));
+ Node root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ Node a1 = root1.addChild("a");
+ a1.addChild("c");
+ a1.addChild("d");
+ a1.addChild("e");
+ Node b1 = root1.addChild("b");
+ b1.addChild("f");
+ b1.addChild("g");
+ b1.addChild("h");
+ service.saveNode(root1.context);
+
+ //
+ sync(true);
+
+ //
+ root1 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ a1 = root1.getChild("a");
+ Node c1 = a1.getChild("c");
+ Node d1 = a1.getChild("d");
+ Node e1 = a1.getChild("e");
+ b1 = root1.getChild("b");
+ Node f1 = b1.getChild("f");
+ Node g1 = b1.getChild("g");
+ Node h1 = b1.getChild("h");
+
+ //
+ Node root2 = service.loadNode(Node.MODEL, navigation, Scope.ALL).getNode();
+ Node a2 = root2.getChild("a");
+ a2.removeChild("e");
+ Node b2 = root2.getChild("b");
+ b2.addChild(2, a2.getChild("d"));
+ a2.addChild(1, "d");
+ b2.removeChild("g");
+ service.saveNode(root2.context);
+
+ //
+ sync(true);
+
+ //
+ Iterator<NodeChange<Node>> changes = service.updateNode(root1.context, null);
+ NodeChange.Added<Node> added = (NodeChange.Added<Node>)changes.next();
+ assertSame(a1, added.parent);
+ assertEquals("d", added.node.getName());
+ assertSame(c1, added.previous);
+ NodeChange.Removed<Node> removed1 = (NodeChange.Removed<Node>)changes.next();
+ assertSame(a1 , removed1.parent);
+ assertSame(e1 , removed1.node);
+ NodeChange.Moved<Node> moved = (NodeChange.Moved<Node>)changes.next();
+ assertSame(a1 , moved.from);
+ assertSame(b1 , moved.to);
+ assertSame(d1 , moved.node);
+ assertSame(f1 , moved.previous);
+ NodeChange.Removed<Node> removed2 = (NodeChange.Removed<Node>)changes.next();
+ assertSame(b1 , removed2.parent);
+ assertSame(g1 , removed2.node);
+ assertFalse(changes.hasNext());
+
+ //
+ assertSame(a1, root1.getChild("a"));
+ assertSame(b1, root1.getChild("b"));
+ assertEquals(2, a1.getSize());
+ assertSame(c1, a1.getChild(0));
+ assertNotNull(a1.getChild(1));
+ assertEquals("d", a1.getChild(1).getName());
+ assertFalse(d1.getId().equals(a1.getChild(1).getId()));
+ assertEquals(3, b1.getSize());
+ assertSame(f1, b1.getChild(0));
+ assertSame(d1, b1.getChild(1));
+ assertSame(h1, b1.getChild(2));
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceWrapper.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceWrapper.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/mop/navigation/TestNavigationServiceWrapper.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.mop.navigation;
+
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.portal.config.AbstractPortalTest;
+import org.exoplatform.portal.mop.EventType;
+import org.exoplatform.portal.mop.SiteKey;
+import org.exoplatform.portal.pom.config.POMSessionManager;
+import org.exoplatform.services.listener.Event;
+import org.exoplatform.services.listener.Listener;
+import org.exoplatform.services.listener.ListenerService;
+import org.gatein.mop.api.workspace.ObjectType;
+
+import java.util.LinkedList;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestNavigationServiceWrapper extends AbstractPortalTest
+{
+
+ /** . */
+ private NavigationService navigationService;
+
+ /** . */
+ private ListenerService listenerService;
+
+ /** . */
+ private POMSessionManager mgr;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+
+ //
+ PortalContainer container = getContainer();
+
+ //
+ listenerService = (ListenerService)container.getComponentInstanceOfType(ListenerService.class);
+ navigationService = (NavigationService)container.getComponentInstanceOfType(NavigationService.class);
+ mgr = (POMSessionManager)container.getComponentInstanceOfType(POMSessionManager.class);
+ }
+
+ public void testNotification() throws NavigationServiceException
+ {
+ class ListenerImpl extends Listener<NavigationService, SiteKey>
+ {
+
+ /** . */
+ private final LinkedList<Event> events = new LinkedList<Event>();
+
+ @Override
+ public void onEvent(Event event) throws Exception
+ {
+ events.addLast(event);
+ }
+ }
+
+ //
+ ListenerImpl createListener = new ListenerImpl();
+ ListenerImpl updateListener = new ListenerImpl();
+ ListenerImpl destroyListener = new ListenerImpl();
+
+ //
+ listenerService.addListener(EventType.NAVIGATION_CREATED, createListener);
+ listenerService.addListener(EventType.NAVIGATION_UPDATED, updateListener);
+ listenerService.addListener(EventType.NAVIGATION_DESTROYED, destroyListener);
+
+ //
+ begin();
+ mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "notification");
+
+ // Create
+ navigationService.saveNavigation(SiteKey.portal("notification"), new NavigationState(3));
+ assertEquals(1, createListener.events.size());
+ Event event = createListener.events.removeFirst();
+ assertEquals(SiteKey.portal("notification"), event.getData());
+ assertEquals(EventType.NAVIGATION_CREATED, event.getEventName());
+ assertSame(navigationService, event.getSource());
+ assertEquals(0, updateListener.events.size());
+ assertEquals(0, destroyListener.events.size());
+
+ // Update
+ navigationService.saveNavigation(SiteKey.portal("notification"), new NavigationState(1));
+ assertEquals(0, createListener.events.size());
+ assertEquals(1, updateListener.events.size());
+ event = updateListener.events.removeFirst();
+ assertEquals(SiteKey.portal("notification"), event.getData());
+ assertEquals(EventType.NAVIGATION_UPDATED, event.getEventName());
+ assertSame(navigationService, event.getSource());
+ assertEquals(0, destroyListener.events.size());
+
+ // Update
+ NavigationContext navigation = navigationService.loadNavigation(SiteKey.portal("notification"));
+ Node root = navigationService.loadNode(Node.MODEL, navigation, Scope.CHILDREN).getNode();
+ root.setState(new NodeState.Builder(root.getState()).setLabel("foo").capture());
+ navigationService.saveNode(root.context);
+ assertEquals(0, createListener.events.size());
+ assertEquals(1, updateListener.events.size());
+ event = updateListener.events.removeFirst();
+ assertEquals(SiteKey.portal("notification"), event.getData());
+ assertEquals(EventType.NAVIGATION_UPDATED, event.getEventName());
+ assertSame(navigationService, event.getSource());
+ assertEquals(0, destroyListener.events.size());
+
+ // Destroy
+ navigationService.saveNavigation(SiteKey.portal("notification"), null);
+ assertEquals(0, createListener.events.size());
+ assertEquals(0, updateListener.events.size());
+ assertEquals(1, destroyListener.events.size());
+ event = destroyListener.events.removeFirst();
+ assertEquals(SiteKey.portal("notification"), event.getData());
+ assertEquals(EventType.NAVIGATION_DESTROYED, event.getEventName());
+ assertSame(navigationService, event.getSource());
+
+ //
+ end();
+ }
+}
Added: epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/list/TestListTree.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/list/TestListTree.java (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/component/portal/src/test/java/org/exoplatform/portal/tree/list/TestListTree.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.exoplatform.portal.tree.list;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestListTree extends TestCase
+{
+
+ public static class IntegerTree extends ListTree<IntegerTree>
+ {
+
+ /** . */
+ private final int value;
+
+ public IntegerTree(int value)
+ {
+ this.value = value;
+ }
+ }
+
+ private static IntegerTree tree(String name, int value, IntegerTree... trees)
+ {
+ IntegerTree tree = new IntegerTree(value);
+ if (trees != null)
+ {
+ for (IntegerTree child : trees)
+ {
+ tree.insertAt(null, child);
+ }
+ }
+ return tree;
+ }
+
+ private void assertChildren(IntegerTree tree, Integer... expected)
+ {
+ List<Integer> children = new ArrayList<Integer>();
+ for (Iterator<IntegerTree> iterator = tree.listIterator();iterator.hasNext();)
+ {
+ IntegerTree next = iterator.next();
+ children.add(next.value);
+ }
+ assertEquals(Arrays.asList(expected), children);
+ }
+
+ private void assertAllChildren(IntegerTree tree, Integer... expected)
+ {
+ List<Integer> children = new ArrayList<Integer>();
+ for (IntegerTree current = tree.getFirst();current != null;current = current.getNext())
+ {
+ children.add(current.value);
+ }
+ assertEquals(Arrays.asList(expected), children);
+ }
+
+ private void assertAllChildren(IntegerTree tree)
+ {
+ assertAllChildren(tree, new Integer[0]);
+ }
+
+ public void testInsert1()
+ {
+ IntegerTree root = tree("", 0);
+ assertChildren(root);
+ assertAllChildren(root);
+
+ //
+ root = tree("", 0);
+ root.insertAt(0, tree("a", 1));
+ assertChildren(root, 1);
+ assertAllChildren(root, 1);
+
+ //
+ root = tree("", 0);
+ root.insertAt(null, tree("a", 1));
+ assertChildren(root, 1);
+ assertAllChildren(root, 1);
+ }
+
+/*
+ public void testInsertDuplicate()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1));
+ assertChildren(root, 1);
+ assertAllChildren(root, 1);
+
+ //
+ try
+ {
+ root.insertAt(0, tree("a", 2));
+ fail();
+ }
+ catch (IllegalArgumentException ignore)
+ {
+ assertAllChildren(root, 1);
+ }
+ }
+*/
+
+ public void testInsertMove1()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree b = tree("b", 2);
+ IntegerTree root1 = tree("", 0, a, b);
+
+ //
+ root1.insertAt(0, b);
+ assertAllChildren(root1, 2, 1);
+ }
+
+ public void testInsertMove2()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree root1 = tree("", 0, a);
+
+ //
+ root1.insertAt(null, a);
+ assertAllChildren(root1, 1);
+
+ //
+ root1.insertAt(0, a);
+ assertAllChildren(root1, 1);
+ }
+
+ public void testInsertMove3()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree root1 = tree("", 0, a);
+ IntegerTree root2 = tree("", 0);
+
+ //
+ root2.insertAt(0, a);
+ assertAllChildren(root1);
+ assertAllChildren(root2, 1);
+ assertSame(root2, a.getParent());
+ }
+
+ public void testInsertReorder1()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree root1 = tree("", 0, a);
+
+ //
+ root1.insertAt(0, a);
+ assertAllChildren(root1, 1);
+ assertSame(root1, a.getParent());
+ }
+
+ public void testInsertReorder2()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree root1 = tree("", 0, a, tree("b", 2));
+
+ //
+ root1.insertAt(2, a);
+ assertAllChildren(root1, 2, 1);
+ assertSame(root1, a.getParent());
+
+ //
+ root1.insertAt(0, a);
+ assertAllChildren(root1, 1, 2);
+ assertSame(root1, a.getParent());
+ }
+
+ public void testRemove()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2), tree("c", 3));
+ assertAllChildren(root, 1, 2, 3);
+
+ //
+ IntegerTree b = root.get(1);
+ b.remove();
+ assertNull(b.getParent());
+ assertNull(b.getPrevious());
+ assertNull(b.getNext());
+ assertEquals(2, b.value);
+ assertAllChildren(root, 1, 3);
+ }
+
+ public void testRemoveLast()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2));
+ assertAllChildren(root, 1, 2);
+
+ //
+ IntegerTree b = root.get(1);
+ assertEquals(2, b.value);
+ b.remove();
+ assertAllChildren(root, 1);
+ assertEquals(1, root.getLast().value);
+ }
+
+/*
+ public void testRename()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2), tree("c", 3));
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+
+ //
+ root.rename("a", "a");
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+
+ //
+ root.rename("a", "d");
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "d", "b", "c");
+ }
+
+ public void testRenameWithNoChildren()
+ {
+ IntegerTree root = tree("", 0, (IntegerTree[]) null);
+ assertFalse(root.hasTrees());
+
+ //
+ try
+ {
+ root.rename("a", "b");
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ assertFalse(root.hasTrees());
+ }
+ }
+
+ public void testRenameWithNonExisting()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2), tree("c", 3));
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+
+ //
+ try
+ {
+ root.rename("d", "e");
+ fail();
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+ }
+ }
+
+ public void testRenameWithExisting()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2), tree("c", 3));
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+
+ //
+ try
+ {
+ root.rename("a", "c");
+ fail();
+ }
+ catch (IllegalArgumentException e)
+ {
+ assertAllChildren(root, 1, 2, 3);
+ assertAllChildren(root, "a", "b", "c");
+ }
+ }
+*/
+
+/*
+ public void testGetByIndexWithNoChildren()
+ {
+ IntegerTree root = tree("", 0, (IntegerTree[]) null);
+
+ //
+ try
+ {
+ root.get(0);
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+ }
+*/
+
+ public void testIteratorRemove()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1));
+ Iterator<IntegerTree> it = root.listIterator();
+
+ //
+ try
+ {
+ it.remove();
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ }
+
+ //
+ IntegerTree a = it.next();
+ it.remove();
+ assertNull(a.getParent());
+ assertFalse(it.hasNext());
+ assertAllChildren(root);
+ }
+
+ public void testListIterator1()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree root = tree("", 0, a);
+
+ //
+ ListIterator<IntegerTree> i = root.listIterator();
+ assertTrue(i.hasNext());
+ assertEquals(0, i.nextIndex());
+ assertFalse(i.hasPrevious());
+ assertEquals(-1, i.previousIndex());
+
+ //
+ assertSame(a, i.next());
+ assertFalse(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+
+ //
+ assertSame(a, i.previous());
+ assertTrue(i.hasNext());
+ assertEquals(0, i.nextIndex());
+ assertFalse(i.hasPrevious());
+ assertEquals(-1, i.previousIndex());
+ }
+
+ public void testListIterator2()
+ {
+ IntegerTree a = tree("a", 1);
+ IntegerTree b = tree("b", 2);
+ IntegerTree root = tree("", 0, a, b);
+
+ //
+ ListIterator<IntegerTree> i = root.listIterator();
+ assertTrue(i.hasNext());
+ assertEquals(0, i.nextIndex());
+ assertFalse(i.hasPrevious());
+ assertEquals(-1, i.previousIndex());
+ assertSame(a, i.next());
+ assertTrue(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ assertSame(b, i.next());
+ assertFalse(i.hasNext());
+ assertEquals(2, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(1, i.previousIndex());
+ i.remove();
+ assertFalse(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ }
+
+ public void testListIterator3()
+ {
+ // Remove middle
+ IntegerTree a = tree("a", 1);
+ IntegerTree b = tree("b", 2);
+ IntegerTree c = tree("c", 3);
+ IntegerTree root = tree("", 0, a, b, c);
+ ListIterator<IntegerTree> i = root.listIterator();
+ i.next();
+ i.next();
+ i.remove();
+ assertTrue(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ assertSame(c, i.next());
+
+ // Remove middle
+ root = tree("", 0, a = tree("a", 1), b = tree("b", 2), c = tree("c", 3));
+ i = root.listIterator();
+ i.next();
+ i.next();
+ i.next();
+ i.previous();
+ i.previous();
+ i.remove();
+ assertTrue(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ assertSame(c, i.next());
+
+ // Remove middle
+ root = tree("", 0, a = tree("a", 1), b = tree("b", 2), c = tree("c", 3));
+ i = root.listIterator();
+ i.next();
+ i.next();
+ i.remove();
+ assertTrue(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ assertSame(a, i.previous());
+
+ // Remove middle
+ root = tree("", 0, a = tree("a", 1), b = tree("b", 2), c = tree("c", 3));
+ i = root.listIterator();
+ i.next();
+ i.next();
+ i.next();
+ i.previous();
+ i.previous();
+ i.remove();
+ assertTrue(i.hasNext());
+ assertEquals(1, i.nextIndex());
+ assertTrue(i.hasPrevious());
+ assertEquals(0, i.previousIndex());
+ assertSame(a, i.previous());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testListIteratorNavigation()
+ {
+ IntegerTree root = tree("", 0, tree("1", 1), tree("2", 2), tree("3", 3), tree("4", 4), tree("5", 5));
+ ListIterator<IntegerTree> it = root.listIterator();
+ assertTrue(it.hasNext());
+ assertTrue(!it.hasPrevious());
+ assertEquals(-1, it.previousIndex());
+ assertEquals(0, it.nextIndex());
+ assertEquals(1, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ assertEquals(1, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(!it.hasPrevious());
+ assertEquals(-1, it.previousIndex());
+ assertEquals(0, it.nextIndex());
+ assertEquals(1, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ assertEquals(2, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertEquals(2, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ assertEquals(2, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertEquals(3, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(2, it.previousIndex());
+ assertEquals(3, it.nextIndex());
+ assertEquals(4, it.next().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(3, it.previousIndex());
+ assertEquals(4, it.nextIndex());
+ assertEquals(5, it.next().value);
+ assertTrue(!it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(4, it.previousIndex());
+ assertEquals(5, it.nextIndex());
+ assertEquals(5, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(3, it.previousIndex());
+ assertEquals(4, it.nextIndex());
+ assertEquals(4, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(2, it.previousIndex());
+ assertEquals(3, it.nextIndex());
+ assertEquals(3, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertEquals(2, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(it.hasPrevious());
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ assertEquals(1, it.previous().value);
+ assertTrue(it.hasNext());
+ assertTrue(!it.hasPrevious());
+ assertEquals(-1, it.previousIndex());
+ assertEquals(0, it.nextIndex());
+ }
+
+ /*
+ @Override
+ @SuppressWarnings("unchecked")
+ public void testListIteratorSet() {
+ list.add((E) "1");
+ list.add((E) "2");
+ list.add((E) "3");
+ list.add((E) "4");
+ list.add((E) "5");
+
+ ListIterator<E> it = list.listIterator();
+ assertEquals("1", it.next());
+ it.set((E) "a");
+ assertEquals("a", it.previous());
+ it.set((E) "A");
+ assertEquals("A", it.next());
+ assertEquals("2", it.next());
+ it.set((E) "B");
+ assertEquals("3", it.next());
+ assertEquals("4", it.next());
+ it.set((E) "D");
+ assertEquals("5", it.next());
+ it.set((E) "E");
+ assertEquals("[A, B, 3, D, E]", list.toString());
+ }
+ */
+
+ public void testListIteratorRemove()
+ {
+ IntegerTree root = tree("", 0, tree("1", 1), tree("2", 2), tree("3", 3), tree("4", 4), tree("5", 5));
+ ListIterator<IntegerTree> it = root.listIterator();
+ try
+ {
+ it.remove();
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ // expected
+ }
+ assertEquals(1, it.next().value);
+ assertEquals(2, it.next().value);
+ assertAllChildren(root, 1, 2, 3, 4, 5);
+ it.remove();
+ assertAllChildren(root, 1, 3, 4, 5);
+ assertEquals(3, it.next().value);
+ assertEquals(3, it.previous().value);
+ assertEquals(1, it.previous().value);
+ it.remove();
+ assertAllChildren(root, 3, 4, 5);
+ assertTrue(!it.hasPrevious());
+ assertEquals(3, it.next().value);
+ it.remove();
+ assertAllChildren(root, 4, 5);
+ try
+ {
+ it.remove();
+ fail();
+ }
+ catch (IllegalStateException e)
+ {
+ // expected
+ }
+ assertEquals(4, it.next().value);
+ assertEquals(5, it.next().value);
+ it.remove();
+ assertAllChildren(root, 4);
+ assertEquals(4, it.previous().value);
+ it.remove();
+ assertAllChildren(root);
+ }
+
+ public void testListIteratorAdd()
+ {
+ IntegerTree root = tree("", 0);
+ ListIterator<IntegerTree> it = root.listIterator();
+ it.add(tree("a", 1));
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ assertAllChildren(root, 1);
+ it.add(tree("c", 3));
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertAllChildren(root, 1, 3);
+ it.add(tree("e", 5));
+ assertEquals(2, it.previousIndex());
+ assertEquals(3, it.nextIndex());
+ assertAllChildren(root, 1, 3, 5);
+ assertEquals(5, it.previous().value);
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ it.add(tree("d", 4));
+ assertEquals(2, it.previousIndex());
+ assertEquals(3, it.nextIndex());
+ assertAllChildren(root, 1, 3, 4, 5);
+ assertEquals(4, it.previous().value);
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertEquals(3, it.previous().value);
+ assertEquals(0, it.previousIndex());
+ assertEquals(1, it.nextIndex());
+ it.add(tree("b", 2));
+ assertEquals(1, it.previousIndex());
+ assertEquals(2, it.nextIndex());
+ assertAllChildren(root, 1, 2, 3, 4, 5);
+ }
+
+ public void testListIteratorMove()
+ {
+ IntegerTree root = tree("", 0, tree("a", 1), tree("b", 2), tree("c", 3));
+ ListIterator<IntegerTree> it = root.listIterator();
+ it.add(root.get(2));
+ assertAllChildren(root, 3, 1, 2);
+ }
+
+ public void testInsertFirstThrowsNPE()
+ {
+ IntegerTree a = tree("a", 0);
+ try
+ {
+ a.insertFirst(null);
+ fail();
+ }
+ catch (NullPointerException ignore)
+ {
+ }
+ }
+
+ public void testInsertLastThrowsNPE()
+ {
+ IntegerTree a = tree("a", 0);
+ try
+ {
+ a.insertLast(null);
+ fail();
+ }
+ catch (NullPointerException ignore)
+ {
+ }
+ }
+
+ public void testInsertBeforeThrowsNPE()
+ {
+ IntegerTree a = tree("a", 0);
+ try
+ {
+ a.insertBefore(null);
+ fail();
+ }
+ catch (NullPointerException ignore)
+ {
+ }
+ }
+
+ public void testInsertBeforeThrowsISE()
+ {
+ IntegerTree a = tree("a", 0);
+ IntegerTree b = tree("b", 1);
+ try
+ {
+ a.insertBefore(b);
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+ }
+
+ public void testInsertAfterThrowsNPE()
+ {
+ IntegerTree a = tree("a", 0);
+ try
+ {
+ a.insertAfter(null);
+ fail();
+ }
+ catch (NullPointerException ignore)
+ {
+ }
+ }
+
+ public void testInsertAfterThrowsISE()
+ {
+ IntegerTree a = tree("a", 0);
+ IntegerTree b = tree("b", 1);
+ try
+ {
+ a.insertAfter(b);
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+ }
+
+ public void testRemoveThrowsISE()
+ {
+ IntegerTree a = tree("a", 0);
+ try
+ {
+ a.remove();
+ fail();
+ }
+ catch (IllegalStateException ignore)
+ {
+ }
+ }
+}
\ No newline at end of file
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/dashboard/src/main/java/org/exoplatform/dashboard/webui/component/UITabPaneDashboard.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/dashboard/src/main/java/org/exoplatform/dashboard/webui/component/UITabPaneDashboard.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/dashboard/src/main/java/org/exoplatform/dashboard/webui/component/UITabPaneDashboard.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -25,6 +25,7 @@
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.Visibility;
+import org.exoplatform.portal.mop.navigation.NavigationServiceException;
import org.exoplatform.portal.mop.navigation.NodeFilter;
import org.exoplatform.portal.mop.navigation.Scope;
import org.exoplatform.portal.mop.user.NavigationPath;
@@ -84,6 +85,8 @@
private DataStorage dataService;
private UIPortal uiPortal;
+
+ private UserNode cachedParent;
final private static int MAX_SHOWED_TAB_NUMBER = 6;
@@ -129,17 +132,18 @@
public UserNode getParentTab() throws Exception
{
NavigationPath navPath = uiPortal.getNavPath();
- UserNode selectedNode = navPath.getTarget();
-
- UserPortal userPortal = getUserPortal();
- UserNode parent = userPortal.getNode(selectedNode.getParent(), TAB_PANE_DASHBOARD_SCOPE);
- if (parent == null)
+ UserNode selectedNode = navPath.getTarget();
+ //parent can be null if child has been removed, and the parent is reloaded
+ UserNode parent = selectedNode.getParent() == null ? this.cachedParent : selectedNode.getParent();
+
+ if (parent != null)
{
- uiPortal.setNavPath(null);
- return null;
- }
- parent.filter(TAB_PANE_DASHBOARD_FILTER);
-
+ UserPortal userPortal = getUserPortal();
+ //Reload to get new data
+ parent = userPortal.getNode(parent, TAB_PANE_DASHBOARD_SCOPE);
+ if (parent != null) parent.filter(TAB_PANE_DASHBOARD_FILTER);
+ }
+ this.cachedParent = parent;
return parent;
}
@@ -387,6 +391,7 @@
UITabPaneDashboard source = event.getSource();
WebuiRequestContext context = event.getRequestContext();
String nodeName = context.getRequestParameter(UIComponent.OBJECTID);
+ String newUri = source.getFirstAvailableURI();
UserNode selectedNode = source.removePageNode(nodeName);
//If the node is removed successfully, then redirect to the node specified by tab on the left
@@ -399,11 +404,12 @@
{
uiPageBody.setMaximizedUIComponent(null);
}
+ newUri = selectedNode.getURI();
+ }
- PortalRequestContext prContext = Util.getPortalRequestContext();
- prContext.setResponseComplete(true);
- prContext.getResponse().sendRedirect(prContext.getPortalURI() + source.encodeURI(selectedNode.getURI()));
- }
+ PortalRequestContext prContext = Util.getPortalRequestContext();
+ prContext.setResponseComplete(true);
+ prContext.getResponse().sendRedirect(prContext.getPortalURI() + source.encodeURI(newUri));
}
}
@@ -414,28 +420,24 @@
UITabPaneDashboard tabPane = event.getSource();
WebuiRequestContext context = event.getRequestContext();
String newTabLabel = context.getRequestParameter(UIComponent.OBJECTID);
+ String newUri = tabPane.getFirstAvailableURI();
if (!tabPane.validateName(newTabLabel))
- {
- //TODO nguyenanhkien2a(a)gmail.com
- //We should redirect to current node while adding new tab fails
- UserNode currentNode = tabPane.uiPortal.getNavPath().getTarget();
- PortalRequestContext prContext = Util.getPortalRequestContext();
-
- prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(currentNode.getURI()));
-
+ {
Object[] args = {newTabLabel};
context.getUIApplication().addMessage(new ApplicationMessage("UITabPaneDashboard.msg.wrongTabName", args));
- return;
}
- String uri = tabPane.createNewPageNode(newTabLabel);
-
- //If new node is created with success, then redirect to it
- if (uri != null)
+ else
{
- PortalRequestContext prContext = Util.getPortalRequestContext();
- prContext.setResponseComplete(true);
- prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(uri));
+ String uri = tabPane.createNewPageNode(newTabLabel);
+ if (uri != null)
+ {
+ newUri = uri;
+ }
}
+
+ PortalRequestContext prContext = Util.getPortalRequestContext();
+ prContext.setResponseComplete(true);
+ prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(newUri));
}
}
@@ -453,30 +455,29 @@
public void execute(Event<UITabPaneDashboard> event) throws Exception
{
- UITabPaneDashboard tabPane = event.getSource();
+ UITabPaneDashboard tabPane = event.getSource();
WebuiRequestContext context = event.getRequestContext();
- String nodeName = context.getRequestParameter(UIComponent.OBJECTID);
+ UIApplication rootUI = context.getUIApplication();
+
String newTabLabel = context.getRequestParameter(RENAMED_TAB_LABEL_PARAMETER);
+ String newUri = tabPane.getFirstAvailableURI();
if (!tabPane.validateName(newTabLabel))
- {
- //We should redirect to current node while renaming fails
- UserNode currentNode = tabPane.uiPortal.getNavPath().getTarget();
- PortalRequestContext prContext = Util.getPortalRequestContext();
- prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(currentNode.getURI()));
-
+ {
Object[] args = {newTabLabel};
- context.getUIApplication().addMessage(new ApplicationMessage("UITabPaneDashboard.msg.wrongTabName", args));
- return;
+ rootUI.addMessage(new ApplicationMessage("UITabPaneDashboard.msg.wrongTabName", args));
}
- String newUri = tabPane.renamePageNode(nodeName, newTabLabel);
-
- //If page node is renamed with success, then redirect to new URL
- if (newUri != null)
+ else
{
- PortalRequestContext prContext = Util.getPortalRequestContext();
- prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(newUri));
- prContext.setResponseComplete(true);
+ String nodeName = context.getRequestParameter(UIComponent.OBJECTID);
+ String returnUri = tabPane.renamePageNode(nodeName, newTabLabel);
+ if (returnUri != null)
+ {
+ newUri = returnUri;
+ }
}
+ PortalRequestContext prContext = Util.getPortalRequestContext();
+ prContext.getResponse().sendRedirect(prContext.getPortalURI() + tabPane.encodeURI(newUri));
+ prContext.setResponseComplete(true);
}
}
@@ -499,4 +500,33 @@
}
}
}
+
+ /**
+ * Return the current node uri, if it's been deleted, return first sibling node uri
+ * if there is no node remain, return default path
+ * @throws Exception
+ */
+ public String getFirstAvailableURI() throws Exception
+ {
+ UserNode parentTab = getParentTab();
+ if (parentTab != null)
+ {
+ UserNode currNode = Util.getUIPortal().getNavPath().getTarget();
+ if (parentTab.getChildren().size() == 0 && parentTab.getURI() != null)
+ {
+ return parentTab.getURI();
+ }
+
+ if (parentTab.getChild(currNode.getName()) != null)
+ {
+ return currNode.getURI();
+ }
+ else
+ {
+ return parentTab.getChild(0).getURI();
+ }
+ }
+
+ return getUserPortal().getDefaultPath().getTarget().getURI();
+ }
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UIGroupNavigationManagement.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UIGroupNavigationManagement.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UIGroupNavigationManagement.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -164,6 +164,8 @@
if (navigation == null)
{
uiApplication.addMessage(new ApplicationMessage("UIGroupNavigationManagement.msg.navigation-not-exist", null));
+ UIWorkingWorkspace uiWorkingWS = Util.getUIPortalApplication().getChild(UIWorkingWorkspace.class);
+ uiWorkingWS.updatePortletsByName("UserToolbarGroupPortlet");
return;
}
@@ -267,7 +269,10 @@
uiMaskWS.setUIComponent(uiNewPortal);
uiMaskWS.setShow(true);
prContext.addUIComponentToUpdateByAjax(uiMaskWS);
-
+
+ //If other users has add or remove group navigation, we need to refresh this portlet
+ UIWorkingWorkspace uiWorkingWS = Util.getUIPortalApplication().getChild(UIWorkingWorkspace.class);
+ uiWorkingWS.updatePortletsByName("UserToolbarGroupPortlet");
}
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UISiteManagement.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UISiteManagement.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/navigation/webui/component/UISiteManagement.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -261,8 +261,9 @@
UISiteManagement uicomp = event.getSource();
String portalName = event.getRequestContext().getRequestParameter(OBJECTID);
UserPortalConfigService service = uicomp.getApplicationComponent(UserPortalConfigService.class);
- PortalRequestContext prContext = Util.getPortalRequestContext();
+ PortalRequestContext prContext = Util.getPortalRequestContext();
UIPortalApplication portalApp = (UIPortalApplication)prContext.getUIApplication();
+ UIWorkingWorkspace uiWorkingWS = portalApp.getChildById(UIPortalApplication.UI_WORKING_WS_ID);
UserPortalConfig userConfig = service.getUserPortalConfig(portalName, prContext.getRemoteUser());
@@ -270,6 +271,7 @@
{
portalApp.addMessage(new ApplicationMessage("UISiteManagement.msg.portal-not-exist",
new String[]{portalName}));
+ uiWorkingWS.updatePortletsByName("UserToolbarSitePortlet");
return;
}
PortalConfig portalConfig = userConfig.getPortalConfig();
@@ -281,8 +283,7 @@
new String[]{portalConfig.getName()}));
return;
}
-
- UIWorkingWorkspace uiWorkingWS = portalApp.getChildById(UIPortalApplication.UI_WORKING_WS_ID);
+
//UIEditInlineWorkspace uiEditWS = uiWorkingWS.addChild(UIEditInlineWorkspace.class, null, UIPortalApplication.UI_EDITTING_WS_ID);
UIEditInlineWorkspace uiEditWS = uiWorkingWS.getChildById(UIPortalApplication.UI_EDITTING_WS_ID);
UIPortalComposer uiComposer = uiEditWS.getComposer().setRendered(true);
@@ -327,7 +328,7 @@
UISiteManagement uicomp = event.getSource();
String portalName = event.getRequestContext().getRequestParameter(OBJECTID);
WebuiRequestContext context = event.getRequestContext();
- UIApplication uiApplication = context.getUIApplication();
+ UIApplication uiApplication = context.getUIApplication();
//Minh Hoang TO: User could edit navigation if he/she has edit permissions on PortalConfig. That is not
//at all logical and should be modified after release 3.1 GA
@@ -337,7 +338,9 @@
if(userPortalConfig == null)
{
uiApplication.addMessage(new ApplicationMessage("UISiteManagement.msg.portal-not-exist",
- new String[]{portalName}));
+ new String[]{portalName}));
+ UIWorkingWorkspace uiWorkingWS = Util.getUIPortalApplication().getChildById(UIPortalApplication.UI_WORKING_WS_ID);
+ uiWorkingWS.updatePortletsByName("UserToolbarSitePortlet");
return;
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarDashboardPortlet.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarDashboardPortlet.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarDashboardPortlet.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -58,7 +58,6 @@
public static String DEFAULT_TAB_NAME = "Tab_0";
private final NodeFilter TOOLBAR_DASHBOARD_FILTER;
- private static final Scope TOOLBAR_DASHBOARD_SCOPE = Scope.CHILDREN;
public UIUserToolBarDashboardPortlet() throws Exception
{
@@ -74,7 +73,7 @@
UserNavigation userNav = getCurrentUserNavigation();
if (userNav != null)
{
- UserNode rootNodes = userPortal.getNode(userNav, TOOLBAR_DASHBOARD_SCOPE);
+ UserNode rootNodes = userPortal.getNode(userNav, Scope.GRANDCHILDREN);
if (rootNodes != null)
{
rootNodes.filter(TOOLBAR_DASHBOARD_FILTER);
@@ -124,7 +123,7 @@
{
PortalRequestContext prContext = Util.getPortalRequestContext();
prContext.getResponse().sendRedirect(
- prContext.getPortalURI() + nodes.iterator().next());
+ prContext.getPortalURI() + nodes.iterator().next().getURI());
}
}
@@ -154,7 +153,7 @@
page.setName(_nodeName);
toolBarPortlet.getApplicationComponent(DataStorage.class).create(page);
- UserNode rootNode = userPortal.getNode(userNav, TOOLBAR_DASHBOARD_SCOPE);
+ UserNode rootNode = userPortal.getNode(userNav, Scope.CHILDREN);
if (rootNode == null)
{
return;
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarGroupPortlet.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarGroupPortlet.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarGroupPortlet.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,24 +19,35 @@
package org.exoplatform.toolbar.webui.component;
+import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.SiteType;
import org.exoplatform.portal.mop.Visibility;
import org.exoplatform.portal.mop.navigation.NodeFilter;
import org.exoplatform.portal.mop.navigation.Scope;
+import org.exoplatform.portal.mop.user.NavigationPath;
import org.exoplatform.portal.mop.user.UserNavigation;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.mop.user.UserNodePredicate;
import org.exoplatform.portal.mop.user.UserPortal;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.workspace.UIPortalApplication;
+import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.core.UIPortletApplication;
import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle;
+import org.gatein.common.util.ParameterValidation;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import javax.portlet.MimeResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceURL;
+
/**
* Created by The eXo Platform SAS
* Author : Pham Thanh Tung
@@ -48,7 +59,8 @@
{
private final NodeFilter TOOLBAR_GROUP_FILTER;
- private static final Scope TOOLBAR_GROUP_SCOPE = Scope.GRANDCHILDREN;
+ private static final Scope TOOLBAR_GROUP_SCOPE = Scope.CHILDREN;
+ private static final String SPLITTER_STRING = "::";
public UIUserToolBarGroupPortlet() throws Exception
{
@@ -62,7 +74,7 @@
{
UserPortal userPortal = getUserPortal();
List<UserNavigation> allNavs = userPortal.getNavigations();
-
+
List<UserNavigation> groupNav = new ArrayList<UserNavigation>();
for (UserNavigation nav : allNavs)
{
@@ -86,11 +98,113 @@
return Collections.emptyList();
}
+ @Override
+ public void serveResource(WebuiRequestContext context) throws Exception
+ {
+ super.serveResource(context);
+
+ ResourceRequest req = context.getRequest();
+ String resourceId = req.getResourceID();
+
+ JSONArray jsChilds = getChildrenAsJSON(resourceId);
+ if (jsChilds == null)
+ {
+ return;
+ }
+
+ MimeResponse res = context.getResponse();
+ res.setContentType("text/json");
+ res.getWriter().write(jsChilds.toString());
+ }
+
public UserNode getSelectedNode() throws Exception
{
return Util.getUIPortal().getNavPath().getTarget();
}
+
+ private JSONArray getChildrenAsJSON(String resourceId) throws Exception
+ {
+ String[] parsedId = parseResourceId(resourceId);
+ if (parsedId == null)
+ {
+ throw new IllegalArgumentException("resourceId " + resourceId + " is invalid");
+ }
+ String groupId = parsedId[0];
+ String nodeURI = parsedId[1];
+
+ UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
+ UserNavigation grpNav = getNavigation(groupId);
+ if (grpNav == null) return null;
+
+ NavigationPath navPath = userPortal.resolvePath(grpNav, nodeURI);
+
+ Collection<UserNode> childs = null;
+ if (navPath != null)
+ {
+ UserNode userNode = navPath.getTarget();
+ userNode = userPortal.getNode(userNode, TOOLBAR_GROUP_SCOPE);
+ userNode.filter(TOOLBAR_GROUP_FILTER);
+ childs = userNode.getChildren();
+ }
+
+ JSONArray jsChilds = new JSONArray();
+ if (childs == null)
+ {
+ return null;
+ }
+
+ WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
+ MimeResponse res = context.getResponse();
+ for (UserNode child : childs)
+ {
+ jsChilds.put(toJSON(child, groupId, res));
+ }
+ return jsChilds;
+ }
+ private JSONObject toJSON(UserNode node, String groupId, MimeResponse res) throws Exception
+ {
+ JSONObject json = new JSONObject();
+ String nodeId = node.getId();
+
+ json.put("label", node.getEncodedResolvedLabel());
+ json.put("hasChild", node.getChildrenCount() > 0);
+ json.put("isSelected", nodeId.equals(getSelectedNode().getId()));
+ json.put("icon", node.getIcon());
+
+ ResourceURL rsURL = res.createResourceURL();
+ rsURL.setResourceID(res.encodeURL(groupId + SPLITTER_STRING + node.getURI()));
+ json.put("getNodeURL", rsURL.toString());
+ json.put("actionLink", Util.getPortalRequestContext().getPortalURI() + node.getURI());
+
+ JSONArray childs = new JSONArray();
+ for (UserNode child : node.getChildren())
+ {
+ childs.put(toJSON(child, groupId, res));
+ }
+ json.put("childs", childs);
+ return json;
+ }
+
+ private UserNavigation getNavigation(String groupId) throws Exception
+ {
+ UserPortal userPortal = getUserPortal();
+ return userPortal.getNavigation(SiteKey.group(groupId));
+ }
+
+ private String[] parseResourceId(String resourceId)
+ {
+ if (!ParameterValidation.isNullOrEmpty(resourceId))
+ {
+ String[] parsedId = resourceId.split(SPLITTER_STRING);
+ if (parsedId.length == 2)
+ {
+ return parsedId;
+ }
+ }
+ return null;
+ }
+
private UserPortal getUserPortal()
{
UIPortalApplication uiApp = Util.getUIPortalApplication();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarSitePortlet.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarSitePortlet.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/java/org/exoplatform/toolbar/webui/component/UIUserToolBarSitePortlet.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,23 +19,32 @@
package org.exoplatform.toolbar.webui.component;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.portlet.MimeResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceURL;
+
import org.exoplatform.portal.config.UserPortalConfigService;
import org.exoplatform.portal.mop.SiteKey;
import org.exoplatform.portal.mop.Visibility;
import org.exoplatform.portal.mop.navigation.NodeFilter;
import org.exoplatform.portal.mop.navigation.Scope;
+import org.exoplatform.portal.mop.user.NavigationPath;
import org.exoplatform.portal.mop.user.UserNavigation;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.mop.user.UserNodePredicate;
import org.exoplatform.portal.mop.user.UserPortal;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.workspace.UIPortalApplication;
+import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
import org.exoplatform.webui.core.UIPortletApplication;
import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
+import org.json.JSONArray;
+import org.json.JSONObject;
/**
* Created by The eXo Platform SAS
@@ -50,7 +59,7 @@
{
private final NodeFilter TOOLBAR_SITE_FILTER;
- private static final Scope TOOLBAR_SITE_SCOPE = Scope.GRANDCHILDREN;
+ private static final Scope TOOLBAR_SITE_SCOPE = Scope.CHILDREN;
public UIUserToolBarSitePortlet() throws Exception
{
@@ -79,11 +88,16 @@
return currentPortalURI.substring(0, currentPortalURI.lastIndexOf(getCurrentPortal())) + portalName + "/";
}
- public Collection<UserNode> getCurrentPortalNavigation() throws Exception
+ public UserNavigation getCurrentUserNavigation(UserPortal userPortal) throws Exception
+ {
+ return userPortal.getNavigation(SiteKey.portal(getCurrentPortal()));
+ }
+
+ public Collection<UserNode> getNavigationNodes() throws Exception
{
UIPortalApplication uiApp = Util.getUIPortalApplication();
UserPortal userPortal = uiApp.getUserPortalConfig().getUserPortal();
- UserNavigation nav = userPortal.getNavigation(SiteKey.portal(getCurrentPortal()));
+ UserNavigation nav = getCurrentUserNavigation(userPortal);
if (nav != null)
{
UserNode rootNodes = userPortal.getNode(nav, TOOLBAR_SITE_SCOPE);
@@ -96,8 +110,83 @@
return Collections.emptyList();
}
+ @Override
+ public void serveResource(WebuiRequestContext context) throws Exception
+ {
+ super.serveResource(context);
+
+ ResourceRequest req = context.getRequest();
+ String nodeURI = req.getResourceID();
+
+ JSONArray jsChilds = getChildrenAsJSON(nodeURI);
+ if (jsChilds == null)
+ {
+ return;
+ }
+
+ MimeResponse res = context.getResponse();
+ res.setContentType("text/json");
+ res.getWriter().write(jsChilds.toString());
+ }
+
public UserNode getSelectedNode() throws Exception
{
return Util.getUIPortal().getNavPath().getTarget();
}
+
+ private JSONArray getChildrenAsJSON(String nodeURI) throws Exception
+ {
+ WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
+ Collection<UserNode> childs = null;
+
+ UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
+ UserNavigation currNav = getCurrentUserNavigation(userPortal);
+ if (currNav == null) return null;
+
+ NavigationPath navPath = userPortal.resolvePath(currNav, nodeURI);
+
+ if (navPath != null)
+ {
+ UserNode userNode = navPath.getTarget();
+ userNode = userPortal.getNode(userNode, TOOLBAR_SITE_SCOPE);
+ userNode.filter(TOOLBAR_SITE_FILTER);
+ childs = userNode.getChildren();
+ }
+
+ JSONArray jsChilds = new JSONArray();
+ if (childs == null)
+ {
+ return null;
+ }
+ MimeResponse res = context.getResponse();
+ for (UserNode child : childs)
+ {
+ jsChilds.put(toJSON(child, res));
+ }
+ return jsChilds;
+ }
+
+ private JSONObject toJSON(UserNode node, MimeResponse res) throws Exception
+ {
+ JSONObject json = new JSONObject();
+ String nodeId = node.getId();
+
+ json.put("label", node.getEncodedResolvedLabel());
+ json.put("hasChild", node.getChildrenCount() > 0);
+ json.put("isSelected", nodeId.equals(getSelectedNode().getId()));
+ json.put("icon", node.getIcon());
+
+ ResourceURL rsURL = res.createResourceURL();
+ rsURL.setResourceID(res.encodeURL(node.getURI()));
+ json.put("getNodeURL", rsURL.toString());
+ json.put("actionLink", Util.getPortalRequestContext().getPortalURI() + node.getURI());
+
+ JSONArray childs = new JSONArray();
+ for (UserNode child : node.getChildren())
+ {
+ childs.put(toJSON(child, res));
+ }
+ json.put("childs", childs);
+ return json;
+ }
}
\ No newline at end of file
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarDashboardPortlet.gtmpl
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarDashboardPortlet.gtmpl 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarDashboardPortlet.gtmpl 2011-05-01 19:34:54 UTC (rev 6419)
@@ -36,7 +36,7 @@
tabStyleNavigation = "SelectedItem";
}
- boolean hasChild = (node.getChildren() != null && node.getChildren().size() > 0);
+ boolean hasChild = (node.getChildrenCount() > 0);
String clazz = "";
if(hasChild) clazz = "ArrowIcon";
String href = Util.getPortalRequestContext().getPortalURI() + node.getURI();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarGroupPortlet.gtmpl
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarGroupPortlet.gtmpl 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarGroupPortlet.gtmpl 2011-05-01 19:34:54 UTC (rev 6419)
@@ -5,6 +5,8 @@
import org.gatein.common.text.EntityEncoder;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.mop.user.UserNavigation;
+ import javax.portlet.MimeResponse;
+ import javax.portlet.ResourceURL;
def rcontext = _ctx.getRequestContext() ;
JavascriptManager jsmanager = rcontext.getJavascriptManager();
@@ -15,7 +17,7 @@
def groupNavigations = uicomponent.getGroupNavigations();
def portalURI = Util.getPortalRequestContext().getPortalURI();
void renderGroupPageNavigation(UserNavigation navigation) {
- nodes = uicomponent.getNodes(navigation);
+ def nodes = uicomponent.getNodes(navigation);
if(nodes.size() < 1) return ;
String navTitle = _ctx.appRes("UIPageNavigation.label.titleBar") ;
def ownerId = navigation.getKey().getName();
@@ -26,21 +28,21 @@
""" ;
int idx = 0;
for(UserNode node : nodes) {
- renderPageNode(node, idx++ % 2 == 0);
+ renderPageNode(node, ownerId, idx++ % 2 == 0);
}
print """
</div>
""" ;
}
- void renderPageNode(UserNode node, boolean flag) {
+ void renderPageNode(UserNode node, String groupId, boolean flag) {
UserNode selectedNode = uicomponent.getSelectedNode();
String tabStyleNavigation = "";
if(selectedNode != null && node.getURI() == selectedNode.getURI()) {
tabStyleNavigation = "SelectedItem";
}
- boolean hasChild = (node.getChildren() != null && node.getChildren().size() > 0);
+ boolean hasChild = node.getChildrenCount() > 0;
String clazz = "";
if(hasChild) clazz = "ArrowIcon";
String href = Util.getPortalRequestContext().getPortalURI() + node.getURI();
@@ -53,8 +55,17 @@
else title = "";
EntityEncoder entityEncoder = EntityEncoder.FULL;
label = entityEncoder.encode(label);
+
+ def getNodeURL = "";
+ if (hasChild) {
+ MimeResponse res = _ctx.getRequestContext().getResponse();
+ ResourceURL resourceURL = res.createResourceURL();
+ resourceURL.setResourceID(res.encodeURL(groupId + "::" + node.getURI()));
+ getNodeURL = "exo:getNodeURL='" + resourceURL.toString() + "'";
+ }
+
print """
- <div class="MenuItem $tabStyleNavigation">
+ <div class="MenuItem $tabStyleNavigation" $getNodeURL>
<div class="$clazz">
""";
if(node.pageRef != null) {
@@ -72,7 +83,7 @@
""" ;
int idx = 0;
for(UserNode child : node.getChildren()) {
- renderPageNode(child, idx++ % 2 == 0);
+ renderPageNode(child, groupId, idx++ % 2 == 0);
}
print """
</div>
@@ -92,7 +103,9 @@
<div class="">
<a class="GroupIcon TBIcon" href="<%= portalURI + "groupnavigation" %>">Group</a>
</div>
- <% if (!groupNavigations.isEmpty()) { %>
+ <%
+ if (!groupNavigations.isEmpty()) {
+ %>
<div style="display:none" class="MenuItemContainer">
<% for(navigation in groupNavigations) {
renderGroupPageNavigation(navigation);
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarSitePortlet.gtmpl
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarSitePortlet.gtmpl 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/exoadmin/src/main/webapp/groovy/admintoolbar/webui/component/UIUserToolBarSitePortlet.gtmpl 2011-05-01 19:34:54 UTC (rev 6419)
@@ -4,17 +4,19 @@
import org.exoplatform.webui.organization.OrganizationUtils;
import org.gatein.common.text.EntityEncoder;
import org.exoplatform.portal.mop.user.UserNode;
+ import java.util.Collection;
+ import javax.portlet.MimeResponse;
+ import javax.portlet.ResourceURL;
def rcontext = _ctx.getRequestContext() ;
JavascriptManager jsmanager = rcontext.getJavascriptManager();
jsmanager.importJavascript('eXo.portal.UIPortalNavigation') ;
jsmanager.importJavascript('eXo.portal.UIAdminToolbar') ;
jsmanager.addCustomizedOnLoadScript('eXo.portal.UIAdminToolbar.onLoad("' + uicomponent.id + '");');
-
def portalURI = Util.getPortalRequestContext().getPortalURI();
void renderPortalNavigations() {
- def nodes = uicomponent.getCurrentPortalNavigation();
+ def nodes = uicomponent.getNavigationNodes();
print """
<div style="position: absolute; display:none" class="MenuItemContainer">
<div class="SubBlock">
@@ -41,7 +43,7 @@
</div>
""";
if(isCurrent) {
- renderCurrentPortal();
+ renderCurrentPortal(nodes);
}
print """
</div>
@@ -53,8 +55,7 @@
""";
}
- void renderCurrentPortal() {
- def nodes = uicomponent.getCurrentPortalNavigation();
+ void renderCurrentPortal(Collection nodes) {
print """
<div style="position: absolute; display:none" class="MenuItemContainer">
<div class="SubBlock">
@@ -72,11 +73,11 @@
void renderPageNode(UserNode node, boolean flag) {
UserNode selectedNode = uicomponent.getSelectedNode();
String tabStyleNavigation = "";
- if(selectedNode != null && node.getURI() == selectedNode.getURI()) {
+ if(selectedNode != null && node.getId() == selectedNode.getId()) {
tabStyleNavigation = "SelectedItem";
}
- boolean hasChild = (node.getChildren() != null && node.getChildren().size() > 0);
+ boolean hasChild = node.getChildrenCount() > 0;
String clazz = "";
if(hasChild) clazz = "ArrowIcon";
String href = Util.getPortalRequestContext().getPortalURI() + node.getURI();
@@ -89,8 +90,17 @@
else title = "";
EntityEncoder entityEncoder = EntityEncoder.FULL;
label = entityEncoder.encode(label);
+
+ def getNodeURL = "";
+ if (hasChild) {
+ MimeResponse res = _ctx.getRequestContext().getResponse();
+ ResourceURL resourceURL = res.createResourceURL();
+ resourceURL.setResourceID(res.encodeURL(node.getURI()));
+ getNodeURL = "exo:getNodeURL='" + resourceURL.toString() + "'";
+ }
+
print """
- <div class="MenuItem $tabStyleNavigation">
+ <div class="MenuItem $tabStyleNavigation" $getNodeURL>
<div class="$clazz">
""";
if(node.pageRef != null) {
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UINavigationPortlet.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UINavigationPortlet.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UINavigationPortlet.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,7 +19,19 @@
package org.exoplatform.portal.webui.component;
+import java.util.Collection;
+
+import javax.portlet.MimeResponse;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceURL;
+
+import org.exoplatform.portal.mop.user.NavigationPath;
+import org.exoplatform.portal.mop.user.UserNode;
+import org.exoplatform.portal.mop.user.UserPortal;
import org.exoplatform.portal.webui.navigation.UIPortalNavigation;
+import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
@@ -27,10 +39,9 @@
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIPortletApplication;
import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle;
+import org.json.JSONArray;
+import org.json.JSONObject;
-import javax.portlet.PortletPreferences;
-import javax.portlet.PortletRequest;
-
@ComponentConfigs({
@ComponentConfig(lifecycle = UIApplicationLifecycle.class),
@ComponentConfig(type = UIPortalNavigation.class, id = "UIHorizontalNavigation", events = @EventConfig(listeners = UIPortalNavigation.SelectNodeActionListener.class))})
@@ -44,10 +55,118 @@
String template = prefers.getValue("template", "app:/groovy/portal/webui/component/UIPortalNavigation.gtmpl");
UIPortalNavigation portalNavigation = addChild(UIPortalNavigation.class, "UIHorizontalNavigation", null);
- portalNavigation.setUseAjax(Boolean.valueOf(prefers.getValue("useAJAX", "true")));
+ portalNavigation.setUseAjax(isUseAjax());
portalNavigation.setShowUserNavigation(Boolean.valueOf(prefers.getValue("showUserNavigation", "true")));
portalNavigation.setTemplate(template);
portalNavigation.setCssClassName(prefers.getValue("CSSClassName", ""));
}
+
+ @Override
+ public void serveResource(WebuiRequestContext context) throws Exception
+ {
+ super.serveResource(context);
+
+ ResourceRequest req = context.getRequest();
+ String nodeURI = req.getResourceID();
+
+ JSONArray jsChilds = getChildrenAsJSON(nodeURI);
+ if (jsChilds == null)
+ {
+ return;
+ }
+
+ MimeResponse res = context.getResponse();
+ res.setContentType("text/json");
+ res.getWriter().write(jsChilds.toString());
+ }
+
+
+ public JSONArray getChildrenAsJSON(String nodeURI) throws Exception
+ {
+ WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
+ Collection<UserNode> childs = null;
+
+ UIPortalNavigation uiPortalNavigation = getChild(UIPortalNavigation.class);
+ UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
+
+ NavigationPath navPath;
+ if (context.getRemoteUser() != null)
+ {
+ navPath = userPortal.resolvePath(Util.getUIPortal().getUserNavigation(), nodeURI);
+ }
+ else
+ {
+ navPath = userPortal.resolvePath(nodeURI);
+ }
+
+ if (navPath != null)
+ {
+ UserNode userNode = uiPortalNavigation.updateNode(navPath.getTarget());
+ if (userNode != null)
+ {
+ childs = userNode.getChildren();
+ }
+ }
+
+ JSONArray jsChilds = new JSONArray();
+ if (childs == null)
+ {
+ return null;
+ }
+ MimeResponse res = context.getResponse();
+ for (UserNode child : childs)
+ {
+ jsChilds.put(toJSON(child, res));
+ }
+ return jsChilds;
+ }
+
+ private JSONObject toJSON(UserNode node, MimeResponse res) throws Exception
+ {
+ JSONObject json = new JSONObject();
+ String nodeId = node.getId();
+
+ json.put("label", node.getEncodedResolvedLabel());
+ json.put("hasChild", node.getChildrenCount() > 0);
+
+ UserNode selectedNode = Util.getUIPortal().getNavPath().getTarget();
+ json.put("isSelected", nodeId.equals(selectedNode.getId()));
+ json.put("icon", node.getIcon());
+
+ ResourceURL rsURL = res.createResourceURL();
+ rsURL.setResourceID(res.encodeURL(node.getURI()));
+ json.put("getNodeURL", rsURL.toString());
+
+ String actionLink;
+ if (node.getPageRef() == null)
+ {
+ actionLink = null;
+ }
+ else if (isUseAjax())
+ {
+ actionLink = event("SelectNode", nodeId);
+ }
+ else
+ {
+ actionLink = Util.getPortalRequestContext().getPortalURI() + node.getURI();
+ }
+ json.put("actionLink", actionLink);
+
+ JSONArray childs = new JSONArray();
+ for (UserNode child : node.getChildren())
+ {
+ childs.put(toJSON(child, res));
+ }
+ json.put("childs", childs);
+ return json;
+ }
+
+ public boolean isUseAjax()
+ {
+ PortletRequestContext context = (PortletRequestContext)WebuiRequestContext.getCurrentInstance();
+ PortletRequest prequest = context.getRequest();
+ PortletPreferences prefers = prequest.getPreferences();
+ return Boolean.valueOf(prefers.getValue("useAJAX", "true"));
+ }
}
\ No newline at end of file
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UISitemapPortlet.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UISitemapPortlet.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/java/org/exoplatform/portal/webui/component/UISitemapPortlet.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,7 +19,18 @@
package org.exoplatform.portal.webui.component;
+import java.util.List;
+
+import javax.portlet.MimeResponse;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceURL;
+
+import org.exoplatform.portal.mop.user.UserNode;
+import org.exoplatform.portal.webui.navigation.TreeNode;
import org.exoplatform.portal.webui.navigation.UIPortalNavigation;
+import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.webui.application.WebuiRequestContext;
import org.exoplatform.webui.application.portlet.PortletRequestContext;
import org.exoplatform.webui.config.annotation.ComponentConfig;
@@ -27,10 +38,9 @@
import org.exoplatform.webui.config.annotation.EventConfig;
import org.exoplatform.webui.core.UIPortletApplication;
import org.exoplatform.webui.core.lifecycle.UIApplicationLifecycle;
+import org.json.JSONArray;
+import org.json.JSONObject;
-import javax.portlet.PortletPreferences;
-import javax.portlet.PortletRequest;
-
/**
* Created by The eXo Platform SARL
* Author : Dang Van Minh
@@ -58,8 +68,99 @@
UIPortalNavigation uiPortalNavigation = addChild(UIPortalNavigation.class, "UISiteMap", null);
uiPortalNavigation.setTemplate(template);
+ uiPortalNavigation.setUseAjax(isUseAjax());
}
+ @Override
+ public void serveResource(WebuiRequestContext context) throws Exception
+ {
+ super.serveResource(context);
+
+ ResourceRequest req = context.getRequest();
+ String nodeID = req.getResourceID();
+
+ JSONArray jsChilds = getChildrenAsJSON(nodeID);
+ if (jsChilds == null)
+ {
+ return;
+ }
+
+ MimeResponse res = context.getResponse();
+ res.setContentType("text/json");
+ res.getWriter().write(jsChilds.toString());
+ }
+
+ private JSONArray getChildrenAsJSON(String nodeID) throws Exception
+ {
+ WebuiRequestContext context = WebuiRequestContext.getCurrentInstance();
+ List<TreeNode> childs = null;
+
+ UIPortalNavigation uiPortalNavigation = getChild(UIPortalNavigation.class);
+ TreeNode tnode = uiPortalNavigation.getTreeNodes().findNodes(nodeID);
+ if (tnode != null)
+ {
+ UserNode userNode = uiPortalNavigation.updateNode(tnode.getNode());
+ if (userNode != null)
+ {
+ tnode.setExpanded(true);
+ tnode.setChildren(userNode.getChildren());
+ childs = tnode.getChildren();
+ }
+ }
+
+ JSONArray jsChilds = new JSONArray();
+ if (childs == null)
+ {
+ return null;
+ }
+ MimeResponse res = context.getResponse();
+ for (TreeNode child : childs)
+ {
+ jsChilds.put(toJSON(child, res));
+ }
+ return jsChilds;
+ }
+
+ private JSONObject toJSON(TreeNode tnode, MimeResponse res) throws Exception
+ {
+ UIPortalNavigation uiPortalNavigation = getChild(UIPortalNavigation.class);
+ JSONObject json = new JSONObject();
+ UserNode node = tnode.getNode();
+ String nodeId = node.getId();
+
+ json.put("label", node.getEncodedResolvedLabel());
+ json.put("hasChild", tnode.hasChild());
+ json.put("isExpanded", tnode.isExpanded());
+ json.put("collapseURL", uiPortalNavigation.url("CollapseNode", nodeId));
+
+ ResourceURL rsURL = res.createResourceURL();
+ rsURL.setResourceID(nodeId);
+ json.put("getNodeURL", rsURL.toString());
+
+ String actionLink;
+ if (node.getPageRef() == null)
+ {
+ actionLink = null;
+ }
+ else if (isUseAjax())
+ {
+ actionLink = uiPortalNavigation.event("SelectNode", nodeId);
+ }
+ else
+ {
+ actionLink = Util.getPortalRequestContext().getPortalURI() + node.getURI();
+ }
+ json.put("actionLink", actionLink);
+
+ JSONArray childs = new JSONArray();
+ for (TreeNode child : tnode.getChildren())
+ {
+ childs.put(toJSON(child, res));
+ }
+ json.put("childs", childs);
+ return json;
+ }
+
public boolean isUseAjax()
{
PortletRequestContext context = (PortletRequestContext)WebuiRequestContext.getCurrentInstance();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/webapp/groovy/portal/webui/component/UIPortalNavigation.gtmpl
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/webapp/groovy/portal/webui/component/UIPortalNavigation.gtmpl 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/portlet/web/src/main/webapp/groovy/portal/webui/component/UIPortalNavigation.gtmpl 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,8 +1,10 @@
<%
- import org.exoplatform.portal.mop.user.UserNode;
+ import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.web.application.JavascriptManager;
import org.exoplatform.portal.webui.util.Util;
import org.gatein.common.text.EntityEncoder;
+ import javax.portlet.MimeResponse;
+ import javax.portlet.ResourceURL;
def rcontext = _ctx.getRequestContext();
JavascriptManager jsmanager = rcontext.getJavascriptManager();
@@ -11,53 +13,56 @@
jsmanager.addOnLoadJavascript('eXo.portal.UIPortalNavigation.onLoad');
jsmanager.addOnLoadJavascript('eXo.portal.UIPortalNavigation.loadScroll');
- //jsmanager.addOnResizeJavascript('eXo.portal.UIPortalNavigation.initScroll');
+ //jsmanager.addOnResizeJavascript('eXo.portal.UIPortalNavigation.initScroll');
- rootNodes = uicomponent.getNavigations();
-
public void renderChildrenContainer(UserNode parentNode, UserNode node) {
- print """
- <div class="MenuItemContainer" style="display: none;">
- <div class="MenuItemDecorator">
- <div class="LeftTopMenuDecorator">
- <div class="RightTopMenuDecorator">
- <div class="CenterTopMenuDecorator"><span></span></div>
- </div>
- </div>
- <div class="LeftMiddleMenuDecorator">
- <div class="RightMiddleMenuDecorator">
- <div class="CenterMiddleMenuDecorator">
- """;
- for(child in node.getChildren()) {
- renderChildNode(parentNode, child);
- }
- print """
- </div>
- </div>
- </div>
- <div class="LeftBottomMenuDecorator">
- <div class="RightBottomMenuDecorator">
- <div class="CenterBottomMenuDecorator"><span></span></div>
- </div>
- </div>
- </div>
- </div>
- """;
- }
+ print """
+ <div class="MenuItemContainer" style="display: none;">
+ <div class="MenuItemDecorator">
+ <div class="LeftTopMenuDecorator">
+ <div class="RightTopMenuDecorator">
+ <div class="CenterTopMenuDecorator"><span></span></div>
+ </div>
+ </div>
+ <div class="LeftMiddleMenuDecorator">
+ <div class="RightMiddleMenuDecorator">
+ <div class="CenterMiddleMenuDecorator">
+ """;
+ for(child in node.getChildren()) {
+ renderChildNode(parentNode, child);
+ }
+ print """
+ </div>
+ </div>
+ </div>
+ <div class="LeftBottomMenuDecorator">
+ <div class="RightBottomMenuDecorator">
+ <div class="CenterBottomMenuDecorator"><span></span></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ """;
+ }
+
public void renderChildNode(UserNode parentNode, UserNode node) {
- UserNode selectedNode = uicomponent.getSelectedPageNode();
- UserNode selectedNav = uicomponent.getCurrentNavigation();
+ UserNode selectedNode = uicomponent.getSelectedNode();
String tabStyleNavigation = "NormalItem"; // OverItem
- if(selectedNode != null && selectedNav != null &&
- selectedNav.getId () == parentNode.getId() &&
- node.getURI() == selectedNode.getURI()) {
+ if(selectedNode != null && node.getId() == selectedNode.getId()) {
tabStyleNavigation = "SelectedItem";
- }
+ }
String icon = node.getIcon();
if(icon == null) icon = "DefaultPageIcon";
String arrowIcon = "";
- if (node.getChildren().size() > 0) arrowIcon = "ArrowIcon";
+ String getNodeURL = "";
+ if (node.getChildrenCount() > 0) {
+ arrowIcon = "ArrowIcon";
+ MimeResponse res = _ctx.getRequestContext().getResponse();
+ ResourceURL resourceURL = res.createResourceURL();
+ resourceURL.setResourceID(res.encodeURL(node.getURI()));
+ getNodeURL = "exo:getNodeURL='" + resourceURL.toString() + "'";
+ }
String label = node.getResolvedLabel();
String title = "";
@@ -70,9 +75,9 @@
String pageURI = Util.getPortalRequestContext().getPortalURI() + node.getURI();
if(node.getPageRef() != null) {
if(uicomponent.isUseAjax()) {
- String onclickEvt = uicomponent.event("SelectNode", parentNode.getId() + "::" + node.getURI()) + ";return false;" ;
+ String onclickEvt = uicomponent.event("SelectNode", node.getId()) + ";return false;" ;
print """
- <div class="MenuItem $tabStyleNavigation">
+ <div class="MenuItem $tabStyleNavigation" $getNodeURL>
<div class="$arrowIcon" title="$title">
<div class="ItemIcon $icon">
<a href="$pageURI" onclick="$onclickEvt">$label</a>
@@ -81,7 +86,7 @@
""";
} else {
print """
- <div class="MenuItem $tabStyleNavigation">
+ <div class="MenuItem $tabStyleNavigation" $getNodeURL>
<div class="$arrowIcon" title="$title">
<div class="ItemIcon $icon">
<a href="$pageURI">$label</a>
@@ -91,7 +96,7 @@
}
} else {
print """
- <div class="MenuItem $tabStyleNavigation">
+ <div class="MenuItem $tabStyleNavigation" $getNodeURL>
<div class="$arrowIcon" title="$title">
<div class="ItemIcon $icon">
<a href="$pageURI">$label</a>
@@ -106,7 +111,7 @@
print "</div>";
}
%>
-
+
<div class="UINavigationBar <%=uicomponent.getCssClassName()%>">
<div class="LeftNavigationBar">
<div class="RightNavigationBar">
@@ -114,23 +119,29 @@
<div class="UIHorizontalTabs">
<div class="TabsContainer">
<%
- UserNode selectedNav = uicomponent.getCurrentNavigation();
- UserNode selectedNode = uicomponent.getSelectedPageNode();
+ MimeResponse res = _ctx.getRequestContext().getResponse();
+
+ def rootNodes = uicomponent.getNavigations();
+ UserNode selectedNode = uicomponent.getSelectedNode();
if(rootNodes != null) {
for(nav in rootNodes) {
- def pageNodes = nav.getChildren();
+ def childs = nav.getChildren();
- for(Node node in pageNodes) {
+ for(Node node in childs) {
String tabStyleNavigation = "NormalNavigationTab";
- if(selectedNode != null && selectedNav != null &&
- selectedNav.getId() == nav.getId() &&
- node.getURI() == selectedNode.getURI()) {
+ if(selectedNode != null && node.getId() == selectedNode.getId()) {
tabStyleNavigation = "SelectedNavigationTab";
}
- %>
-
+
+ if (node.getChildrenCount() > 0) {
+ ResourceURL resourceURL = res.createResourceURL();
+ resourceURL.setResourceID(res.encodeURL(node.getURI()));
+ %>
+ <div class="UITab" exo:getNodeURL="<%=resourceURL.toString() %>">
+ <% } else { %>
<div class="UITab">
+ <% } %>
<div class="$tabStyleNavigation">
<div class="LeftTab">
<div class="RightTab">
@@ -138,7 +149,7 @@
<div class="TabIcon">
<%
String arrowIcon = "";
- if (node.getChildren().size() > 0) {
+ if (node.getChildrenCount() > 0) {
arrowIcon = "DropDownArrowIcon";
}
String iconType = node.getIcon();
@@ -153,7 +164,7 @@
label=entityEncoder.encode(label);
if(node.getPageRef() != null) {
if(uicomponent.isUseAjax()) {
- String onclickEvt = uicomponent.event("SelectNode", nav.getId() + "::" + node.getURI()) + ";return false;";
+ String onclickEvt = uicomponent.event("SelectNode", node.getId()) + ";return false;";
%>
<a class="TabLabel ${iconType}" onclick="$onclickEvt" href="$pageURI">$label</a>
<%
@@ -171,11 +182,11 @@
</div>
</div>
<%
- /*Render Popup Menu*/
- if (node.getChildren().size() > 0) {
- renderChildrenContainer(nav, node);
- }
- %>
+ /*Render Popup Menu*/
+ if (node.getChildren().size() > 0) {
+ renderChildrenContainer(nav, node);
+ }
+ %>
</div>
<%
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortal.js
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortal.js 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortal.js 2011-05-01 19:34:54 UTC (rev 6419)
@@ -654,31 +654,24 @@
var requestStr = eXo.env.server.createPortalURL(portalComposer.id, "Toggle", true);
ajaxAsyncGetRequest(requestStr);
};
+
/**
* Clollapse or expand an element (all its children) of tree
* @param {Object} element object to collapse or expand
*/
-UIPortal.prototype.collapseExpand = function(element, actExpand, actCollapse) {
+UIPortal.prototype.collapseExpand = function(element) {
var subGroup = eXo.core.DOMUtil.findFirstChildByClass(element.parentNode, "div", "ChildrenContainer") ;
var className = element.className;
if(!subGroup) return;
if(subGroup.style.display == "none") {
- if (className.indexOf("ExpandIcon") == 0) element.className = "CollapseIcon ClearFix" ;
-// subGroup.style.display = "block" ;
- if (actExpand)
- {
- actExpand.call();
- }
+ if (className.indexOf("ExpandIcon") == 0) element.className = "CollapseIcon ClearFix" ;
+ subGroup.style.display = "block" ;
} else {
if (className.indexOf("CollapseIcon") == 0) element.className = "ExpandIcon ClearFix" ;
subGroup.style.display = "none" ;
- if (actCollapse)
- {
- actCollapse.call();
- }
}
};
-
+
/*
* This method will start the creation of a new javascript application such as a widget
*
Modified: epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortalNavigation.js
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortalNavigation.js 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/portal/UIPortalNavigation.js 2011-05-01 19:34:54 UTC (rev 6419)
@@ -23,7 +23,7 @@
function UIPortalNavigation() {
this.currentOpenedMenu = null;
this.scrollMgr = null;
- this.scrollManagerLoaded = false;
+ this.scrollManagerLoaded = false;
};
/**
* Sets some parameters :
@@ -54,7 +54,7 @@
eXo.portal.UIPortalNavigation.init(uiNavPortlets[0], mainContainer, 0, 0);
for (var i = 1; i < uiNavPortlets.length; ++i) {
uiNavPortlets[i].style.display = "none";
- }
+ }
}
};
/**
@@ -83,32 +83,34 @@
item.onmousemove = eXo.portal.UIPortalNavigation.tabOnMouseMove ;
}
item.style.width = item.offsetWidth + "px";
- /**
- * TODO: fix IE7;
- */
- var container = DOMUtil.findFirstDescendantByClass(item, "div", this.containerStyleClass);
- if (container) {
- if (eXo.core.Browser.isIE6()) {
- container.style.width = item.offsetWidth + "px";
- } else {
- container.style.minWidth = item.offsetWidth + "px";
- }
- }
}
- var itemConts = DOMUtil.findDescendantsByClass(topContainer, "div", this.containerStyleClass);
- for (var i = 0; i < itemConts.length; i++) {
- var cont = itemConts[i];
- if(!cont.id) cont.id = DOMUtil.generateId("PortalNavigationContainer");
- cont.resized = false;
-
- var items = DOMUtil.findDescendantsByClass(cont, "div", this.tabStyleClass);
- if(items.length == 0) cont.parentNode.removeChild(cont);
- for(var j = 0; j < items.length; j ++) {
- items[j].onmouseover = eXo.portal.UIPortalNavigation.onMenuItemOver;
- items[j].onmouseout = eXo.portal.UIPortalNavigation.onMenuItemOut;
- }
- }
+ /**
+ * TODO: fix IE7;
+ */
+ var container = DOMUtil.findFirstDescendantByClass(item, "div", this.containerStyleClass);
+ if (container) {
+ if (eXo.core.Browser.isIE6()) {
+ container.style.width = item.offsetWidth + "px";
+ } else {
+ container.style.minWidth = item.offsetWidth + "px";
+ }
+ }
+
+ var itemConts = DOMUtil.findDescendantsByClass(topContainer, "div", this.containerStyleClass);
+ for (var i = 0; i < itemConts.length; i++) {
+ var cont = itemConts[i];
+ if(!cont.id) cont.id = DOMUtil.generateId("PortalNavigationContainer");
+ cont.resized = false;
+
+ var items = DOMUtil.findDescendantsByClass(cont, "div", this.tabStyleClass);
+ if(items.length == 0) cont.parentNode.removeChild(cont);
+ for(var j = 0; j < items.length; j ++) {
+ items[j].onmouseover = eXo.portal.UIPortalNavigation.onMenuItemOver;
+ items[j].onmouseout = eXo.portal.UIPortalNavigation.onMenuItemOut;
+ }
+ }
+
};
/**
* Sets the tab style on mouse over and mouse out
@@ -129,16 +131,62 @@
// }
//}
+UIPortalNavigation.prototype.generateContainer = function(data) {
+ var htmlFrags = "<div class='" + this.containerStyleClass + "' style='display: none;' id='";
+ htmlFrags += eXo.core.DOMUtil.generateId("PortalNavigationContainer") + "' resized='false'>";
+ htmlFrags += "<div class='MenuItemDecorator'>";
+ htmlFrags += "<div class='LeftTopMenuDecorator'><div class='RightTopMenuDecorator'>";
+ htmlFrags += "<div class='CenterTopMenuDecorator'><span></span></div></div></div>";
+ htmlFrags += "<div class='LeftMiddleMenuDecorator'><div class='RightMiddleMenuDecorator'>";
+ htmlFrags += "<div class='CenterMiddleMenuDecorator'>";
+ for (var i = 0; i < data.length; i++) {
+ var node = data[i];
+ var actionLink = node.actionLink ? node.actionLink : "javascript:void(0);";
+
+ htmlFrags += ("<div class='MenuItem " + (node.isSelected ? "SelectedItem'" : "NormalItem'"));
+ htmlFrags += (node.hasChild ? (" exo:getNodeURL='" + node.getNodeURL + "' ") : "" );
+ htmlFrags += ("onmouseover='eXo.portal.UIPortalNavigation.onMenuItemOver(this)' onmouseout='eXo.portal.UIPortalNavigation.onMenuItemOut(this)'>");
+ htmlFrags += ("<div class='" + (node.hasChild ? "ArrowIcon" : "") + "' title='" + node.label + "'>");
+ htmlFrags += ("<div class='ItemIcon " + (node.icon ? node.icon : "DefaultPageIcon") + "'>");
+ htmlFrags += ("<a href='" + actionLink + "'>" + (node.label.length > 40 ? node.label.substring(0,37) + "..." : node.label) + "</a>");
+ htmlFrags += ("</div></div></div>");
+ if (node.childs.length) {
+ htmlFrags += eXo.portal.UIPortalNavigation.generateContainer(node.childs);
+ }
+ }
+ htmlFrags += "</div></div></div><div class='LeftBottomMenuDecorator'><div class='RightBottomMenuDecorator'>";
+ htmlFrags += "<div class='CenterBottomMenuDecorator'><span></span></div></div></div></div></div>";
+ return htmlFrags;
+};
+
UIPortalNavigation.prototype.setTabStyleOnMouseOver = function(e) {
var tab = this ;
if (eXo.portal.UIPortalNavigation.previousMenuItem != tab) {
eXo.portal.UIPortalNavigation.hideMenu() ;
}
- eXo.portal.UIPortalNavigation.setTabStyleOnMouseOut(e, tab) ;
- eXo.portal.UIPortalNavigation.previousMenuItem = tab ;
- if (!eXo.portal.UIPortalNavigation.menuVisible) {
- var menuItemContainer = eXo.core.DOMUtil.findFirstDescendantByClass(tab, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
+ eXo.portal.UIPortalNavigation.setTabStyleOnMouseOut(e, tab) ;
+ eXo.portal.UIPortalNavigation.previousMenuItem = tab ;
+
+ var getNodeURL = tab.getAttribute("exo:getNodeURL");
+ var menuItemContainer = eXo.core.DOMUtil.findFirstDescendantByClass(tab, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
+ if (getNodeURL && !menuItemContainer) {
+ var jsChilds = ajaxAsyncGetRequest(getNodeURL,false)
+ try {
+ var data = eXo.core.JSON.parse(jsChilds);
+ if (isNaN(data.length)) {
+ return;
+ }
+ var temp = document.createElement("div");
+ temp.innerHTML = eXo.portal.UIPortalNavigation.generateContainer(data);
+ tab.appendChild(eXo.core.DOMUtil.findFirstChildByClass(temp, "div", eXo.portal.UIPortalNavigation.containerStyleClass));
+ } catch (e) {
+ return;
+ }
+ }
+
+ if (!eXo.portal.UIPortalNavigation.menuVisible) {
var hideSubmenu = tab.getAttribute('hideSubmenu') ;
+ menuItemContainer = eXo.core.DOMUtil.findFirstDescendantByClass(tab, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
if (menuItemContainer && !hideSubmenu) {
var DOMUtil = eXo.core.DOMUtil ;
if(eXo.core.Browser.browserType == "ie") {
@@ -157,8 +205,10 @@
}
eXo.portal.UIPortalNavigation.toggleSubMenu(e, tab, menuItemContainer) ;
}
- }
- eXo.portal.UIPortalNavigation.menuVisible = true ;
+ }
+
+ eXo.portal.UIPortalNavigation.cancelHideMenuContainer() ;
+ eXo.portal.UIPortalNavigation.menuVisible = true ;
} ;
UIPortalNavigation.prototype.setTabStyleOnMouseOut = function(e, src) {
@@ -223,8 +273,8 @@
eXo.portal.UIPortalNavigation.superClass.setPosition(menuItemContainer, x, y, eXo.core.I18n.isRT());
eXo.portal.UIPortalNavigation.superClass.show(menuItemContainer);
- menuItemContainer.style.width = menuItemContainer.offsetWidth - parseInt(DOMUtil.getStyle(menuItemContainer, "borderLeftWidth"))
- - parseInt(DOMUtil.getStyle(menuItemContainer, "borderRightWidth")) + "px";
+ menuItemContainer.style.width = menuItemContainer.offsetWidth - parseInt(DOMUtil.getStyle(menuItemContainer, "borderLeftWidth",true))
+ - parseInt(DOMUtil.getStyle(menuItemContainer, "borderRightWidth",true)) + "px";
var posXinBrowser = eXo.core.Browser.findPosX(menuItemContainer);
if(eXo.core.I18n.isLT()) {
if(posXinBrowser + menuItemContainer.offsetWidth >= eXo.core.Browser.getBrowserWidth()) {
@@ -281,7 +331,7 @@
eXo.portal.UIPortalNavigation.superClass.popVisibleContainer();
eXo.portal.UIPortalNavigation.superClass.setCloseTimeout();
eXo.portal.UIPortalNavigation.superClass.hide(menuItemContainer);
- eXo.portal.UIPortalNavigation.currentOpenedMenu = null;
+ eXo.portal.UIPortalNavigation.currentOpenedMenu = null;
}
this.previousMenuItem = false ;
eXo.portal.UIPortalNavigation.menuVisible = false ;
@@ -308,17 +358,35 @@
tabsContainer.style.position = "relative" ;
}
}
- }
+ }
};
/**
* When the mouse goes over a menu item (in the main nav menu)
* Check if this menu item has a sub menu, if yes, opens it
* Changes the style of the button
*/
-UIPortalNavigation.prototype.onMenuItemOver = function(e) {
- var menuItem = this;
+UIPortalNavigation.prototype.onMenuItemOver = function(menuItem) {
+ if (!menuItem || !menuItem.nodeName) menuItem = this;
var DOMUtil = eXo.core.DOMUtil;
+
+ var getNodeURL = menuItem.getAttribute("exo:getNodeURL");
var subContainer = DOMUtil.findFirstDescendantByClass(menuItem, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
+ if (getNodeURL && !subContainer) {
+ var jsChilds = ajaxAsyncGetRequest(getNodeURL,false)
+ try {
+ var data = eXo.core.JSON.parse(jsChilds);
+ if (isNaN(data.length)) {
+ return;
+ }
+ var temp = document.createElement("div");
+ temp.innerHTML = eXo.portal.UIPortalNavigation.generateContainer(data);
+ menuItem.appendChild(eXo.core.DOMUtil.findFirstChildByClass(temp, "div", eXo.portal.UIPortalNavigation.containerStyleClass));
+ } catch (e) {
+ return;
+ }
+ }
+
+ subContainer = DOMUtil.findFirstDescendantByClass(menuItem, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
if (subContainer) {
eXo.portal.UIPortalNavigation.superClass.pushVisibleContainer(subContainer.id);
eXo.portal.UIPortalNavigation.showMenuItemContainer(menuItem, subContainer) ;
@@ -327,7 +395,6 @@
subContainer.firstTime = true;
}
}
- eXo.portal.UIPortalNavigation.cancelHideMenuContainer() ;
};
/**
* Shows a sub menu, uses the methods from superClass (eXo.webui.UIPopupMenu)
@@ -347,8 +414,9 @@
* When the mouse goes out a menu item from the main nav menu
* Checks if this item has a sub menu, if yes calls methods from superClass to hide it
*/
-UIPortalNavigation.prototype.onMenuItemOut = function(e) {
- var menuItem = this;
+UIPortalNavigation.prototype.onMenuItemOut = function(menuItem) {
+ if (!menuItem || !menuItem.nodeName) menuItem = this;
+
var subContainer = eXo.core.DOMUtil.findFirstDescendantByClass(menuItem, "div", eXo.portal.UIPortalNavigation.containerStyleClass);
if (subContainer) {
eXo.portal.UIPortalNavigation.superClass.pushHiddenContainer(subContainer.id);
Added: epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/webui/UISiteMap.js
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/webui/UISiteMap.js (rev 0)
+++ epp/portal/branches/EPP_5_1_RH_Branch/web/eXoResources/src/main/webapp/javascript/eXo/webui/UISiteMap.js 2011-05-01 19:34:54 UTC (rev 6419)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 eXo Platform SAS.
+ *
+ * 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.
+ */
+
+function UISiteMap() {};
+
+UISiteMap.prototype.updateTreeNode = function (nodeToUpdate, getNodeURL) {
+ if (!nodeToUpdate || ! getNodeURL) return;
+
+ var subGroup = eXo.core.DOMUtil.findFirstChildByClass(nodeToUpdate.parentNode, "div", "ChildrenContainer") ;
+ if (!subGroup || subGroup.innerHTML.trim() !== "") return;
+
+ var jsChilds = ajaxAsyncGetRequest(getNodeURL, false);
+ try {
+ var data = eXo.core.JSON.parse(jsChilds);
+ eXo.webui.UISiteMap.generateHtml(data, nodeToUpdate, subGroup);
+ } catch (e) {
+ }
+};
+
+UISiteMap.prototype.generateHtml = function(data, nodeToUpdate, subGroup) {
+ function toHtml(node, isLast) {
+ if (!node) return;
+ var lastNode = isLast ? "LastNode" : "";
+ var actionLink = node.actionLink ? node.actionLink : "javascript:void(0);";
+
+ var actionExpand = 'eXo.webui.UISiteMap.updateTreeNode(this, "' + node.getNodeURL + '")';
+ var actionCollapse = 'ajaxAsyncGetRequest("' + node.collapseURL + '", true)';
+
+ var str = "";
+ if (node.hasChild) {
+ str += "<div class='" + lastNode + " Node'>";
+ if (node.isExpanded) {
+ str += "<div class='CollapseIcon ClearFix' onclick='eXo.portal.UIPortal.collapseExpand(this); " + actionCollapse + "'>";
+ str += "<a class='NodeIcon DefaultPageIcon' href='" + actionLink + "'>" + node.label + "</a>";
+ str += "</div><div class='ChildrenContainer' style='display: block'>";
+ for (var idx = 0; idx < node.childs.length; i++) {
+ str += toHtml(node.childs[idx], idx == node.childs.length - 1);
+ }
+ } else {
+ str += "<div class='ExpandIcon ClearFix' onclick='eXo.portal.UIPortal.collapseExpand(this); " + actionExpand + "'>";
+ str += "<a class='NodeIcon DefaultPageIcon' href='" + actionLink + "'>" + node.label + "</a>";
+ str += "</div><div class='ChildrenContainer' style='display: none'>";
+ }
+ str += "</div></div>";
+ } else {
+ str += "<div class='" + lastNode + " Node ClearFix'><div class='NullItem'><div class='ClearFix'>";
+ str += "<a class='NodeIcon DefaultPageIcon' href='" + actionLink + "'>" + node.label + "</a></div></div></div>";
+ }
+ return str;
+ }
+
+ var htmlFrags = "";
+ for (var i = 0; i < data.length; i++) {
+ htmlFrags += toHtml(data[i], i == data.length - 1);
+ }
+
+ subGroup.innerHTML = htmlFrags;
+ subGroup.style.display = "block";
+};
+
+eXo.webui.UISiteMap = new UISiteMap();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/web/portal/src/main/webapp/groovy/webui/core/UISitemapTree.gtmpl
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/web/portal/src/main/webapp/groovy/webui/core/UISitemapTree.gtmpl 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/web/portal/src/main/webapp/groovy/webui/core/UISitemapTree.gtmpl 2011-05-01 19:34:54 UTC (rev 6419)
@@ -1,17 +1,22 @@
<%
+ import org.exoplatform.web.application.JavascriptManager;
import org.exoplatform.webui.core.UIPortletApplication;
import org.exoplatform.portal.mop.user.UserNode;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.navigation.TreeNode;
import org.exoplatform.portal.mop.SiteKey;
+ import javax.portlet.MimeResponse;
+ import javax.portlet.ResourceURL;
%>
<%
- PortalRequestContext pcontext = Util.getPortalRequestContext();
- def String portalURI = pcontext.getPortalURI();
+ PortalRequestContext pcontext = Util.getPortalRequestContext();
+ JavascriptManager jsmanager = pcontext.getJavascriptManager();
+ jsmanager.importJavascript('eXo.webui.UISiteMap') ;
+
+ def portalURI = pcontext.getPortalURI();
UIPortletApplication siteMapPortlet = uicomponent.getParent();
-
def useAJAX = siteMapPortlet.isUseAjax();
def actionExpandAll = uicomponent.event("ExpandAllNode");
@@ -26,11 +31,9 @@
// count size;
size++;
- node = treeNode.getNode();
- def treePath = node.getId();
- String label = node.getEncodedResolvedLabel();
- actionExpand = uicomponent.event("ExpandNode", treePath).replace("javascript:", "");
- def actionCollapse = "ajaxAsyncGetRequest('" + uicomponent.url("CollapseNode", treePath) + "', true)";
+ def node = treeNode.getNode();
+ def treePath = node.getId();
+ String label = node.getEncodedResolvedLabel();
if(useAjax){
actionLink = uicomponent.event("SelectNode", treePath);
}else{
@@ -38,7 +41,6 @@
}
lastNode = '';
-
if (size == childrenSize) {
lastNode = 'LastNode';
}
@@ -46,9 +48,10 @@
if(treeNode.hasChild()) {
if (treeNode.isExpanded()) {
+ def actionCollapse = "ajaxAsyncGetRequest('" + uicomponent.url("CollapseNode", treePath) + "', true)";
println """
<div class="$lastNode Node">
- <div class="CollapseIcon ClearFix" onclick="eXo.portal.UIPortal.collapseExpand(this, function() {$actionExpand}, function() {$actionCollapse})">
+ <div class="CollapseIcon ClearFix" onclick="eXo.portal.UIPortal.collapseExpand(this); $actionCollapse">
""";
if(treeNode.getNode().getPageRef() == null) println "<a class='NodeIcon DefaultPageIcon' href='javascript:void(0);'>$label</a>";
else println "<a class='NodeIcon DefaultPageIcon' href='$actionLink'>$label</a>";
@@ -60,9 +63,15 @@
renderNodes(treeNode, portalUri, useAjax);
} else {
+ MimeResponse res = _ctx.getRequestContext().getResponse();
+ ResourceURL resourceURL = res.createResourceURL();
+ resourceURL.setResourceID(treePath);
+
+ def actionExpand = "eXo.webui.UISiteMap.updateTreeNode(this, '" + resourceURL.toString() + "')";
+
println """
<div class="$lastNode Node">
- <div class="ExpandIcon ClearFix" onclick="eXo.portal.UIPortal.collapseExpand(this, function() {$actionExpand}, function() {$actionCollapse})">
+ <div class="ExpandIcon ClearFix" onclick="eXo.portal.UIPortal.collapseExpand(this); $actionExpand">
""";
if(treeNode.getNode().getPageRef() == null) println "<a class='NodeIcon DefaultPageIcon' href='javascript:void(0);'>$label</a>";
else println "<a class='NodeIcon DefaultPageIcon' href='$actionLink'>$label</a>";
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/TreeNode.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/TreeNode.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/TreeNode.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,15 +19,15 @@
package org.exoplatform.portal.webui.navigation;
-import org.exoplatform.portal.mop.user.UserNode;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import javax.jcr.RepositoryException;
+import org.exoplatform.portal.mop.user.UserNode;
+
/**
* Created by The eXo Platform SARL
* Author : Tam Nguyen
@@ -70,11 +70,6 @@
isExpanded_ = isExpanded;
}
- public String getName() throws RepositoryException
- {
- return node_.getName();
- }
-
public UserNode getNode()
{
return node_;
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIAddGroupNavigation.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIAddGroupNavigation.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIAddGroupNavigation.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -23,18 +23,11 @@
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.UserACL;
-import org.exoplatform.portal.config.UserPortalConfig;
import org.exoplatform.portal.config.UserPortalConfigService;
-import org.exoplatform.portal.config.model.PageNavigation;
-import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteKey;
-import org.exoplatform.portal.mop.SiteType;
-import org.exoplatform.portal.mop.navigation.Navigation;
+import org.exoplatform.portal.mop.navigation.NavigationContext;
import org.exoplatform.portal.mop.navigation.NavigationService;
import org.exoplatform.portal.mop.navigation.NavigationState;
-import org.exoplatform.portal.mop.user.UserNavigation;
-import org.exoplatform.portal.mop.user.UserPortal;
-import org.exoplatform.portal.webui.portal.UIPortal;
import org.exoplatform.portal.webui.util.Util;
import org.exoplatform.portal.webui.workspace.UIMaskWorkspace;
import org.exoplatform.portal.webui.workspace.UIPortalApplication;
@@ -56,9 +49,7 @@
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
/*
* Created by The eXo Platform SAS
@@ -121,7 +112,7 @@
List<String> groupsHavingNavigation = new ArrayList<String>();
for(String groupName : listGroup)
{
- Navigation navigation = navigationService.loadNavigation(SiteKey.group(groupName));
+ NavigationContext navigation = navigationService.loadNavigation(SiteKey.group(groupName));
if(navigation != null && navigation.getState() != null)
{
groupsHavingNavigation.add(groupName);
@@ -148,25 +139,26 @@
// ensure this navigation does not exist
NavigationService navigationService = uicomp.getApplicationComponent(NavigationService.class);
- Navigation navigation = navigationService.loadNavigation(SiteKey.group(ownerId));
+ NavigationContext navigation = navigationService.loadNavigation(SiteKey.group(ownerId));
if (navigation != null && navigation.getState() != null)
{
uiPortalApp.addMessage(new ApplicationMessage("UIPageNavigationForm.msg.existPageNavigation",
new String[]{ownerId}));
- return;
}
-
- // Create portal config of the group when it does not exist
- DataStorage dataService = uicomp.getApplicationComponent(DataStorage.class);
- if (dataService.getPortalConfig("group", ownerId) == null)
+ else
{
- UserPortalConfigService configService = uicomp.getApplicationComponent(UserPortalConfigService.class);
- configService.createGroupSite(ownerId);
+ // Create portal config of the group when it does not exist
+ DataStorage dataService = uicomp.getApplicationComponent(DataStorage.class);
+ if (dataService.getPortalConfig("group", ownerId) == null)
+ {
+ UserPortalConfigService configService = uicomp.getApplicationComponent(UserPortalConfigService.class);
+ configService.createGroupSite(ownerId);
+ }
+
+ // create navigation for group
+ navigationService.saveNavigation(SiteKey.group(ownerId), new NavigationState(0));
}
- // create navigation for group
- navigationService.saveNavigation(SiteKey.group(ownerId), new NavigationState(0));
-
//Update group navigation list
ctx.addUIComponentToUpdateByAjax(uicomp);
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UINavigationNodeSelector.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UINavigationNodeSelector.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UINavigationNodeSelector.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -130,7 +130,14 @@
cachedNodes.clear();
initRootNode();
- selectNode(rootNode);
+ if (rootNode.getChildren().size() > 0)
+ {
+ selectNode(rootNode.getChild(0));
+ }
+ else
+ {
+ selectNode(rootNode);
+ }
}
public TreeNodeData selectNode(String nodeID) throws Exception
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNavigationForm.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNavigationForm.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNavigationForm.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -152,9 +152,10 @@
UIPortalApplication uiPortalApp = (UIPortalApplication)prContext.getUIApplication();
uiPortalApp.addMessage(new ApplicationMessage("UINavigationManagement.msg.NavigationNotExistAnymore", null));
UIWorkingWorkspace uiWorkingWS = uiPortalApp.getChildById(UIPortalApplication.UI_WORKING_WS_ID);
+ prContext.addUIComponentToUpdateByAjax(uiWorkingWS);
+ prContext.setFullRender(true);
UIPopupWindow uiPopup = uiForm.getParent();
- uiPopup.setShow(false);
- prContext.addUIComponentToUpdateByAjax(uiWorkingWS);
+ uiPopup.setShow(false);
return;
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNodeSelector.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNodeSelector.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPageNodeSelector.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -65,9 +65,7 @@
public void setNavigation(UserNavigation nav) throws Exception
{
- navigation = nav;
- UserNode selectedNode = Util.getUIPortal().getSelectedUserNode();
- setSelectedNode(selectedNode);
+ navigation = nav;
}
private UserNode load(UserNode node) throws Exception
@@ -75,7 +73,7 @@
return userPortal.getNode(node, Scope.GRANDCHILDREN).filter(NODE_SELECTOR_FILTER);
}
- private void setSelectedNode(UserNode node) throws Exception
+ public void setSelectedNode(UserNode node) throws Exception
{
if (node == null)
{
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPortalNavigation.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPortalNavigation.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/navigation/UIPortalNavigation.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,6 +19,10 @@
package org.exoplatform.portal.webui.navigation;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.model.PortalConfig;
import org.exoplatform.portal.mop.SiteType;
@@ -37,9 +41,6 @@
import org.exoplatform.webui.core.UIComponent;
import org.exoplatform.webui.event.Event;
import org.exoplatform.webui.event.EventListener;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
/**
* Created by The eXo Platform SARL Author : Dang Van Minh minhdv81(a)yahoo.com
@@ -58,10 +59,9 @@
private String template;
private final NodeFilter NAVIGATION_FILTER;
- private static final Scope PORTAL_NAVIGATION_SCOPE = Scope.GRANDCHILDREN;
+
+ private static final Scope NAVIGATION_SCOPE = Scope.CHILDREN;
- private static final Scope SITEMAP_SCOPE = Scope.CHILDREN;
-
public UIPortalNavigation()
{
UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
@@ -140,7 +140,7 @@
continue;
}
- UserNode rootNode = userPortal.getNode(userNav, PORTAL_NAVIGATION_SCOPE);
+ UserNode rootNode = userPortal.getNode(userNav, NAVIGATION_SCOPE);
if (rootNode != null)
{
rootNode.filter(NAVIGATION_FILTER);
@@ -165,7 +165,7 @@
{
continue;
}
- UserNode rootNode = userPortal.getNode(nav, SITEMAP_SCOPE);
+ UserNode rootNode = userPortal.getNode(nav, NAVIGATION_SCOPE);
if (rootNode != null)
{
rootNode.filter(NAVIGATION_FILTER);
@@ -174,7 +174,18 @@
}
treeNode_.setChildren(childNodes);
}
-
+
+ public UserNode updateNode(UserNode node) throws Exception
+ {
+ UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
+ UserNode userNode = userPortal.getNode(node, NAVIGATION_SCOPE);
+ if (userNode != null)
+ {
+ userNode.filter(NAVIGATION_FILTER);
+ }
+ return userNode;
+ }
+
/**
*
* @param listNavigation
@@ -217,23 +228,28 @@
return treeNode_;
}
- public UserNode getCurrentNavigation() throws Exception
+ public UserNode getSelectedNode() throws Exception
{
+ UIPortal uiPortal = Util.getUIPortal();
+ if (uiPortal != null)
+ {
+ return uiPortal.getNavPath().getTarget();
+ }
+ return null;
+ }
+
+ private UserNode getCurrentNavigation() throws Exception
+ {
UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
UserNavigation userNavigation = Util.getUIPortal().getUserNavigation();
- UserNode rootNode = userPortal.getNode(userNavigation, PORTAL_NAVIGATION_SCOPE);
+ UserNode rootNode = userPortal.getNode(userNavigation, NAVIGATION_SCOPE);
if (rootNode != null)
{
rootNode.filter(NAVIGATION_FILTER);
}
return rootNode;
}
-
- public UserNode getSelectedPageNode() throws Exception
- {
- return Util.getUIPortal().getSelectedUserNode();
- }
-
+
static public class SelectNodeActionListener extends EventListener<UIPortalNavigation>
{
public void execute(Event<UIPortalNavigation> event) throws Exception
@@ -241,16 +257,16 @@
UIPortal uiPortal = Util.getUIPortal();
String treePath = event.getRequestContext().getRequestParameter(OBJECTID);
- TreeNode selectedode = event.getSource().getTreeNodes().findNodes(treePath);
+ TreeNode selectedNode = event.getSource().getTreeNodes().findNodes(treePath);
//There're may be interuption between browser and server
- if (selectedode == null)
+ if (selectedNode == null)
{
event.getRequestContext().addUIComponentToUpdateByAjax(event.getSource());
return;
}
PageNodeEvent<UIPortal> pnevent;
- pnevent = new PageNodeEvent<UIPortal>(uiPortal, PageNodeEvent.CHANGE_PAGE_NODE, selectedode.getNode().getURI());
+ pnevent = new PageNodeEvent<UIPortal>(uiPortal, PageNodeEvent.CHANGE_PAGE_NODE, selectedNode.getNode().getURI());
uiPortal.broadcast(pnevent, Event.Phase.PROCESS);
}
}
@@ -272,7 +288,7 @@
UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
- UserNode expandNode = userPortal.getNode(expandTree.getNode(), SITEMAP_SCOPE);
+ UserNode expandNode = userPortal.getNode(expandTree.getNode(), NAVIGATION_SCOPE);
if (expandNode == null)
{
event.getSource().loadTreeNodes();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/page/UIPageCreationWizard.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/page/UIPageCreationWizard.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/page/UIPageCreationWizard.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,13 +19,16 @@
package org.exoplatform.portal.webui.page;
+import org.apache.poi.hssf.record.SCLRecord;
import org.exoplatform.portal.application.PortalRequestContext;
import org.exoplatform.portal.config.DataStorage;
import org.exoplatform.portal.config.UserACL;
import org.exoplatform.portal.config.model.Page;
import org.exoplatform.portal.config.model.PortalConfig;
+import org.exoplatform.portal.mop.navigation.Scope;
import org.exoplatform.portal.mop.user.UserNavigation;
import org.exoplatform.portal.mop.user.UserNode;
+import org.exoplatform.portal.mop.user.UserPortal;
import org.exoplatform.portal.webui.navigation.UIPageNodeSelector;
import org.exoplatform.portal.webui.portal.PageNodeEvent;
import org.exoplatform.portal.webui.portal.UIPortal;
@@ -68,19 +71,29 @@
public UIPageCreationWizard() throws Exception
{
UIWizardPageSetInfo uiPageInfo = addChild(UIWizardPageSetInfo.class, null, null).setRendered(false);
+ UIPageNodeSelector nodeSelector = uiPageInfo.getChild(UIPageNodeSelector.class);
addChild(UIWizardPageSelectLayoutForm.class, null, null).setRendered(false);
addChild(UIPagePreview.class, null, null).setRendered(false);
setNumberSteps(NUMBER_OF_STEPs);
viewStep(FIRST_STEP);
setShowWelcomeComponent(false);
+
boolean isUserNav = Util.getUIPortal().getSiteKey().getTypeName().equals(PortalConfig.USER_TYPE);
- UserNavigation navigation = Util.getUIPortal().getNavPath().getNavigation();
- uiPageInfo.getChild(UIPageNodeSelector.class).setNavigation(navigation);
+ UserNavigation navigation = Util.getUIPortal().getNavPath().getNavigation();
+ nodeSelector.setNavigation(navigation);
+ UserNode selectedNode;
if (isUserNav)
{
- uiPageInfo.getChild(UIPageNodeSelector.class).setRendered(false);
+ nodeSelector.setRendered(false);
+ UserPortal userPortal = Util.getUIPortalApplication().getUserPortalConfig().getUserPortal();
+ selectedNode = userPortal.getNode(navigation, Scope.CHILDREN);
}
+ else
+ {
+ selectedNode = Util.getUIPortal().getSelectedUserNode();
+ }
+ nodeSelector.setSelectedNode(selectedNode);
}
private UserNode saveData() throws Exception
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalComponentActionListener.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalComponentActionListener.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalComponentActionListener.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -482,10 +482,13 @@
UIPortal uiPortal = Util.getUIPortal();
UIPortalApplication uiApp = uiPortal.getAncestorOfType(UIPortalApplication.class);
UserPortalConfigService service = uiApp.getApplicationComponent(UserPortalConfigService.class);
+ PortalRequestContext context = Util.getPortalRequestContext();
if (portalName != null
&& service.getUserPortalConfig(portalName, event.getRequestContext().getRemoteUser()) == null)
{
uiApp.addMessage(new ApplicationMessage("UISiteManagement.msg.portal-not-exist", new String[]{portalName}));
+ context.addUIComponentToUpdateByAjax(uiApp.findFirstComponentOfType(UIWorkingWorkspace.class));
+ context.setFullRender(true);
return;
}
@@ -494,8 +497,7 @@
portalForm.setPortalOwner(portalName);
portalForm.setBindingBean();
uiMaskWS.setWindowSize(700, -1);
- event.getRequestContext().addUIComponentToUpdateByAjax(uiMaskWS);
-
+ context.addUIComponentToUpdateByAjax(uiMaskWS);
}
}
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalForm.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalForm.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portal/src/main/java/org/exoplatform/portal/webui/portal/UIPortalForm.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -333,6 +333,7 @@
UIWorkingWorkspace uiWorkingWS = uiPortalApp.getChildById(UIPortalApplication.UI_WORKING_WS_ID);
prContext.addUIComponentToUpdateByAjax(uiWorkingWS);
+ prContext.setFullRender(true);
}
UIMaskWorkspace uiMaskWorkspace = uiForm.getParent();
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -50,6 +50,8 @@
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
/**
* May 26, 2006
@@ -214,6 +216,50 @@
WebuiRequestContext.setCurrentInstance(parentAppRequestContext);
}
}
+
+ /**
+ * This method is called when a JSR 286 serveResource lifecycle method is targeting the current portlet.
+ *
+ * 1) The current instance of the WebuiRequestContext (stored in a ThreadLocal in the class) is referenced
+ * 2) A new request context of type PortletRequestContext (which extends the class WebuiRequestContext) is
+ * created as a child of the current context instance
+ * 3) The new context is place inside the ThreadLocal and hence overides its parent one there,
+ * only for the portlet request lifecycle
+ * 4) The method onStartRequest() is called in all the ApplicationLifecycle objects referenced in the webui
+ * configuration XML file
+ * 5) The StateManager object (in case of portlet it is an object of type ParentAppStateManager) is used to get the RootComponent
+ * also referenced in the XML configuration file
+ * 6) The method serveResource of UIPortletApplication is called
+ * 7) Finally, the method onEndRequest() is called on every ApplicationLifecycle referenced in the portlet
+ * configuration XML file and the parent WebuiRequestContext is restored
+ */
+ public void serveResource(ResourceRequest req, ResourceResponse res) throws Exception
+ {
+ WebuiRequestContext parentAppRequestContext = WebuiRequestContext.getCurrentInstance();
+ PortletRequestContext context = createRequestContext(req, res, parentAppRequestContext);
+ WebuiRequestContext.setCurrentInstance(context);
+ try
+ {
+ for (ApplicationLifecycle<RequestContext> lifecycle : getApplicationLifecycle())
+ {
+ lifecycle.onStartRequest(this, context);
+ }
+ StateManager sm = getStateManager();
+ UIApplication uiApp = sm.restoreUIRootComponent(context);
+ context.setUIApplication(uiApp);
+ if (uiApp instanceof UIPortletApplication)
+ {
+ ((UIPortletApplication)uiApp).serveResource(context);
+ }
+
+ // Store ui root
+ sm.storeUIRootComponent(context);
+ }
+ finally
+ {
+ WebuiRequestContext.setCurrentInstance(parentAppRequestContext);
+ }
+ }
/**
* The render method business logic is quite similar to the processAction() one.
@@ -313,5 +359,4 @@
context.setParentAppRequestContext(parentAppRequestContext);
return context;
}
-
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplicationController.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplicationController.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletApplicationController.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -38,6 +38,8 @@
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
/**
* Created by The eXo Platform SAS
@@ -84,6 +86,7 @@
log.error("Error while processing action in the porlet", ex);
}
}
+
/**
* Delegate the action to the PortletApplication object
@@ -99,6 +102,21 @@
log.error("Error while processing event in the porlet", ex);
}
}
+
+ /**
+ * Delegate the action to the PortletApplication object
+ */
+ public void serveResource(ResourceRequest req, ResourceResponse res) throws PortletException, IOException
+ {
+ try
+ {
+ getPortletApplication().serveResource(req, res);
+ }
+ catch (Exception ex)
+ {
+ log.error("Error while serving resource in the porlet", ex);
+ }
+ }
/**
* Delegate the render to the PortletApplication object
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -19,24 +19,24 @@
package org.exoplatform.webui.application.portlet;
-import org.exoplatform.commons.utils.WriterPrinter;
-import org.exoplatform.services.resources.Orientation;
-import org.exoplatform.web.application.URLBuilder;
-import org.exoplatform.webui.application.WebuiApplication;
-import org.exoplatform.webui.application.WebuiRequestContext;
-import org.exoplatform.webui.core.UIApplication;
-import org.exoplatform.webui.core.UIComponent;
-
import java.io.Writer;
import javax.portlet.ActionResponse;
+import javax.portlet.MimeResponse;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
-import javax.portlet.RenderResponse;
import javax.portlet.StateAwareResponse;
+import org.exoplatform.commons.utils.WriterPrinter;
+import org.exoplatform.services.resources.Orientation;
+import org.exoplatform.web.application.URLBuilder;
+import org.exoplatform.webui.application.WebuiApplication;
+import org.exoplatform.webui.application.WebuiRequestContext;
+import org.exoplatform.webui.core.UIApplication;
+import org.exoplatform.webui.core.UIComponent;
+
/**
* The request context of a portlet
*
@@ -195,7 +195,7 @@
public URLBuilder<UIComponent> getURLBuilder()
{
- RenderResponse renderRes = (RenderResponse)response_;
+ MimeResponse renderRes = (MimeResponse)response_;
urlBuilder.setBaseURL(renderRes.createActionURL().toString());
return urlBuilder;
}
Modified: epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/core/UIPortletApplication.java
===================================================================
--- epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/core/UIPortletApplication.java 2011-04-29 14:10:14 UTC (rev 6418)
+++ epp/portal/branches/EPP_5_1_RH_Branch/webui/portlet/src/main/java/org/exoplatform/webui/core/UIPortletApplication.java 2011-05-01 19:34:54 UTC (rev 6419)
@@ -23,7 +23,10 @@
import java.util.Map;
import java.util.Set;
+import javax.portlet.ResourceRequest;
+import javax.portlet.ResourceResponse;
import javax.portlet.WindowState;
+import javax.resource.spi.IllegalStateException;
import org.apache.commons.collections.map.HashedMap;
import org.exoplatform.commons.serialization.api.annotations.Serialized;
@@ -145,4 +148,16 @@
}
super.processRender(context);
}
+
+ /**
+ * Root uicomponent of a portlet should override this method to leverage serveResource that JSR286 offers
+ * @param context - WebUI context
+ */
+ public void serveResource(WebuiRequestContext context) throws Exception
+ {
+ if (!(context.getRequest() instanceof ResourceRequest))
+ {
+ throw new IllegalStateException("serveSource can only be called in portlet context");
+ }
+ }
}
\ No newline at end of file
13 years, 8 months