/* * 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.LinkedList; import org.exoplatform.container.PortalContainer; 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; /** * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> * @version $Revision$ */ public class TestNavigationServiceWrapper extends AbstractTestNavigationService { /** . */ private NavigationService navigationService; /** . */ private ListenerService listenerService; /** . */ private POMSessionManager mgr; @Override protected void setUp() throws Exception { PortalContainer container = getContainer(); // listenerService = (ListenerService) container.getComponentInstanceOfType(ListenerService.class); navigationService = (NavigationService) container.getComponentInstanceOfType(NavigationService.class); mgr = (POMSessionManager) container.getComponentInstanceOfType(POMSessionManager.class); // super.setUp(); } 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 NavigationContext navigation = new NavigationContext(SiteKey.portal("notification"), new NavigationState(3)); navigationService.saveNavigation(navigation); 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 navigation.setState(new NavigationState(1)); navigationService.saveNavigation(navigation); 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 navigation = navigationService.loadNavigation(SiteKey.portal("notification")); Node root = navigationService.loadNode(Node.MODEL, navigation, Scope.CHILDREN, null).getNode(); root.setState(new NodeState.Builder(root.getState()).label("foo").build()); navigationService.saveNode(root.context, null); 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.destroyNavigation(navigation); 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(); } public void testCacheInvalidation() throws Exception { SiteKey key = SiteKey.portal("wrapper_cache_invalidation"); // begin(); mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "wrapper_cache_invalidation") .getRootNavigation().addChild("default"); end(true); // begin(); navigationService.saveNavigation(new NavigationContext(key, new NavigationState(0))); end(true); // begin(); NavigationContext nav = navigationService.loadNavigation(key); assertNotNull(nav); NodeContext<Node> root = navigationService.loadNode(Node.MODEL, nav, Scope.ALL, null); assertNotNull(root); end(true); // begin(); mgr.getPOMService().getModel().getWorkspace().getSite(ObjectType.PORTAL_SITE, "wrapper_cache_invalidation").destroy(); end(true); // begin(); assertNull(navigationService.loadNavigation(key)); try { navigationService.rebaseNode(root, null, null); fail(); } catch (NavigationServiceException e) { assertEquals(NavigationError.UPDATE_CONCURRENTLY_REMOVED_NODE, e.getError()); } end(); } public void testCachingInMultiThreading() throws InterruptedException { final SiteKey foo = SiteKey.portal("test_caching_in_multi_threading"); assertNull(navigationService.loadNavigation(foo)); mgr.getPOMService().getModel().getWorkspace().addSite(ObjectType.PORTAL_SITE, "test_caching_in_multi_threading"); assertTrue(mgr.getSession().isModified()); sync(true); navigationService.saveNavigation(new NavigationContext(foo, new NavigationState(0))); // Start a new thread to work with navigations in parallels Thread t = new Thread(new Runnable() { @Override public void run() { begin(); // Loading the foo navigation and update into the cache if any assertFalse(mgr.getSession().isModified()); assertNull(navigationService.loadNavigation(foo)); end(true); } }); t.start(); t.join(); // It loads directly from DB assertTrue(mgr.getSession().isModified()); assertNotNull(navigationService.loadNavigation(foo)); sync(true); // It will load from Cache first if any assertFalse(mgr.getSession().isModified()); assertNotNull(navigationService.loadNavigation(foo)); } }