diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index dcdf237e8a..85d2d706e8 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1221,6 +1221,7 @@ delete_reports_confirm=Are you sure you want to delete all deployment reports ac release_server_title=Release Test Server release_server_info=To release the test server from this sandbox, click Yes. release_server_confirm=Are you sure you want to release the test server allocated to this sandbox? +website_showallsandboxes=Show All Sandboxes # Website actions and dialog messages title_import_content=Web Project Bulk Import diff --git a/source/java/org/alfresco/web/action/evaluator/WCMUnlockEvaluator.java b/source/java/org/alfresco/web/action/evaluator/WCMUnlockEvaluator.java index d870079593..0a3fb5ded6 100644 --- a/source/java/org/alfresco/web/action/evaluator/WCMUnlockEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/WCMUnlockEvaluator.java @@ -63,8 +63,6 @@ public class WCMUnlockEvaluator extends BaseActionEvaluator if (avmService.lookup(p.getFirst(), path) != null) { - String relPath = AVMUtil.getStoreRelativePath(path); - WebProject webProject = avmBrowseBean.getWebProject(); if (webProject == null) { @@ -74,7 +72,7 @@ public class WCMUnlockEvaluator extends BaseActionEvaluator } // determine if the item is locked - AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), relPath); + AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), AVMUtil.getStoreRelativePath(path)); proceed = (lock != null); } diff --git a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowDeletedEvaluator.java b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowDeletedEvaluator.java index e42b2de882..e27e695b40 100644 --- a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowDeletedEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowDeletedEvaluator.java @@ -28,10 +28,13 @@ import javax.faces.context.FacesContext; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.avm.AVMService; +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.wcm.AVMBrowseBean; import org.alfresco.web.bean.wcm.AVMNode; import org.alfresco.web.bean.wcm.AVMUtil; +import org.alfresco.web.bean.wcm.WebProject; /** * UI Action Evaluator - return true if the node is not part of an in-progress WCM workflow. @@ -51,14 +54,24 @@ public class WCMWorkflowDeletedEvaluator extends WCMLockEvaluator boolean proceed = false; if (super.evaluate(node)) { - final FacesContext facesContext = FacesContext.getCurrentInstance(); - final AVMService avmService = Repository.getServiceRegistry(facesContext).getAVMService(); - final String path = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()).getSecond(); - - // evaluate to true if we are within a workflow store (i.e. list of resources in the task - // dialog) or not part of an already in-progress workflow - proceed = (AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) || - !((AVMNode)node).isWorkflowInFlight()); + final FacesContext fc = FacesContext.getCurrentInstance(); + final AVMService avmService = Repository.getServiceRegistry(fc).getAVMService(); + final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME); + WebProject webProject = avmBrowseBean.getWebProject(); + if (webProject == null || webProject.hasWorkflow()) + { + final String path = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()).getSecond(); + + // evaluate to true if we are within a workflow store (i.e. list of resources in the task + // dialog) or not part of an already in-progress workflow + proceed = (AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) || + !((AVMNode)node).isWorkflowInFlight()); + } + else + { + // if the WebProject has no workflow then we can proceed without checking further + proceed = true; + } } return proceed; } diff --git a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java index d6bf4e3aa1..413bc8058d 100644 --- a/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java +++ b/source/java/org/alfresco/web/action/evaluator/WCMWorkflowEvaluator.java @@ -29,10 +29,13 @@ import javax.faces.context.FacesContext; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.util.Pair; +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.wcm.AVMBrowseBean; import org.alfresco.web.bean.wcm.AVMNode; import org.alfresco.web.bean.wcm.AVMUtil; +import org.alfresco.web.bean.wcm.WebProject; /** * UI Action Evaluator - return true if the node is not part of an in-progress WCM workflow. @@ -51,18 +54,27 @@ public class WCMWorkflowEvaluator extends WCMLockEvaluator boolean proceed = false; if (super.evaluate(node)) { - final FacesContext facesContext = FacesContext.getCurrentInstance(); - final AVMService avmService = Repository.getServiceRegistry(facesContext).getAVMService(); - - final Pair p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()); - final String path = p.getSecond(); - - // evaluate to true if we are not deleted and within a workflow store (i.e. list of resources - // in the task dialog) or not part of an already in-progress workflow - proceed = ((AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) || - !((AVMNode)node).isWorkflowInFlight()) && - avmService.lookup(p.getFirst(), path) != null); + final FacesContext fc = FacesContext.getCurrentInstance(); + final AVMService avmService = Repository.getServiceRegistry(fc).getAVMService(); + final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME); + WebProject webProject = avmBrowseBean.getWebProject(); + if (webProject == null || webProject.hasWorkflow()) + { + final Pair p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()); + final String path = p.getSecond(); + + // evaluate to true if we are not deleted and within a workflow store (i.e. list of resources + // in the task dialog) or not part of an already in-progress workflow + proceed = ((AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) || + !((AVMNode)node).isWorkflowInFlight()) && + avmService.lookup(p.getFirst(), path) != null); + } + else + { + // if the WebProject has no workflow then we can proceed without checking further + proceed = true; + } } return proceed; } -} +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 92c2d57d30..7c71e8c18d 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -53,9 +53,7 @@ import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeType; import org.alfresco.repo.avm.actions.AVMRevertStoreAction; import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction; -import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.web.scripts.FileTypeImageUtils; -import org.alfresco.sandbox.SandboxConstants; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; @@ -77,7 +75,7 @@ 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.workflow.WorkflowService; -import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.Pair; import org.alfresco.util.VirtServerUtils; import org.alfresco.web.app.Application; @@ -197,6 +195,9 @@ public class AVMBrowseBean implements IContextListener /** breadcrumb location */ private List location = null; + /** Show all user sandboxes flag */ + private boolean showAllSandboxes = false; + /** The current view page sizes */ private int pageSizeFolders; private int pageSizeFiles; @@ -482,7 +483,8 @@ public class AVMBrowseBean implements IContextListener final ResourceBundle msg = Application.getBundle(fc); final String stagingStore = this.getStagingStore(); final AVMStoreDescriptor store = getAvmService().getStore(stagingStore); - final String storeId = (String)this.getWebProject().getStoreId(); + WebProject webProject = this.getWebProject(); + final String storeId = (String)webProject.getStoreId(); if (store != null) { summary.append(msg.getString(MSG_CREATED_ON)).append(": ") @@ -491,7 +493,8 @@ public class AVMBrowseBean implements IContextListener summary.append(msg.getString(MSG_CREATED_BY)).append(": ") .append(store.getCreator()) .append("

