Author: rwatler
Date: Thu Aug 20 19:13:52 2009
New Revision: 806309
URL: http://svn.apache.org/viewvc?rev=806309&view=rev
Log:
implement portal site page manager object model view/proxy reaping
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/AbstractPageManager.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/AbstractPageManager.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/AbstractPageManager.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/AbstractPageManager.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/AbstractPageManager.java
Thu Aug 20 19:13:52 2009
@@ -57,10 +57,13 @@
{
private final static Log log =
LogFactory.getLog(AbstractPageManager.class);
+ private final static long DEFAULT_NODE_REAPING_INTERVAL = 300000;
+
private final static String FOLDER_NODE_TYPE = "folder";
private final static String PAGE_NODE_TYPE = "page";
private final static String FRAGMENT_NODE_TYPE = "fragment";
private final static String LINK_NODE_TYPE = "link";
+
protected Class fragmentClass;
protected Class pageClass;
protected Class folderClass;
@@ -91,11 +94,38 @@
private boolean constraintsEnabled;
private List listeners = new LinkedList();
+
+ private long nodeReapingInterval = DEFAULT_NODE_REAPING_INTERVAL;
public AbstractPageManager(boolean permissionsEnabled, boolean
constraintsEnabled)
- {
+ {
this.permissionsEnabled = permissionsEnabled;
this.constraintsEnabled = constraintsEnabled;
+ // start node reaping deamon thread
+ if (this.nodeReapingInterval > 0)
+ {
+ Thread nodeReapingThread = new Thread(new Runnable()
+ {
+ public void run()
+ {
+ while (true)
+ {
+ try
+ {
+ // wait for reap interval and invoke reaping
+ // notification on page manager event listeners
+ Thread.sleep(nodeReapingInterval);
+ notifyReapNodes();
+ }
+ catch (InterruptedException ie)
+ {
+ }
+ }
+ }
+ }, "PageManagerNodeReapingThread");
+ nodeReapingThread.setDaemon(true);
+ nodeReapingThread.start();
+ }
}
public AbstractPageManager(boolean permissionsEnabled, boolean
constraintsEnabled, Map modelClasses)
@@ -127,26 +157,16 @@
this.fragmentPreferenceClass =
(Class)modelClasses.get("FragmentPreferenceImpl");
}
- /**
- * <p>
- * getPermissionsEnabled
- * </p>
- *
+ /* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPermissionsEnabled()
- * @return
*/
public boolean getPermissionsEnabled()
{
return permissionsEnabled;
}
- /**
- * <p>
- * getConstraintsEnabled
- * </p>
- *
+ /* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getConstraintsEnabled()
- * @return
*/
public boolean getConstraintsEnabled()
{
@@ -154,6 +174,14 @@
}
/* (non-Javadoc)
+ * @see org.apache.jetspeed.page.PageManager#getNodeReapingInterval()
+ */
+ public long getNodeReapingInterval()
+ {
+ return nodeReapingInterval;
+ }
+
+ /* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPage(java.lang.String)
*/
public Page newPage(String path)
@@ -792,6 +820,34 @@
}
}
+ /**
+ * notifyReapNodes - notify page manager event listeners of
+ * reap nodes event
+ */
+ public void notifyReapNodes()
+ {
+ // copy listeners list to reduce synchronization deadlock
+ List listenersList = null;
+ synchronized (listeners)
+ {
+ listenersList = new ArrayList(listeners);
+ }
+ // notify listeners
+ Iterator listenersIter = listenersList.iterator();
+ while (listenersIter.hasNext())
+ {
+ PageManagerEventListener listener =
(PageManagerEventListener)listenersIter.next();
+ try
+ {
+ listener.reapNodes(nodeReapingInterval);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to notify page manager event listener", e);
+ }
+ }
+ }
+
public Folder copyFolder(Folder source, String path)
throws NodeException
{
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/impl/DatabasePageManager.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/java/org/apache/jetspeed/page/impl/DatabasePageManager.java
Thu Aug 20 19:13:52 2009
@@ -187,6 +187,14 @@
}
/* (non-Javadoc)
+ * @see org.apache.jetspeed.page.PageManager#getNodeReapingInterval()
+ */
+ public long getNodeReapingInterval()
+ {
+ return delegator.getNodeReapingInterval();
+ }
+
+ /* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPage(java.lang.String)
*/
public Page newPage(String path)
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/page-manager/src/test/org/apache/jetspeed/page/TestDatabasePageManager.java
Thu Aug 20 19:13:52 2009
@@ -152,6 +152,13 @@
{
removedNodeCount++;
}
+
+ /* (non-Javadoc)
+ * @see org.apache.jetspeed.page.PageManagerEventListener#reapNodes(long)
+ */
+ public void reapNodes(long interval)
+ {
+ }
public void testCreates() throws Exception
{
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/components/portal-site/src/java/org/apache/jetspeed/portalsite/impl/PortalSiteSessionContextImpl.java
Thu Aug 20 19:13:52 2009
@@ -129,6 +129,11 @@
private transient String pipeline = "";
/**
+ * locatorsLastUpdateCheck - time stamp of last locators update check.
+ */
+ private transient long locatorsLastUpdateCheck;
+
+ /**
* PortalSiteSessionContextImpl - constructor
*
* @param pageManager PageManager component instance
@@ -277,13 +282,13 @@
// clear all history entries for fallback
// request path in advance to make fallback
// page selection more predictable
- Iterator folderIter =
getFolderPageHistory().keySet().iterator();
- while (folderIter.hasNext())
+ Iterator folderPathIter =
getFolderPageHistory().keySet().iterator();
+ while (folderPathIter.hasNext())
{
- Folder folder = (Folder)folderIter.next();
- if (folder.getUrl().equals(fallbackRequestPath))
+ String folderPath = (String)folderPathIter.next();
+ if (folderPath.equals(fallbackRequestPath))
{
- folderIter.remove();
+ folderPathIter.remove();
break;
}
}
@@ -538,21 +543,34 @@
{
Page requestPage = null;
- // attempt to lookup last visited page by folder proxy
- // path, (proxies are hashed by their path), contains
- // test must be performed since identical paths may
- // occur in multiple site views
+ // attempt to lookup last visited page by folder path;
+ // page id test must be performed since identical paths
+ // may occur in multiple site views
if (useHistory)
{
- requestPage =
(Page)getFolderPageHistory().get(requestFolder);
- if ((requestPage != null) &&
requestFolderPages.contains(requestPage))
+ String requestPageId =
(String)getFolderPageHistory().get(requestFolder.getPath());
+ if (requestPageId != null)
{
+ // find page by id in request folder pages
+ Iterator requestFolderPagesIter =
requestFolderPages.iterator();
+ while ((requestPage == null) &&
(requestFolderPagesIter.hasNext()))
+ {
+ Page requestFolderPage =
(Page)requestFolderPagesIter.next();
+ if
(requestPageId.equals(requestFolderPage.getId()))
+ {
+ requestPage = requestFolderPage;
+ }
+ }
+
// log selected request page
- if (log.isDebugEnabled())
+ if (requestPage != null)
{
- log.debug("Selected folder historical page:
path=" + view.getManagedPage(requestPage).getPath());
+ if (log.isDebugEnabled())
+ {
+ log.debug("Selected folder historical
page: path=" + view.getManagedPage(requestPage).getPath());
+ }
+ return requestPage;
}
- return requestPage;
}
}
@@ -569,13 +587,12 @@
}
try
{
- // save last visited non-hidden page for folder
proxy
- // path, (proxies are hashed by their path), and
- // return default page
+ // save last visited non-hidden page for folder
path
+ // and return default page
requestPage =
requestFolder.getPage(defaultPageName);
if (!requestPage.isHidden())
{
- getFolderPageHistory().put(requestFolder,
requestPage);
+
getFolderPageHistory().put(requestFolder.getPath(), requestPage.getId());
}
// log selected request page
@@ -599,12 +616,11 @@
// default page not available, select first page
// proxy in request folder; save last visited
- // non-hidden page for folder proxy path, (proxies
- // are hashed by their path), and return default page
+ // non-hidden page for folder path and return default page
requestPage = (Page)requestFolderPages.iterator().next();
if (!requestPage.isHidden())
{
- getFolderPageHistory().put(requestFolder, requestPage);
+ getFolderPageHistory().put(requestFolder.getPath(),
requestPage.getId());
}
// log selected request page
@@ -619,13 +635,12 @@
{
Page requestPage = (Page)requestNode;
- // save last visited non-hidden page for folder proxy
- // path, (proxies are hashed by their path), and
- // return matched page
+ // save last visited non-hidden page for folder path
+ // and return matched page
Folder requestFolder = (Folder)requestPage.getParent();
if (!requestPage.isHidden())
{
- getFolderPageHistory().put(requestFolder, requestPage);
+ getFolderPageHistory().put(requestFolder.getPath(),
requestPage.getId());
}
// log selected request page
@@ -729,6 +744,7 @@
userPrincipal = currentUserPrincipal;
updated = true;
}
+ locatorsLastUpdateCheck = System.currentTimeMillis();
}
// log session context setup and update
@@ -759,11 +775,11 @@
{
debug.append("Updated stale");
}
- debug.append(" context: user=" + userPrincipal + ",
profileLocators=(");
- if (profileLocators != null)
+ debug.append(" context: user=" + currentUserPrincipal + ",
profileLocators=(");
+ if (requestProfileLocators != null)
{
boolean firstEntry = true;
- Iterator entriesIter =
profileLocators.entrySet().iterator();
+ Iterator entriesIter =
requestProfileLocators.entrySet().iterator();
while (entriesIter.hasNext())
{
Map.Entry entry = (Map.Entry)entriesIter.next();
@@ -801,23 +817,20 @@
/**
* clearSessionProfileLocators - clear cache session profile locators
*/
- private void clearSessionProfileLocators()
+ private synchronized 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 = null;
+ if (menuDefinitionLocatorCache != null)
{
- profileLocators = null;
- userPrincipal = null;
- siteView = null;
- folderPageHistory = null;
- if (menuDefinitionLocatorCache != null)
- {
- menuDefinitionLocatorCache.clear();
- }
- stale = false;
+ menuDefinitionLocatorCache.clear();
}
+ stale = false;
}
/**
@@ -828,18 +841,27 @@
*/
public SiteView getSiteView()
{
- if ((siteView == null) && (pageManager != null) && (profileLocators !=
null))
+ // get or create site view
+ SiteView view = null;
+ boolean viewCreated = false;
+ synchronized (this)
{
- // create new site view
- siteView = new SiteView(pageManager, profileLocators);
-
- // log site view creation
- if (log.isDebugEnabled())
+ if ((siteView == null) && (pageManager != null) &&
(profileLocators != null))
{
- log.debug("Created site view: search paths=" +
siteView.getSearchPathsString());
+ // create new site view
+ siteView = new SiteView(pageManager, profileLocators);
+ viewCreated = true;
}
+ view = siteView;
+ }
+
+ // log site view creation
+ if (viewCreated && log.isDebugEnabled())
+ {
+ log.debug("Created site view: search paths=" +
view.getSearchPathsString());
}
- return siteView;
+
+ return view;
}
/**
@@ -861,7 +883,7 @@
*/
public boolean isValid()
{
- // existant transient page manager implies valid context
+ // existent transient page manager implies valid context
return (pageManager != null);
}
@@ -1111,12 +1133,8 @@
}
*/
- /**
- * 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
+ /* (non-Javadoc)
+ * @see
org.apache.jetspeed.page.PageManagerEventListener#newNode(org.apache.jetspeed.page.document.Node)
*/
public void newNode(Node node)
{
@@ -1124,12 +1142,8 @@
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
+ /* (non-Javadoc)
+ * @see
org.apache.jetspeed.page.PageManagerEventListener#updatedNode(org.apache.jetspeed.page.document.Node)
*/
public void updatedNode(Node node)
{
@@ -1153,18 +1167,28 @@
}
}
- /**
- * 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
+ /* (non-Javadoc)
+ * @see
org.apache.jetspeed.page.PageManagerEventListener#removedNode(org.apache.jetspeed.page.document.Node)
*/
public void removedNode(Node node)
{
// equivalent to node updated event
updatedNode(node);
}
+
+ /* (non-Javadoc)
+ * @see org.apache.jetspeed.page.PageManagerEventListener#reapNodes(long)
+ */
+ public synchronized void reapNodes(long interval)
+ {
+ // reap page manager nodes for idle sessions to free
+ // system resources; the site view will be lazily
+ // recalculated if the session is resumed
+ if ((locatorsLastUpdateCheck > 0) &&
(System.currentTimeMillis()-locatorsLastUpdateCheck > interval))
+ {
+ siteView = null;
+ }
+ }
/**
* sessionDidActivate - notification that the session has just
@@ -1238,18 +1262,18 @@
*/
public void valueUnbound(HttpSessionBindingEvent event)
{
- // unsubscribe this session context to page manager events
synchronized (this)
{
+ // unsubscribe this session context to page manager events
if (subscribed && (pageManager != null))
{
pageManager.removeListener(this);
subscribed = false;
}
- }
- // clear session context state
- clearSessionProfileLocators();
+ // clear session context state
+ clearSessionProfileLocators();
+ }
// log binding event
if (log.isDebugEnabled())
@@ -1258,7 +1282,7 @@
}
}
- private Map getFolderPageHistory()
+ private synchronized Map getFolderPageHistory()
{
if (folderPageHistory == null)
{
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManager.java
Thu Aug 20 19:13:52 2009
@@ -58,24 +58,27 @@
public String SERVICE_NAME = "PageManager";
/**
- * <p>
- * getConstraintsEnabled
- * </p>
+ * Get constraints enabled.
*
* @return enabled indicator
*/
public boolean getConstraintsEnabled();
/**
- * <p>
- * getPermissionsEnabled
- * </p>
+ * Get permissions enabled.
*
* @return enabled indicator
*/
public boolean getPermissionsEnabled();
/**
+ * Get node reaping interval.
+ *
+ * @return reaping interval
+ */
+ public long getNodeReapingInterval();
+
+ /**
* Creates a new empty Page instance
*
* @return a newly created Page object
Modified:
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java?rev=806309&r1=806308&r2=806309&view=diff
==============================================================================
---
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java
(original)
+++
portals/jetspeed-2/portal/branches/JETSPEED-2.1.3-POSTRELEASE/jetspeed-api/src/java/org/apache/jetspeed/page/PageManagerEventListener.java
Thu Aug 20 19:13:52 2009
@@ -53,4 +53,13 @@
* @param node removed managed node if known
*/
void removedNode(Node node);
+
+ /**
+ * reapNodes - periodically invoked by page manager to
+ * indicate lifetime of node references should
+ * be checked to see if they should be reaped
+ *
+ * @param interval reap nodes interval
+ */
+ void reapNodes(long interval);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]