/*
* 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.om.folder.impl;
import java.security.AccessController;
import java.security.Permission;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.jetspeed.JetspeedActions;
import org.apache.jetspeed.om.folder.Folder;
import org.apache.jetspeed.om.folder.FolderNotFoundException;
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.page.DynamicPage;
import org.apache.jetspeed.om.page.Fragment;
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.PageMetadataImpl;
import org.apache.jetspeed.om.page.PageSecurity;
import org.apache.jetspeed.om.page.PageTemplate;
import org.apache.jetspeed.om.page.impl.DynamicPageImpl;
import org.apache.jetspeed.om.page.impl.FragmentDefinitionImpl;
import org.apache.jetspeed.om.page.impl.LinkImpl;
import org.apache.jetspeed.om.page.impl.PageImpl;
import org.apache.jetspeed.om.page.impl.PageSecurityImpl;
import org.apache.jetspeed.om.page.impl.PageTemplateImpl;
import org.apache.jetspeed.page.PageNotFoundException;
import org.apache.jetspeed.page.document.DocumentException;
import org.apache.jetspeed.page.document.DocumentNotFoundException;
import org.apache.jetspeed.page.document.Node;
import org.apache.jetspeed.page.document.NodeException;
import org.apache.jetspeed.page.document.NodeNotFoundException;
import org.apache.jetspeed.page.document.NodeSet;
import org.apache.jetspeed.page.document.impl.NodeImpl;
import org.apache.jetspeed.page.document.impl.NodeSetImpl;
import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
import org.apache.jetspeed.security.PermissionFactory;
import org.apache.ojb.broker.core.proxy.ProxyHelper;
/**
* FolderImpl
*
* @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
* @version $Id$
*/
public class FolderImpl extends NodeImpl implements Folder
{
private String defaultPage;
private String skin;
private String defaultLayoutDecorator;
private String defaultPortletDecorator;
private List orders;
private List menus;
private List folders;
private boolean foldersCached;
private List pages;
private boolean pagesCached;
private List pageTemplates;
private boolean pageTemplatesCached;
private List dynamicPages;
private boolean dynamicPagesCached;
private List fragmentDefinitions;
private boolean fragmentDefinitionsCached;
private List links;
private boolean linksCached;
private PageSecurityImpl pageSecurity;
private boolean pageSecurityCached;
private List all;
private boolean allCached;
private FolderOrderList documentOrder;
private boolean documentOrderComparatorValid;
private Comparator documentOrderComparator;
private NodeSet foldersNodeSet;
private NodeSet pagesNodeSet;
private NodeSet pageTemplatesNodeSet;
private NodeSet dynamicPagesNodeSet;
private NodeSet fragmentDefinitionsNodeSet;
private NodeSet linksNodeSet;
private NodeSet allNodeSet;
private FolderMenuDefinitionList menuDefinitions;
protected static PermissionFactory pf;
public static void setPermissionsFactory(PermissionFactory pf)
{
FolderImpl.pf = pf;
}
public FolderImpl()
{
super(new FolderSecurityConstraintsImpl());
}
/**
* accessFolderOrders
*
* Access mutable persistent collection member for List wrappers.
*
* @return persistent collection
*/
List accessFolderOrders()
{
// create initial collection if necessary
if (orders == null)
{
orders = DatabasePageManagerUtils.createList();
}
return orders;
}
/**
* accessMenus
*
* Access mutable persistent collection member for List wrappers.
*
* @return persistent collection
*/
List accessMenus()
{
// create initial collection if necessary
if (menus == null)
{
menus = DatabasePageManagerUtils.createList();
}
return menus;
}
/**
* accessFolders
*
* Access folders transient cache collection for use by PageManager.
*
* @return folders collection
*/
public List accessFolders()
{
// create initial collection if necessary
if (folders == null)
{
folders = DatabasePageManagerUtils.createList();
}
return folders;
}
/**
* resetFolders
*
* Reset folders transient caches for use by PageManager.
*
* @param cached set cached state for folders
*/
public void resetFolders(boolean cached)
{
// save cached state
foldersCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessFolders().clear();
}
accessAll().clear();
// reset cached node sets
foldersNodeSet = null;
allNodeSet = null;
}
/**
* accessPages
*
* Access pages transient cache collection for use by PageManager.
*
* @return pages collection
*/
public List accessPages()
{
// create initial collection if necessary
if (pages == null)
{
pages = DatabasePageManagerUtils.createList();
}
return pages;
}
/**
* resetPages
*
* Reset pages transient caches for use by PageManager.
*
* @param cached set cached state for pages
*/
public void resetPages(boolean cached)
{
// save cached state
pagesCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessPages().clear();
}
accessAll().clear();
// reset cached node sets
pagesNodeSet = null;
allNodeSet = null;
}
/**
* accessPageTemplates
*
* Access page templates transient cache collection for use by PageManager.
*
* @return page templates collection
*/
public List accessPageTemplates()
{
// create initial collection if necessary
if (pageTemplates == null)
{
pageTemplates = DatabasePageManagerUtils.createList();
}
return pageTemplates;
}
/**
* resetPageTemplates
*
* Reset page templates transient caches for use by PageManager.
*
* @param cached set cached state for page templates
*/
public void resetPageTemplates(boolean cached)
{
// save cached state
pageTemplatesCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessPageTemplates().clear();
}
accessAll().clear();
// reset cached node sets
pageTemplatesNodeSet = null;
allNodeSet = null;
}
/**
* accessDynamicPages
*
* Access dynamic pages transient cache collection for use by PageManager.
*
* @return dynamic pages collection
*/
public List accessDynamicPages()
{
// create initial collection if necessary
if (dynamicPages == null)
{
dynamicPages = DatabasePageManagerUtils.createList();
}
return dynamicPages;
}
/**
* resetDynamicPages
*
* Reset dynamic pages transient caches for use by PageManager.
*
* @param cached set cached state for dynamic pages
*/
public void resetDynamicPages(boolean cached)
{
// save cached state
dynamicPagesCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessDynamicPages().clear();
}
accessAll().clear();
// reset cached node sets
dynamicPagesNodeSet = null;
allNodeSet = null;
}
/**
* accessFragmentDefinitions
*
* Access fragment definitions transient cache collection for use by PageManager.
*
* @return fragment definitions collection
*/
public List accessFragmentDefinitions()
{
// create initial collection if necessary
if (fragmentDefinitions == null)
{
fragmentDefinitions = DatabasePageManagerUtils.createList();
}
return fragmentDefinitions;
}
/**
* resetFragmentDefinitions
*
* Reset fragment definitions transient caches for use by PageManager.
*
* @param cached set cached state for fragment definitions
*/
public void resetFragmentDefinitions(boolean cached)
{
// save cached state
fragmentDefinitionsCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessFragmentDefinitions().clear();
}
accessAll().clear();
// reset cached node sets
fragmentDefinitionsNodeSet = null;
allNodeSet = null;
}
/**
* accessLinks
*
* Access links transient cache collection for use by PageManager.
*
* @return links collection
*/
public List accessLinks()
{
// create initial collection if necessary
if (links == null)
{
links = DatabasePageManagerUtils.createList();
}
return links;
}
/**
* resetLinks
*
* Reset links transient caches for use by PageManager.
*
* @param cached set cached state for links
*/
public void resetLinks(boolean cached)
{
// save cached state
linksCached = cached;
allCached = false;
// update node caches
if (!cached)
{
accessLinks().clear();
}
accessAll().clear();
// reset cached node sets
linksNodeSet = null;
allNodeSet = null;
}
/**
* accessPageSecurity
*
* Access pageSecurity cached instance for use by PageManager.
*
* @return pageSecurity instance
*/
public PageSecurityImpl accessPageSecurity()
{
return pageSecurity;
}
/**
* resetPageSecurity
*
* Reset pageSecurity transient cache instance for use by PageManager.
*
* @param newPageSecurty cached page security instance.
* @param cached set cached state for page security
*/
public void resetPageSecurity(PageSecurityImpl newPageSecurity, boolean cached)
{
// save cached state
pageSecurity = newPageSecurity;
pageSecurityCached = cached;
allCached = false;
// update node caches
accessAll().clear();
// reset cached node sets
allNodeSet = null;
}
/**
* accessAll
*
* Access all transient cache collection for use by PageManager.
*
* @return all collection
*/
public List accessAll()
{
// create initial collection if necessary
if (all == null)
{
all = DatabasePageManagerUtils.createList();
}
return all;
}
/**
* resetAll
*
* Reset all transient caches for use by PageManager.
*
* @param cached set cached state for all
*/
public void resetAll(boolean cached)
{
// save cached state
allCached = cached;
foldersCached = cached;
pagesCached = cached;
pageTemplatesCached = cached;
dynamicPagesCached = cached;
fragmentDefinitionsCached = cached;
linksCached = cached;
pageSecurityCached = cached;
// update node caches
accessFolders().clear();
accessPages().clear();
accessPageTemplates().clear();
accessDynamicPages().clear();
accessFragmentDefinitions().clear();
accessLinks().clear();
pageSecurity = null;
if (cached)
{
// populate node caches
synchronized(all)
{
Iterator nodeIter = accessAll().iterator();
while (nodeIter.hasNext())
{
Node node = (Node)nodeIter.next();
if (node instanceof PageImpl)
{
pages.add(node);
}
else if (node instanceof PageTemplateImpl)
{
pageTemplates.add(node);
}
else if (node instanceof DynamicPageImpl)
{
dynamicPages.add(node);
}
else if (node instanceof FragmentDefinitionImpl)
{
fragmentDefinitions.add(node);
}
else if (node instanceof FolderImpl)
{
folders.add(node);
}
else if (node instanceof LinkImpl)
{
links.add(node);
}
else if (node instanceof PageSecurityImpl)
{
pageSecurity = (PageSecurityImpl)node;
}
}
}
}
else
{
accessAll().clear();
}
// reset cached node sets
allNodeSet = null;
foldersNodeSet = null;
pagesNodeSet = null;
pageTemplatesNodeSet = null;
dynamicPagesNodeSet = null;
fragmentDefinitionsNodeSet = null;
linksNodeSet = null;
}
/**
* createDocumentOrderComparator
*
* @return document order comparator
*/
private Comparator createDocumentOrderComparator()
{
if (!documentOrderComparatorValid)
{
documentOrderComparatorValid = true;
// return null if no document order exists;
// (null implies natural ordering by name)
final List documentOrder = getDocumentOrder();
if ((documentOrder == null) || documentOrder.isEmpty())
{
return null;
}
// create new document order comparator
documentOrderComparator = new Comparator()
{
/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object o1, Object o2)
{
// Compare node names using document order;
// use indices as names if found in document
// order to force explicitly ordered items
// ahead of unordered items
String name1 = (String)o1;
int index1 = documentOrder.indexOf(name1);
if (index1 >= 0)
{
// use order index as name1
name1 = String.valueOf(index1);
}
String name2 = (String)o2;
int index2 = documentOrder.indexOf(name2);
if (index2 >= 0)
{
// use order index as name2
name2 = String.valueOf(index2);
if (index1 >= 0)
{
// pad order indices for numeric string compare
while (name1.length() != name2.length())
{
if (name1.length() < name2.length())
{
name1 = "0" + name1;
}
else
{
name2 = "0" + name2;
}
}
}
}
// compare names and/or indices
return name1.compareTo(name2);
}
};
}
return documentOrderComparator;
}
/**
* clearDocumentOrderComparator
*/
void clearDocumentOrderComparator()
{
// clear node set ordering
documentOrderComparatorValid = false;
documentOrderComparator = null;
// clear previously cached node sets
allNodeSet = null;
foldersNodeSet = null;
pagesNodeSet = null;
pageTemplatesNodeSet = null;
dynamicPagesNodeSet = null;
fragmentDefinitionsNodeSet = null;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.document.impl.NodeImpl#newPageMetadata(java.util.Collection)
*/
public PageMetadataImpl newPageMetadata(Collection fields)
{
PageMetadataImpl pageMetadata = new PageMetadataImpl(FolderMetadataLocalizedFieldImpl.class);
pageMetadata.setFields(fields);
return pageMetadata;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.page.impl.BaseElementImpl#getEffectivePageSecurity()
*/
public PageSecurity getEffectivePageSecurity()
{
// return page security instance if available
if (!pageSecurityCached)
{
// use PageManager to get and cache page security
// instance for this folder
try
{
return getPageManager().getPageSecurity(this);
}
catch (NodeException ne)
{
}
catch (NodeNotFoundException nnfe)
{
}
}
else if (pageSecurity != null)
{
return pageSecurity;
}
// delegate to real parent folder implementation
FolderImpl parentFolderImpl = (FolderImpl)ProxyHelper.getRealObject(getParent());
if (parentFolderImpl != null)
{
return parentFolderImpl.getEffectivePageSecurity();
}
return null;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.page.impl.BaseElementImpl#checkPermissions(java.lang.String, int, boolean, boolean)
*/
public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
{
// check granted folder permissions unless the check is
// to be skipped due to explicitly granted access
if (!checkParentsOnly)
{
AccessController.checkPermission((Permission)pf.newPermission(pf.FOLDER_PERMISSION, path, mask));
}
// if not checking node only, recursively check
// all parent permissions in hierarchy
if (!checkNodeOnly)
{
FolderImpl parentFolderImpl = (FolderImpl)ProxyHelper.getRealObject(getParent());
if (parentFolderImpl != null)
{
parentFolderImpl.checkPermissions(mask, false, false);
}
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.page.BaseElement#getTitle()
*/
public String getTitle()
{
// default title to folder name
String title = super.getTitle();
if (title == null)
{
title = defaultTitleFromName();
setTitle(title);
}
return title;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getSkin()
*/
public String getSkin()
{
return skin;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#setSkin(java.lang.String)
*/
public void setSkin(String skinName)
{
this.skin = skinName;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getEffectiveDefaultDecorator(java.lang.String)
*/
public String getEffectiveDefaultDecorator(String fragmentType)
{
// get locally defined decorator
String decorator = getDefaultDecorator(fragmentType);
if (decorator == null)
{
// delegate to parent folder
Folder parentFolder = (Folder)ProxyHelper.getRealObject(getParent());
if (parentFolder != null)
{
return parentFolder.getEffectiveDefaultDecorator(fragmentType);
}
}
return decorator;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDefaultDecorator(java.lang.String)
*/
public String getDefaultDecorator(String fragmentType)
{
// retrieve supported decorator types
if (fragmentType != null)
{
if (fragmentType.equals(Fragment.LAYOUT))
{
return defaultLayoutDecorator;
}
if (fragmentType.equals(Fragment.PORTLET))
{
return defaultPortletDecorator;
}
}
return null;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDefaultDecorator(java.lang.String,java.lang.String)
*/
public void setDefaultDecorator(String decoratorName, String fragmentType)
{
// save supported decorator types
if (fragmentType != null)
{
if (fragmentType.equals(Fragment.LAYOUT))
{
defaultLayoutDecorator = decoratorName;
}
if (fragmentType.equals(Fragment.PORTLET))
{
defaultPortletDecorator = decoratorName;
}
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDocumentOrder()
*/
public List getDocumentOrder()
{
// return mutable document order list
// by using list wrapper to manage sort
// order and element uniqueness
if (documentOrder == null)
{
documentOrder = new FolderOrderList(this);
}
return documentOrder;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#setDocumentOrder(java.util.List)
*/
public void setDocumentOrder(List docNames)
{
// set document order using ordered document
// names by replacing existing entries with
// new elements if new collection is specified
List documentOrder = getDocumentOrder();
if (docNames != documentOrder)
{
// replace all document order names
documentOrder.clear();
if (docNames != null)
{
documentOrder.addAll(docNames);
}
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDefaultPage()
*/
public String getDefaultPage()
{
return defaultPage;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#setDefaultPage(java.lang.String)
*/
public void setDefaultPage(String defaultPage)
{
this.defaultPage = defaultPage;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getFolders()
*/
public NodeSet getFolders() throws DocumentException
{
// get folders collection
if (!foldersCached)
{
// use PageManager to get and cache folders
// collection for this folder
return getPageManager().getFolders(this);
}
// return nodes with view access
return filterNodeSetByAccess(getFoldersNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getFolder(java.lang.String)
*/
public Folder getFolder(String name) throws FolderNotFoundException, DocumentException
{
// get folder instance if folders collection not available
if (!foldersCached)
{
// use PageManager to get folder instance without
// caching the folders collection for this folder
return getPageManager().getFolder(this, name);
}
// select folder by name from cached folders collection
Folder folder = (Folder)getFoldersNodeSet().get(name);
if (folder == null)
{
throw new FolderNotFoundException("Folder not found: " + name);
}
// check for view access on folder
folder.checkAccess(JetspeedActions.VIEW);
return folder;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getPages()
*/
public NodeSet getPages() throws NodeException
{
// get pages collection
if (!pagesCached)
{
// use PageManager to get and cache pages
// collection for this folder
return getPageManager().getPages(this);
}
// return nodes with view access
return filterNodeSetByAccess(getPagesNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getPage(java.lang.String)
*/
public Page getPage(String name) throws PageNotFoundException, NodeException
{
// get page instance if pages collection not available
if (!pagesCached)
{
// use PageManager to get page instance without
// caching the pages collection for this folder
return getPageManager().getPage(this, name);
}
// select page by name from cached pages collection
Page page = (Page)getPagesNodeSet().get(name);
if (page == null)
{
throw new PageNotFoundException("Page not found: " + name);
}
// check for view access on page
page.checkAccess(JetspeedActions.VIEW);
return page;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getPageTemplates()
*/
public NodeSet getPageTemplates() throws NodeException
{
// get page templates collection
if (!pageTemplatesCached)
{
// use PageManager to get and cache page templates
// collection for this folder
return getPageManager().getPageTemplates(this);
}
// return nodes with view access
return filterNodeSetByAccess(getPageTemplatesNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getPageTemplate(java.lang.String)
*/
public PageTemplate getPageTemplate(String name) throws PageNotFoundException, NodeException
{
// get page template instance if page templates collection not available
if (!pageTemplatesCached)
{
// use PageManager to get page template instance without
// caching the page templates collection for this folder
return getPageManager().getPageTemplate(this, name);
}
// select page template by name from cached page templates collection
PageTemplate pageTemplate = (PageTemplate)getPageTemplatesNodeSet().get(name);
if (pageTemplate == null)
{
throw new PageNotFoundException("PageTemplate not found: " + name);
}
// check for view access on page template
pageTemplate.checkAccess(JetspeedActions.VIEW);
return pageTemplate;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDynamicPages()
*/
public NodeSet getDynamicPages() throws NodeException
{
// get dynamic pages collection
if (!dynamicPagesCached)
{
// use PageManager to get and cache dynamic pages
// collection for this folder
return getPageManager().getDynamicPages(this);
}
// return nodes with view access
return filterNodeSetByAccess(getDynamicPagesNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getDynamicPage(java.lang.String)
*/
public DynamicPage getDynamicPage(String name) throws PageNotFoundException, NodeException
{
// get dynamic page instance if dynamic pages collection not available
if (!dynamicPagesCached)
{
// use PageManager to get dynamic page instance without
// caching the dynamic pages collection for this folder
return getPageManager().getDynamicPage(this, name);
}
// select dynamic page by name from cached dynamic pages collection
DynamicPage dynamicPage = (DynamicPage)getDynamicPagesNodeSet().get(name);
if (dynamicPage == null)
{
throw new PageNotFoundException("DynamicPage not found: " + name);
}
// check for view access on page
dynamicPage.checkAccess(JetspeedActions.VIEW);
return dynamicPage;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getFragmentDefinitions()
*/
public NodeSet getFragmentDefinitions() throws NodeException
{
// get fragment definitions collection
if (!fragmentDefinitionsCached)
{
// use PageManager to get and cache fragment definitions
// collection for this folder
return getPageManager().getFragmentDefinitions(this);
}
// return nodes with view access
return filterNodeSetByAccess(getFragmentDefinitionsNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getFragmentDefinition(java.lang.String)
*/
public FragmentDefinition getFragmentDefinition(String name) throws PageNotFoundException, NodeException
{
// get fragment definitions instance if fragment definitions collection not available
if (!fragmentDefinitionsCached)
{
// use PageManager to get fragment definition instance without
// caching the fragment definitions collection for this folder
return getPageManager().getFragmentDefinition(this, name);
}
// select fragment definition by name from cached fragment definitions collection
FragmentDefinition fragmentDefinition = (FragmentDefinition)getFragmentDefinitionsNodeSet().get(name);
if (fragmentDefinition == null)
{
throw new PageNotFoundException("FragmentDefinition not found: " + name);
}
// check for view access on page
fragmentDefinition.checkAccess(JetspeedActions.VIEW);
return fragmentDefinition;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getLinks()
*/
public NodeSet getLinks() throws NodeException
{
// get links collection
if (!linksCached)
{
// use PageManager to get and cache links
// collection for this folder
return getPageManager().getLinks(this);
}
// return nodes with view access
return filterNodeSetByAccess(getLinksNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getLink(java.lang.String)
*/
public Link getLink(String name) throws DocumentNotFoundException, NodeException
{
// get link instance if links collection not available
if (!linksCached)
{
// use PageManager to get link instance without
// caching the links collection for this folder
return getPageManager().getLink(this, name);
}
// select link by name from cached links collection
Link link = (Link)getLinksNodeSet().get(name);
if (link == null)
{
throw new DocumentNotFoundException("Link not found: " + name);
}
// check for view access on link
link.checkAccess(JetspeedActions.VIEW);
return link;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getPageSecurity()
*/
public PageSecurity getPageSecurity() throws DocumentNotFoundException, NodeException
{
// get page security instance
if (!pageSecurityCached)
{
// use PageManager to get and cache page security
// instance for this folder
return getPageManager().getPageSecurity(this);
}
if (pageSecurity == null)
{
throw new DocumentNotFoundException("Page security document not found");
}
// check for view access on document
pageSecurity.checkAccess(JetspeedActions.VIEW);
return pageSecurity;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getAll()
*/
public NodeSet getAll() throws DocumentException
{
// get all nodes collection
if (!allCached)
{
// use PageManager to get and cache all nodes
// collection for this folder
return getPageManager().getAll(this);
}
// return nodes with view access
return filterNodeSetByAccess(getAllNodeSet());
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getMenuDefinitions()
*/
public List getMenuDefinitions()
{
// return mutable menu definition list
// by using list wrapper to manage
// element uniqueness
if (menuDefinitions == null)
{
menuDefinitions = new FolderMenuDefinitionList(this);
}
return menuDefinitions;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#newMenuDefinition()
*/
public MenuDefinition newMenuDefinition()
{
return new FolderMenuDefinitionImpl();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#newMenuExcludeDefinition()
*/
public MenuExcludeDefinition newMenuExcludeDefinition()
{
return new FolderMenuExcludeDefinitionImpl();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#newMenuIncludeDefinition()
*/
public MenuIncludeDefinition newMenuIncludeDefinition()
{
return new FolderMenuIncludeDefinitionImpl();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#newMenuOptionsDefinition()
*/
public MenuOptionsDefinition newMenuOptionsDefinition()
{
return new FolderMenuOptionsDefinitionImpl();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#newMenuSeparatorDefinition()
*/
public MenuSeparatorDefinition newMenuSeparatorDefinition()
{
return new FolderMenuSeparatorDefinitionImpl();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#setMenuDefinitions(java.util.List)
*/
public void setMenuDefinitions(List definitions)
{
// set menu definitions by replacing
// existing entries with new elements if
// new collection is specified
List menuDefinitions = getMenuDefinitions();
if (definitions != menuDefinitions)
{
// replace all menu definitions
menuDefinitions.clear();
if (definitions != null)
{
menuDefinitions.addAll(definitions);
}
}
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#isReserved()
*/
public boolean isReserved()
{
// folders are always concrete in this implementation
return false;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.folder.Folder#getReservedType()
*/
public int getReservedType()
{
// folders are always concrete in this implementation
return RESERVED_FOLDER_NONE;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.page.document.Node#getType()
*/
public String getType()
{
return FOLDER_TYPE;
}
/**
* getFoldersNodeSet
*
* Latently create and access folders node set.
*
* @return folders node set
*/
private NodeSet getFoldersNodeSet()
{
if (foldersNodeSet == null)
{
if ((folders != null) && !folders.isEmpty())
{
foldersNodeSet = new NodeSetImpl(folders, createDocumentOrderComparator());
}
else
{
foldersNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return foldersNodeSet;
}
/**
* getPagesNodeSet
*
* Latently create and access pages node set.
*
* @return folders node set
*/
private NodeSet getPagesNodeSet() throws NodeException
{
if (pagesNodeSet == null)
{
if ((pages != null) && !pages.isEmpty())
{
pagesNodeSet = new NodeSetImpl(pages, createDocumentOrderComparator());
}
else
{
pagesNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return pagesNodeSet;
}
/**
* getPageTemplatesNodeSet
*
* Latently create and access page templates node set.
*
* @return folders node set
*/
private NodeSet getPageTemplatesNodeSet() throws NodeException
{
if (pageTemplatesNodeSet == null)
{
if ((pageTemplates != null) && !pageTemplates.isEmpty())
{
pageTemplatesNodeSet = new NodeSetImpl(pageTemplates, createDocumentOrderComparator());
}
else
{
pageTemplatesNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return pageTemplatesNodeSet;
}
/**
* getDynamicPagesNodeSet
*
* Latently create and access dynamic pages node set.
*
* @return folders node set
*/
private NodeSet getDynamicPagesNodeSet() throws NodeException
{
if (dynamicPagesNodeSet == null)
{
if ((dynamicPages != null) && !dynamicPages.isEmpty())
{
dynamicPagesNodeSet = new NodeSetImpl(dynamicPages, createDocumentOrderComparator());
}
else
{
dynamicPagesNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return dynamicPagesNodeSet;
}
/**
* getFragmentDefinitionsNodeSet
*
* Latently create and access fragment definitions node set.
*
* @return folders node set
*/
private NodeSet getFragmentDefinitionsNodeSet() throws NodeException
{
if (fragmentDefinitionsNodeSet == null)
{
if ((fragmentDefinitions != null) && !fragmentDefinitions.isEmpty())
{
fragmentDefinitionsNodeSet = new NodeSetImpl(fragmentDefinitions, createDocumentOrderComparator());
}
else
{
fragmentDefinitionsNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return fragmentDefinitionsNodeSet;
}
/**
* getLinksNodeSet
*
* Latently create and access links node set.
*
* @return folders node set
*/
private NodeSet getLinksNodeSet() throws NodeException
{
if (linksNodeSet == null)
{
if ((links != null) && !links.isEmpty())
{
linksNodeSet = new NodeSetImpl(links, createDocumentOrderComparator());
}
else
{
linksNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return linksNodeSet;
}
/**
* getAllNodeSet
*
* Latently create and access all nodes node set.
*
* @return all nodes node set
*/
private NodeSet getAllNodeSet()
{
if (allNodeSet == null)
{
if ((all != null) && !all.isEmpty())
{
List allCopy = new java.util.ArrayList();
synchronized(all)
{
allCopy.addAll(all);
}
allNodeSet = new NodeSetImpl(allCopy, createDocumentOrderComparator());
}
else
{
allNodeSet = NodeSetImpl.EMPTY_NODE_SET;
}
}
return allNodeSet;
}
/**
* filterNodeSetByAccess
*
* Filter node set elements for view access.
*
* @param nodes node set containing nodes to check
* @return checked subset of nodes
*/
static NodeSet filterNodeSetByAccess(NodeSet nodes)
{
if ((nodes != null) && !nodes.isEmpty())
{
// check permissions and constraints, filter nodes as required
NodeSetImpl filteredNodes = null;
Iterator checkAccessIter = nodes.iterator();
while (checkAccessIter.hasNext())
{
Node node = (Node)checkAccessIter.next();
try
{
// check access
node.checkAccess(JetspeedActions.VIEW);
// add to filteredNodes nodes if copying
if (filteredNodes != null)
{
// permitted, add to filteredNodes nodes
filteredNodes.add(node);
}
}
catch (SecurityException se)
{
// create filteredNodes nodes if not already copying
if (filteredNodes == null)
{
// not permitted, copy previously permitted nodes
// to new filteredNodes node set with same comparator
filteredNodes = new NodeSetImpl(nodes);
Iterator copyIter = nodes.iterator();
while (copyIter.hasNext())
{
Node copyNode = (Node)copyIter.next();
if (copyNode != node)
{
filteredNodes.add(copyNode);
}
else
{
break;
}
}
}
}
}
// return filteredNodes nodes if generated
if (filteredNodes != null)
{
return filteredNodes;
}
}
return nodes;
}
}