"); - final int numUsers = this.getRelatedStoreNames(storeId, SandboxConstants.PROP_SANDBOX_AUTHOR_MAIN).size(); + final int numUsers = nodeService.getChildAssocs( + webProject.getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL).size(); summary.append(MessageFormat.format(msg.getString(MSG_WORKING_USERS), numUsers)); } @@ -500,32 +503,6 @@ public class AVMBrowseBean implements IContextListener return summary.toString(); } - - /** - * Returns the list of store names related to the storeId provided that have - * any of the provided types as store properties. - * - * @return a list of related store names. - */ - private List getRelatedStoreNames(final String storeId, final QName... types) - { - QName qn = QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + storeId + "%"); - final Map> relatedSandboxes = - getAvmService().queryStoresPropertyKeys(qn); - final List result = new LinkedList(); - for (String storeName : relatedSandboxes.keySet()) - { - for (final QName type : types) - { - if (getAvmService().getStoreProperty(storeName, type) != null) - { - result.add(storeName); - break; - } - } - } - return result; - } /** * @return the current staging store name @@ -1039,6 +1016,22 @@ public class AVMBrowseBean implements IContextListener return this.getWebProject().isManager(user); } + /** + * @return true to show all sandboxes visible to this user, false to only show the current user sandbox + */ + public boolean getShowAllSandboxes() + { + return this.showAllSandboxes; + } + + /** + * @param value true to show all sandboxes visible to this user, false to only show the current user sandbox + */ + public void setShowAllSandboxes(boolean value) + { + this.showAllSandboxes = value; + } + /** * @return true if the website has had a deployment attempt */ @@ -2020,6 +2013,9 @@ public class AVMBrowseBean implements IContextListener this.files = null; this.folders = null; + + // reset the WebProject instance - as values may be cached that have now changed + this.webProject = null; } /** diff --git a/source/java/org/alfresco/web/bean/wcm/AVMNode.java b/source/java/org/alfresco/web/bean/wcm/AVMNode.java index 30bad51ca9..4c93f957e6 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMNode.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMNode.java @@ -276,15 +276,6 @@ public class AVMNode extends Node implements Map return this.workflowInFlight; } - public WebProject getWebProject() - { - if (this.webProject == null) - { - this.webProject = new WebProject(this.id); - } - return this.webProject; - } - /** * @return All the properties known about this node. */ diff --git a/source/java/org/alfresco/web/bean/wcm/UpdatePermissionsDialog.java b/source/java/org/alfresco/web/bean/wcm/UpdatePermissionsDialog.java index 3934f9fa44..04a050d21d 100644 --- a/source/java/org/alfresco/web/bean/wcm/UpdatePermissionsDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/UpdatePermissionsDialog.java @@ -82,13 +82,14 @@ public class UpdatePermissionsDialog extends BasePermissionsDialog */ protected void createLock(AVMNode node) { - if (getAvmLockingService().getLock(node.getWebProject().getStoreId(), node.getPath().substring(node.getPath().indexOf("/"))) == null && !node.isDirectory()) + String webProject = AVMUtil.getStoreId(AVMUtil.getStoreName(node.getPath())); + + if (getAvmLockingService().getLock(webProject, node.getPath().substring(node.getPath().indexOf("/"))) == null && !node.isDirectory()) { String userName = getAuthenticationService().getCurrentUserName(); List owners = new ArrayList(1); owners.add(userName); - String webProject = node.getWebProject().getStoreId(); String[] storePath = node.getPath().split(":"); AVMLock lock = new AVMLock(webProject, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners); diff --git a/source/java/org/alfresco/web/bean/wcm/WebProject.java b/source/java/org/alfresco/web/bean/wcm/WebProject.java index 1123b855dd..f1a1975560 100644 --- a/source/java/org/alfresco/web/bean/wcm/WebProject.java +++ b/source/java/org/alfresco/web/bean/wcm/WebProject.java @@ -71,7 +71,6 @@ import org.apache.commons.logging.LogFactory; */ public class WebProject implements Serializable { - ///////////////////////////////////////////////////////////////////////////// private static final long serialVersionUID = 2480625511643744703L; @@ -184,10 +183,13 @@ public class WebProject implements Serializable ///////////////////////////////////////////////////////////////////////////// private final static Log LOGGER = LogFactory.getLog(WebProject.class); - private static String websitesFolderId; - + + private static NodeRef websitesFolder; private final NodeRef nodeRef; - + private String storeId = null; + private Boolean hasWorkflow = null; + private Map userRoles = new HashMap(16, 1.0f); + public WebProject(final NodeRef nodeRef) { if (nodeRef == null) @@ -195,8 +197,7 @@ public class WebProject implements Serializable throw new NullPointerException(); } - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); + final NodeService nodeService = getServiceRegistry().getNodeService(); if (!WCMAppModel.TYPE_AVMWEBFOLDER.equals(nodeService.getType(nodeRef))) { throw new IllegalArgumentException(nodeRef + " is not a " + WCMAppModel.TYPE_AVMWEBFOLDER); @@ -236,8 +237,7 @@ public class WebProject implements Serializable */ public String getName() { - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); + final NodeService nodeService = this.getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME); } @@ -248,8 +248,7 @@ public class WebProject implements Serializable */ public String getTitle() { - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); + final NodeService nodeService = this.getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_TITLE); } @@ -260,8 +259,7 @@ public class WebProject implements Serializable */ public String getDescription() { - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); + final NodeService nodeService = this.getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION); } @@ -272,9 +270,12 @@ public class WebProject implements Serializable */ public String getStoreId() { - final ServiceRegistry serviceRegistry = this.getServiceRegistry(); - final NodeService nodeService = serviceRegistry.getNodeService(); - return (String)nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_AVMSTORE); + if (this.storeId == null) + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + this.storeId = (String)nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_AVMSTORE); + } + return this.storeId; } /** @@ -327,6 +328,35 @@ public class WebProject implements Serializable } return result; } + + /** + * @return true if this WebProject has any workflows assigned directly to the website or + * assigned to any of the forms attached to it + */ + public boolean hasWorkflow() + { + if (this.hasWorkflow == null) + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + List webWorkflowRefs = nodeService.getChildAssocs( + this.nodeRef, WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, RegexQNamePattern.MATCH_ALL); + this.hasWorkflow = (webWorkflowRefs.size() != 0); + if (!this.hasWorkflow) + { + // might have a workflow assigned to one of the forms used in the website + Map forms = getFormsImpl(); + for (Form form : forms.values()) + { + if (form.getDefaultWorkflow() != null) + { + this.hasWorkflow = Boolean.TRUE; + break; + } + } + } + } + return this.hasWorkflow.booleanValue(); + } /** * Returns true if the user is a manager of this web project. @@ -337,68 +367,89 @@ public class WebProject implements Serializable */ public boolean isManager(final User user) { - if (user.isAdmin()) + String userrole; + String username = user.getUserName(); + synchronized (userRoles) { - return true; + userrole = userRoles.get(username); + if (userrole == null) + { + userrole = WebProject.getWebProjectUserRole(nodeRef, user); + userRoles.put(username, userrole); + } } - - String userrole = WebProject.getWebProjectUserRole(nodeRef, user); return AVMUtil.ROLE_CONTENT_MANAGER.equals(userrole); } /** * @return the role of this user in the given Web Project, or null for no assigned role */ - public static String getWebProjectUserRole(NodeRef webProjectRef, User currentUser) + public static String getWebProjectUserRole(NodeRef webProjectRef, User user) { - long start = System.currentTimeMillis(); - String userrole = null; - - if (currentUser.isAdmin()) - { - // fake the Content Manager role for an admin user - userrole = AVMUtil.ROLE_CONTENT_MANAGER; - } - else - { - final ServiceRegistry serviceRegistry = WebProject.getServiceRegistry(); - final SearchService searchService = serviceRegistry.getSearchService(); - final NodeService nodeService = serviceRegistry.getNodeService(); - - StringBuilder query = new StringBuilder(128); - query.append("+PARENT:\"").append(webProjectRef).append("\" "); - query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" "); - query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\""); - query.append(currentUser.getUserName()); - query.append("\""); - - ResultSet resultSet = searchService.query( - Repository.getStoreRef(), - SearchService.LANGUAGE_LUCENE, - query.toString()); - List nodes = resultSet.getNodeRefs(); + String userrole = null; + + long start = 0; + if (LOGGER.isDebugEnabled()) + { + start = System.currentTimeMillis(); + } + + if (user.isAdmin()) + { + // fake the Content Manager role for an admin user + userrole = AVMUtil.ROLE_CONTENT_MANAGER; + } + else + { + NodeService nodeService = WebProject.getServiceRegistry().getNodeService(); + + NodeRef roleRef = findUserRoleNodeRef(webProjectRef, user); + if (roleRef != null) + { + userrole = (String)nodeService.getProperty(roleRef, WCMAppModel.PROP_WEBUSERROLE); + } + else + { + LOGGER.warn("getWebProjectUserRole: user role not found for " + user); + } + } + + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("getWebProjectUserRole: " + user.getUserName() + " " + userrole + " in " + (System.currentTimeMillis()-start) + " ms"); + } + + return userrole; + } - if (nodes.size() == 1) - { - userrole = (String)nodeService.getProperty(nodes.get(0), WCMAppModel.PROP_WEBUSERROLE); - } - else if (nodes.size() == 0) - { - LOGGER.warn("getWebProjectUserRole: user role not found for " + currentUser); - } - else - { - LOGGER.warn("getWebProjectUserRole: more than one user role found for " + currentUser); - } - } - - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("getWebProjectUserRole: "+currentUser.getUserName()+" "+userrole+" in "+(System.currentTimeMillis()-start)+" ms"); - } - - return userrole; - } + /** + * Perform a Lucene search to return a NodeRef to the node representing the the User Role + * within the given WebProject. + * + * @param webProjectRef Web Project to search against + * @param user User to test against + * + * @return NodeRef of the User Role node or null if none found + */ + public static NodeRef findUserRoleNodeRef(NodeRef webProjectRef, User user) + { + SearchService searchService = WebProject.getServiceRegistry().getSearchService(); + + StringBuilder query = new StringBuilder(128); + query.append("+PARENT:\"").append(webProjectRef).append("\" "); + query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" "); + query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\""); + query.append(user.getUserName()); + query.append("\""); + + ResultSet resultSet = searchService.query( + Repository.getStoreRef(), + SearchService.LANGUAGE_LUCENE, + query.toString()); + List nodes = resultSet.getNodeRefs(); + + return (nodes.size() == 1 ? nodes.get(0) : null); + } /** * Returns the default webapp for this web project. @@ -420,9 +471,9 @@ public class WebProject implements Serializable * * @throws AlfrescoRuntimeException if unable to find the required folder */ - public static NodeRef getWebsitesFolder() + public synchronized static NodeRef getWebsitesFolder() { - if (WebProject.websitesFolderId == null) + if (WebProject.websitesFolder == null) { // get the template from the special Content Templates folder final FacesContext fc = FacesContext.getCurrentInstance(); @@ -433,7 +484,7 @@ public class WebProject implements Serializable final List results = WebProject.getServiceRegistry().getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false); if (results.size() == 1) { - WebProject.websitesFolderId = results.get(0).getId(); + WebProject.websitesFolder = new NodeRef(Repository.getStoreRef(), results.get(0).getId()); } else { @@ -441,7 +492,7 @@ public class WebProject implements Serializable } } - return new NodeRef(Repository.getStoreRef(), WebProject.websitesFolderId); + return WebProject.websitesFolder; } public static List getWebProjects() diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java b/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java index caefc27025..5c58939a88 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIAVMLockIcon.java @@ -28,18 +28,17 @@ import java.io.IOException; import java.util.List; import javax.faces.context.FacesContext; -import javax.faces.context.ResponseWriter; -import javax.faces.el.ValueBinding; -import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.repository.User; +import org.alfresco.web.bean.wcm.AVMBrowseBean; +import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.bean.wcm.WebProject; import org.alfresco.web.ui.repo.component.UILockIcon; @@ -61,7 +60,6 @@ public class UIAVMLockIcon extends UILockIcon return ALFRESCO_FACES_AVMLOCKICON; } - /** * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext) */ @@ -75,7 +73,8 @@ public class UIAVMLockIcon extends UILockIcon // get the value and see if the image is locked final AVMService avmService = Repository.getServiceRegistry(context).getAVMService(); final AVMLockingService avmLockingService = Repository.getServiceRegistry(context).getAVMLockingService(); - + final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME); + boolean locked = false; boolean lockedOwner = false; Object val = getValue(); @@ -89,14 +88,21 @@ public class UIAVMLockIcon extends UILockIcon { if (avmService.lookup(-1, avmPath) != null) { - final WebProject webProject = new WebProject(avmPath); - final AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), avmPath.substring(avmPath.indexOf("/"))); + // optimization to reuse the current WebProject object if it represents the + // same webproject that the lock item path is contained within - this ensures + // we do not perform slow store property lookups for every UIAVMLockIcon instance + String stagingStore = AVMUtil.buildStagingStoreName(AVMUtil.getStoreId(AVMUtil.getStoreName(avmPath))); + WebProject webProject = avmBrowseBean.getWebProject(); + if (webProject == null || !webProject.getStagingStore().equals(stagingStore)) + { + webProject = new WebProject(avmPath); + } + AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), avmPath.substring(avmPath.indexOf("/"))); if (lock != null) { locked = true; - final User currentUser = Application.getCurrentUser(context); lockUsers = lock.getOwners(); - lockedOwner = (lockUsers.contains(currentUser.getUserName())); + lockedOwner = (lockUsers.contains(Application.getCurrentUser(context).getUserName())); } } } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index a9fbcede22..9054ecb0f0 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -303,6 +303,8 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa AVMService avmService = getAVMService(context); NodeService nodeService = getNodeService(context); PermissionService permissionService = getPermissionService(context); + AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME); + boolean showAllSandboxes = avmBrowseBean.getShowAllSandboxes(); UserTransaction tx = null; try { @@ -317,19 +319,25 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa String storeRoot = (String)nodeService.getProperty(websiteRef, WCMAppModel.PROP_AVMSTORE); // find out the current user role in the web project - List userInfoRefs = nodeService.getChildAssocs( - websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); User currentUser = Application.getCurrentUser(context); String currentUserName = currentUser.getUserName(); - String currentUserRole = WebProject.getWebProjectUserRole(websiteRef, currentUser); - // sort the user list alphabetically and insert the current user at the top of the list - List userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); + // sort the user list alphabetically and insert the current user at the top of the list + List userRoleWrappers; + if (showAllSandboxes) + { + List userInfoRefs = nodeService.getChildAssocs( + websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); + userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); + } + else + { + userRoleWrappers = buildCurrentUserRole(nodeService, websiteRef, currentUser); + } // determine whether the check links action should be shown boolean linkValidationEnabled = true; - AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, "AVMBrowseBean"); if (avmBrowseBean != null) { linkValidationEnabled = avmBrowseBean.isLinkValidationEnabled(); @@ -366,9 +374,12 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa // check the permissions on this store for the current user if (logger.isDebugEnabled()) logger.debug("Checking user role to view store: " + mainStore); - if (currentUserName.equals(username) || - AVMUtil.ROLE_CONTENT_MANAGER.equals(currentUserRole) || - AVMUtil.ROLE_CONTENT_PUBLISHER.equals(currentUserRole)) + + if ((showAllSandboxes && + (currentUserName.equals(username) || + AVMUtil.ROLE_CONTENT_MANAGER.equals(currentUserRole) || + AVMUtil.ROLE_CONTENT_PUBLISHER.equals(currentUserRole))) || + showAllSandboxes == false) { if (logger.isDebugEnabled()) logger.debug("Building sandbox view for user store: " + mainStore); @@ -584,7 +595,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa "innerwhite"); // spacer row - if (index++ < userInfoRefs.size() - 1) + if (index++ < userRoleWrappers.size() - 1) { out.write("

"); } @@ -644,6 +655,29 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa return wrappers; } + + /** + * Build a list containing one item representing the current user role for the website. + */ + private static List buildCurrentUserRole( + NodeService nodeService, NodeRef webProjectRef, User user) + { + // build a list of wrappers to hold the fields we need for each user and role + List wrappers = new ArrayList(0); + NodeRef userInfoRef = WebProject.findUserRoleNodeRef(webProjectRef, user); + if (userInfoRef != null) + { + wrappers = new ArrayList(1); + + String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + + UserRoleWrapper wrapper = new UserRoleWrapper(username, userrole); + wrapper.IsCurrentUser = true; + wrappers.add(0, wrapper); + } + return wrappers; + } /** * Render the list of user modified files/folders in the layered sandbox area. diff --git a/source/web/jsp/wcm/browse-website.jsp b/source/web/jsp/wcm/browse-website.jsp index 70420df03a..3393800888 100644 --- a/source/web/jsp/wcm/browse-website.jsp +++ b/source/web/jsp/wcm/browse-website.jsp @@ -230,7 +230,16 @@ - + <%-- used by the panel to add additional component facets --%> + + + + + + + + + <%-- User Sandboxes List --%>