/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.impl;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.security.auth.Subject;
import org.apache.jetspeed.JetspeedActions;
import org.apache.jetspeed.cache.JetspeedCache;
import org.apache.jetspeed.components.dao.InitablePersistenceBrokerDaoSupport;
import org.apache.jetspeed.idgenerator.IdGenerator;
import org.apache.jetspeed.om.common.SecurityConstraint;
import org.apache.jetspeed.om.common.SecurityConstraints;
import org.apache.jetspeed.om.folder.Folder;
import org.apache.jetspeed.om.folder.FolderNotFoundException;
import org.apache.jetspeed.om.folder.InvalidFolderException;
import org.apache.jetspeed.om.folder.MenuDefinition;
import org.apache.jetspeed.om.folder.MenuExcludeDefinition;
import org.apache.jetspeed.om.folder.MenuIncludeDefinition;
import org.apache.jetspeed.om.folder.MenuOptionsDefinition;
import org.apache.jetspeed.om.folder.MenuSeparatorDefinition;
import org.apache.jetspeed.om.folder.impl.FolderImpl;
import org.apache.jetspeed.om.folder.impl.FolderMenuDefinitionImpl;
import org.apache.jetspeed.om.folder.impl.FolderMenuExcludeDefinitionImpl;
import org.apache.jetspeed.om.folder.impl.FolderMenuIncludeDefinitionImpl;
import org.apache.jetspeed.om.folder.impl.FolderMenuOptionsDefinitionImpl;
import org.apache.jetspeed.om.folder.impl.FolderMenuSeparatorDefinitionImpl;
import org.apache.jetspeed.om.folder.impl.FolderSecurityConstraintImpl;
import org.apache.jetspeed.om.page.BaseFragmentElement;
import org.apache.jetspeed.om.page.BaseFragmentsElement;
import org.apache.jetspeed.om.page.DynamicPage;
import org.apache.jetspeed.om.page.Fragment;
import org.apache.jetspeed.om.page.FragmentDefinition;
import org.apache.jetspeed.om.page.FragmentProperty;
import org.apache.jetspeed.om.page.FragmentReference;
import org.apache.jetspeed.om.page.Link;
import org.apache.jetspeed.om.page.Page;
import org.apache.jetspeed.om.page.PageFragment;
import org.apache.jetspeed.om.page.PageSecurity;
import org.apache.jetspeed.om.page.PageTemplate;
import org.apache.jetspeed.om.page.SecurityConstraintsDef;
import org.apache.jetspeed.om.page.impl.BaseFragmentElementImpl;
import org.apache.jetspeed.om.page.impl.BaseFragmentsElementImpl;
import org.apache.jetspeed.om.page.impl.DynamicPageImpl;
import org.apache.jetspeed.om.page.impl.FragmentDefinitionImpl;
import org.apache.jetspeed.om.page.impl.FragmentImpl;
import org.apache.jetspeed.om.page.impl.FragmentPreferenceImpl;
import org.apache.jetspeed.om.page.impl.FragmentPropertyImpl;
import org.apache.jetspeed.om.page.impl.FragmentPropertyListImpl;
import org.apache.jetspeed.om.page.impl.FragmentReferenceImpl;
import org.apache.jetspeed.om.page.impl.FragmentSecurityConstraintImpl;
import org.apache.jetspeed.om.page.impl.LinkImpl;
import org.apache.jetspeed.om.page.impl.LinkSecurityConstraintImpl;
import org.apache.jetspeed.om.page.impl.PageFragmentImpl;
import org.apache.jetspeed.om.page.impl.PageImpl;
import org.apache.jetspeed.om.page.impl.PageMenuDefinitionImpl;
import org.apache.jetspeed.om.page.impl.PageMenuExcludeDefinitionImpl;
import org.apache.jetspeed.om.page.impl.PageMenuIncludeDefinitionImpl;
import org.apache.jetspeed.om.page.impl.PageMenuOptionsDefinitionImpl;
import org.apache.jetspeed.om.page.impl.PageMenuSeparatorDefinitionImpl;
import org.apache.jetspeed.om.page.impl.PageSecurityConstraintImpl;
import org.apache.jetspeed.om.page.impl.PageSecurityImpl;
import org.apache.jetspeed.om.page.impl.PageSecuritySecurityConstraintImpl;
import org.apache.jetspeed.om.page.impl.PageTemplateImpl;
import org.apache.jetspeed.om.page.impl.SecurityConstraintsDefImpl;
import org.apache.jetspeed.om.page.impl.SecurityConstraintsImpl;
import org.apache.jetspeed.om.preference.FragmentPreference;
import org.apache.jetspeed.page.DelegatingPageManager;
import org.apache.jetspeed.page.FolderNotRemovedException;
import org.apache.jetspeed.page.FolderNotUpdatedException;
import org.apache.jetspeed.page.FragmentPropertyList;
import org.apache.jetspeed.page.FragmentPropertyManagement;
import org.apache.jetspeed.page.LinkNotRemovedException;
import org.apache.jetspeed.page.LinkNotUpdatedException;
import org.apache.jetspeed.page.PageManager;
import org.apache.jetspeed.page.PageManagerEventListener;
import org.apache.jetspeed.page.PageManagerSecurityUtils;
import org.apache.jetspeed.page.PageManagerUtils;
import org.apache.jetspeed.page.PageNotFoundException;
import org.apache.jetspeed.page.PageNotRemovedException;
import org.apache.jetspeed.page.PageNotUpdatedException;
import org.apache.jetspeed.page.document.DocumentException;
import org.apache.jetspeed.page.document.DocumentNotFoundException;
import org.apache.jetspeed.page.document.FailedToDeleteDocumentException;
import org.apache.jetspeed.page.document.FailedToUpdateDocumentException;
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.impl.NodeImpl;
import org.apache.jetspeed.security.Group;
import org.apache.jetspeed.security.JSSubject;
import org.apache.jetspeed.security.Role;
import org.apache.jetspeed.security.SubjectHelper;
import org.apache.jetspeed.security.User;
import org.apache.ojb.broker.core.proxy.ProxyHelper;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.QueryByCriteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* DatabasePageManager
*
* @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
* @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
* @version $Id: $
*/
public class DatabasePageManager extends InitablePersistenceBrokerDaoSupport implements PageManager, FragmentPropertyManagement
{
private static Logger log = LoggerFactory.getLogger(DatabasePageManager.class);
private static final int MIN_THREAD_CACHE_SIZE = 16;
private static ThreadLocal fragmentPropertyListsCache = new ThreadLocal();
private static Map modelClasses = new HashMap();
static
{
modelClasses.put("FragmentImpl", FragmentImpl.class);
modelClasses.put("PageImpl", PageImpl.class);
modelClasses.put("FolderImpl", FolderImpl.class);
modelClasses.put("LinkImpl", LinkImpl.class);
modelClasses.put("PageSecurityImpl", PageSecurityImpl.class);
modelClasses.put("FolderMenuDefinitionImpl", FolderMenuDefinitionImpl.class);
modelClasses.put("FolderMenuExcludeDefinitionImpl", FolderMenuExcludeDefinitionImpl.class);
modelClasses.put("FolderMenuIncludeDefinitionImpl", FolderMenuIncludeDefinitionImpl.class);
modelClasses.put("FolderMenuOptionsDefinitionImpl", FolderMenuOptionsDefinitionImpl.class);
modelClasses.put("FolderMenuSeparatorDefinitionImpl", FolderMenuSeparatorDefinitionImpl.class);
modelClasses.put("PageMenuDefinitionImpl", PageMenuDefinitionImpl.class);
modelClasses.put("PageMenuExcludeDefinitionImpl", PageMenuExcludeDefinitionImpl.class);
modelClasses.put("PageMenuIncludeDefinitionImpl", PageMenuIncludeDefinitionImpl.class);
modelClasses.put("PageMenuOptionsDefinitionImpl", PageMenuOptionsDefinitionImpl.class);
modelClasses.put("PageMenuSeparatorDefinitionImpl", PageMenuSeparatorDefinitionImpl.class);
modelClasses.put("SecurityConstraintsImpl", SecurityConstraintsImpl.class);
modelClasses.put("FolderSecurityConstraintImpl", FolderSecurityConstraintImpl.class);
modelClasses.put("PageSecurityConstraintImpl", PageSecurityConstraintImpl.class);
modelClasses.put("FragmentSecurityConstraintImpl", FragmentSecurityConstraintImpl.class);
modelClasses.put("LinkSecurityConstraintImpl", LinkSecurityConstraintImpl.class);
modelClasses.put("PageSecuritySecurityConstraintImpl", PageSecuritySecurityConstraintImpl.class);
modelClasses.put("SecurityConstraintsDefImpl", SecurityConstraintsDefImpl.class);
modelClasses.put("FragmentPreferenceImpl", FragmentPreferenceImpl.class);
modelClasses.put("FragmentReferenceImpl", FragmentReferenceImpl.class);
modelClasses.put("PageFragmentImpl", PageFragmentImpl.class);
modelClasses.put("PageTemplateImpl", PageTemplateImpl.class);
modelClasses.put("DynamicPageImpl", DynamicPageImpl.class);
modelClasses.put("FragmentDefinitionImpl", FragmentDefinitionImpl.class);
modelClasses.put("FragmentPropertyImpl", FragmentPropertyImpl.class);
}
private DelegatingPageManager delegator;
private int maxThreadCacheSize;
private PageManager pageManagerProxy;
public DatabasePageManager(String repositoryPath, IdGenerator generator, boolean isPermissionsSecurity, boolean isConstraintsSecurity, JetspeedCache oidCache, JetspeedCache pathCache,
JetspeedCache propertiesCache, JetspeedCache propertiesPathCache, JetspeedCache principalPropertiesCache, JetspeedCache principalPropertiesPathCache)
{
super(repositoryPath);
delegator = new DelegatingPageManager(generator, isPermissionsSecurity, isConstraintsSecurity, modelClasses);
maxThreadCacheSize = Math.max(Math.max(Math.max(oidCache.getMaxSize()/10, propertiesCache.getMaxSize()/10), principalPropertiesCache.getMaxSize()/10), MIN_THREAD_CACHE_SIZE);
DatabasePageManagerCache.cacheInit(oidCache, pathCache, propertiesCache, propertiesPathCache, principalPropertiesCache, principalPropertiesPathCache, this);
}
/**
* Initialize PageManager component.
*/
public void init() throws Exception
{
// initialize persistence broker support
super.init();
// initialize PageManager delegate
delegator.init();
}
/**
* Destroy PageManager component.
*/
public void destroy()
{
// destroy PageManager delegate
delegator.destroy();
}
/**
* getPageManagerProxy
*
* @return proxied page manager interface used to
* inject into Folder instances to provide
* transaction/interception
*/
public PageManager getPageManagerProxy()
{
return pageManagerProxy;
}
/**
* setPageManagerProxy
*
* @param proxy proxied page manager interface used to
* inject into Folder instances to provide
* transaction/interception
*/
public void setPageManagerProxy(PageManager proxy)
{
// set/reset page manager proxy and propagate to cache
if (pageManagerProxy != proxy)
{
pageManagerProxy = proxy;
DatabasePageManagerCache.setPageManagerProxy(proxy);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getConstraintsEnabled()
*/
public boolean getConstraintsEnabled()
{
return delegator.getConstraintsEnabled();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPermissionsEnabled()
*/
public boolean getPermissionsEnabled()
{
return delegator.getPermissionsEnabled();
}
/* (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)
{
return delegator.newPage(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageTemplate(java.lang.String)
*/
public PageTemplate newPageTemplate(String path)
{
return delegator.newPageTemplate(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newDynamicPage(java.lang.String)
*/
public DynamicPage newDynamicPage(String path)
{
return delegator.newDynamicPage(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragmentDefinition(java.lang.String)
*/
public FragmentDefinition newFragmentDefinition(String path)
{
return delegator.newFragmentDefinition(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolder(java.lang.String)
*/
public Folder newFolder(String path)
{
return delegator.newFolder(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newLink(java.lang.String)
*/
public Link newLink(String path)
{
return delegator.newLink(path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageSecurity()
*/
public PageSecurity newPageSecurity()
{
return delegator.newPageSecurity();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragment()
*/
public Fragment newFragment()
{
return delegator.newFragment();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPortletFragment()
*/
public Fragment newPortletFragment()
{
return delegator.newPortletFragment();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragmentReference()
*/
public FragmentReference newFragmentReference()
{
return delegator.newFragmentReference();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageFragment()
*/
public PageFragment newPageFragment()
{
return delegator.newPageFragment();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderMenuDefinition()
*/
public MenuDefinition newFolderMenuDefinition()
{
return delegator.newFolderMenuDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderMenuExcludeDefinition()
*/
public MenuExcludeDefinition newFolderMenuExcludeDefinition()
{
return delegator.newFolderMenuExcludeDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderMenuIncludeDefinition()
*/
public MenuIncludeDefinition newFolderMenuIncludeDefinition()
{
return delegator.newFolderMenuIncludeDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderMenuOptionsDefinition()
*/
public MenuOptionsDefinition newFolderMenuOptionsDefinition()
{
return delegator.newFolderMenuOptionsDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderMenuSeparatorDefinition()
*/
public MenuSeparatorDefinition newFolderMenuSeparatorDefinition()
{
return delegator.newFolderMenuSeparatorDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageMenuDefinition()
*/
public MenuDefinition newPageMenuDefinition()
{
return delegator.newPageMenuDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageMenuExcludeDefinition()
*/
public MenuExcludeDefinition newPageMenuExcludeDefinition()
{
return delegator.newPageMenuExcludeDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageMenuIncludeDefinition()
*/
public MenuIncludeDefinition newPageMenuIncludeDefinition()
{
return delegator.newPageMenuIncludeDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageMenuOptionsDefinition()
*/
public MenuOptionsDefinition newPageMenuOptionsDefinition()
{
return delegator.newPageMenuOptionsDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageMenuSeparatorDefinition()
*/
public MenuSeparatorDefinition newPageMenuSeparatorDefinition()
{
return delegator.newPageMenuSeparatorDefinition();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newSecurityConstraints()
*/
public SecurityConstraints newSecurityConstraints()
{
return delegator.newSecurityConstraints();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFolderSecurityConstraint()
*/
public SecurityConstraint newFolderSecurityConstraint()
{
return delegator.newFolderSecurityConstraint();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageSecurityConstraint()
*/
public SecurityConstraint newPageSecurityConstraint()
{
return delegator.newPageSecurityConstraint();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragmentSecurityConstraint()
*/
public SecurityConstraint newFragmentSecurityConstraint()
{
return delegator.newFragmentSecurityConstraint();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newLinkSecurityConstraint()
*/
public SecurityConstraint newLinkSecurityConstraint()
{
return delegator.newLinkSecurityConstraint();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newPageSecuritySecurityConstraint()
*/
public SecurityConstraint newPageSecuritySecurityConstraint()
{
return delegator.newPageSecuritySecurityConstraint();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newSecurityConstraintsDef()
*/
public SecurityConstraintsDef newSecurityConstraintsDef()
{
return delegator.newSecurityConstraintsDef();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragmentPreference()
*/
public FragmentPreference newFragmentPreference()
{
return delegator.newFragmentPreference();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#newFragmentPreference()
*/
public FragmentProperty newFragmentProperty()
{
return delegator.newFragmentProperty();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#addListener(org.apache.jetspeed.page.PageManagerEventListener)
*/
public void addListener(PageManagerEventListener listener)
{
delegator.addListener(listener);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removeListener(org.apache.jetspeed.page.PageManagerEventListener)
*/
public void removeListener(PageManagerEventListener listener)
{
delegator.removeListener(listener);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#reset()
*/
public void reset()
{
// propagate to delegator
delegator.reset();
// clear cache to force subsequent refreshs from persistent store
DatabasePageManagerCache.cacheClear();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#shutdown()
*/
public void shutdown()
{
// delegate
delegator.shutdown();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPage(java.lang.String)
*/
public Page getPage(String path) throws PageNotFoundException, NodeException
{
return (Page)getFragmentsElement(Page.class, PageImpl.class, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageTemplate(java.lang.String)
*/
public PageTemplate getPageTemplate(String path) throws PageNotFoundException, NodeException
{
return (PageTemplate)getFragmentsElement(PageTemplate.class, PageTemplateImpl.class, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getDynamicPage(java.lang.String)
*/
public DynamicPage getDynamicPage(String path) throws PageNotFoundException, NodeException
{
return (DynamicPage)getFragmentsElement(DynamicPage.class, DynamicPageImpl.class, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFragmentDefinition(java.lang.String)
*/
public FragmentDefinition getFragmentDefinition(String path) throws PageNotFoundException, NodeException
{
return (FragmentDefinition)getFragmentsElement(FragmentDefinition.class, FragmentDefinitionImpl.class, path);
}
/**
* Get generic fragments/page element from cache or query from database by class.
*
* @param fragmentsElementType fragments/page type
* @param fragmentsElementImplType fragments/page implementation type
* @param path page path
* @return page element
* @throws PageNotFoundException
* @throws NodeException
*/
protected BaseFragmentsElement getFragmentsElement(Class fragmentsElementType, Class fragmentsElementImplType, String path) throws PageNotFoundException, NodeException
{
// construct page element attributes from path
path = NodeImpl.getCanonicalNodePath(path);
// optimized retrieval from cache by path if available
NodeImpl cachedNode = DatabasePageManagerCache.cacheLookup(path);
if (fragmentsElementType.isInstance(cachedNode))
{
// check for view access on page element
cachedNode.checkAccess(JetspeedActions.VIEW);
return (BaseFragmentsElement)cachedNode;
}
// retrieve page element from database
try
{
Criteria filter = new Criteria();
filter.addEqualTo("path", path);
QueryByCriteria query = QueryFactory.newQuery(fragmentsElementImplType, filter);
BaseFragmentsElement fragmentsElement = (BaseFragmentsElement)getPersistenceBrokerTemplate().getObjectByQuery(query);
// return page element or throw exception
if (fragmentsElement == null)
{
throw new PageNotFoundException("Fragments/page element " + path + " not found.");
}
// check for view access on page element
fragmentsElement.checkAccess(JetspeedActions.VIEW);
return fragmentsElement;
}
catch (PageNotFoundException pnfe)
{
throw pnfe;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new PageNotFoundException("Fragments/page element " + path + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getLink(java.lang.String)
*/
public Link getLink(String path) throws DocumentNotFoundException, NodeException
{
// construct link attributes from path
path = NodeImpl.getCanonicalNodePath(path);
// optimized retrieval from cache by path if available
NodeImpl cachedNode = DatabasePageManagerCache.cacheLookup(path);
if (cachedNode instanceof Link)
{
// check for view access on link
cachedNode.checkAccess(JetspeedActions.VIEW);
return (Link)cachedNode;
}
// retrieve link from database
try
{
Criteria filter = new Criteria();
filter.addEqualTo("path", path);
QueryByCriteria query = QueryFactory.newQuery(LinkImpl.class, filter);
Link link = (Link)getPersistenceBrokerTemplate().getObjectByQuery(query);
// return link or throw exception
if (link == null)
{
throw new DocumentNotFoundException("Link " + path + " not found.");
}
// check for view access on link
link.checkAccess(JetspeedActions.VIEW);
return link;
}
catch (DocumentNotFoundException dnfe)
{
throw dnfe;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new DocumentNotFoundException("Link " + path + " not found.", e);
}
}
/**
* Given a securityConstraintName definition and a set of actions,
* run a security constraint checks
*/
public boolean checkConstraint(String securityConstraintName, String actions)
{
try
{
PageSecurity security = this.getPageSecurity();
SecurityConstraintsDef def = security.getSecurityConstraintsDef(securityConstraintName);
if (def != null)
{
return PageManagerSecurityUtils.checkConstraint(def, actions);
}
}
catch(Exception e)
{
e.printStackTrace();
}
return false;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageSecurity()
*/
public PageSecurity getPageSecurity() throws DocumentNotFoundException, NodeException
{
// construct document attributes from path
String path = Folder.PATH_SEPARATOR + PageSecurity.DOCUMENT_TYPE;
// optimized retrieval from cache by path if available
NodeImpl cachedNode = DatabasePageManagerCache.cacheLookup(path);
if (cachedNode instanceof PageSecurity)
{
// check for view access on document
cachedNode.checkAccess(JetspeedActions.VIEW);
return (PageSecurity)cachedNode;
}
// retrieve document from database
try
{
Criteria filter = new Criteria();
filter.addEqualTo("path", path);
QueryByCriteria query = QueryFactory.newQuery(PageSecurityImpl.class, filter);
PageSecurity document = (PageSecurity)getPersistenceBrokerTemplate().getObjectByQuery(query);
// return page or throw exception
if (document == null)
{
throw new DocumentNotFoundException("Document " + path + " not found.");
}
// check for view access on document
document.checkAccess(JetspeedActions.VIEW);
return document;
}
catch (DocumentNotFoundException dnfe)
{
throw dnfe;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new DocumentNotFoundException("Document " + path + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFolder(java.lang.String)
*/
public Folder getFolder(String folderPath) throws FolderNotFoundException, InvalidFolderException, NodeException
{
// construct folder attributes from path
folderPath = NodeImpl.getCanonicalNodePath(folderPath);
// optimized retrieval from cache by path if available
NodeImpl cachedNode = DatabasePageManagerCache.cacheLookup(folderPath);
if (cachedNode instanceof Folder)
{
// check for view access on folder
cachedNode.checkAccess(JetspeedActions.VIEW);
return (Folder)cachedNode;
}
// retrieve folder from database
try
{
Criteria filter = new Criteria();
filter.addEqualTo("path", folderPath);
QueryByCriteria query = QueryFactory.newQuery(FolderImpl.class, filter);
Folder folder = (Folder)getPersistenceBrokerTemplate().getObjectByQuery(query);
// return folder or throw exception
if (folder == null)
{
throw new FolderNotFoundException("Folder " + folderPath + " not found.");
}
// check for view access on folder
folder.checkAccess(JetspeedActions.VIEW);
return folder;
}
catch (FolderNotFoundException fnfe)
{
throw fnfe;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotFoundException("Folder " + folderPath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFolders(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getFolders(Folder folder) throws DocumentException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder folders collection and cache in folder
try
{
// query for folders
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(FolderImpl.class, filter);
Collection folders = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache folders in folder
folderImpl.accessFolders().clear();
if (folders != null)
{
folderImpl.accessFolders().addAll(folders);
}
folderImpl.resetFolders(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetFolders(false);
throw new DocumentException("Unable to access folders for folder " + folder.getPath() + ".");
}
// folder folders cache populated, get folders from folder
// to provide packaging as filtered node set
return folder.getFolders();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFolder(org.apache.jetspeed.om.folder.Folder,java.lang.String)
*/
public Folder getFolder(Folder folder, String name) throws FolderNotFoundException, DocumentException
{
// perform lookup by path so that cache can be used
String folderPath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getFolder(folderPath);
}
catch (FolderNotFoundException fnfe)
{
throw fnfe;
}
catch (Exception e)
{
throw new FolderNotFoundException("Folder " + folderPath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPages(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getPages(Folder folder) throws NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder pages collection and cache in folder
try
{
// query for pages
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(PageImpl.class, filter);
Collection pages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache pages in folder
folderImpl.accessPages().clear();
if (pages != null)
{
folderImpl.accessPages().addAll(pages);
}
folderImpl.resetPages(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetPages(false);
throw new NodeException("Unable to access pages for folder " + folder.getPath() + ".");
}
// folder pages cache populated, get pages from folder
// to provide packaging as filtered node set
return folder.getPages();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPage(org.apache.jetspeed.om.folder.Folder,java.lang.String)
*/
public Page getPage(Folder folder, String name) throws PageNotFoundException, NodeException
{
// perform lookup by path so that cache can be used
String pagePath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getPage(pagePath);
}
catch (PageNotFoundException pnfe)
{
throw pnfe;
}
catch (Exception e)
{
throw new PageNotFoundException("Page " + pagePath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageTemplates(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getPageTemplates(Folder folder) throws NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder page templates collection and cache in folder
try
{
// query for page templates
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(PageTemplateImpl.class, filter);
Collection pageTemplates = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache page templates in folder
folderImpl.accessPageTemplates().clear();
if (pageTemplates != null)
{
folderImpl.accessPageTemplates().addAll(pageTemplates);
}
folderImpl.resetPageTemplates(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetPageTemplates(false);
throw new NodeException("Unable to access page templates for folder " + folder.getPath() + ".");
}
// folder page templates cache populated, get page templates
// from folder to provide packaging as filtered node set
return folder.getPageTemplates();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageTemplate(org.apache.jetspeed.om.folder.Folder, java.lang.String)
*/
public PageTemplate getPageTemplate(Folder folder, String name) throws PageNotFoundException, NodeException
{
// perform lookup by path so that cache can be used
String pageTemplatePath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getPageTemplate(pageTemplatePath);
}
catch (PageNotFoundException pnfe)
{
throw pnfe;
}
catch (Exception e)
{
throw new PageNotFoundException("Page template " + pageTemplatePath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getDynamicPages(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getDynamicPages(Folder folder) throws NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder dynamic pages collection and cache in folder
try
{
// query for dynamic pages
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(DynamicPageImpl.class, filter);
Collection dynamicPages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache dynamic pages in folder
folderImpl.accessDynamicPages().clear();
if (dynamicPages != null)
{
folderImpl.accessDynamicPages().addAll(dynamicPages);
}
folderImpl.resetDynamicPages(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetDynamicPages(false);
throw new NodeException("Unable to access dynamic pages for folder " + folder.getPath() + ".");
}
// folder dynamic pages cache populated, get dynamic pages
// from folder to provide packaging as filtered node set
return folder.getDynamicPages();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getDynamicPage(org.apache.jetspeed.om.folder.Folder, java.lang.String)
*/
public DynamicPage getDynamicPage(Folder folder, String name) throws PageNotFoundException, NodeException
{
// perform lookup by path so that cache can be used
String dynamicPagePath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getDynamicPage(dynamicPagePath);
}
catch (PageNotFoundException pnfe)
{
throw pnfe;
}
catch (Exception e)
{
throw new PageNotFoundException("Dynamic page " + dynamicPagePath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFragmentDefinitions(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getFragmentDefinitions(Folder folder) throws NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder fragment definition collection and cache in folder
try
{
// query for fragment definition
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(FragmentDefinitionImpl.class, filter);
Collection fragmentDefinitions = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache fragment definition in folder
folderImpl.accessFragmentDefinitions().clear();
if (fragmentDefinitions != null)
{
folderImpl.accessFragmentDefinitions().addAll(fragmentDefinitions);
}
folderImpl.resetFragmentDefinitions(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetFragmentDefinitions(false);
throw new NodeException("Unable to access fragment definition for folder " + folder.getPath() + ".");
}
// folder fragment definition cache populated, get fragment definition
// from folder to provide packaging as filtered node set
return folder.getFragmentDefinitions();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFragmentDefinition(org.apache.jetspeed.om.folder.Folder, java.lang.String)
*/
public FragmentDefinition getFragmentDefinition(Folder folder, String name) throws PageNotFoundException, NodeException
{
// perform lookup by path so that cache can be used
String fragmentDefinitionPath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getFragmentDefinition(fragmentDefinitionPath);
}
catch (PageNotFoundException pnfe)
{
throw pnfe;
}
catch (Exception e)
{
throw new PageNotFoundException("Fragment definition " + fragmentDefinitionPath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getLinks(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getLinks(Folder folder) throws NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder links collection and cache in folder
try
{
// query for links
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(LinkImpl.class, filter);
Collection links = getPersistenceBrokerTemplate().getCollectionByQuery(query);
// cache links in folder
folderImpl.accessLinks().clear();
if (links != null)
{
folderImpl.accessLinks().addAll(links);
}
folderImpl.resetLinks(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetLinks(false);
throw new NodeException("Unable to access links for folder " + folder.getPath() + ".");
}
// folder links cache populated, get links from folder
// to provide packaging as filtered node set
return folder.getLinks();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getLink(org.apache.jetspeed.om.folder.Folder,java.lang.String)
*/
public Link getLink(Folder folder, String name) throws DocumentNotFoundException, NodeException
{
// perform lookup by path so that cache can be used
String linkPath = folder.getPath() + Folder.PATH_SEPARATOR + name;
try
{
return getLink(linkPath);
}
catch (DocumentNotFoundException dnfe)
{
throw dnfe;
}
catch (Exception e)
{
throw new DocumentNotFoundException("Link " + linkPath + " not found.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageSecurity(org.apache.jetspeed.om.folder.Folder)
*/
public PageSecurity getPageSecurity(Folder folder) throws DocumentNotFoundException, NodeException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of page security document and cache
// in folder; limit lookup to root folder since page
// security document is currently supported only as a
// root folder singleton
if (folder.getPath().equals(Folder.PATH_SEPARATOR))
{
try
{
// query for page security
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(PageSecurityImpl.class, filter);
PageSecurity document = (PageSecurity)getPersistenceBrokerTemplate().getObjectByQuery(query);
// cache page security in folder
folderImpl.resetPageSecurity((PageSecurityImpl)document, true);
}
catch (Exception e)
{
// reset page security in folder
folderImpl.resetPageSecurity(null, true);
throw new NodeException("Unable to access page security for folder " + folder.getPath() + ".");
}
}
else
{
// cache page security in folder
folderImpl.resetPageSecurity(null, true);
}
// folder page security instance cache populated, get
// instance from folder to provide security checks
return folder.getPageSecurity();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getAll(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getAll(Folder folder) throws DocumentException
{
FolderImpl folderImpl = (FolderImpl)folder;
// perform lookup of folder nodes collection and cache in folder
try
{
// query for all nodes
List all = DatabasePageManagerUtils.createList();
// query for subfolders
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(FolderImpl.class, filter);
Collection folders = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (folders != null)
{
all.addAll(folders);
}
// polymorphic query for pages, page templates, dynamic pages,
// and fragment definitions
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(BaseFragmentsElementImpl.class, filter);
Collection baseFragments = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (baseFragments != null)
{
all.addAll(baseFragments);
}
// query for links
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(LinkImpl.class, filter);
Collection links = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (links != null)
{
all.addAll(links);
}
// query for page security
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageSecurityImpl.class, filter);
PageSecurity document = (PageSecurity)getPersistenceBrokerTemplate().getObjectByQuery(query);
if (document != null)
{
all.add(document);
}
// cache links in folder
folderImpl.accessAll().clear();
folderImpl.accessAll().addAll(all);
folderImpl.resetAll(true);
}
catch (Exception e)
{
// reset cache in folder
folderImpl.resetAll(false);
throw new DocumentException("Unable to access all nodes for folder " + folder.getPath() + ".");
}
// folder all nodes cache populated, get all from folder
// to provide packaging as filtered node set
return folder.getAll();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updatePage(org.apache.jetspeed.om.page.Page)
*/
public void updatePage(Page page) throws NodeException, PageNotUpdatedException
{
// dereference page in case proxy is supplied
page = (Page)ProxyHelper.getRealObject(page);
// update page
boolean newPage[] = new boolean[]{false};
FolderImpl parentFolder = updateFragmentsElement(page, newPage);
// reset parent folder in case page is new or
// parent is holding an out of date copy of
// this page that was removed from the cache
// before this one was accessed
if (parentFolder != null)
{
parentFolder.resetPages(false);
}
// notify page manager listeners
if (newPage[0])
{
delegator.notifyNewNode(page);
}
else
{
delegator.notifyUpdatedNode(page);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updatePageTemplate(org.apache.jetspeed.om.page.PageTemplate)
*/
public void updatePageTemplate(PageTemplate pageTemplate) throws NodeException, PageNotUpdatedException
{
// dereference page template in case proxy is supplied
pageTemplate = (PageTemplate)ProxyHelper.getRealObject(pageTemplate);
// update page template
boolean newPageTemplate[] = new boolean[]{false};
FolderImpl parentFolder = updateFragmentsElement(pageTemplate, newPageTemplate);
// reset parent folder in case page is new or
// parent is holding an out of date copy of
// this page that was removed from the cache
// before this one was accessed
if (parentFolder != null)
{
parentFolder.resetPageTemplates(false);
}
// notify page manager listeners
if (newPageTemplate[0])
{
delegator.notifyNewNode(pageTemplate);
}
else
{
delegator.notifyUpdatedNode(pageTemplate);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateDynamicPage(org.apache.jetspeed.om.page.DynamicPage)
*/
public void updateDynamicPage(DynamicPage dynamicPage) throws NodeException, PageNotUpdatedException
{
// dereference dynamic page in case proxy is supplied
dynamicPage = (DynamicPage)ProxyHelper.getRealObject(dynamicPage);
// update dynamic page
boolean newDynamicPage[] = new boolean[]{false};
FolderImpl parentFolder = updateFragmentsElement(dynamicPage, newDynamicPage);
// reset parent folder in case page is new or
// parent is holding an out of date copy of
// this page that was removed from the cache
// before this one was accessed
if (parentFolder != null)
{
parentFolder.resetDynamicPages(false);
}
// notify page manager listeners
if (newDynamicPage[0])
{
delegator.notifyNewNode(dynamicPage);
}
else
{
delegator.notifyUpdatedNode(dynamicPage);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition)
*/
public void updateFragmentDefinition(FragmentDefinition fragmentsDefinition) throws NodeException, PageNotUpdatedException
{
// dereference fragment definition in case proxy is supplied
fragmentsDefinition = (FragmentDefinition)ProxyHelper.getRealObject(fragmentsDefinition);
// update fragment definition
boolean newFragmentDefinition[] = new boolean[]{false};
FolderImpl parentFolder = updateFragmentsElement(fragmentsDefinition, newFragmentDefinition);
// reset parent folder in case page is new or
// parent is holding an out of date copy of
// this page that was removed from the cache
// before this one was accessed
if (parentFolder != null)
{
parentFolder.resetFragmentDefinitions(false);
}
// notify page manager listeners
if (newFragmentDefinition[0])
{
delegator.notifyNewNode(fragmentsDefinition);
}
else
{
delegator.notifyUpdatedNode(fragmentsDefinition);
}
}
/**
* Update fragments/page element.
*
* @param fragmentsElement fragments/page element to update
* @param newFragmentsElement new fragments/page element flag
* @return parent folder
* @throws NodeException
* @throws PageNotUpdatedException
*/
protected FolderImpl updateFragmentsElement(BaseFragmentsElement fragmentsElement, boolean [] newFragmentsElement) throws NodeException, PageNotUpdatedException
{
try
{
// validate fragments element
BaseFragmentsElementImpl fragmentsElementImpl = (BaseFragmentsElementImpl)fragmentsElement;
if (!fragmentsElementImpl.validateFragments())
{
throw new PageNotUpdatedException("Fragments hierarchy invalid for fragments/page: " + fragmentsElement.getPath() + ", not updated.");
}
// look up and set parent folder if necessary
FolderImpl parent = (FolderImpl)fragmentsElement.getParent();
if (parent == null)
{
// access folder by path
String pageElementPath = fragmentsElement.getPath();
String parentPath = pageElementPath.substring(0, pageElementPath.lastIndexOf(Folder.PATH_SEPARATOR));
if (parentPath.length() == 0)
{
parentPath = Folder.PATH_SEPARATOR;
}
try
{
parent = (FolderImpl)getFolder(parentPath);
}
catch (FolderNotFoundException fnfe)
{
throw new PageNotUpdatedException("Missing parent folder: " + parentPath);
}
// check for edit access on parent folder; fragments/page
// access not checked on create
parent.checkAccess(JetspeedActions.EDIT);
// update fragments/page and mark cache transaction
fragmentsElement.setParent(parent);
storeEntity(fragmentsElement, pageElementPath, true);
// new fragments/page
newFragmentsElement[0] = true;
}
else
{
// check for edit access on fragments/page and parent folder
fragmentsElement.checkAccess(JetspeedActions.EDIT);
// update fragments/page and mark cache transaction
storeEntity(fragmentsElement, fragmentsElement.getPath(), false);
// updated fragments/page
newFragmentsElement[0] = false;
}
// return parent folder to update its caches after update
return parent;
}
catch (PageNotUpdatedException pnue)
{
throw pnue;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new PageNotUpdatedException("Fragments/page element " + fragmentsElement.getPath() + " not updated.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removePage(org.apache.jetspeed.om.page.Page)
*/
public void removePage(Page page) throws NodeException, PageNotRemovedException
{
// dereference page in case proxy is supplied
page = (Page)ProxyHelper.getRealObject(page);
// remove page
FolderImpl parentFolder = removeFragmentsElement(page);
// reset parent folder holding removed page
parentFolder.resetPages(false);
// notify page manager listeners
delegator.notifyRemovedNode(page);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removePageTemplate(org.apache.jetspeed.om.page.PageTemplate)
*/
public void removePageTemplate(PageTemplate pageTemplate) throws NodeException, PageNotRemovedException
{
// dereference page template in case proxy is supplied
pageTemplate = (PageTemplate)ProxyHelper.getRealObject(pageTemplate);
// remove page template
FolderImpl parentFolder = removeFragmentsElement(pageTemplate);
// reset parent folder holding removed page
parentFolder.resetPages(false);
// notify page manager listeners
delegator.notifyRemovedNode(pageTemplate);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removeDynamicPage(org.apache.jetspeed.om.page.DynamicPage)
*/
public void removeDynamicPage(DynamicPage dynamicPage) throws NodeException, PageNotRemovedException
{
// dereference dynamic page in case proxy is supplied
dynamicPage = (DynamicPage)ProxyHelper.getRealObject(dynamicPage);
// remove dynamic page
FolderImpl parentFolder = removeFragmentsElement(dynamicPage);
// reset parent folder holding removed page
parentFolder.resetPages(false);
// notify page manager listeners
delegator.notifyRemovedNode(dynamicPage);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removeFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition)
*/
public void removeFragmentDefinition(FragmentDefinition fragmentDefinition) throws NodeException, PageNotRemovedException
{
// dereference fragment definition in case proxy is supplied
fragmentDefinition = (FragmentDefinition)ProxyHelper.getRealObject(fragmentDefinition);
// remove fragment definition
FolderImpl parentFolder = removeFragmentsElement(fragmentDefinition);
// reset parent folder holding removed page
parentFolder.resetPages(false);
// notify page manager listeners
delegator.notifyRemovedNode(fragmentDefinition);
}
/**
* Remove fragments/page element.
*
* @param fragmentsElement fragments/page element to remove
* @return parent folder
* @throws NodeException
* @throws PageNotUpdatedException
*/
protected FolderImpl removeFragmentsElement(BaseFragmentsElement fragmentsElement) throws NodeException, PageNotRemovedException
{
try
{
// check for edit access on fragments/page and parent folder
fragmentsElement.checkAccess(JetspeedActions.EDIT);
// look up and update parent folder if necessary
FolderImpl parent = (FolderImpl)ProxyHelper.getRealObject(fragmentsElement.getParent());
// delete fragments/page
getPersistenceBrokerTemplate().delete(fragmentsElement);
// return parent folder to update is caches after remove
return parent;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new PageNotRemovedException("Fragments/page element " + fragmentsElement.getPath() + " not removed.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateFolder(org.apache.jetspeed.om.folder.Folder)
*/
public void updateFolder(Folder folder) throws NodeException, FolderNotUpdatedException
{
// shallow update by default
updateFolder(folder, false);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateFolder(org.apache.jetspeed.om.folder.Folder,boolean)
*/
public void updateFolder(Folder folder, boolean deep) throws NodeException, FolderNotUpdatedException
{
try
{
// dereference folder in case proxy is supplied
folder = (Folder)ProxyHelper.getRealObject(folder);
FolderImpl folderImpl = (FolderImpl)folder;
// look up and set parent folder if required
FolderImpl parent = (FolderImpl)folder.getParent();
if ((parent == null) && !folder.getPath().equals(Folder.PATH_SEPARATOR))
{
// access folder by path
String folderPath = folder.getPath();
String parentPath = folderPath.substring(0, folderPath.lastIndexOf(Folder.PATH_SEPARATOR));
if (parentPath.length() == 0)
{
parentPath = Folder.PATH_SEPARATOR;
}
try
{
parent = (FolderImpl)getFolder(parentPath);
}
catch (FolderNotFoundException fnfe)
{
throw new FolderNotUpdatedException("Missing parent folder: " + parentPath);
}
// check for edit access on parent folder; folder
// access not checked on create
parent.checkAccess(JetspeedActions.EDIT);
// update folder and mark cache transaction
folder.setParent(parent);
storeEntity(folder, folderPath, true);
// reset parent folder folders cache
parent.resetFolders(false);
// notify page manager listeners
delegator.notifyNewNode(folder);
}
else
{
// determine if folder is new by checking autoincrement id
boolean newFolder = (folderImpl.getIdentity() == 0);
// check for edit access on folder and parent folder
// if not being initially created; access is not
// checked on create
String folderPath = folder.getPath();
if (!newFolder || !folderPath.equals(Folder.PATH_SEPARATOR))
{
folder.checkAccess(JetspeedActions.EDIT);
}
// create root folder or update folder and mark cache transaction
storeEntity(folder, folderPath, (newFolder && (folderImpl.getIdentity() != 0)));
// reset parent folder folders cache in case
// parent is holding an out of date copy of
// this folder that was removed from the cache
// before this one was accessed
if (parent != null)
{
parent.resetFolders(false);
}
// notify page manager listeners
if (newFolder && (folderImpl.getIdentity() != 0))
{
delegator.notifyNewNode(folder);
}
else
{
delegator.notifyUpdatedNode(folder);
}
}
// update deep recursively if specified
if (deep)
{
// update recursively, (breadth first)
updateFolderNodes(folderImpl);
}
}
catch (FolderNotUpdatedException fnue)
{
throw fnue;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotUpdatedException("Folder " + folder.getPath() + " not updated.", e);
}
}
/**
* updateFolderNodes - recursively update all folder nodes
*
* @param folderImpl folder whose nodes are to be updated
* @param throws FolderNotUpdatedException
*/
private void updateFolderNodes(FolderImpl folderImpl) throws FolderNotUpdatedException
{
try
{
// update pages
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(PageImpl.class, filter);
Collection pages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (pages != null)
{
Iterator pagesIter = pages.iterator();
while (pagesIter.hasNext())
{
updatePage((Page)pagesIter.next());
}
}
// update page templates
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageTemplateImpl.class, filter);
Collection pageTemplates = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (pageTemplates != null)
{
Iterator pageTemplatesIter = pageTemplates.iterator();
while (pageTemplatesIter.hasNext())
{
updatePageTemplate((PageTemplate)pageTemplatesIter.next());
}
}
// update dynamic pages
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(DynamicPageImpl.class, filter);
Collection dynamicPages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (dynamicPages != null)
{
Iterator dynamicPagesIter = dynamicPages.iterator();
while (dynamicPagesIter.hasNext())
{
updateDynamicPage((DynamicPage)dynamicPagesIter.next());
}
}
// update fragment definitions
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(FragmentDefinitionImpl.class, filter);
Collection fragmentDefinitions = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (fragmentDefinitions != null)
{
Iterator fragmentDefinitionsIter = fragmentDefinitions.iterator();
while (fragmentDefinitionsIter.hasNext())
{
updateFragmentDefinition((FragmentDefinition)fragmentDefinitionsIter.next());
}
}
// update links
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(LinkImpl.class, filter);
Collection links = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (links != null)
{
Iterator linksIter = links.iterator();
while (linksIter.hasNext())
{
updateLink((Link)linksIter.next());
}
}
// update page security
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageSecurityImpl.class, filter);
PageSecurity document = (PageSecurity)getPersistenceBrokerTemplate().getObjectByQuery(query);
if (document != null)
{
updatePageSecurity(document);
}
// update folders last: breadth first recursion
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(FolderImpl.class, filter);
Collection folders = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (folders != null)
{
Iterator foldersIter = folders.iterator();
while (foldersIter.hasNext())
{
updateFolder((Folder)foldersIter.next(), true);
}
}
}
catch (FolderNotUpdatedException fnue)
{
throw fnue;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotUpdatedException("Folder " + folderImpl.getPath() + " not updated.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removeFolder(org.apache.jetspeed.om.folder.Folder)
*/
public void removeFolder(Folder folder) throws NodeException, FolderNotRemovedException
{
try
{
// dereference folder in case proxy is supplied
folder = (Folder)ProxyHelper.getRealObject(folder);
// check for edit access on folder and parent folder
folder.checkAccess(JetspeedActions.EDIT);
// reset folder nodes cache
((FolderImpl)folder).resetAll(false);
// remove recursively, (depth first)
removeFolderNodes((FolderImpl)folder);
// look up and update parent folder if necessary
if (folder.getParent() != null)
{
FolderImpl parent = (FolderImpl)ProxyHelper.getRealObject(folder.getParent());
// delete folder
getPersistenceBrokerTemplate().delete(folder);
// reset parent folder folders cache
parent.resetFolders(false);
}
else
{
// delete folder: depth recursion
getPersistenceBrokerTemplate().delete(folder);
}
// notify page manager listeners
delegator.notifyRemovedNode((FolderImpl)folder);
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotRemovedException("Folder " + folder.getPath() + " not removed.", e);
}
}
/**
* removeFolderNodes - recursively remove all folder nodes
*
* @param folderImpl folder whose nodes are to be removed
* @param throws FolderNotRemovedException
*/
private void removeFolderNodes(FolderImpl folderImpl) throws FolderNotRemovedException
{
try
{
// remove folders first: depth first recursion
Criteria filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
QueryByCriteria query = QueryFactory.newQuery(FolderImpl.class, filter);
Collection folders = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (folders != null)
{
Iterator foldersIter = folders.iterator();
while (foldersIter.hasNext())
{
removeFolder((Folder)foldersIter.next());
}
}
// remove pages
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageImpl.class, filter);
Collection pages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (pages != null)
{
Iterator pagesIter = pages.iterator();
while (pagesIter.hasNext())
{
removePage((Page)pagesIter.next());
}
}
// remove page templates
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageTemplateImpl.class, filter);
Collection pageTemplates = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (pageTemplates != null)
{
Iterator pageTemplatesIter = pageTemplates.iterator();
while (pageTemplatesIter.hasNext())
{
removePageTemplate((PageTemplate)pageTemplatesIter.next());
}
}
// remove dynamic pages
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(DynamicPageImpl.class, filter);
Collection dynamicPages = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (dynamicPages != null)
{
Iterator dynamicPagesIter = dynamicPages.iterator();
while (dynamicPagesIter.hasNext())
{
removeDynamicPage((DynamicPage)dynamicPagesIter.next());
}
}
// remove fragment definitions
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(FragmentDefinitionImpl.class, filter);
Collection fragmentDefinitions = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (fragmentDefinitions != null)
{
Iterator fragmentDefinitionsIter = fragmentDefinitions.iterator();
while (fragmentDefinitionsIter.hasNext())
{
removeFragmentDefinition((FragmentDefinition)fragmentDefinitionsIter.next());
}
}
// remove links
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(LinkImpl.class, filter);
Collection links = getPersistenceBrokerTemplate().getCollectionByQuery(query);
if (links != null)
{
Iterator linksIter = links.iterator();
while (linksIter.hasNext())
{
removeLink((Link)linksIter.next());
}
}
// remove page security
filter = new Criteria();
filter.addEqualTo("parent", new Integer(folderImpl.getIdentity()));
query = QueryFactory.newQuery(PageSecurityImpl.class, filter);
PageSecurity document = (PageSecurity)getPersistenceBrokerTemplate().getObjectByQuery(query);
if (document != null)
{
removePageSecurity(document);
}
}
catch (FolderNotRemovedException fnre)
{
throw fnre;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotRemovedException("Folder " + folderImpl.getPath() + " not removed.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateLink(org.apache.jetspeed.om.page.Link)
*/
public void updateLink(Link link) throws NodeException, LinkNotUpdatedException
{
try
{
// dereference link in case proxy is supplied
link = (Link)ProxyHelper.getRealObject(link);
// look up and set parent folder if necessary
boolean newLink = false;
FolderImpl parent = (FolderImpl)link.getParent();
if (parent == null)
{
// access folder by path
String linkPath = link.getPath();
String parentPath = linkPath.substring(0, linkPath.lastIndexOf(Folder.PATH_SEPARATOR));
if (parentPath.length() == 0)
{
parentPath = Folder.PATH_SEPARATOR;
}
try
{
parent = (FolderImpl)getFolder(parentPath);
}
catch (FolderNotFoundException fnfe)
{
throw new FailedToUpdateDocumentException("Missing parent folder: " + parentPath);
}
// check for edit access on parent folder; link
// access not checked on create
parent.checkAccess(JetspeedActions.EDIT);
// update link and mark cache transaction
link.setParent(parent);
storeEntity(link, linkPath, true);
// new link
newLink = true;
}
else
{
// check for edit access on link and parent folder
link.checkAccess(JetspeedActions.EDIT);
// update link and mark cache transaction
storeEntity(link, link.getPath(), false);
// update link
newLink = false;
}
// reset parent folder links cache in case
// new or parent is holding an out of date copy
// of this link that was removed from the cache
// before this one was accessed
parent.resetLinks(false);
// notify page manager listeners
if (newLink)
{
delegator.notifyNewNode(link);
}
else
{
delegator.notifyUpdatedNode(link);
}
}
catch (FailedToUpdateDocumentException fude)
{
throw fude;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FailedToUpdateDocumentException("Link " + link.getPath() + " not updated.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removeLink(org.apache.jetspeed.om.page.Link)
*/
public void removeLink(Link link) throws NodeException, LinkNotRemovedException
{
try
{
// dereference link in case proxy is supplied
link = (Link)ProxyHelper.getRealObject(link);
// check for edit access on link and parent folder
link.checkAccess(JetspeedActions.EDIT);
// look up and update parent folder if necessary
if (link.getParent() != null)
{
FolderImpl parent = (FolderImpl)ProxyHelper.getRealObject(link.getParent());
// delete link
getPersistenceBrokerTemplate().delete(link);
// reset parent folder links cache
parent.resetLinks(false);
}
else
{
// delete link
getPersistenceBrokerTemplate().delete(link);
}
// notify page manager listeners
delegator.notifyRemovedNode(link);
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FailedToDeleteDocumentException("Link " + link.getPath() + " not removed.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updatePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
*/
public void updatePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToUpdateDocumentException
{
try
{
// dereference document in case proxy is supplied
pageSecurity = (PageSecurity)ProxyHelper.getRealObject(pageSecurity);
// look up and set parent folder if necessary
boolean newPageSecurity = false;
FolderImpl parent = (FolderImpl)pageSecurity.getParent();
if (parent == null)
{
// access folder by path
String pageSecurityPath = pageSecurity.getPath();
String parentPath = pageSecurityPath.substring(0, pageSecurityPath.lastIndexOf(Folder.PATH_SEPARATOR));
if (parentPath.length() == 0)
{
parentPath = Folder.PATH_SEPARATOR;
}
try
{
parent = (FolderImpl)getFolder(parentPath);
}
catch (FolderNotFoundException fnfe)
{
throw new FailedToUpdateDocumentException("Missing parent folder: " + parentPath);
}
// do not replace existing page security documents
try
{
parent.getPageSecurity();
throw new FailedToUpdateDocumentException("Parent folder page security exists: " + parentPath);
}
catch (DocumentNotFoundException dnfe)
{
// check for edit access on parent folder; document
// access not checked on create
parent.checkAccess(JetspeedActions.EDIT);
// update document and mark cache transaction
pageSecurity.setParent(parent);
storeEntity(pageSecurity, pageSecurityPath, true);
// new page security
newPageSecurity = true;
}
catch (Exception e)
{
throw new FailedToUpdateDocumentException("Parent folder page security exists: " + parentPath);
}
}
else
{
// check for edit access on document and parent folder
pageSecurity.checkAccess(JetspeedActions.EDIT);
// update document and mark cache transaction
storeEntity(pageSecurity, pageSecurity.getPath(), false);
// update page security
newPageSecurity = false;
}
// reset parent folder page security cache if new or
// in case parent is holding an out of date copy of
// this page security that was removed from the cache
// before this one was accessed
parent.resetPageSecurity((PageSecurityImpl)pageSecurity, true);
// reset all cached security constraints
DatabasePageManagerCache.resetCachedSecurityConstraints();
// notify page manager listeners
if (newPageSecurity)
{
delegator.notifyNewNode(pageSecurity);
}
else
{
delegator.notifyUpdatedNode(pageSecurity);
}
}
catch (FailedToUpdateDocumentException fude)
{
throw fude;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FailedToUpdateDocumentException("Document " + pageSecurity.getPath() + " not updated.", e);
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
*/
public void removePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToDeleteDocumentException
{
try
{
// dereference document in case proxy is supplied
pageSecurity = (PageSecurity)ProxyHelper.getRealObject(pageSecurity);
// check for edit access on document and parent folder
pageSecurity.checkAccess(JetspeedActions.EDIT);
// look up and update parent folder if necessary
if (pageSecurity.getParent() != null)
{
FolderImpl parent = (FolderImpl)ProxyHelper.getRealObject(pageSecurity.getParent());
// delete document
getPersistenceBrokerTemplate().delete(pageSecurity);
// reset parent folder page security cache
parent.resetPageSecurity(null, true);
}
else
{
// delete document
getPersistenceBrokerTemplate().delete(pageSecurity);
}
// reset all cached security constraints
DatabasePageManagerCache.resetCachedSecurityConstraints();
// notify page manager listeners
delegator.notifyRemovedNode(pageSecurity);
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FailedToDeleteDocumentException("Document " + pageSecurity.getPath() + " not removed.", e);
}
}
/**
* Add or update persistence object by storing to persistence broker.
*
* @param node node to store
* @param path node path
*/
private void storeEntity(Object node, String path)
{
// store object for add/update and interoperate with cache
// to signal update operations
DatabasePageManagerCache.addUpdatePath(path);
try
{
getPersistenceBrokerTemplate().store(node);
}
finally
{
DatabasePageManagerCache.removeUpdatePath(path);
}
}
/**
* Add or update persistence object by storing to persistence broker
* with thread cache transaction management.
*
* @param node node to store
* @param path node path
* @param add whether transaction operation is add or update
*/
private void storeEntity(Object node, String path, boolean add)
{
// store object for add/update and interoperate with cache
// to signal update operations and record thread transactions
storeEntity(node, path);
DatabasePageManagerCache.addTransaction(new TransactionedOperation(path, (add ? TransactionedOperation.ADD_OPERATION : TransactionedOperation.UPDATE_OPERATION)));
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyPage(org.apache.jetspeed.om.page.Page,java.lang.String)
*/
public Page copyPage(Page source, String path)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyPage(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyPage(org.apache.jetspeed.om.page.Page, java.lang.String, boolean)
*/
public Page copyPage(Page source, String path, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyPage(source, path, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyPageTemplate(org.apache.jetspeed.om.page.PageTemplate, java.lang.String)
*/
public PageTemplate copyPageTemplate(PageTemplate source, String path)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyPageTemplate(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyPageTemplate(org.apache.jetspeed.om.page.PageTemplate, java.lang.String, boolean)
*/
public PageTemplate copyPageTemplate(PageTemplate source, String path, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyPageTemplate(source, path, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyDynamicPage(org.apache.jetspeed.om.page.DynamicPage, java.lang.String)
*/
public DynamicPage copyDynamicPage(DynamicPage source, String path)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyDynamicPage(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyDynamicPage(org.apache.jetspeed.om.page.DynamicPage, java.lang.String, boolean)
*/
public DynamicPage copyDynamicPage(DynamicPage source, String path, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyDynamicPage(source, path, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition, java.lang.String)
*/
public FragmentDefinition copyFragmentDefinition(FragmentDefinition source, String path)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyFragmentDefinition(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition, java.lang.String, boolean)
*/
public FragmentDefinition copyFragmentDefinition(FragmentDefinition source, String path, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyFragmentDefinition(source, path, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyLink(org.apache.jetspeed.om.page.Link,java.lang.String)
*/
public Link copyLink(Link source, String path)
throws NodeException, LinkNotUpdatedException
{
return this.delegator.copyLink(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyFolder(org.apache.jetspeed.om.folder.Folder,java.lang.String)
*/
public Folder copyFolder(Folder source, String path)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyFolder(source, path);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyFragment(org.apache.jetspeed.om.page.BaseFragmentElement,java.lang.String)
*/
public BaseFragmentElement copyFragment(BaseFragmentElement source, String name)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyFragment(source, name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyFragment(org.apache.jetspeed.om.page.BaseFragmentElement, java.lang.String, boolean)
*/
public BaseFragmentElement copyFragment(BaseFragmentElement source, String name, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
return this.delegator.copyFragment(source, name, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#copyPageSecurity(org.apache.jetspeed.om.page.PageSecurity)
*/
public PageSecurity copyPageSecurity(PageSecurity source)
throws NodeException
{
return this.delegator.copyPageSecurity(source);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getUserPage(java.lang.String,java.lang.String)
*/
public Page getUserPage(String userName, String pageName)
throws PageNotFoundException, NodeException
{
return this.getPage(Folder.USER_FOLDER + userName + Folder.PATH_SEPARATOR + pageName);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getUserFolder(java.lang.String)
*/
public Folder getUserFolder(String userName)
throws FolderNotFoundException, InvalidFolderException, NodeException
{
return this.getFolder(Folder.USER_FOLDER + userName);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#folderExists(java.lang.String)
*/
public boolean folderExists(String folderName)
{
try
{
getFolder(folderName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#pageExists(java.lang.String)
*/
public boolean pageExists(String pageName)
{
try
{
getPage(pageName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#pageTemplateExists(java.lang.String)
*/
public boolean pageTemplateExists(String pageName)
{
try
{
getPageTemplate(pageName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#dynamicPageExists(java.lang.String)
*/
public boolean dynamicPageExists(String pageName)
{
try
{
getDynamicPage(pageName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#fragmentDefinitionExists(java.lang.String)
*/
public boolean fragmentDefinitionExists(String name)
{
try
{
getFragmentDefinition(name);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#linkExists(java.lang.String)
*/
public boolean linkExists(String linkName)
{
try
{
getLink(linkName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#userFolderExists(java.lang.String)
*/
public boolean userFolderExists(String userName)
{
try
{
getFolder(Folder.USER_FOLDER + userName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#userPageExists(java.lang.String)
*/
public boolean userPageExists(String userName, String pageName)
{
try
{
getPage(Folder.USER_FOLDER + userName + Folder.PATH_SEPARATOR + pageName);
}
catch (Exception e)
{
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#createUserHomePagesFromRoles(java.security.auth.Subject)
*/
public void createUserHomePagesFromRoles(Subject subject)
throws NodeException
{
PageManagerUtils.createUserHomePagesFromRoles(this, subject);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#deepCopyFolder(org.apache.jetspeed.om.folder.Folder, java.lang.String, java.lang.String)
*/
public void deepCopyFolder(Folder srcFolder, String destinationPath, String owner)
throws NodeException, PageNotUpdatedException
{
deepCopyFolder(srcFolder, destinationPath, owner, false);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#deepCopyFolder(org.apache.jetspeed.om.folder.Folder, java.lang.String, java.lang.String, boolean)
*/
public void deepCopyFolder(Folder srcFolder, String destinationPath, String owner, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
PageManagerUtils.deepCopyFolder(this, srcFolder, destinationPath, owner, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#deepMergeFolder(org.apache.jetspeed.om.folder.Folder, java.lang.String, java.lang.String)
*/
public void deepMergeFolder(Folder srcFolder, String destinationPath, String owner)
throws NodeException, PageNotUpdatedException
{
deepMergeFolder(srcFolder, destinationPath, owner, false);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#deepMergeFolder(org.apache.jetspeed.om.folder.Folder, java.lang.String, java.lang.String, boolean)
*/
public void deepMergeFolder(Folder srcFolder, String destinationPath, String owner, boolean copyIds)
throws NodeException, PageNotUpdatedException
{
PageManagerUtils.deepMergeFolder(this, srcFolder, destinationPath, owner, copyIds);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#addPages(org.apache.jetspeed.om.page.Page[])
*/
public int addPages(Page[] pages)
throws NodeException
{
if (pages.length > 0 && pages[0].getPath().equals("/tx__test1.psml"))
{
// for tx testing
log.debug("Adding first page");
this.updatePage(pages[0]);
log.debug("Adding second page");
this.updatePage(pages[1]);
log.debug("About to throw ex");
throw new NodeException("Its gonna blow captain!");
}
for (int ix = 0; ix < pages.length; ix++)
{
this.updatePage(pages[ix]);
}
return pages.length;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#isDistributed()
*/
public boolean isDistributed()
{
return DatabasePageManagerCache.isDistributed();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#notifyUpdatedNode(org.apache.jetspeed.page.document.Node)
*/
public void notifyUpdatedNode(Node node)
{
// notify page manager listeners
delegator.notifyUpdatedNode(node);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#cleanupRequestCache()
*/
public void cleanupRequestCache()
{
// clear thread local cache on request completion
fragmentPropertyListsCache.remove();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updateFragmentProperties(org.apache.jetspeed.om.page.BaseFragmentElement, java.lang.String)
*/
public void updateFragmentProperties(BaseFragmentElement fragment, String scope) throws NodeException, PageNotUpdatedException
{
try
{
// validate fragment element
BaseFragmentElementImpl baseFragmentElementImpl = (BaseFragmentElementImpl)fragment;
if (baseFragmentElementImpl.getIdentity() == 0)
{
throw new PageNotUpdatedException("Properties for transient fragment cannot be updated");
}
// update lists only if not global or all scope
if ((scope != null) && !scope.equals(ALL_PROPERTY_SCOPE))
{
// check access
boolean checkEditAccess = !scope.equals(USER_PROPERTY_SCOPE);
baseFragmentElementImpl.checkAccess(checkEditAccess ? JetspeedActions.EDIT : JetspeedActions.VIEW);
// update fragment properties
updateFragmentPropertyList(baseFragmentElementImpl, scope, null);
}
else
{
// update entire page
BaseFragmentsElementImpl baseFragmentsElementImpl = ((baseFragmentElementImpl != null) ? baseFragmentElementImpl.getBaseFragmentsElement() : null);
if (baseFragmentsElementImpl != null)
{
updateFragmentsElement(baseFragmentsElementImpl, new boolean[]{false});
}
else
{
throw new PageNotUpdatedException("Unable to update fragment properties: no owning page");
}
}
}
catch (PageNotUpdatedException pnue)
{
throw pnue;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new PageNotUpdatedException("Fragment properties for fragment " + fragment.getId() + " not updated.", e);
}
}
/**
* Get and cache fragment property list for specified fragment.
*
* @param baseFragmentElementImpl owning fragment of fragment property list
* @param transientList transient fragment property list
* @return new or cached fragment property list
*/
public FragmentPropertyList getFragmentPropertyList(BaseFragmentElementImpl baseFragmentElementImpl, FragmentPropertyList transientList)
{
// access thread local fragment property lists cache
String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
Subject subject = JSSubject.getSubject(AccessController.getContext());
Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject, User.class) : null);
String fragmentListKey = getFragmentPropertyListKey(fragmentKey, userPrincipal);
Map threadLocalCache = (Map)fragmentPropertyListsCache.get();
WeakReference listReference = ((threadLocalCache != null) ? (WeakReference)threadLocalCache.get(fragmentListKey) : null);
FragmentPropertyList list = ((listReference != null) ? (FragmentPropertyList)listReference.get() : null);
// get and cache persistent list
if (list == null)
{
// get cached fragment property list components or
// query from database if not cached and cache
DatabasePageManagerCachedFragmentPropertyList globalFragmentPropertyList = DatabasePageManagerCache.fragmentPropertyListCacheLookup(fragmentKey);
if (globalFragmentPropertyList == null)
{
globalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(baseFragmentElementImpl.getBaseFragmentsElement().getPath());
Criteria filter = new Criteria();
filter.addEqualTo("fragment", new Integer(baseFragmentElementImpl.getIdentity()));
filter.addIsNull("scope");
QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
globalFragmentPropertyList.addAll(fragmentProperties);
DatabasePageManagerCache.fragmentPropertyListCacheAdd(fragmentKey, globalFragmentPropertyList, false);
}
Map principalFragmentPropertyLists = null;
DatabasePageManagerCachedFragmentPropertyList userFragmentPropertyList = null;
if (subject != null)
{
if (GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
{
Set principals = subject.getPrincipals();
Iterator principalsIter = principals.iterator();
while (principalsIter.hasNext())
{
Principal principal = (Principal)principalsIter.next();
String principalScope = null;
if (principal instanceof User)
{
principalScope = USER_PROPERTY_SCOPE;
}
else if (principal instanceof Group)
{
principalScope = GROUP_PROPERTY_SCOPE;
}
else if (principal instanceof Role)
{
principalScope = ROLE_PROPERTY_SCOPE;
}
if (principalScope != null)
{
String principalKey = getFragmentPropertyListPrincipalKey(principalScope, principal.getName());
DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList = DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
if (principalFragmentPropertyList == null)
{
principalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(principalScope, principalKey);
Criteria filter = new Criteria();
filter.addEqualTo("scope", principalScope);
filter.addEqualTo("scopeValue", principal.getName());
QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
principalFragmentPropertyList.addAll(fragmentProperties);
DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey, principalFragmentPropertyList, false);
}
if (principalFragmentPropertyList != null)
{
if (principalFragmentPropertyLists == null)
{
principalFragmentPropertyLists = new HashMap();
}
principalFragmentPropertyLists.put(principalKey, principalFragmentPropertyList);
}
}
}
}
else if (userPrincipal != null)
{
String principalKey = getFragmentPropertyListPrincipalKey(USER_PROPERTY_SCOPE, userPrincipal.getName());
userFragmentPropertyList = DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
if (userFragmentPropertyList == null)
{
userFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(USER_PROPERTY_SCOPE, principalKey);
Criteria filter = new Criteria();
filter.addEqualTo("scope", USER_PROPERTY_SCOPE);
filter.addEqualTo("scopeValue", userPrincipal.getName());
QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
Collection fragmentProperties = getPersistenceBrokerTemplate().getCollectionByQuery(query);
userFragmentPropertyList.addAll(fragmentProperties);
DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey, userFragmentPropertyList, false);
}
}
}
// assemble fragment property list instance, (use transient
// list or create new fragment property list)
list = new FragmentPropertyListImpl(baseFragmentElementImpl);
list.getProperties().addAll(globalFragmentPropertyList);
if (subject != null)
{
if (GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
{
if (principalFragmentPropertyLists != null)
{
Set principals = subject.getPrincipals();
Iterator principalsIter = principals.iterator();
while (principalsIter.hasNext())
{
Principal principal = (Principal)principalsIter.next();
String principalScope = null;
if (principal instanceof User)
{
principalScope = USER_PROPERTY_SCOPE;
}
else if (principal instanceof Group)
{
principalScope = GROUP_PROPERTY_SCOPE;
}
else if (principal instanceof Role)
{
principalScope = ROLE_PROPERTY_SCOPE;
}
if (principalScope != null)
{
String principalKey = getFragmentPropertyListPrincipalKey(principalScope, principal.getName());
DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList = (DatabasePageManagerCachedFragmentPropertyList)principalFragmentPropertyLists.get(principalKey);
List principalFragmentProperties = filterPrincipalFragmentPropertyList(principalFragmentPropertyList, baseFragmentElementImpl);
if (principalFragmentProperties != null)
{
list.getProperties().addAll(principalFragmentProperties);
}
}
}
}
}
else if (userFragmentPropertyList != null)
{
List userFragmentProperties = filterPrincipalFragmentPropertyList(userFragmentPropertyList, baseFragmentElementImpl);
if (userFragmentProperties != null)
{
list.getProperties().addAll(userFragmentProperties);
}
}
}
// merge results into transient list if specified
if ((list != null) && (transientList != null))
{
synchronized (transientList)
{
// merge into persistent list; this is unsafe due to the
// lack of transactional isolation in shared objects, but
// this should only happen before new objects are committed
// and here we are assuming that only the current user has
// access to the new objects
Iterator sourceIter = transientList.iterator();
while (sourceIter.hasNext())
{
FragmentProperty sourceProperty = (FragmentProperty)sourceIter.next();
FragmentProperty targetProperty = list.getMatchingProperty(sourceProperty);
if (targetProperty != null)
{
targetProperty.setValue(sourceProperty.getValue());
}
else
{
list.add(sourceProperty);
}
}
// clear transient list
transientList.clearProperties();
}
}
// save fragment property list in thread local cache utilizing
// weak references to ensure threads locals for pooled threads
// are cleaned up when cleanupRequestCache() is not invoked,
// (typically batch processes accessing the PageManager).
if (threadLocalCache == null)
{
// create bounded LRU cache per thread to limit footprint
// of long running or pooled threads, (typically batch
// processes accessing the PageManager).
threadLocalCache = new LinkedHashMap(MIN_THREAD_CACHE_SIZE, 0.75F, true)
{
protected boolean removeEldestEntry(Map.Entry eldest)
{
return (size() > maxThreadCacheSize);
}
};
fragmentPropertyListsCache.set(threadLocalCache);
}
threadLocalCache.put(fragmentListKey, new WeakReference(list));
}
return list;
}
/**
* Update fragment property list.
*
* @param baseFragmentElementImpl fragment element
* @param scope fragment property scope to update
* @param transientList transient fragment property list
*/
public void updateFragmentPropertyList(BaseFragmentElementImpl baseFragmentElementImpl, String scope, FragmentPropertyList transientList)
{
// update persistent list
FragmentPropertyList list = getFragmentPropertyList(baseFragmentElementImpl, transientList);
if (list != null)
{
// get subject
Subject subject = JSSubject.getSubject(AccessController.getContext());
Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject, User.class) : null);
String userPrincipalKey = ((userPrincipal != null) ? getFragmentPropertyListPrincipalKey(USER_PROPERTY_SCOPE, userPrincipal.getName()) : null);
// update fragment properties in list in database
boolean updateAllScopes = ((scope != null) && scope.equals(ALL_PROPERTY_SCOPE));
synchronized (list)
{
// store property objects for add/update and decompose
// update into cache updates, (assumes scoped property
// extents are fully represented in list).
boolean updateTransaction = false;
DatabasePageManagerCachedFragmentPropertyList globalFragmentPropertyList = null;
Map principalPartialFragmentPropertyLists = null;
String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
List properties = list.getProperties();
List removedProperties = list.getRemovedProperties();
// construct scoped properties lists for cache updates from
// all properties, (add, update, and remove)
List allProperties = new ArrayList(properties);
if (removedProperties != null)
{
allProperties.addAll(removedProperties);
}
Iterator allPropertiesIter = allProperties.iterator();
while (allPropertiesIter.hasNext())
{
FragmentPropertyImpl property = (FragmentPropertyImpl)allPropertiesIter.next();
property.setFragment(baseFragmentElementImpl);
String propertyScope = property.getScope();
String propertyScopeValue = property.getScopeValue();
if (updateAllScopes || ((scope == null) && (propertyScope == null)) || ((scope != null) && scope.equals(propertyScope)))
{
// classify property by scopes and create scoped lists
if (propertyScope == null)
{
if (globalFragmentPropertyList == null)
{
globalFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(baseFragmentElementImpl.getBaseFragmentsElement().getPath());
}
}
else if ((subject != null) && GROUP_AND_ROLE_PROPERTY_SCOPES_ENABLED)
{
boolean subjectHasPrincipal = false;
if (propertyScope.equals(USER_PROPERTY_SCOPE))
{
subjectHasPrincipal = ((userPrincipal != null) && userPrincipal.getName().equals(propertyScopeValue));
}
else if (propertyScope.equals(GROUP_PROPERTY_SCOPE))
{
subjectHasPrincipal = (SubjectHelper.getPrincipal(subject, Group.class, propertyScopeValue) != null);
}
else if (propertyScope.equals(ROLE_PROPERTY_SCOPE))
{
subjectHasPrincipal = (SubjectHelper.getPrincipal(subject, Role.class, propertyScopeValue) != null);
}
if (subjectHasPrincipal)
{
if (principalPartialFragmentPropertyLists == null)
{
principalPartialFragmentPropertyLists = new HashMap();
}
String principalKey = getFragmentPropertyListPrincipalKey(propertyScope, propertyScopeValue);
DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList = (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(principalKey);
if (principalPartialFragmentPropertyList == null)
{
principalPartialFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(propertyScope, principalKey);
principalPartialFragmentPropertyLists.put(principalKey, principalPartialFragmentPropertyList);
}
}
}
else if ((subject != null) && propertyScope.equals(USER_PROPERTY_SCOPE))
{
if ((userPrincipal != null) && userPrincipal.getName().equals(propertyScopeValue))
{
if (principalPartialFragmentPropertyLists == null)
{
principalPartialFragmentPropertyLists = new HashMap();
}
DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList = (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(userPrincipalKey);
if (principalPartialFragmentPropertyList == null)
{
principalPartialFragmentPropertyList = new DatabasePageManagerCachedFragmentPropertyList(USER_PROPERTY_SCOPE, userPrincipalKey);
principalPartialFragmentPropertyLists.put(userPrincipalKey, principalPartialFragmentPropertyList);
}
}
}
}
}
// populate properties lists for cache updates and
// update persistent properties
Iterator propertiesIter = properties.iterator();
while (propertiesIter.hasNext())
{
FragmentPropertyImpl storeProperty = (FragmentPropertyImpl)propertiesIter.next();
String storePropertyScope = storeProperty.getScope();
String storePropertyScopeValue = storeProperty.getScopeValue();
if (updateAllScopes || ((scope == null) && (storePropertyScope == null)) || ((scope != null) && scope.equals(storePropertyScope)))
{
// classify and decompose update into individual caches:
// allow update only if scoped properties list created above
// exists since the subject matching rules are checked there
updateTransaction = (updateTransaction || (storeProperty.getIdentity() != 0));
boolean store = false;
if (storePropertyScope == null)
{
if (globalFragmentPropertyList != null)
{
globalFragmentPropertyList.add(storeProperty);
store = true;
}
}
else if (subject != null)
{
if (principalPartialFragmentPropertyLists != null)
{
String principalKey = getFragmentPropertyListPrincipalKey(storePropertyScope, storePropertyScopeValue);
DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList = (DatabasePageManagerCachedFragmentPropertyList)principalPartialFragmentPropertyLists.get(principalKey);
if (principalPartialFragmentPropertyList != null)
{
principalPartialFragmentPropertyList.add(storeProperty);
store = true;
}
}
}
// store persistent property object
if (store)
{
getPersistenceBrokerTemplate().store(storeProperty);
}
}
}
if (removedProperties != null)
{
Iterator removedPropertiesIter = removedProperties.iterator();
while (removedPropertiesIter.hasNext())
{
FragmentPropertyImpl deleteProperty = (FragmentPropertyImpl)removedPropertiesIter.next();
deleteProperty.setFragment(baseFragmentElementImpl);
String deletePropertyScope = deleteProperty.getScope();
String deletePropertyScopeValue = deleteProperty.getScopeValue();
if (updateAllScopes || ((scope == null) && (deletePropertyScope == null)) || ((scope != null) && scope.equals(deletePropertyScope)))
{
// classify and decompose delete: allow delete only
// if scoped properties list created above exists
// since the subject matching rules are checked there
updateTransaction = true;
boolean delete = false;
if (deletePropertyScope == null)
{
delete = (globalFragmentPropertyList != null);
}
else if (subject != null)
{
if (principalPartialFragmentPropertyLists != null)
{
String principalKey = getFragmentPropertyListPrincipalKey(deletePropertyScope, deletePropertyScopeValue);
delete = principalPartialFragmentPropertyLists.containsKey(principalKey);
}
}
// delete persistent property object
if (delete)
{
getPersistenceBrokerTemplate().delete(deleteProperty);
}
}
}
}
// interoperate with cache to signal update operations and
// record thread transactions
if (globalFragmentPropertyList != null)
{
// cache new global fragment property list
DatabasePageManagerCache.fragmentPropertyListCacheAdd(fragmentKey, globalFragmentPropertyList, true);
DatabasePageManagerCache.addTransaction(new TransactionedOperation(fragmentKey, (updateTransaction ? TransactionedOperation.UPDATE_FRAGMENT_PROPERTIES_OPERATION : TransactionedOperation.ADD_FRAGMENT_PROPERTIES_OPERATION)));
}
if (principalPartialFragmentPropertyLists != null)
{
// update cached principal scoped fragment property lists
Iterator listsIter = principalPartialFragmentPropertyLists.entrySet().iterator();
while (listsIter.hasNext())
{
Map.Entry entry = (Map.Entry)listsIter.next();
String principalKey = (String)entry.getKey();
DatabasePageManagerCachedFragmentPropertyList principalPartialFragmentPropertyList = (DatabasePageManagerCachedFragmentPropertyList)entry.getValue();
// update cached principal scoped fragment property list
DatabasePageManagerCachedFragmentPropertyList cachedPrincipalFragmentPropertyList = DatabasePageManagerCache.principalFragmentPropertyListCacheLookup(principalKey);
if (cachedPrincipalFragmentPropertyList != null)
{
synchronized (cachedPrincipalFragmentPropertyList)
{
removeAllPrincipalFragmentPropertyList(cachedPrincipalFragmentPropertyList, baseFragmentElementImpl);
cachedPrincipalFragmentPropertyList.addAll(principalPartialFragmentPropertyList);
}
DatabasePageManagerCache.principalFragmentPropertyListCacheAdd(principalKey, cachedPrincipalFragmentPropertyList, true);
}
DatabasePageManagerCache.addTransaction(new TransactionedOperation(principalKey, (updateTransaction ? TransactionedOperation.UPDATE_PRINCIPAL_FRAGMENT_PROPERTIES_OPERATION : TransactionedOperation.ADD_PRINCIPAL_FRAGMENT_PROPERTIES_OPERATION)));
}
}
}
}
}
/**
* Remove fragment property list.
*
* @param baseFragmentElementImpl fragment element
* @param transientList transient fragment property list
*/
public void removeFragmentPropertyList(BaseFragmentElementImpl baseFragmentElementImpl, FragmentPropertyList transientList)
{
// access thread local fragment property lists cache
String fragmentKey = getFragmentPropertyListFragmentKey(baseFragmentElementImpl);
Subject subject = JSSubject.getSubject(AccessController.getContext());
Principal userPrincipal = ((subject != null) ? SubjectHelper.getBestPrincipal(subject, User.class) : null);
String fragmentListKey = getFragmentPropertyListKey(fragmentKey, userPrincipal);
Map threadLocalCache = (Map)fragmentPropertyListsCache.get();
WeakReference listReference = ((threadLocalCache != null) ? (WeakReference)threadLocalCache.get(fragmentListKey) : null);
FragmentPropertyList list = ((listReference != null) ? (FragmentPropertyList)listReference.get() : null);
// remove cached persistent list
if (list != null)
{
// remove list from cache
threadLocalCache.remove(fragmentKey);
// cleanup list
list.clearProperties();
}
// cleanup transient list
if (transientList != null)
{
transientList.clearProperties();
}
// remove all fragment properties in list from database
Integer fragmentId = new Integer(baseFragmentElementImpl.getIdentity());
Criteria filter = new Criteria();
filter.addEqualTo("fragment", fragmentId);
QueryByCriteria query = QueryFactory.newQuery(FragmentPropertyImpl.class, filter);
getPersistenceBrokerTemplate().deleteByQuery(query);
// interoperate with cache to signal remove operations
DatabasePageManagerCache.fragmentPropertyListCacheRemove(fragmentKey);
DatabasePageManagerCache.addTransaction(new TransactionedOperation(fragmentKey, TransactionedOperation.UPDATE_FRAGMENT_PROPERTIES_OPERATION));
}
/**
* Compute thread local fragment property list key for fragment properties.
*
* @param fragmentKey fragment key
* @param userPrincipal current subject user principal
* @return fragment property list key string
*/
private static String getFragmentPropertyListKey(String fragmentKey, Principal userPrincipal)
{
if (userPrincipal != null)
{
return fragmentKey+"/"+userPrincipal.getName();
}
return fragmentKey;
}
/**
* Compute fragment key for fragment properties.
*
* @param baseFragmentElementImpl owner of fragment properties
* @return fragment key string
*/
private static String getFragmentPropertyListFragmentKey(BaseFragmentElementImpl baseFragmentElementImpl)
{
return baseFragmentElementImpl.getBaseFragmentsElement().getPath()+"/"+baseFragmentElementImpl.getId()+":"+baseFragmentElementImpl.getIdentity();
}
/**
* Compute principal key for fragment properties.
*
* @param principalType principal type
* @param principalName principal name
* @return principal key string
*/
private static String getFragmentPropertyListPrincipalKey(String principalType, String principalName)
{
return principalType+":"+principalName;
}
/**
* Filter principal fragment property list.
*
* @param principalFragmentPropertyList principal fragment property list
* @param baseFragmentElementImpl fragment property owning fragment
* @return fragment property list for owning fragment
*/
private static List filterPrincipalFragmentPropertyList(DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList, BaseFragmentElementImpl baseFragmentElementImpl)
{
List filteredList = null;
synchronized (principalFragmentPropertyList)
{
for (Iterator iter = principalFragmentPropertyList.iterator(); iter.hasNext();)
{
FragmentPropertyImpl fragmentProperty = (FragmentPropertyImpl)iter.next();
if (((BaseFragmentElementImpl)fragmentProperty.getFragment()).getIdentity() == baseFragmentElementImpl.getIdentity())
{
if (filteredList == null)
{
filteredList = new ArrayList();
}
filteredList.add(fragmentProperty);
}
}
}
return filteredList;
}
/**
* Remove matching principal fragment properties from list.
*
* @param principalFragmentPropertyList principal fragment property list
* @param baseFragmentElementImpl fragment property owning fragment
*/
private static void removeAllPrincipalFragmentPropertyList(DatabasePageManagerCachedFragmentPropertyList principalFragmentPropertyList, BaseFragmentElementImpl baseFragmentElementImpl)
{
synchronized (principalFragmentPropertyList)
{
for (Iterator iter = principalFragmentPropertyList.iterator(); iter.hasNext();)
{
FragmentPropertyImpl fragmentProperty = (FragmentPropertyImpl)iter.next();
if (((BaseFragmentElementImpl)fragmentProperty.getFragment()).getIdentity() == baseFragmentElementImpl.getIdentity())
{
iter.remove();
}
}
}
}
/**
* Rollback transactions registered with current thread.
*/
public static void rollbackTransactions()
{
// clear thread local cache on rollback to ensure clean reset
fragmentPropertyListsCache.remove();
}
/**
* Clear transactions registered with current thread.
*/
public static void clearTransactions()
{
// do not clear thread local cache: cache across transactions
}
public FragmentPropertyManagement getFragmentPropertyManager()
{
return this;
}
public FragmentPropertyList getFragmentPropertyList(
BaseFragmentElement baseFragmentElement,
FragmentPropertyList transientList)
{
return getFragmentPropertyList((BaseFragmentElementImpl)baseFragmentElement, transientList);
}
public void removeFragmentPropertyList(
BaseFragmentElement baseFragmentElement,
FragmentPropertyList transientList)
{
removeFragmentPropertyList((BaseFragmentElementImpl)baseFragmentElement, transientList);
}
public void updateFragmentPropertyList(
BaseFragmentElement baseFragmentElement, String scope,
FragmentPropertyList transientList)
{
updateFragmentPropertyList((BaseFragmentElementImpl)baseFragmentElement, scope, transientList);
}
}