Files
alfresco-community-repo/source/java/org/alfresco/web/bean/NavigationBean.java
Alan Davis 924d54c552 Merged BRANCHES/DEV/V3.4-BUG-FIX to HEAD
28236: ALF-8810: Removed trailing space from discussion.discussion_for Italian translation
   28241: Incremented version revision for 3.4.4
   28284: ALF-835 - WCM/AVM: copy (empty) folder into itself
   28285: ALF-6863: More than one cifs device breaks the web UI (explorer)
   28290: ALF-8840: user-*.atomentry.ftl
   28291: ALF-6863: Continuation of fix by Arseny
   28336: ALF-8768: Fixed typo in comment on wcm-bootstrap-context.xml
   28363: Merged DEV to V3.4-BUG-FIX
      28262: ALF-8847: WCM: OrphanReaper contention throws error after 39 retries.
             Checkin Comment:
                Use JobLockService to make sure that only one OrphanReaper job is working.
                Generate list of nodes that must be processed in OrphanReaper.doBatch() transaction. 
   28386: ALF-9100: Merged PATCHES/V3.4.1 to V3.4-BUG-FIX
      28249: ALF-8946: Avoid one full table scan per batch in full reindex
         - Now each batch scans a single time sample, dynamically adjusted based on the number of transactions
		   in the previous sample, always aiming for 1000 transactions per sample.
   28394: Fixed ALF-9090: NPE during inter-cluster subsystem messaging
    - Bean ID is a List<String> and might not be recognized on receiving machine
    - Log warning when bean ID is not available (unsymmetrical configuration, perhaps?)
   28396: Merged DEV to V3.4-BUG-FIX
      28384: ALF-6150: Initial state lost when non-versionable document is saved for the first time
             Creation of new version of document before writing its content was added to
             - AbstractAlfrescoMethodHandler->putDocument (this method is used by Office 2003, 2007)
             - VtiIfHeaderAction->doPut (this method is used by Office 2007 and 2010 on Windows 7)
               Creation of new version was added twice to AbstractAlfrescoMethodHandler to avoid affecting
               initial version when transaction is committed. 
   28432: Merged DEV to V3.4-BUG-FIX
      28431: ALF-8530: Pressing the info icon creates an unrecorded file in the ContentStore
             Use ContentService.getTempWriter() in BaseContentNode$TemplateContentData.getContentAsText() method. 
   28435: Merged DEV/TEMPORARY to V3.4-BUG-FIX
      28428: ALF-9015: cm:modifier not updated when document is updated via CIFS
         In ContentDiskDriver.closeFile() added ContentModel.PROP_MODIFIER property update.
   28436: ALF-8550: Number of http requests (currentThreadsBusy) increases when session times out during creation of webform
   - Corrected use of read and write locks
   28465: Fix for ALF-8023 Share preview doesn't work if...
     fixed as outlined by Dmitry.
   28478: Merged BRANCHES/DEV/ALAN/AUDIT to BRANCHES/DEV/V3.4-BUG-FIX:
      28062-28477 (28062,28063,28080,28081,28302,28303,28334,28340,28464,28469,28477) ALF-8438 Need higher level audit of user actions

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28481 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
2011-06-20 12:42:10 +00:00

1251 lines
40 KiB
Java

