diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index ca1238a020..4d1db64cd1 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -85,11 +85,14 @@ 2 3 - - - + + + + + + path diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index 4c93f13722..75944348d6 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -76,6 +76,7 @@ import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.search.SearchContext; import org.alfresco.web.bean.spaces.CreateSpaceWizard; import org.alfresco.web.bean.users.UserPreferencesBean; +import org.alfresco.web.config.ClientConfigElement; import org.alfresco.web.config.ViewsConfigElement; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.Utils.URLMode; @@ -1660,10 +1661,10 @@ public class BrowseBean implements IContextListener { List location = navigator.getLocation(); IBreadcrumbHandler handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) + if (handler instanceof IRepoBreadcrumbHandler) { // see if the current breadcrumb location is our node - if ( ((BrowseBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) + if ( ((IRepoBreadcrumbHandler)handler).getNodeRef().equals(node.getNodeRef()) == true ) { location.remove(location.size() - 1); @@ -1671,17 +1672,23 @@ public class BrowseBean implements IContextListener if (location.size() != 0) { handler = location.get(location.size() - 1); - if (handler instanceof BrowseBreadcrumbHandler) + + if (handler instanceof IRepoBreadcrumbHandler) { // change the current node Id - navigator.setCurrentNodeId(((BrowseBreadcrumbHandler)handler).getNodeRef().getId()); + navigator.setCurrentNodeId(((IRepoBreadcrumbHandler)handler).getNodeRef().getId()); } else { - // TODO: shouldn't do this - but for now the user home dir is the root! - navigator.setCurrentNodeId(Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId()); + // if we don't have access to the NodeRef to go to next then go to the home space + navigator.processToolbarLocation(NavigationBean.LOCATION_HOME, false); } } + else + { + // if there is no breadcrumb left go to the user's home space + navigator.processToolbarLocation(NavigationBean.LOCATION_HOME, false); + } } } } @@ -1827,8 +1834,26 @@ public class BrowseBean implements IContextListener // add new node to the end of the existing breadcrumb if (foundNode == false) { - String name = Repository.getNameForNode(this.nodeService, ref); - location.add(new BrowseBreadcrumbHandler(ref, name)); + FacesContext context = FacesContext.getCurrentInstance(); + String breadcrumbMode = Application.getClientConfig(context).getBreadcrumbMode(); + + if (ClientConfigElement.BREADCRUMB_LOCATION.equals(breadcrumbMode)) + { + // if the breadcrumb is in "location" mode set the breadcrumb + // to the full path to the node + + // TODO: check the end of the current breadcrumb, if the given + // node is a child then we can shortcut the build of the + // whole path. + + Repository.setupBreadcrumbLocation(context, this.navigator, location, ref); + } + else + { + // if the breadcrum is in "path" mode just add the given item to the end + String name = Repository.getNameForNode(this.nodeService, ref); + location.add(new BrowseBreadcrumbHandler(ref, name)); + } } } else @@ -1837,6 +1862,9 @@ public class BrowseBean implements IContextListener String name = Repository.getNameForNode(this.nodeService, ref); location.add(new BrowseBreadcrumbHandler(ref, name)); } + + if (logger.isDebugEnabled()) + logger.debug("Updated breadcrumb: " + location); // set the current node Id ready for page refresh this.navigator.setCurrentNodeId(ref.getId()); diff --git a/source/java/org/alfresco/web/bean/NavigationBean.java b/source/java/org/alfresco/web/bean/NavigationBean.java index abd9028041..c428696cf0 100644 --- a/source/java/org/alfresco/web/bean/NavigationBean.java +++ b/source/java/org/alfresco/web/bean/NavigationBean.java @@ -295,6 +295,9 @@ public class NavigationBean 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(); @@ -309,8 +312,23 @@ public class NavigationBean List elements = new ArrayList(1); String homeSpaceId = Application.getCurrentUser(context).getHomeSpaceId(); NodeRef homeSpaceRef = new NodeRef(Repository.getStoreRef(), homeSpaceId); - String homeSpaceName = Repository.getNameForNode(this.nodeService, homeSpaceRef); - elements.add(new NavigationBreadcrumbHandler(homeSpaceRef, homeSpaceName)); + + 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.nodeService, 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()); @@ -327,7 +345,22 @@ public class NavigationBean { List elements = new ArrayList(1); Node guestHome = getGuestHomeNode(); - elements.add(new NavigationBreadcrumbHandler(guestHome.getNodeRef(), guestHome.getName())); + + 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()); @@ -366,6 +399,10 @@ public class NavigationBean 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 @@ -933,6 +970,9 @@ public class NavigationBean // 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; diff --git a/source/java/org/alfresco/web/bean/repository/Repository.java b/source/java/org/alfresco/web/bean/repository/Repository.java index cdedd98c17..e7ab174dae 100644 --- a/source/java/org/alfresco/web/bean/repository/Repository.java +++ b/source/java/org/alfresco/web/bean/repository/Repository.java @@ -58,13 +58,17 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.service.transaction.TransactionService; import org.alfresco.web.app.Application; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.NavigationBean.NavigationBreadcrumbHandler; import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.IBreadcrumbHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.context.support.WebApplicationContextUtils; @@ -411,6 +415,56 @@ public final class Repository return buf.toString(); } + + /** + * Sets up the breadcrumb location representation for the given node in + * the given list. + * + * @param context FacesContext + * @param navBean NavigationBean instance + * @param location The location list to setup + * @param node The Node being navigated to + */ + public static void setupBreadcrumbLocation(FacesContext context, + NavigationBean navBean, List location, NodeRef node) + { + // make the sure the given list is empty + location.clear(); + + // get required services + NodeService nodeService = Repository.getServiceRegistry(context).getNodeService(); + PermissionService permsService = Repository.getServiceRegistry(context).getPermissionService(); + + // add the given node to start + String nodeName = Repository.getNameForNode(nodeService, node); + location.add(navBean.new NavigationBreadcrumbHandler(node, nodeName)); + + // get the given node's parent node + NodeRef parent = nodeService.getPrimaryParent(node).getParentRef(); + while (parent != null) + { + // check the user can read the parent node + if (permsService.hasPermission(parent, PermissionService.READ) == AccessStatus.ALLOWED) + { + // get the grand parent so we can check for the root node + NodeRef grandParent = nodeService.getPrimaryParent(parent).getParentRef(); + + if (grandParent != null) + { + // current node is not the root node so add it to the breadcrumb + String parentName = Repository.getNameForNode(nodeService, parent); + location.add(0, navBean.new NavigationBreadcrumbHandler(parent, parentName)); + } + + parent = grandParent; + } + else + { + // the user does not have Read permission above this point so stop! + break; + } + } + } /** * Return the mimetype code for the specified file name. diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java index 72a25ea2c7..a0bb0dab5b 100644 --- a/source/java/org/alfresco/web/config/ClientConfigElement.java +++ b/source/java/org/alfresco/web/config/ClientConfigElement.java @@ -48,6 +48,8 @@ public class ClientConfigElement extends ConfigElementAdapter private static Log logger = LogFactory.getLog(ClientConfigElement.class); public static final String CONFIG_ELEMENT_ID = "client"; + public static final String BREADCRUMB_PATH = "path"; + public static final String BREADCRUMB_LOCATION = "location"; private static final String DEFAULT_FROM_ADDRESS = "alfresco@alfresco.org"; @@ -74,6 +76,7 @@ public class ClientConfigElement extends ConfigElementAdapter private List simpleSearchAdditionalAttributes = null; private int minUsernameLength = 2; private int minPasswordLength = 3; + private String breadcrumbMode = BREADCRUMB_PATH; private String cifsURLSuffix; /** @@ -236,7 +239,13 @@ public class ClientConfigElement extends ConfigElementAdapter if ( newElement.getCifsURLSuffix() != null && newElement.getCifsURLSuffix().equals(combinedElement.getCifsURLSuffix()) == false) { - combinedElement.setCifsURLSuffix(newElement.getCifsURLSuffix()); + combinedElement.setCifsURLSuffix(newElement.getCifsURLSuffix()); + } + + if (newElement.getBreadcrumbMode() != null && + newElement.getBreadcrumbMode().equals(combinedElement.getBreadcrumbMode()) == false) + { + combinedElement.setBreadcrumbMode(newElement.getBreadcrumbMode()); } return combinedElement; @@ -631,6 +640,30 @@ public class ClientConfigElement extends ConfigElementAdapter this.minPasswordLength = minPasswordLength; } + /** + * Get the breadcrumb mode + * + * @return String + */ + public final String getBreadcrumbMode() + { + return breadcrumbMode; + } + + /** + * Set the breadcrumb mode + * + * @param mode String + */ + void setBreadcrumbMode(String mode) + { + // make sure it's being set to a valid option + if (BREADCRUMB_PATH.equals(mode) || BREADCRUMB_LOCATION.equals(mode)) + { + breadcrumbMode = mode; + } + } + /** * Get the CIFs URL suffix * diff --git a/source/java/org/alfresco/web/config/ClientElementReader.java b/source/java/org/alfresco/web/config/ClientElementReader.java index 699cef93d5..eb3753eed3 100644 --- a/source/java/org/alfresco/web/config/ClientElementReader.java +++ b/source/java/org/alfresco/web/config/ClientElementReader.java @@ -63,6 +63,7 @@ public class ClientElementReader implements ConfigElementReader public static final String ELEMENT_SIMPLESEARCHADDITIONALATTRSQNAME = "qname"; public static final String ELEMENT_MINUSERNAMELENGTH = "username-min-length"; public static final String ELEMENT_MINPASSWORDLENGTH = "password-min-length"; + public static final String ELEMENT_BREADCRUMB_MODE = "breadcrumb-mode"; public static final String ELEMENT_CIFSURLSUFFIX = "cifs-url-suffix"; /** @@ -246,6 +247,13 @@ public class ClientElementReader implements ConfigElementReader configElement.setMinPasswordLength(Integer.parseInt(minPassword.getTextTrim())); } + // get the breadcrumb mode + Element breadcrumbMode = element.element(ELEMENT_BREADCRUMB_MODE); + if (breadcrumbMode != null) + { + configElement.setBreadcrumbMode(breadcrumbMode.getTextTrim()); + } + // Get the CIFS URL suffix Element cifsSuffix = element.element(ELEMENT_CIFSURLSUFFIX); if ( cifsSuffix != null)