/*
* 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.psml;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.jetspeed.JetspeedActions;
import org.apache.jetspeed.cache.file.FileCache;
import org.apache.jetspeed.cache.file.FileCacheEntry;
import org.apache.jetspeed.cache.file.FileCacheEventListener;
import org.apache.jetspeed.idgenerator.IdGenerator;
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.psml.FolderImpl;
import org.apache.jetspeed.om.folder.psml.MenuDefinitionImpl;
import org.apache.jetspeed.om.folder.psml.MenuExcludeDefinitionImpl;
import org.apache.jetspeed.om.folder.psml.MenuIncludeDefinitionImpl;
import org.apache.jetspeed.om.folder.psml.MenuOptionsDefinitionImpl;
import org.apache.jetspeed.om.folder.psml.MenuSeparatorDefinitionImpl;
import org.apache.jetspeed.om.page.BaseFragmentElement;
import org.apache.jetspeed.om.page.DynamicPage;
import org.apache.jetspeed.om.page.FragmentDefinition;
import org.apache.jetspeed.om.page.Link;
import org.apache.jetspeed.om.page.Page;
import org.apache.jetspeed.om.page.PageSecurity;
import org.apache.jetspeed.om.page.PageTemplate;
import org.apache.jetspeed.om.page.SecurityConstraintImpl;
import org.apache.jetspeed.om.page.SecurityConstraintsDef;
import org.apache.jetspeed.om.page.psml.AbstractBaseFragmentElement;
import org.apache.jetspeed.om.page.psml.AbstractBaseFragmentsElement;
import org.apache.jetspeed.om.page.psml.DynamicPageImpl;
import org.apache.jetspeed.om.page.psml.FragmentDefinitionImpl;
import org.apache.jetspeed.om.page.psml.FragmentImpl;
import org.apache.jetspeed.om.page.psml.FragmentPreferenceImpl;
import org.apache.jetspeed.om.page.psml.FragmentReferenceImpl;
import org.apache.jetspeed.om.page.psml.LinkImpl;
import org.apache.jetspeed.om.page.psml.PageFragmentImpl;
import org.apache.jetspeed.om.page.psml.PageImpl;
import org.apache.jetspeed.om.page.psml.PageSecurityImpl;
import org.apache.jetspeed.om.page.psml.PageTemplateImpl;
import org.apache.jetspeed.om.page.psml.PropertyImpl;
import org.apache.jetspeed.om.page.psml.SecurityConstraintsDefImpl;
import org.apache.jetspeed.om.page.psml.SecurityConstraintsImpl;
import org.apache.jetspeed.page.AbstractPageManager;
import org.apache.jetspeed.page.FolderNotUpdatedException;
import org.apache.jetspeed.page.FragmentPropertyList;
import org.apache.jetspeed.page.FragmentPropertyManagement;
import org.apache.jetspeed.page.PageManager;
import org.apache.jetspeed.page.PageManagerSecurityUtils;
import org.apache.jetspeed.page.PageNotFoundException;
import org.apache.jetspeed.page.PageNotUpdatedException;
import org.apache.jetspeed.page.document.DocumentException;
import org.apache.jetspeed.page.document.DocumentHandlerFactory;
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.FolderHandler;
import org.apache.jetspeed.page.document.Node;
import org.apache.jetspeed.page.document.NodeException;
import org.apache.jetspeed.page.document.NodeSet;
import org.apache.jetspeed.page.document.UnsupportedDocumentTypeException;
import org.apache.jetspeed.page.document.psml.NodeSetImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This service is responsible for loading and saving PSML pages serialized to
* disk
*
* @author <a href="mailto:raphael@apache.org">Rapha�l Luta </a>
* @author <a href="mailto:weaver@apache.org">Scott T Weaver </a>
* @version $Id: CastorXmlPageManager.java 989442 2010-08-26 04:43:00Z taylor $
*/
public class CastorXmlPageManager extends AbstractPageManager implements PageManager, FileCacheEventListener, FragmentPropertyManagement
{
private final static Logger log = LoggerFactory.getLogger(CastorXmlPageManager.class);
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", MenuDefinitionImpl.class);
modelClasses.put("FolderMenuExcludeDefinitionImpl", MenuExcludeDefinitionImpl.class);
modelClasses.put("FolderMenuIncludeDefinitionImpl", MenuIncludeDefinitionImpl.class);
modelClasses.put("FolderMenuOptionsDefinitionImpl", MenuOptionsDefinitionImpl.class);
modelClasses.put("FolderMenuSeparatorDefinitionImpl", MenuSeparatorDefinitionImpl.class);
modelClasses.put("PageMenuDefinitionImpl", MenuDefinitionImpl.class);
modelClasses.put("PageMenuExcludeDefinitionImpl", MenuExcludeDefinitionImpl.class);
modelClasses.put("PageMenuIncludeDefinitionImpl", MenuIncludeDefinitionImpl.class);
modelClasses.put("PageMenuOptionsDefinitionImpl", MenuOptionsDefinitionImpl.class);
modelClasses.put("PageMenuSeparatorDefinitionImpl", MenuSeparatorDefinitionImpl.class);
modelClasses.put("SecurityConstraintsImpl", SecurityConstraintsImpl.class);
modelClasses.put("FolderSecurityConstraintImpl", SecurityConstraintImpl.class);
modelClasses.put("PageSecurityConstraintImpl", SecurityConstraintImpl.class);
modelClasses.put("FragmentSecurityConstraintImpl", SecurityConstraintImpl.class);
modelClasses.put("LinkSecurityConstraintImpl", SecurityConstraintImpl.class);
modelClasses.put("PageSecuritySecurityConstraintImpl", SecurityConstraintImpl.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", PropertyImpl.class);
}
private DocumentHandlerFactory handlerFactory;
private FolderHandler folderHandler;
private FileCache fileCache;
public CastorXmlPageManager( IdGenerator generator, DocumentHandlerFactory handlerFactory,
FolderHandler folderHandler, FileCache fileCache,
boolean permissionsEnabled, boolean constraintsEnabled ) throws FileNotFoundException
{
super(generator, permissionsEnabled, constraintsEnabled, modelClasses);
handlerFactory.setPermissionsEnabled(permissionsEnabled);
handlerFactory.setConstraintsEnabled(constraintsEnabled);
this.handlerFactory = handlerFactory;
this.folderHandler = folderHandler;
this.fileCache = fileCache;
this.fileCache.addListener(this);
}
/**
* <p>
* getPage
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getPage(java.lang.String)
* @param path
* @return page
* @throws PageNotFoundException
* @throws NodeException
* @throws FolderNotFoundException
*/
public Page getPage(String path) throws PageNotFoundException, NodeException
{
// get page via folder, (access checked in Folder.getPage())
try
{
FolderImpl folder = getNodeFolder(path);
return folder.getPage(getNodeName(path));
}
catch (FolderNotFoundException fnfe)
{
throw new PageNotFoundException(fnfe.getMessage());
}
}
/**
* <p>
* getPageTemplate
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getPageTemplate(java.lang.String)
* @param path
* @return page template
* @throws PageNotFoundException
* @throws NodeException
* @throws FolderNotFoundException
*/
public PageTemplate getPageTemplate(String path) throws PageNotFoundException, NodeException
{
// get page template via folder, (access checked in Folder.getPageTemplate())
try
{
FolderImpl folder = getNodeFolder(path);
return folder.getPageTemplate(getNodeName(path));
}
catch (FolderNotFoundException fnfe)
{
throw new PageNotFoundException(fnfe.getMessage());
}
}
/**
* <p>
* getDynamicPage
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getDynamicPage(java.lang.String)
* @param path
* @return dynamic page
* @throws PageNotFoundException
* @throws NodeException
* @throws FolderNotFoundException
*/
public DynamicPage getDynamicPage(String path) throws PageNotFoundException, NodeException
{
// get dynamic page via folder, (access checked in Folder.getDynamicPage())
try
{
FolderImpl folder = getNodeFolder(path);
return folder.getDynamicPage(getNodeName(path));
}
catch (FolderNotFoundException fnfe)
{
throw new PageNotFoundException(fnfe.getMessage());
}
}
/**
* <p>
* getFragmentDefinition
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getFragmentDefinition(java.lang.String)
* @param path
* @return dynamic page
* @throws PageNotFoundException
* @throws NodeException
* @throws FolderNotFoundException
*/
public FragmentDefinition getFragmentDefinition(String path) throws PageNotFoundException, NodeException
{
// get fragment definition via folder, (access checked in Folder.getDynamicPage())
try
{
FolderImpl folder = getNodeFolder(path);
return folder.getFragmentDefinition(getNodeName(path));
}
catch (FolderNotFoundException fnfe)
{
throw new PageNotFoundException(fnfe.getMessage());
}
}
/**
* <p>
* updatePage
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#updatePage(org.apache.jetspeed.om.page.Page)
*/
public void updatePage(Page page) throws NodeException
{
PageImpl pageImpl = (PageImpl)page;
updateFragmentsElement(pageImpl, Page.DOCUMENT_TYPE, true);
}
/**
* <p>
* updatePageTemplate
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#updatePageTemplate(org.apache.jetspeed.om.page.PageTemplate)
*/
public void updatePageTemplate(PageTemplate pageTemplate) throws NodeException
{
PageTemplateImpl pageTemplateImpl = (PageTemplateImpl)pageTemplate;
updateFragmentsElement(pageTemplateImpl, PageTemplate.DOCUMENT_TYPE, true);
}
/**
* <p>
* updateDynamicPage
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#updateDynamicPage(org.apache.jetspeed.om.page.DynamicPage)
*/
public void updateDynamicPage(DynamicPage dynamicPage) throws NodeException
{
DynamicPageImpl dynamicPageImpl = (DynamicPageImpl)dynamicPage;
updateFragmentsElement(dynamicPageImpl, DynamicPage.DOCUMENT_TYPE, true);
}
/**
* <p>
* updateFragmentDefinition
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#updateFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition)
*/
public void updateFragmentDefinition(FragmentDefinition fragmentDefinition) throws NodeException
{
FragmentDefinitionImpl fragmentDefinitionImpl = (FragmentDefinitionImpl)fragmentDefinition;
updateFragmentsElement(fragmentDefinitionImpl, FragmentDefinition.DOCUMENT_TYPE, true);
}
/**
* <p>
* updateFragmentProperty
* </p>
*
* @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
{
// fragment property writes not supported: lookup and
// update entire page, dynamic page, page template, or
// fragment definition; security is checked unless user
// scope is specified
AbstractBaseFragmentElement fragmentElement = (AbstractBaseFragmentElement)fragment;
AbstractBaseFragmentsElement fragmentsElement = ((fragmentElement != null) ? fragmentElement.getBaseFragmentsElement() : null);
boolean checkEditAccess = ((scope == null) || !scope.equals(USER_PROPERTY_SCOPE));
if (fragmentsElement instanceof Page)
{
updateFragmentsElement(fragmentsElement, Page.DOCUMENT_TYPE, checkEditAccess);
}
else if (fragmentsElement instanceof DynamicPage)
{
updateFragmentsElement(fragmentsElement, DynamicPage.DOCUMENT_TYPE, checkEditAccess);
}
else if (fragmentsElement instanceof PageTemplate)
{
updateFragmentsElement(fragmentsElement, PageTemplate.DOCUMENT_TYPE, checkEditAccess);
}
else if (fragmentsElement instanceof FragmentDefinition)
{
updateFragmentsElement(fragmentsElement, FragmentDefinition.DOCUMENT_TYPE, checkEditAccess);
}
else
{
throw new PageNotUpdatedException("Unable to update fragment properties: no owning page");
}
}
/**
* <p>
* updateFragmentsElement
* </p>
*
* @param fragmentsElement generic fragments/page element implementation
* @param documentType document type
* @throws NodeException thrown on update error
*/
private void updateFragmentsElement(AbstractBaseFragmentsElement fragmentsElement, String documentType, boolean checkEditAccess) throws NodeException
{
// make sure path and related members are set
if (fragmentsElement.getPath() != null)
{
if (!fragmentsElement.getPath().equals(fragmentsElement.getId()))
{
throw new NodeException("Fragments/page paths and ids must match!");
}
}
else
{
throw new NodeException("Fragments/page paths and ids must be set!");
}
// validate fragments element
if (!fragmentsElement.validateFragments())
{
throw new NodeException("Fragments hierarchy invalid for fragments/page: " + fragmentsElement.getPath() + ", not updated.");
}
try
{
// set parent
boolean newPageElement = false;
FolderImpl parentFolder = getNodeFolder(fragmentsElement.getPath());
if (fragmentsElement.getParent() == null)
{
fragmentsElement.setParent(parentFolder);
newPageElement = true;
}
// enable permissions/constraints
fragmentsElement.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
fragmentsElement.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
// check for edit/view access
fragmentsElement.checkAccess(checkEditAccess ? JetspeedActions.EDIT : JetspeedActions.VIEW);
// update fragments/page
handlerFactory.getDocumentHandler(documentType).updateDocument(fragmentsElement);
// update parent folder
if (parentFolder != null)
{
NodeSetImpl parentAllNodes = (NodeSetImpl)parentFolder.getAllNodes();
if (!parentAllNodes.contains(fragmentsElement))
{
// add new fragments/page element
parentAllNodes.add(fragmentsElement);
newPageElement = true;
}
else if (parentAllNodes.get(fragmentsElement.getPath()) != fragmentsElement)
{
// remove stale fragments/page element and add updated element
parentAllNodes.remove(fragmentsElement);
parentAllNodes.add(fragmentsElement);
}
}
// notify page manager listeners
if (newPageElement)
{
notifyNewNode(fragmentsElement);
}
else
{
notifyUpdatedNode(fragmentsElement);
}
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
}
/**
* <p>
* removePage
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removePage(org.apache.jetspeed.om.page.Page)
*/
public void removePage(Page page) throws NodeException
{
PageImpl pageImpl = (PageImpl)page;
removeFragmentsElement(pageImpl, Page.DOCUMENT_TYPE);
}
/**
* <p>
* removePageTemplate
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removePageTemplate(org.apache.jetspeed.om.page.PageTemplate)
*/
public void removePageTemplate(PageTemplate pageTemplate) throws NodeException
{
PageTemplateImpl pageTemplateImpl = (PageTemplateImpl)pageTemplate;
removeFragmentsElement(pageTemplateImpl, PageTemplate.DOCUMENT_TYPE);
}
/**
* <p>
* removeDynamicPage
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removeDynamicPage(org.apache.jetspeed.om.page.DynamicPage)
*/
public void removeDynamicPage(DynamicPage dynamicPage) throws NodeException
{
DynamicPageImpl dynamicPageImpl = (DynamicPageImpl)dynamicPage;
removeFragmentsElement(dynamicPageImpl, DynamicPage.DOCUMENT_TYPE);
}
/**
* <p>
* removeFragmentDefinition
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removeFragmentDefinition(org.apache.jetspeed.om.page.FragmentDefinition)
*/
public void removeFragmentDefinition(FragmentDefinition fragmentsDefinition) throws NodeException
{
FragmentDefinitionImpl fragmentsDefinitionImpl = (FragmentDefinitionImpl)fragmentsDefinition;
removeFragmentsElement(fragmentsDefinitionImpl, FragmentDefinition.DOCUMENT_TYPE);
}
/**
* <p>
* removeFragmentsElement
* </p>
*
* @param fragmentsElement generic fragments/page element implementation
* @param documentType document type
* @throws NodeException thrown on remove error
*/
private void removeFragmentsElement(AbstractBaseFragmentsElement fragmentsElement, String documentType) throws NodeException
{
// check for edit access
fragmentsElement.checkAccess(JetspeedActions.EDIT);
try
{
FolderImpl folder = getNodeFolder(fragmentsElement.getPath());
// remove fragments/page
handlerFactory.getDocumentHandler(documentType).removeDocument(fragmentsElement);
// update folder
((NodeSetImpl)folder.getAllNodes()).remove(fragmentsElement);
// notify page manager listeners
notifyRemovedNode(fragmentsElement);
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
catch (DocumentNotFoundException dnfe)
{
throw new NodeException(dnfe.getMessage());
}
}
/**
* <p>
* getLink
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getLink(java.lang.String)
* @param path
* @return link
* @throws DocumentNotFoundException
* @throws UnsupportedDocumentTypeException
* @throws NodeException
*/
public Link getLink(String path) throws DocumentNotFoundException, UnsupportedDocumentTypeException, NodeException
{
// get link via folder, (access checked in Folder.getLink())
try
{
FolderImpl folder = getNodeFolder(path);
return folder.getLink(getNodeName(path));
}
catch (FolderNotFoundException fnfe)
{
throw new DocumentNotFoundException(fnfe.getMessage());
}
}
/**
* <p>
* updateLink
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#updateLink(org.apache.jetspeed.om.page.Link)
*/
public void updateLink(Link link) throws NodeException
{
// make sure path and related members are set
if (link.getPath() != null)
{
if (!link.getPath().equals(link.getId()))
{
log.error("Link paths and ids must match!");
return;
}
}
else
{
log.error("Link paths and ids must be set!");
return;
}
try
{
// set parent
boolean newLink = false;
FolderImpl parentFolder = getNodeFolder(link.getPath());
if (link.getParent() == null)
{
link.setParent(parentFolder);
newLink = true;
}
// enable permissions/constraints
LinkImpl linkImpl = (LinkImpl)link;
linkImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
linkImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
// check for edit access
link.checkAccess(JetspeedActions.EDIT);
// update link
handlerFactory.getDocumentHandler(Link.DOCUMENT_TYPE).updateDocument(link);
// update parent folder
if (parentFolder != null)
{
NodeSetImpl parentAllNodes = (NodeSetImpl)parentFolder.getAllNodes();
if (!parentAllNodes.contains(link))
{
// add new link
parentAllNodes.add(link);
newLink = true;
}
else if (parentAllNodes.get(link.getPath()) != link)
{
// remove stale link and add updated link
parentAllNodes.remove(link);
parentAllNodes.add(link);
}
}
// notify page manager listeners
if (newLink)
{
notifyNewNode(link);
}
else
{
notifyUpdatedNode(link);
}
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
}
/**
* <p>
* removeLink
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removeLink(org.apache.jetspeed.om.page.Link)
*/
public void removeLink(Link link) throws NodeException
{
// check for edit access
link.checkAccess(JetspeedActions.EDIT);
try
{
FolderImpl folder = getNodeFolder(link.getPath());
// remove link
handlerFactory.getDocumentHandler(Link.DOCUMENT_TYPE).removeDocument(link);
// update folder
((NodeSetImpl)folder.getAllNodes()).remove(link);
// notify page manager listeners
notifyRemovedNode(link);
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
catch (DocumentNotFoundException dnfe)
{
throw new NodeException(dnfe.getMessage());
}
}
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)
{
log.error(e.getMessage(), e);
}
return false;
}
/**
* <p>
* getPageSecurity
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getPageSecurity()
* @return page security instance
* @throws DocumentNotFoundException
* @throws UnsupportedDocumentTypeException
* @throws NodeException
*/
public PageSecurity getPageSecurity() throws DocumentNotFoundException, UnsupportedDocumentTypeException, NodeException
{
// get page security via folder, (always allow access)
try
{
FolderImpl folder = getNodeFolder(Folder.PATH_SEPARATOR);
return folder.getPageSecurity();
}
catch (FolderNotFoundException fnfe)
{
throw new DocumentNotFoundException(fnfe.getMessage());
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#updatePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
*/
public void updatePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToUpdateDocumentException
{
// validate path... must exist in root folder and
// make sure path and related members are set
if (pageSecurity.getPath() != null)
{
if (!pageSecurity.getPath().equals(Folder.PATH_SEPARATOR + PageSecurity.DOCUMENT_TYPE))
{
log.error("PageSecurity path must be: " + Folder.PATH_SEPARATOR + PageSecurity.DOCUMENT_TYPE);
return;
}
if (!pageSecurity.getPath().equals(pageSecurity.getId()))
{
log.error("PageSecurity paths and ids must match!");
return;
}
}
else
{
log.error("PageSecurity paths and ids must be set!");
return;
}
try
{
// set parent
boolean newPageSecurity = false;
FolderImpl parentFolder = getNodeFolder(Folder.PATH_SEPARATOR);
if (pageSecurity.getParent() == null)
{
pageSecurity.setParent(parentFolder);
newPageSecurity = true;
}
// enable permissions/constraints
PageSecurityImpl pageSecurityImpl = (PageSecurityImpl)pageSecurity;
pageSecurityImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
pageSecurityImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
// check for edit access
pageSecurity.checkAccess(JetspeedActions.EDIT);
// update pageSecurity
handlerFactory.getDocumentHandler(PageSecurity.DOCUMENT_TYPE).updateDocument(pageSecurity);
// update parent folder
if (parentFolder != null)
{
NodeSetImpl parentAllNodes = (NodeSetImpl)parentFolder.getAllNodes();
if (!parentAllNodes.contains(pageSecurity))
{
// add new page security
parentAllNodes.add(pageSecurity);
newPageSecurity = true;
}
else if (parentAllNodes.get(pageSecurity.getPath()) != pageSecurity)
{
// remove stale page security and add updated page security
parentAllNodes.remove(pageSecurity);
parentAllNodes.add(pageSecurity);
}
}
// notify page manager listeners
if (newPageSecurity)
{
notifyNewNode(pageSecurity);
}
else
{
notifyUpdatedNode(pageSecurity);
}
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#removePageSecurity(org.apache.jetspeed.om.page.PageSecurity)
*/
public void removePageSecurity(PageSecurity pageSecurity) throws NodeException, FailedToDeleteDocumentException
{
// check for edit access
pageSecurity.checkAccess(JetspeedActions.EDIT);
try
{
FolderImpl folder = getNodeFolder(Folder.PATH_SEPARATOR);
// remove page security
handlerFactory.getDocumentHandler(PageSecurity.DOCUMENT_TYPE).removeDocument(pageSecurity);
// update folder
((NodeSetImpl)folder.getAllNodes()).remove(pageSecurity);
// notify page manager listeners
notifyRemovedNode(pageSecurity);
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
catch (DocumentNotFoundException dnfe)
{
throw new NodeException(dnfe.getMessage());
}
}
/**
* <p>
* getFolder
* </p>
*
* @see org.apache.jetspeed.page.PageManager#getFolder(java.lang.String)
* @param folderPath
* @return folder instance
* @throws FolderNotFoundException
* @throws NodeException
* @throws InvalidFolderException
*/
public Folder getFolder(String folderPath) throws FolderNotFoundException, InvalidFolderException, NodeException
{
// get folder and check access before returning
Folder folder = folderHandler.getFolder(folderPath);
folder.checkAccess(JetspeedActions.VIEW);
return folder;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFolders(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getFolders(Folder folder) throws DocumentException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getFolder(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPages(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getPages(Folder folder) throws NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getPage(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageTemplates(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getPageTemplates(Folder folder) throws NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getPageTemplate(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getDynamicPages(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getDynamicPages(Folder folder) throws NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getDynamicPage(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getFragmentDefinitions(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getFragmentDefinitions(Folder folder) throws NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getFragmentDefinition(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getLinks(org.apache.jetspeed.om.folder.Folder)
*/
public NodeSet getLinks(Folder folder) throws NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getLink(name);
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#getPageSecurity(org.apache.jetspeed.om.folder.Folder)
*/
public PageSecurity getPageSecurity(Folder folder) throws DocumentNotFoundException, NodeException
{
// delegate back to folder instance
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
{
// delegate back to folder instance
return folder.getAll();
}
/**
* <p>
* updateFolder
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#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
{
// make sure path and related members are set
if (folder.getPath() != null)
{
if (!folder.getPath().equals(folder.getId()))
{
log.error("Folder paths and ids must match!");
return;
}
}
else
{
log.error("Folder paths and ids must be set!");
return;
}
try
{
// set parent
boolean newFolder = false;
FolderImpl parentFolder = null;
if (!folder.getPath().equals(Folder.PATH_SEPARATOR))
{
parentFolder = getNodeFolder(folder.getPath());
if (folder.getParent() == null)
{
folder.setParent(parentFolder);
newFolder = true;
}
}
else
{
folder.setParent(null);
}
// enable permissions/constraints and configure
// folder handler before access is checked
FolderImpl folderImpl = (FolderImpl)folder;
folderImpl.setPermissionsEnabled(handlerFactory.getPermissionsEnabled());
folderImpl.setConstraintsEnabled(handlerFactory.getConstraintsEnabled());
folderImpl.setFolderHandler(folderHandler);
// check for edit access
folder.checkAccess(JetspeedActions.EDIT);
// update folder
folderHandler.updateFolder(folder);
// update parent folder
if (parentFolder != null)
{
NodeSetImpl parentAllNodes = (NodeSetImpl)parentFolder.getAllNodes();
if (!parentAllNodes.contains(folder))
{
// add new folder
parentAllNodes.add(folder);
newFolder = true;
}
else if (parentAllNodes.get(folder.getPath()) != folder)
{
// remove stale folder and add updated folder
parentAllNodes.remove(folder);
parentAllNodes.add(folder);
}
}
// update deep recursively if specified
if (deep)
{
// update recursively, (breadth first)
updateFolderNodes(folderImpl);
}
// notify page manager listeners
if (newFolder)
{
notifyNewNode(folder);
}
else
{
notifyUpdatedNode(folder);
}
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
}
/**
* 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 folder documents
NodeSet nodes = folderImpl.getAllNodes();
Iterator nodesIter = nodes.iterator();
while (nodesIter.hasNext())
{
Node node = (Node) nodesIter.next();
if (node instanceof Page)
{
updatePage((Page)node);
}
else if (node instanceof PageTemplate)
{
updatePageTemplate((PageTemplate)node);
}
else if (node instanceof DynamicPage)
{
updateDynamicPage((DynamicPage)node);
}
else if (node instanceof FragmentDefinition)
{
updateFragmentDefinition((FragmentDefinition)node);
}
else if (node instanceof Link)
{
updateLink((Link)node);
}
else if (node instanceof PageSecurity)
{
updatePageSecurity((PageSecurity)node);
}
}
// update folders last: breadth first recursion
nodesIter = nodes.iterator();
while (nodesIter.hasNext())
{
Node node = (Node) nodesIter.next();
if (node instanceof Folder)
{
updateFolder((Folder)node, true);
}
}
}
catch (FolderNotUpdatedException fnue)
{
throw fnue;
}
catch (SecurityException se)
{
throw se;
}
catch (Exception e)
{
throw new FolderNotUpdatedException("Folder " + folderImpl.getPath() + " not updated.", e);
}
}
/**
* <p>
* removeFolder
* </p>
*
* @see org.apache.jetspeed.services.page.PageManagerService#removeFolder(org.apache.jetspeed.om.folder.Folder)
*/
public void removeFolder(Folder folder) throws NodeException
{
// check for edit access
folder.checkAccess(JetspeedActions.EDIT);
try
{
FolderImpl parentFolder = null;
if (!folder.getPath().equals(Folder.PATH_SEPARATOR))
{
parentFolder = getNodeFolder(folder.getPath());
}
// remove folder
folderHandler.removeFolder(folder);
// update parent folder
if (parentFolder != null)
{
((NodeSetImpl)parentFolder.getAllNodes()).remove(folder);
}
// notify page manager listeners
notifyRemovedNode(folder);
}
catch (FolderNotFoundException fnfe)
{
throw new NodeException(fnfe.getMessage());
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#reset()
*/
public void reset()
{
// propagate to super
super.reset();
// evict all from file cache to force subsequent
// refreshes from persistent store
fileCache.evictAll();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.PageManager#shutdown()
*/
public void shutdown()
{
// propagate to super
super.shutdown();
// disconnect cache listener
fileCache.removeListener(this);
// propagate to handlers
handlerFactory.shutdown();
folderHandler.shutdown();
}
/**
* <p>
* getNodeFolder - get folder implementation associated with specifed path
* </p>
*
* @param nodePath
* @return folder impl instance
* @throws NodeException
* @throws InvalidFolderException
* @throws FolderNotFoundException
*/
private FolderImpl getNodeFolder(String nodePath) throws NodeException, InvalidFolderException, FolderNotFoundException
{
int folderIndex = nodePath.lastIndexOf(Folder.PATH_SEPARATOR);
if (folderIndex > 0)
{
return (FolderImpl) folderHandler.getFolder(nodePath.substring(0, folderIndex));
}
return (FolderImpl) folderHandler.getFolder(Folder.PATH_SEPARATOR);
}
/**
* <p>
* getNodeFolder - get name of node from specified path
* </p>
*
* @param nodePath
* @return name of node
*/
private String getNodeName(String nodePath)
{
int folderIndex = nodePath.lastIndexOf(Folder.PATH_SEPARATOR);
if (folderIndex > -1)
{
return nodePath.substring(folderIndex+1);
}
return nodePath;
}
/**
* <p>
* refresh file cache entry
* </p>
*
* @see org.apache.jetspeed.cache.file.FileCacheEventListener#refresh(org.apache.jetspeed.cache.file.FileCacheEntry)
* @param entry
* @throws Exception
*/
public void refresh( FileCacheEntry entry ) throws Exception
{
// file cache managed component refreshed:
// notify page manager listeners
Node refreshedNode = null;
if (entry.getDocument() instanceof Node)
{
refreshedNode = (Node)entry.getDocument();
}
if (entry.getFile().exists())
{
notifyUpdatedNode(refreshedNode);
}
else
{
notifyRemovedNode(refreshedNode);
}
}
/**
* <p>
* evict file cache entry
* </p>
*
* @see org.apache.jetspeed.cache.file.FileCacheEventListener#evict(org.apache.jetspeed.cache.file.FileCacheEntry)
* @param entry
* @throws Exception
*/
public void evict( FileCacheEntry entry ) throws Exception
{
// file cache managed component evicted:
// no notifications required since eviction
// is normal cache operation and does not
// indicate a change in the nodes managed by
// this page manager
}
public FragmentPropertyManagement getFragmentPropertyManager()
{
return this;
}
public FragmentPropertyList getFragmentPropertyList(
BaseFragmentElement baseFragmentElement,
FragmentPropertyList transientList)
{
return null;
}
public void removeFragmentPropertyList(
BaseFragmentElement baseFragmentElement,
FragmentPropertyList transientList)
{
}
public void updateFragmentPropertyList(
BaseFragmentElement baseFragmentElement, String scope,
FragmentPropertyList transientList)
{
}
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;
}
}