/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.web.bean;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.filesys.repo.ContentDiskInterface;
import org.alfresco.jlan.server.config.ServerConfigurationAccessor;
import org.alfresco.jlan.server.filesys.DiskSharedDevice;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.admin.RepoUsage;
import org.alfresco.service.cmr.repository.FileTypeImageSize;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateService;
import org.alfresco.service.cmr.rule.RuleService;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.MutableAuthenticationService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.bean.search.SearchContext;
import org.alfresco.web.bean.spaces.CreateSpaceWizard;
import org.alfresco.web.bean.spaces.SpaceDetailsDialog;
import org.alfresco.web.bean.users.UserPreferencesBean;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.Utils.URLMode;
import org.alfresco.web.ui.common.component.IBreadcrumbHandler;
import org.alfresco.web.ui.common.component.UIBreadcrumb;
import org.alfresco.web.ui.common.component.UIModeList;
import org.alfresco.web.ui.repo.component.IRepoBreadcrumbHandler;
import org.alfresco.web.ui.repo.component.shelf.UIShelf;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.jsf.FacesContextUtils;
/**
* Bean providing access and management of the various global navigation mechanisms
* such as the My Home, Company Home, Guest Home toolbar shortcuts, breadcrumb and
* the current node id and associated properties.
*
* @author Kevin Roast
*/
public class NavigationBean implements Serializable
{
private static final long serialVersionUID = -648110889585522227L;
/** Public JSF Bean name */
public static final String BEAN_NAME = "NavigationBean";
private static Log logger = LogFactory.getLog(NavigationBean.class);
/**
* Default constructor
*/
public NavigationBean()
{
initFromClientConfig();
}
// ------------------------------------------------------------------------------
// Bean property getters and setters
/**
* @param nodeService The nodeService to set.
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
protected NodeService getNodeService()
{
if (nodeService == null)
nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService();
return nodeService;
}
/**
* @param searchService The searchService to set.
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
protected SearchService getSearchService()
{
if (searchService == null)
this.searchService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getSearchService();
return searchService;
}
/**
* @param namespaceService The namespaceService to set.
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
protected NamespaceService getNamespaceService()
{
if (namespaceService == null)
this.namespaceService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNamespaceService();
return namespaceService;
}
public void setRepoAdminService(RepoAdminService repoAdminService)
{
this.repoAdminService = repoAdminService;
}
public RepoAdminService getRepoAdminService()
{
if (repoAdminService == null)
{
this.repoAdminService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getRepoAdminService();
}
return repoAdminService;
}
/**
* @param ruleService The ruleService to use
*/
public void setRuleService(RuleService ruleService)
{
this.ruleService = ruleService;
}
protected RuleService getRuleService()
{
if (ruleService == null)
this.ruleService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getRuleService();
return ruleService;
}
/**
* @param serverConfiguration The serverConfiguration to set.
*/
public void setServerConfiguration(ServerConfigurationAccessor serverConfiguration)
{
this.serverConfiguration = serverConfiguration;
}
protected ServerConfigurationAccessor getServerConfiguration()
{
if (serverConfiguration == null)
this.serverConfiguration = (ServerConfigurationAccessor) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "fileServerConfiguration");
return serverConfiguration;
}
/**
* @param contentDiskDriver The contentDiskDriver to set.
*/
public void setContentDiskDriver(ContentDiskInterface contentDiskDriver)
{
this.contentDiskDriver = contentDiskDriver;
}
protected ClientConfigElement getClientConfig()
{
if (clientConfig == null)
this.clientConfig = Application.getClientConfig(FacesContext.getCurrentInstance());
return clientConfig;
}
/**
* @param preferences The UserPreferencesBean to set
*/
public void setUserPreferencesBean(UserPreferencesBean preferences)
{
this.preferences = preferences;
}
/**
* @param authService The AuthenticationService to set.
*/
public void setAuthenticationService(MutableAuthenticationService authService)
{
this.authService = authService;
}
protected MutableAuthenticationService getAuthService()
{
if (authService == null)
this.authService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getAuthenticationService();
return authService;
}
/**
* @param permissionService The PermissionService to set.
*/
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
protected PermissionService getPermissionService()
{
if (permissionService == null)
this.permissionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService();
return permissionService;
}
/**
* @return the User object representing the current instance for this user
*/
public User getCurrentUser()
{
return Application.getCurrentUser(FacesContext.getCurrentInstance());
}
/**
* @return true if the system is running within a JSR-168 portal container
*/
public boolean getInPortalServer()
{
return Application.inPortalServer();
}
/**
* Return the expanded state of the Shelf panel wrapper component
*
* @return the expanded state of the Shelf panel wrapper component
*/
public boolean isShelfExpanded()
{
return this.shelfExpanded;
}
/**
* Set the expanded state of the Shelf panel wrapper component
*
* @param expanded true to expanded the Shelf panel area, false to hide it
*/
public void setShelfExpanded(boolean expanded)
{
this.shelfExpanded = expanded;
}
/**
* Return the width of the main work area depending on the visibility of the Shelf panel
*
* @return width, which will either be "80%" or "100%"
*/
public String getWorkAreaWidth()
{
return this.shelfExpanded ? "80%" : "100%";
}
/**
* @return Returns the array containing the expanded state of the shelf items
*/
public boolean[] getShelfItemExpanded()
{
return this.shelfItemExpanded;
}
/**
* @param shelfItemExpanded The array containing the expanded state of the shelf items
*/
public void setShelfItemExpanded(boolean[] shelfItemExpanded)
{
this.shelfItemExpanded = shelfItemExpanded;
}
/**
* @return Returns the toolbar Location - initially set from the user preferences.
*/
public String getToolbarLocation()
{
if (this.toolbarLocation == null)
{
// if the toolbar location has not been set yet, try and get the
// default via the user preferences object
this.toolbarLocation = this.preferences.getStartLocation();
// test that the user still has access to the specified location
// the location will need to be reset if the user permissions are no longer valid
if (NavigationBean.LOCATION_COMPANY.equals(this.toolbarLocation))
{
if (getCompanyHomeVisible() == false)
{
this.toolbarLocation = null;
}
}
else if (NavigationBean.LOCATION_GUEST.equals(this.toolbarLocation))
{
if (getGuestHomeVisible() == false)
{
this.toolbarLocation = null;
}
}
// if don't have a valid start location default to My Home
if (this.toolbarLocation == null)
{
this.toolbarLocation = LOCATION_HOME;
this.preferences.setStartLocation(this.toolbarLocation);
}
}
return this.toolbarLocation;
}
/**
* @param location The toolbar Location to set.
*/
public void setToolbarLocation(String location)
{
this.toolbarLocation = location;
}
/**
* Process the selected toolbar location. Setup the breadcrumb with initial value and
* setup the current node ID. This method can also perform the navigatin setup if requested.
*
* @param location Toolbar location constant
* @param navigate True to perform navigation, false otherwise
*/
@SuppressWarnings("serial")
public void processToolbarLocation(String location, boolean navigate)
{
this.toolbarLocation = location;
FacesContext context = FacesContext.getCurrentInstance();
if (LOCATION_COMPANY.equals(location))
{
List<IBreadcrumbHandler> elements = new ArrayList<IBreadcrumbHandler>(1);
Node companyHome = getCompanyHomeNode();
elements.add(new NavigationBreadcrumbHandler(companyHome.getNodeRef(), companyHome.getName()));
setLocation(elements);
setCurrentNodeId(companyHome.getId());
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb for companyhome: " + elements);
// inform registered beans that the current area has changed
UIContextService.getInstance(FacesContext.getCurrentInstance()).areaChanged();
// we need to force a navigation to refresh the browse screen breadcrumb
if (navigate)
{
context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE);
}
}
else if (LOCATION_HOME.equals(location))
{
List<IBreadcrumbHandler> elements = new ArrayList<IBreadcrumbHandler>(1);
String homeSpaceId = Application.getCurrentUser(context).getHomeSpaceId();
NodeRef homeSpaceRef = new NodeRef(Repository.getStoreRef(), homeSpaceId);
if (this.clientConfig.getBreadcrumbMode().equals(ClientConfigElement.BREADCRUMB_LOCATION))
{
Repository.setupBreadcrumbLocation(context, this, elements, homeSpaceRef);
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb location for userhome: " + elements);
}
else
{
String homeSpaceName = Repository.getNameForNode(this.getNodeService(), homeSpaceRef);
elements.add(new NavigationBreadcrumbHandler(homeSpaceRef, homeSpaceName));
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb path for userhome: " + elements);
}
setLocation(elements);
setCurrentNodeId(homeSpaceRef.getId());
// inform registered beans that the current area has changed
UIContextService.getInstance(FacesContext.getCurrentInstance()).areaChanged();
// we need to force a navigation to refresh the browse screen breadcrumb
if (navigate)
{
context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE);
}
}
else if (LOCATION_GUEST.equals(location))
{
List<IBreadcrumbHandler> elements = new ArrayList<IBreadcrumbHandler>(1);
Node guestHome = getGuestHomeNode();
if (this.clientConfig.getBreadcrumbMode().equals(ClientConfigElement.BREADCRUMB_LOCATION))
{
Repository.setupBreadcrumbLocation(context, this, elements, guestHome.getNodeRef());
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb location for guesthome: " + elements);
}
else
{
elements.add(new NavigationBreadcrumbHandler(guestHome.getNodeRef(), guestHome.getName()));
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb path for guesthome: " + elements);
}
setLocation(elements);
setCurrentNodeId(guestHome.getId());
// inform registered beans that the current area has changed
UIContextService.getInstance(FacesContext.getCurrentInstance()).areaChanged();
// we need to force a navigation to refresh the browse screen breadcrumb
if (navigate)
{
context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_BROWSE);
}
}
else if (LOCATION_MYALFRESCO.equals(location))
{
// make sure we set a current node ID as some screens expect this
if (getCurrentNodeId() == null)
{
String homeSpaceId = Application.getCurrentUser(context).getHomeSpaceId();
NodeRef homeSpaceRef = new NodeRef(Repository.getStoreRef(), homeSpaceId);
setCurrentNodeId(homeSpaceRef.getId());
}
// create a breadcrumb handler for this special case location (not a node)
List<IBreadcrumbHandler> elements = new ArrayList<IBreadcrumbHandler>(1);
elements.add(new IBreadcrumbHandler()
{
@SuppressWarnings("unchecked")
public String navigationOutcome(UIBreadcrumb breadcrumb)
{
setLocation( (List)breadcrumb.getValue() );
return OUTCOME_MYALFRESCO;
};
public String toString()
{
return Application.getMessage(FacesContext.getCurrentInstance(), MSG_MYALFRESCO);
};
});
if (s_logger.isDebugEnabled())
s_logger.debug("Created breadcrumb for myalfresco: " + elements);
setLocation(elements);
// inform registered beans that the current area has changed
UIContextService.getInstance(FacesContext.getCurrentInstance()).areaChanged();
// we need to force a navigation to refresh the browse screen breadcrumb
if (navigate)
{
context.getApplication().getNavigationHandler().handleNavigation(context, null, OUTCOME_MYALFRESCO);
}
}
else
{
// handle outcomes to any other custom location
context.getApplication().getNavigationHandler().handleNavigation(context, null, location);
}
}
/**
* @return Returns the helpUrl.
*/
public String getHelpUrl()
{
return this.helpUrl;
}
/**
* @param helpUrl The helpUrl to set.
*/
public void setHelpUrl(String helpUrl)
{
if (this.helpUrl == null)
{
Descriptor serverDescriptor = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDescriptorService().getServerDescriptor();
// search / replace each available key occurrence in the template string
// Note: server descriptor is looking for "version.major", "version.minor", etc.
Pattern p = Pattern.compile("\\{(\\w+\\.?\\w+)\\}");
Matcher m = p.matcher(helpUrl);
boolean result = m.find();
if (result)
{
StringBuffer sb = new StringBuffer();
String value = null;
do
{
value = serverDescriptor.getDescriptor(m.group(1));
m.appendReplacement(sb, value != null ? value : m.group(1));
result = m.find();
} while (result);
m.appendTail(sb);
helpUrl = sb.toString();
}
this.helpUrl = helpUrl;
}
}
/**
* @return the number of rules associated with the current space
*/
public int getRuleCount()
{
Node node = getCurrentNode();
return (node != null ? this.getRuleService().countRules(node.getNodeRef()) : 0);
}
/**
* @return Returns the search context object if any.
*/
public SearchContext getSearchContext()
{
return this.searchContext;
}
/**
* @param searchContext The search context object to set or null to clear search.
*/
public void setSearchContext(SearchContext searchContext)
{
this.searchContext = searchContext;
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
/**
* @return Returns the currently browsing node Id.
*/
public String getCurrentNodeId()
{
return this.currentNodeId;
}
/**
* Set the node Id of the current folder/space container node.
* <p>
* Setting this value causes the UI to update and display the specified node as current.
*
* @param currentNodeId The currently browsing node Id.
*/
public void setCurrentNodeId(String currentNodeId)
{
if (s_logger.isDebugEnabled())
s_logger.debug("Setting current node id to: " + currentNodeId);
if (currentNodeId == null)
{
throw new AlfrescoRuntimeException("Can not set the current node id to null");
}
// set the current Node Id for our UI context operations
this.currentNodeId = currentNodeId;
// clear other context that is based on or relevant to the Node id
this.currentNode = null;
this.searchContext = null;
// inform any interested beans that the UI needs updating after this change
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
// clear current node context after the notify - this is to ensure that if any delegates
// performed operations on the current node, that we have fresh data for the next View
this.currentNode = null;
}
/**
* @return true if the current node has a custom view available
*/
public boolean getHasCustomView()
{
return getHasWebscriptView() || getHasTemplateView();
}
/**
* @return true if the current node has a Template based custom view available
*/
public boolean getHasTemplateView()
{
Node node = getCurrentNode();
if (node.hasAspect(ContentModel.ASPECT_TEMPLATABLE))
{
NodeRef templateRef = (NodeRef)node.getProperties().get(ContentModel.PROP_TEMPLATE);
return (templateRef != null && this.getNodeService().exists(templateRef) &&
this.getPermissionService().hasPermission(templateRef, PermissionService.READ) == AccessStatus.ALLOWED);
}
return false;
}
/**
* @return true if the current node has a Webscript based custom view available
*/
public boolean getHasWebscriptView()
{
Node node = getCurrentNode();
if (node.hasAspect(ContentModel.ASPECT_WEBSCRIPTABLE))
{
return (node.getProperties().get(ContentModel.PROP_WEBSCRIPT) != null);
}
return false;
}
/**
* @return the NodeRef.toString() for the current node Template custom view if it has one
*/
public String getCurrentNodeTemplate()
{
NodeRef ref = (NodeRef)getCurrentNode().getProperties().get(ContentModel.PROP_TEMPLATE);
return ref != null ? ref.toString() : null;
}
/**
* @return the service url for the current node Webscript custom view if it has one
*/
public String getCurrentNodeWebscript()
{
return (String)getCurrentNode().getProperties().get(ContentModel.PROP_WEBSCRIPT);
}
/**
* Returns a model for use by a template on a space Dashboard page.
*
* @return model containing current current space info.
*/
@SuppressWarnings("unchecked")
public Map getTemplateModel()
{
HashMap model = new HashMap(2, 1.0f);
model.put("space", getCurrentNode().getNodeRef());
model.put(TemplateService.KEY_IMAGE_RESOLVER,
new TemplateImageResolver()
{
public String resolveImagePathForName(String filename, FileTypeImageSize size)
{
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
}
});
return model;
}
/**
* Clear state so that the current node properties cache for the next time they are requested
*/
public void resetCurrentNodeProperties()
{
this.currentNode = null;
}
/**
* @return The Map of properties for the current Node.
*/
public Map<String, Object> getNodeProperties()
{
return getCurrentNode().getProperties();
}
/**
* @return The current Node object for UI context operations
*/
public Node getCurrentNode()
{
if (this.currentNode == null)
{
if (this.currentNodeId == null)
{
// handle the possibility that we have no current location
// this is possible in cluster fail-over or due to a missing node
// default back to the current toolbar root location
this.processToolbarLocation(this.getToolbarLocation(), false);
}
if (s_logger.isDebugEnabled())
s_logger.debug("Caching properties for node id: " + this.currentNodeId);
NodeRef nodeRef;
Node node;
Map<String, Object> props;
try
{
// build a node which components on the JSP page can bind too
nodeRef = new NodeRef(Repository.getStoreRef(), this.currentNodeId);
node = new Node(nodeRef);
// early init properties for this node (by getProperties() call)
// resolve icon in-case one has not been set
props = node.getProperties();
}
catch (InvalidNodeRefException refErr)
{
FacesContext fc = FacesContext.getCurrentInstance();
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
fc, ERROR_DELETED_FOLDER), new Object[] {this.currentNodeId}) );
nodeRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId(fc));
node = new Node(nodeRef);
props = node.getProperties();
}
String icon = (String)props.get("app:icon");
props.put("icon", icon != null ? icon : CreateSpaceWizard.DEFAULT_SPACE_ICON_NAME);
String cifsPath = Utils.generateURL(FacesContext.getCurrentInstance(), node, URLMode.CIFS);
node.getProperties().put("cifsPath", cifsPath == null ? "" : cifsPath);
node.getProperties().put("cifsPathLabel", cifsPath == null ? "" : cifsPath.substring(8)); // strip file:/// part
this.currentNode = node;
}
return this.currentNode;
}
/**
* @return Boolean value according to CREATE_CHILDREN permission on the current node.
*/
public boolean isCreateChildrenPermissionEnabled()
{
return getCurrentNode().hasPermission(PermissionService.CREATE_CHILDREN);
}
/**
* @return Returns the breadcrumb handler elements representing the location path of the UI.
*/
public List<IBreadcrumbHandler> getLocation()
{
if (this.location == null)
{
// get the initial location from the user preferences
processToolbarLocation(getToolbarLocation(), false);
}
return this.location;
}
/**
* @param location The UI location representation to set.
*/
public void setLocation(List<IBreadcrumbHandler> location)
{
this.location = location;
}
/**
* @return true if we are currently the special Guest user
*/
public boolean getIsGuest()
{
return Repository.getIsGuest(FacesContext.getCurrentInstance());
}
/**
* Sets up the dispatch context so that the navigation handler knows
* what object is being acted upon
*
* @param node The node to be added to the dispatch context
*/
public void setupDispatchContext(Node node)
{
this.dispatchContext = node;
}
/**
* Resets the dispatch context
*/
public void resetDispatchContext()
{
this.dispatchContext = null;
}
/**
* Returns the node currently set in the dispatch context
*
* @return The node being dispatched or null if there is no
* dispatch context
*/
public Node getDispatchContextNode()
{
return this.dispatchContext;
}
/**
* @return Node representing the Company Home folder
*/
public Node getCompanyHomeNode()
{
if (this.companyHomeNode == null)
{
FacesContext fc = FacesContext.getCurrentInstance();
String companyRootId = Application.getCompanyRootId(fc);
if (companyRootId != null)
{
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), companyRootId);
this.companyHomeNode = new Node(companyRootRef);
}
}
return this.companyHomeNode;
}
/**
* @return Node representing the Guest Home Space folder
*/
public Node getGuestHomeNode()
{
if (this.guestHomeNode == null)
{
try
{
FacesContext fc = FacesContext.getCurrentInstance();
String xpath = Application.getRootPath(fc) + "/" + Application.getGuestHomeFolderName(fc);
List<NodeRef> guestHomeRefs = this.getSearchService().selectNodes(
this.getNodeService().getRootNode(Repository.getStoreRef()),
xpath, null, this.getNamespaceService(), false);
if (guestHomeRefs.size() == 1)
{
this.guestHomeNode = new Node(guestHomeRefs.get(0));
}
}
catch (InvalidNodeRefException err1)
{
// cannot continue if this occurs
}
catch (AccessDeniedException err2)
{
// cannot see node if this occurs
}
}
return this.guestHomeNode;
}
/**
* @return true if the Company home node is accessible to the current user
*/
public boolean getCompanyHomeVisible()
{
try
{
Node companyHomeNode = getCompanyHomeNode();
if (companyHomeNode != null)
{
return companyHomeNode.hasPermission(PermissionService.READ);
}
else
{
return false;
}
}
catch (Throwable e)
{
if (logger.isDebugEnabled())
{
logger.debug("getCompanyHomeVisible failed", e);
}
return false;
}
}
/**
* @return true if the Guest home node is accessible to the current user
*/
public boolean getGuestHomeVisible()
{
try
{
if (this.getAuthService().guestUserAuthenticationAllowed())
{
Node guestHome = getGuestHomeNode();
return guestHome != null && guestHome.hasPermission(PermissionService.READ);
}
else
{
return false;
}
}
catch (Throwable e)
{
if (logger.isDebugEnabled())
{
logger.debug("getGuestHomeVisible failed", e);
}
return false;
}
}
// ------------------------------------------------------------------------------
// Navigation action event handlers
/**
* Action handler to toggle the expanded state of the shelf.
* The panel component wrapping the shelf area of the UI is value bound to the shelfExpanded property.
*/
public void toggleShelf(ActionEvent event)
{
this.shelfExpanded = !this.shelfExpanded;
}
/**
* Action handler called after a Shelf Group has had its expanded state toggled by the user
*/
public void shelfGroupToggled(ActionEvent event)
{
UIShelf.ShelfEvent shelfEvent = (UIShelf.ShelfEvent)event;
this.shelfItemExpanded[shelfEvent.Index] = shelfEvent.Expanded;
}
/**
* Action to change the toolbar location
* Currently this will changed the location from Company to the users Home space
*/
public void toolbarLocationChanged(ActionEvent event)
{
FacesContext context = FacesContext.getCurrentInstance();
try
{
UIModeList locationList = (UIModeList)event.getComponent();
String location = locationList.getValue().toString();
processToolbarLocation(location, true);
}
catch (InvalidNodeRefException refErr)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_NOHOME), Application.getCurrentUser(context).getHomeSpaceId()), refErr );
}
catch (Exception err)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
}
}
/**
* @param diskShare Filesystem shared device
* @return CIFS server path as network style string label
*/
public String getCIFSServerPath(DiskSharedDevice diskShare)
{
if (this.cifsServerPath == null)
{
StringBuilder buf = new StringBuilder(32);
String serverName = this.getServerConfiguration().getServerName();
if (serverName != null && serverName.length() != 0)
{
buf.append("\\\\");
buf.append(serverName);
// Check if there is a suffix to apply to the host name
if (clientConfig != null && clientConfig.getCifsURLSuffix() != null)
{
buf.append(clientConfig.getCifsURLSuffix());
}
buf.append("\\");
buf.append(diskShare.getName());
}
this.cifsServerPath = buf.toString();
}
return this.cifsServerPath;
}
/**
* @return true if the current space has an RSS feed applied
*/
public boolean isRSSFeed()
{
return SpaceDetailsDialog.hasRSSFeed(getCurrentNode());
}
/**
* @return RSS Feed URL for the current space
*/
public String getRSSFeedURL()
{
return SpaceDetailsDialog.buildRSSFeedURL(getCurrentNode());
}
/**
* @return true if User/Group admin is allowed by admin users
*/
public boolean isAllowUserGroupAdmin()
{
return this.clientConfig.isUserGroupAdmin();
}
/**
* @return true if users can configure their own settings in the User Console
*/
public boolean isAllowUserConfig()
{
return this.clientConfig.getAllowUserConfig();
}
/**
* @return true if a users can modify the password set against their authentication
*/
public boolean isAllowUserChangePassword()
{
return this.authService.isAuthenticationMutable(this.authService.getCurrentUserName());
}
/**
* @return true if this is a team license
*/
public boolean isTeamMode()
{
Boolean teamMode = AuthenticationUtil.runAs(new RunAsWork<Boolean>()
{
public Boolean doWork() throws Exception
{
RepoAdminService s = getRepoAdminService();
if (s != null)
{
if (RepoUsage.LicenseMode.TEAM.equals(s.getRestrictions().getLicenseMode()))
{
return Boolean.TRUE;
}
}
return Boolean.FALSE;
}
}, AuthenticationUtil.getSystemUserName());
return teamMode.booleanValue();
}
// ------------------------------------------------------------------------------
// Helpers
/**
* Initialise default values from client configuration
*
* Package visibility to allow LoginBean to re-init (for example, in context of tenant config)
*/
/* package */ void initFromClientConfig()
{
this.clientConfig = Application.getClientConfig(FacesContext.getCurrentInstance());
this.setHelpUrl(clientConfig.getHelpUrl());
this.shelfExpanded = clientConfig.isShelfVisible();
}
// ------------------------------------------------------------------------------
// Inner classes
/**
* Class to handle breadcrumb interaction for top-level navigation pages
*/
public class NavigationBreadcrumbHandler implements IRepoBreadcrumbHandler
{
private static final long serialVersionUID = 4833194653193016638L;
/**
* Constructor
*
* @param label Element label
*/
public NavigationBreadcrumbHandler(NodeRef ref, String label)
{
this.label = label;
this.ref = ref;
}
/**
* @see java.lang.Object#toString()
*/
public String toString()
{
return this.label;
}
/**
* @see org.alfresco.web.ui.common.component.IBreadcrumbHandler#navigationOutcome(org.alfresco.web.ui.common.component.UIBreadcrumb)
*/
@SuppressWarnings("unchecked")
public String navigationOutcome(UIBreadcrumb breadcrumb)
{
// set the current node to the specified top level node ID
FacesContext fc = FacesContext.getCurrentInstance();
setCurrentNodeId(ref.getId());
setLocation( (List)breadcrumb.getValue() );
// setup the dispatch context
setupDispatchContext(new Node(ref));
// inform any listeners that the current space has changed
UIContextService.getInstance(FacesContext.getCurrentInstance()).spaceChanged();
if (fc.getViewRoot().getViewId().equals(BrowseBean.BROWSE_VIEW_ID))
{
return null;
}
else
{
return OUTCOME_BROWSE;
}
}
public NodeRef getNodeRef()
{
return this.ref;
}
private String label;
private NodeRef ref;
}
// ------------------------------------------------------------------------------
// Private data
private static Log s_logger = LogFactory.getLog(NavigationBean.class);
/** constant values used by the toolbar location modelist control */
public static final String LOCATION_COMPANY = "companyhome";
public static final String LOCATION_HOME = "userhome";
public static final String LOCATION_GUEST = "guesthome";
public static final String LOCATION_MYALFRESCO = "myalfresco";
/** constant value representing the display lables for toolbar locations */
public static final String MSG_MYALFRESCO = "my_alfresco";
public static final String MSG_MYHOME = "my_home";
public static final String MSG_COMPANYHOME = "company_home";
public static final String MSG_GUESTHOME = "guest_home";
private static final String OUTCOME_MYALFRESCO = "myalfresco";
private static final String OUTCOME_BROWSE = "browse";
private static final String ERROR_DELETED_FOLDER = "error_deleted_folder";
/** The NodeService to be used by the bean */
transient private NodeService nodeService;
/** The SearchService to be used by the bean */
transient private SearchService searchService;
/** NamespaceService bean reference */
transient private NamespaceService namespaceService;
/** RuleService bean reference*/
transient private RuleService ruleService;
/** Repo Admin Service reference */
transient private RepoAdminService repoAdminService;
/** File server configuration reference */
transient private ServerConfigurationAccessor serverConfiguration;
/** CIFS content disk driver bean reference */
protected ContentDiskInterface contentDiskDriver;
/** Client configuration object */
protected ClientConfigElement clientConfig = null;
/** The user preferences bean reference */
UserPreferencesBean preferences;
/** The Authentication service bean reference */
transient private MutableAuthenticationService authService;
/** The PermissionService reference */
transient private PermissionService permissionService;
/** Cached path to our CIFS server and top level node DIR */
private String cifsServerPath;
/** Node Id we are using for UI context operations */
private String currentNodeId;
/** Node we are using for UI context operations */
private Node currentNode = null;
/** Node we are using for dispatching */
private Node dispatchContext = null;
/** Node representing the guest home */
private Node guestHomeNode = null;
/** Node representing the company home */
private Node companyHomeNode = null;
/** Current toolbar location */
private String toolbarLocation = null;
/** Search context object we are currently using or null for no search */
private SearchContext searchContext;
/** expanded state of the Shelf panel wrapper component */
private boolean shelfExpanded = true;
/** expanded state of the Shelf item components */
private boolean[] shelfItemExpanded = new boolean[] {true, true, true, false, false};
/** list of the breadcrumb handler elements representing the location path of the UI */
private List<IBreadcrumbHandler> location = null;
/** The client Help file url */
private String helpUrl;
}