Return-Path: Delivered-To: apmail-portals-jetspeed-dev-archive@www.apache.org Received: (qmail 95401 invoked from network); 11 Jul 2005 04:40:42 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 11 Jul 2005 04:40:42 -0000 Received: (qmail 45791 invoked by uid 500); 11 Jul 2005 04:40:40 -0000 Delivered-To: apmail-portals-jetspeed-dev-archive@portals.apache.org Received: (qmail 45362 invoked by uid 500); 11 Jul 2005 04:40:39 -0000 Mailing-List: contact jetspeed-dev-help@portals.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Jetspeed Developers List" Delivered-To: mailing list jetspeed-dev@portals.apache.org Received: (qmail 45349 invoked by uid 99); 11 Jul 2005 04:40:39 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 10 Jul 2005 21:40:39 -0700 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 10 Jul 2005 21:40:36 -0700 Received: (qmail 95361 invoked by uid 65534); 11 Jul 2005 04:40:35 -0000 Message-ID: <20050711044035.95360.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r210065 - in /portals/jetspeed-2/branches/MENUS_BRANCH: components/page-manager/src/java/org/apache/jetspeed/page/impl/ components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/ jetspeed-api/src/java/org/apache/jetspeed/page/ Date: Mon, 11 Jul 2005 04:40:34 -0000 To: jetspeed-dev@portals.apache.org From: rwatler@apache.org X-Mailer: svnmailer-1.0.2 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: rwatler Date: Sun Jul 10 21:40:31 2005 New Revision: 210065 URL: http://svn.apache.org/viewcvs?rev=210065&view=rev Log: implement page manager changed listener and subscribe portal site session context to the page manager and session life cycle events Added: portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java (with props) Modified: portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/AbstractPageManager.java portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/CastorXmlPageManager.java portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java (contents, props changed) portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java Modified: portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/AbstractPageManager.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/AbstractPageManager.java?rev=210065&r1=210064&r2=210065&view=diff ============================================================================== --- portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/AbstractPageManager.java (original) +++ portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/AbstractPageManager.java Sun Jul 10 21:40:31 2005 @@ -15,7 +15,9 @@ */ package org.apache.jetspeed.page.impl; +import java.util.Iterator; import java.util.List; +import java.util.LinkedList; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,6 +40,8 @@ import org.apache.jetspeed.om.page.psml.PageImpl; import org.apache.jetspeed.om.page.psml.PropertyImpl; import org.apache.jetspeed.page.PageManager; +import org.apache.jetspeed.page.PageManagerEventListener; +import org.apache.jetspeed.page.document.Node; /** * AbstractPageManagerService @@ -65,6 +69,8 @@ private boolean constraintsEnabled; + private List listeners = new LinkedList(); + public AbstractPageManager(IdGenerator generator, boolean permissionsEnabled, boolean constraintsEnabled) { this.generator = generator; @@ -286,7 +292,7 @@ * @param classe implementation class * @return a newly created implementation object */ - public Object createObject(Class classe) + private Object createObject(Class classe) { Object object = null; try @@ -299,4 +305,95 @@ } return object; } + + /** + * addListener - add page manager event listener + * + * @param listener page manager event listener + */ + public void addListener(PageManagerEventListener listener) + { + // add listener to listeners list + listeners.add(listener); + } + + /** + * removeListener - remove page manager event listener + * + * @param listener page manager event listener + */ + public void removeListener(PageManagerEventListener listener) + { + // remove listener from listeners list + listeners.remove(listener); + } + + /** + * notifyNewNode - notify page manager event listeners of + * new node event + * + * @param node new managed node if known + */ + protected void notifyNewNode(Node node) + { + Iterator listenersIter = listeners.iterator(); + while (listenersIter.hasNext()) + { + PageManagerEventListener listener = (PageManagerEventListener)listenersIter.next(); + try + { + listener.newNode(node); + } + catch (Exception e) + { + log.error("Failed to notify page manager event listener", e); + } + } + } + + /** + * notifyUpdatedNode - notify page manager event listeners of + * updated node event + * + * @param node updated managed node if known + */ + protected void notifyUpdatedNode(Node node) + { + Iterator listenersIter = listeners.iterator(); + while (listenersIter.hasNext()) + { + PageManagerEventListener listener = (PageManagerEventListener)listenersIter.next(); + try + { + listener.updatedNode(node); + } + catch (Exception e) + { + log.error("Failed to notify page manager event listener", e); + } + } + } + + /** + * notifyRemovedNode - notify page manager event listeners of + * removed node event + * + * @param node removed managed node if known + */ + protected void notifyRemovedNode(Node node) + { + Iterator listenersIter = listeners.iterator(); + while (listenersIter.hasNext()) + { + PageManagerEventListener listener = (PageManagerEventListener)listenersIter.next(); + try + { + listener.removedNode(node); + } + catch (Exception e) + { + log.error("Failed to notify page manager event listener", e); + } + } + } } Modified: portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/CastorXmlPageManager.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/CastorXmlPageManager.java?rev=210065&r1=210064&r2=210065&view=diff ============================================================================== --- portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/CastorXmlPageManager.java (original) +++ portals/jetspeed-2/branches/MENUS_BRANCH/components/page-manager/src/java/org/apache/jetspeed/page/impl/CastorXmlPageManager.java Sun Jul 10 21:40:31 2005 @@ -41,6 +41,7 @@ import org.apache.jetspeed.page.document.DocumentHandlerFactory; import org.apache.jetspeed.page.document.DocumentNotFoundException; import org.apache.jetspeed.page.document.FolderHandler; +import org.apache.jetspeed.page.document.Node; import org.apache.jetspeed.page.document.NodeException; import org.apache.jetspeed.page.document.NodeSet; import org.apache.jetspeed.page.document.NodeSetImpl; @@ -131,6 +132,7 @@ } // make sure path and related members are set + boolean newPageRegistered = false; if ((page.getPath() == null) && (page.getId() != null)) { String path = page.getId(); @@ -144,6 +146,7 @@ } page.setId(path); page.setPath(path); + newPageRegistered = true; } if (page.getPath() != null) { @@ -172,6 +175,16 @@ folder.getAllNodes().add(page); } page.setParent(folder); + + // notify page manager listeners + if (newPageRegistered) + { + notifyNewNode(page); + } + else + { + notifyUpdatedNode(page); + } } /** @@ -217,6 +230,9 @@ FolderImpl folder = getNodeFolder(page.getPath()); ((NodeSetImpl)folder.getAllNodes()).remove(page); page.setParent(null); + + // notify page manager listeners + notifyRemovedNode(page); } /** @@ -327,7 +343,21 @@ */ public void refresh( FileCacheEntry entry ) throws Exception { - // file cache managed component refreshed + // file cache managed component refreshed: + // notify page manager listeners + Node refreshedNode = null; + if (entry.getDocument() instanceof Node) + { + refreshedNode = (Node)entry.getDocument(); + } + if (entry.getFile().exists()) + { + notifyUpdatedNode(refreshedNode); + } + else + { + notifyRemovedNode(refreshedNode); + } } /** @@ -341,7 +371,11 @@ */ public void evict( FileCacheEntry entry ) throws Exception { - // file cache managed component evicted + // file cache managed component evicted: + // no notifications required since eviction + // is normal cache operation and does not + // indicate a change in the nodes managed by + // this page manager } /* (non-Javadoc) Modified: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java?rev=210065&r1=210064&r2=210065&view=diff ============================================================================== --- portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java (original) +++ portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java Sun Jul 10 21:40:31 2005 @@ -24,12 +24,17 @@ import java.util.Set; import javax.security.auth.Subject; +import javax.servlet.http.HttpSessionActivationListener; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; +import javax.servlet.http.HttpSessionEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jetspeed.om.folder.Folder; import org.apache.jetspeed.om.page.Page; import org.apache.jetspeed.page.PageManager; +import org.apache.jetspeed.page.PageManagerEventListener; import org.apache.jetspeed.page.document.Node; import org.apache.jetspeed.page.document.NodeException; import org.apache.jetspeed.page.document.NodeNotFoundException; @@ -45,12 +50,13 @@ /** * This class encapsulates managed session state for and - * interface to the portal-site component. + * interface to the portal-site component and subscribes + * to page manager and session events to flush stale state * * @author Randy Watler * @version $Id$ */ -public class PortalSiteSessionContextImpl implements PortalSiteSessionContext +public class PortalSiteSessionContextImpl implements PortalSiteSessionContext, PageManagerEventListener, HttpSessionActivationListener, HttpSessionBindingListener { /** * log - logging instance @@ -89,6 +95,18 @@ private Map menuDefinitionLocatorCache; /** + * subscribed - flag that indicates whether this context + * is subscribed as event listeners + */ + private boolean subscribed; + + /** + * stale - flag that indicates whether the state + * managed by this context is stale + */ + private boolean stale; + + /** * PortalSiteSessionContextImpl - constructor * * @param pageManager PageManager component instance @@ -404,65 +422,94 @@ } } - // detect modification of user principal or - // profile locators for session - if (((userPrincipal == null) && (currentUserPrincipal != null)) || - ((userPrincipal != null) && !userPrincipal.equals(currentUserPrincipal)) || - (profileLocators == null) || - !locatorsEquals(profileLocators, requestProfileLocators)) - { - // reset cached session profile locators, view, - // folder page history, and menu definition locators - profileLocators = requestProfileLocators; - userPrincipal = currentUserPrincipal; - siteView = null; - folderPageHistory.clear(); - if (menuDefinitionLocatorCache != null) - { - menuDefinitionLocatorCache.clear(); + // detect stale session, modification of user + // principal, or changed profile locators for + // this session context + boolean updated = false; + synchronized (this) + { + if (stale || + ((userPrincipal == null) && (currentUserPrincipal != null)) || + ((userPrincipal != null) && !userPrincipal.equals(currentUserPrincipal)) || + (profileLocators == null) || + !locatorsEquals(profileLocators, requestProfileLocators)) + { + // reset cached session profile locators, view, + // folder page history, menu definition locators, + // and stale flag + clearSessionProfileLocators(); + profileLocators = requestProfileLocators; + userPrincipal = currentUserPrincipal; + updated = true; } + } - // log session context setup and update - if (log.isDebugEnabled()) - { - StringBuffer debug = new StringBuffer(); - debug.append("Updated context: user=" + userPrincipal + ", profileLocators=("); - if (profileLocators != null) + // log session context setup and update + if (updated && log.isDebugEnabled()) + { + StringBuffer debug = new StringBuffer(); + debug.append("Updated context: user=" + userPrincipal + ", profileLocators=("); + if (profileLocators != null) + { + boolean firstEntry = true; + Iterator entriesIter = profileLocators.entrySet().iterator(); + while (entriesIter.hasNext()) { - boolean firstEntry = true; - Iterator entriesIter = profileLocators.entrySet().iterator(); - while (entriesIter.hasNext()) + Map.Entry entry = (Map.Entry)entriesIter.next(); + String locatorName = (String)entry.getKey(); + ProfileLocator locator = (ProfileLocator)entry.getValue(); + if (!firstEntry) { - Map.Entry entry = (Map.Entry)entriesIter.next(); - String locatorName = (String)entry.getKey(); - ProfileLocator locator = (ProfileLocator)entry.getValue(); - if (!firstEntry) - { - debug.append(","); - } - else - { - firstEntry = false; - } - debug.append(locatorName); - debug.append("="); - debug.append(locator.toString()); + debug.append(","); } + else + { + firstEntry = false; + } + debug.append(locatorName); + debug.append("="); + debug.append(locator.toString()); } - else - { - debug.append("null"); - } - debug.append(")"); - log.debug(debug); } + else + { + debug.append("null"); + } + debug.append(")"); + log.debug(debug); } + + // return valid return true; } + + // return invalid return false; } /** + * clearSessionProfileLocators - clear cache session profile locators + */ + private void clearSessionProfileLocators() + { + // clear cached session profile locators, view, + // folder page history, menu definition locators, + // and stale flag + synchronized (this) + { + profileLocators = null; + userPrincipal = null; + siteView = null; + folderPageHistory.clear(); + if (menuDefinitionLocatorCache != null) + { + menuDefinitionLocatorCache.clear(); + } + stale = false; + } + } + + /** * getSiteView - lookup and/or create site view for * profile locators of this context * @@ -734,5 +781,152 @@ } } return requestPath; + } + + /** + * newNode - invoked when the definition of a node is + * created by the page manager or when the + * node creation is otherwise detected + * + * @param node new managed node if known + */ + public void newNode(Node node) + { + // equivalent to node updated event + updatedNode(node); + } + + /** + * updatedNode - invoked when the definition of a node is + * updated by the page manager or when the + * node modification is otherwise detected + * + * @param node updated managed node if known + */ + public void updatedNode(Node node) + { + // set stale flag to force session context state reset + synchronized (this) + { + stale = true; + } + + // log updated node event + if (log.isDebugEnabled()) + { + if (node != null) + { + log.debug("Page manager update event, (node=" + node.getPath() + "): set session context state stale"); + } + else + { + log.debug("Page manager update event: set session context state stale"); + } + } + } + + /** + * removedNode - invoked when the definition of a node is + * removed by the page manager or when the + * node removal is otherwise detected + * + * @param node removed managed node if known + */ + public void removedNode(Node node) + { + // equivalent to node updated event + updatedNode(node); + } + + /** + * sessionDidActivate - notification that the session has just + * been activated + * + * @param event session activation event + */ + public void sessionDidActivate(HttpSessionEvent event) + { + // set stale flag to force session context state reset + synchronized (this) + { + stale = true; + } + + // log activation event + if (log.isDebugEnabled()) + { + log.debug("Session activation event: set session context state stale"); + } + } + + /** + * sessionWillPassivate - notification that the session is about + * to be passivated + * + * @param event session activation event + */ + public void sessionWillPassivate(HttpSessionEvent event) + { + // clear session context state + clearSessionProfileLocators(); + + // log activation event + if (log.isDebugEnabled()) + { + log.debug("Session deactivation event: clear session context state"); + } + } + + /** + * valueBound - notifies this context that it is being bound to + * a session and identifies the session + * + * @param event session binding event + */ + public void valueBound(HttpSessionBindingEvent event) + { + // subscribe this session context to page manager events + synchronized (this) + { + if (!subscribed) + { + pageManager.addListener(this); + subscribed = true; + } + } + + // log binding event + if (log.isDebugEnabled()) + { + log.debug("Session bound event: setup page manager listener"); + } + } + + /** + * valueUnbound - notifies this context that it is being unbound + * from a session and identifies the session + * + * @param event session binding event + */ + public void valueUnbound(HttpSessionBindingEvent event) + { + // unsubscribe this session context to page manager events + synchronized (this) + { + if (subscribed) + { + pageManager.removeListener(this); + subscribed = false; + } + } + + // clear session context state + clearSessionProfileLocators(); + + // log binding event + if (log.isDebugEnabled()) + { + log.debug("Session unbound event: clear page manager listener and session context state"); + } } } Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java?rev=210065&r1=210064&r2=210065&view=diff ============================================================================== --- portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java (original) +++ portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java Sun Jul 10 21:40:31 2005 @@ -213,4 +213,17 @@ */ public void removePage(Page page) throws JetspeedException, PageNotRemovedException; + /** + * addListener - add page manager event listener + * + * @param listener page manager event listener + */ + public void addListener(PageManagerEventListener listener); + + /** + * removeListener - remove page manager event listener + * + * @param listener page manager event listener + */ + public void removeListener(PageManagerEventListener listener); } Added: portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java URL: http://svn.apache.org/viewcvs/portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java?rev=210065&view=auto ============================================================================== --- portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java (added) +++ portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java Sun Jul 10 21:40:31 2005 @@ -0,0 +1,55 @@ +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jetspeed.page; + +import org.apache.jetspeed.page.document.Node; + +/** + * This interface describes the page manager event listener + * that is notified when a managed node is updated or removed + * + * @author Randy Watler + * @version $Id$ + */ +public interface PageManagerEventListener +{ + /** + * newNode - invoked when the definition of a node is + * created by the page manager or when the + * node creation is otherwise detected + * + * @param node new managed node if known + */ + void newNode(Node node); + + /** + * updatedNode - invoked when the definition of a node is + * updated by the page manager or when the + * node modification is otherwise detected + * + * @param node updated managed node if known + */ + void updatedNode(Node node); + + /** + * removedNode - invoked when the definition of a node is + * removed by the page manager or when the + * node removal is otherwise detected + * + * @param node removed managed node if known + */ + void removedNode(Node node); +} Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: portals/jetspeed-2/branches/MENUS_BRANCH/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java ------------------------------------------------------------------------------ svn:keywords = Id --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org For additional commands, e-mail: jetspeed-dev-help@portals.apache.org