Merged V2.2 to HEAD

10992: Merged V2.1 to V2.2
    10318: Several WCM UI performance enhancements and UI improvements to enable faster interface refresh.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11036 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-09-26 12:25:17 +00:00
parent 4bf32304f1
commit e5e448fc9b
11 changed files with 269 additions and 157 deletions

View File

@@ -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_title=Release Test Server
release_server_info=To release the test server from this sandbox, click Yes. 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? 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 # Website actions and dialog messages
title_import_content=Web Project Bulk Import title_import_content=Web Project Bulk Import

View File

@@ -63,8 +63,6 @@ public class WCMUnlockEvaluator extends BaseActionEvaluator
if (avmService.lookup(p.getFirst(), path) != null) if (avmService.lookup(p.getFirst(), path) != null)
{ {
String relPath = AVMUtil.getStoreRelativePath(path);
WebProject webProject = avmBrowseBean.getWebProject(); WebProject webProject = avmBrowseBean.getWebProject();
if (webProject == null) if (webProject == null)
{ {
@@ -74,7 +72,7 @@ public class WCMUnlockEvaluator extends BaseActionEvaluator
} }
// determine if the item is locked // 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); proceed = (lock != null);
} }

View File

@@ -28,10 +28,13 @@ import javax.faces.context.FacesContext;
import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMService; 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.Node;
import org.alfresco.web.bean.repository.Repository; 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.AVMNode;
import org.alfresco.web.bean.wcm.AVMUtil; 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. * 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; boolean proceed = false;
if (super.evaluate(node)) if (super.evaluate(node))
{ {
final FacesContext facesContext = FacesContext.getCurrentInstance(); final FacesContext fc = FacesContext.getCurrentInstance();
final AVMService avmService = Repository.getServiceRegistry(facesContext).getAVMService(); final AVMService avmService = Repository.getServiceRegistry(fc).getAVMService();
final String path = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()).getSecond(); final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME);
WebProject webProject = avmBrowseBean.getWebProject();
// evaluate to true if we are within a workflow store (i.e. list of resources in the task if (webProject == null || webProject.hasWorkflow())
// dialog) or not part of an already in-progress workflow {
proceed = (AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) || final String path = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()).getSecond();
!((AVMNode)node).isWorkflowInFlight());
// 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; return proceed;
} }

View File

@@ -29,10 +29,13 @@ import javax.faces.context.FacesContext;
import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.util.Pair; 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.Node;
import org.alfresco.web.bean.repository.Repository; 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.AVMNode;
import org.alfresco.web.bean.wcm.AVMUtil; 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. * 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; boolean proceed = false;
if (super.evaluate(node)) if (super.evaluate(node))
{ {
final FacesContext facesContext = FacesContext.getCurrentInstance(); final FacesContext fc = FacesContext.getCurrentInstance();
final AVMService avmService = Repository.getServiceRegistry(facesContext).getAVMService(); final AVMService avmService = Repository.getServiceRegistry(fc).getAVMService();
final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(fc, AVMBrowseBean.BEAN_NAME);
final Pair<Integer, String> p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef()); WebProject webProject = avmBrowseBean.getWebProject();
final String path = p.getSecond(); if (webProject == null || webProject.hasWorkflow())
{
// evaluate to true if we are not deleted and within a workflow store (i.e. list of resources final Pair<Integer, String> p = AVMNodeConverter.ToAVMVersionPath(node.getNodeRef());
// in the task dialog) or not part of an already in-progress workflow final String path = p.getSecond();
proceed = ((AVMUtil.isWorkflowStore(AVMUtil.getStoreName(path)) ||
!((AVMNode)node).isWorkflowInFlight()) && // evaluate to true if we are not deleted and within a workflow store (i.e. list of resources
avmService.lookup(p.getFirst(), path) != null); // 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; return proceed;
} }
} }

View File

@@ -53,9 +53,7 @@ import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.avm.AVMNodeType; import org.alfresco.repo.avm.AVMNodeType;
import org.alfresco.repo.avm.actions.AVMRevertStoreAction; import org.alfresco.repo.avm.actions.AVMRevertStoreAction;
import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction; import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.web.scripts.FileTypeImageUtils; 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.Action;
import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; 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.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.workflow.WorkflowService; 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.Pair;
import org.alfresco.util.VirtServerUtils; import org.alfresco.util.VirtServerUtils;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
@@ -197,6 +195,9 @@ public class AVMBrowseBean implements IContextListener
/** breadcrumb location */ /** breadcrumb location */
private List<IBreadcrumbHandler> location = null; private List<IBreadcrumbHandler> location = null;
/** Show all user sandboxes flag */
private boolean showAllSandboxes = false;
/** The current view page sizes */ /** The current view page sizes */
private int pageSizeFolders; private int pageSizeFolders;
private int pageSizeFiles; private int pageSizeFiles;
@@ -482,7 +483,8 @@ public class AVMBrowseBean implements IContextListener
final ResourceBundle msg = Application.getBundle(fc); final ResourceBundle msg = Application.getBundle(fc);
final String stagingStore = this.getStagingStore(); final String stagingStore = this.getStagingStore();
final AVMStoreDescriptor store = getAvmService().getStore(stagingStore); 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) if (store != null)
{ {
summary.append(msg.getString(MSG_CREATED_ON)).append(": ") 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(": ") summary.append(msg.getString(MSG_CREATED_BY)).append(": ")
.append(store.getCreator()) .append(store.getCreator())
.append("<p>"); .append("<p>");
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)); summary.append(MessageFormat.format(msg.getString(MSG_WORKING_USERS), numUsers));
} }
@@ -500,32 +503,6 @@ public class AVMBrowseBean implements IContextListener
return summary.toString(); 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<String> getRelatedStoreNames(final String storeId, final QName... types)
{
QName qn = QName.createQName(null, SandboxConstants.PROP_SANDBOX_STORE_PREFIX + storeId + "%");
final Map<String, Map<QName, PropertyValue>> relatedSandboxes =
getAvmService().queryStoresPropertyKeys(qn);
final List<String> result = new LinkedList<String>();
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 * @return the current staging store name
@@ -1039,6 +1016,22 @@ public class AVMBrowseBean implements IContextListener
return this.getWebProject().isManager(user); 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 * @return true if the website has had a deployment attempt
*/ */
@@ -2020,6 +2013,9 @@ public class AVMBrowseBean implements IContextListener
this.files = null; this.files = null;
this.folders = null; this.folders = null;
// reset the WebProject instance - as values may be cached that have now changed
this.webProject = null;
} }
/** /**

View File

@@ -276,15 +276,6 @@ public class AVMNode extends Node implements Map<String, Object>
return this.workflowInFlight; 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. * @return All the properties known about this node.
*/ */

View File

@@ -82,13 +82,14 @@ public class UpdatePermissionsDialog extends BasePermissionsDialog
*/ */
protected void createLock(AVMNode node) 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(); String userName = getAuthenticationService().getCurrentUserName();
List<String> owners = new ArrayList<String>(1); List<String> owners = new ArrayList<String>(1);
owners.add(userName); owners.add(userName);
String webProject = node.getWebProject().getStoreId();
String[] storePath = node.getPath().split(":"); String[] storePath = node.getPath().split(":");
AVMLock lock = new AVMLock(webProject, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners); AVMLock lock = new AVMLock(webProject, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners);

View File

@@ -71,7 +71,6 @@ import org.apache.commons.logging.LogFactory;
*/ */
public class WebProject implements Serializable public class WebProject implements Serializable
{ {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
private static final long serialVersionUID = 2480625511643744703L; 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 final static Log LOGGER = LogFactory.getLog(WebProject.class);
private static String websitesFolderId;
private static NodeRef websitesFolder;
private final NodeRef nodeRef; private final NodeRef nodeRef;
private String storeId = null;
private Boolean hasWorkflow = null;
private Map<String, String> userRoles = new HashMap<String, String>(16, 1.0f);
public WebProject(final NodeRef nodeRef) public WebProject(final NodeRef nodeRef)
{ {
if (nodeRef == null) if (nodeRef == null)
@@ -195,8 +197,7 @@ public class WebProject implements Serializable
throw new NullPointerException(); throw new NullPointerException();
} }
final ServiceRegistry serviceRegistry = this.getServiceRegistry(); final NodeService nodeService = getServiceRegistry().getNodeService();
final NodeService nodeService = serviceRegistry.getNodeService();
if (!WCMAppModel.TYPE_AVMWEBFOLDER.equals(nodeService.getType(nodeRef))) if (!WCMAppModel.TYPE_AVMWEBFOLDER.equals(nodeService.getType(nodeRef)))
{ {
throw new IllegalArgumentException(nodeRef + " is not a " + WCMAppModel.TYPE_AVMWEBFOLDER); throw new IllegalArgumentException(nodeRef + " is not a " + WCMAppModel.TYPE_AVMWEBFOLDER);
@@ -236,8 +237,7 @@ public class WebProject implements Serializable
*/ */
public String getName() public String getName()
{ {
final ServiceRegistry serviceRegistry = this.getServiceRegistry(); final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeService nodeService = serviceRegistry.getNodeService();
return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME);
} }
@@ -248,8 +248,7 @@ public class WebProject implements Serializable
*/ */
public String getTitle() public String getTitle()
{ {
final ServiceRegistry serviceRegistry = this.getServiceRegistry(); final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeService nodeService = serviceRegistry.getNodeService();
return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_TITLE); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_TITLE);
} }
@@ -260,8 +259,7 @@ public class WebProject implements Serializable
*/ */
public String getDescription() public String getDescription()
{ {
final ServiceRegistry serviceRegistry = this.getServiceRegistry(); final NodeService nodeService = this.getServiceRegistry().getNodeService();
final NodeService nodeService = serviceRegistry.getNodeService();
return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION); return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION);
} }
@@ -272,9 +270,12 @@ public class WebProject implements Serializable
*/ */
public String getStoreId() public String getStoreId()
{ {
final ServiceRegistry serviceRegistry = this.getServiceRegistry(); if (this.storeId == null)
final NodeService nodeService = serviceRegistry.getNodeService(); {
return (String)nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_AVMSTORE); 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 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<ChildAssociationRef> 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<String, Form> forms = getFormsImpl();
for (Form form : forms.values())
{
if (form.getDefaultWorkflow() != null)
{
this.hasWorkflow = Boolean.TRUE;
break;
}
}
}
}
return this.hasWorkflow.booleanValue();
}
/** /**
* Returns <tt>true</tt> if the user is a manager of this web project. * Returns <tt>true</tt> 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) 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 AVMUtil.ROLE_CONTENT_MANAGER.equals(userrole);
} }
/** /**
* @return the role of this user in the given Web Project, or null for no assigned role * @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;
String userrole = null;
long start = 0;
if (currentUser.isAdmin()) if (LOGGER.isDebugEnabled())
{ {
// fake the Content Manager role for an admin user start = System.currentTimeMillis();
userrole = AVMUtil.ROLE_CONTENT_MANAGER; }
}
else if (user.isAdmin())
{ {
final ServiceRegistry serviceRegistry = WebProject.getServiceRegistry(); // fake the Content Manager role for an admin user
final SearchService searchService = serviceRegistry.getSearchService(); userrole = AVMUtil.ROLE_CONTENT_MANAGER;
final NodeService nodeService = serviceRegistry.getNodeService(); }
else
StringBuilder query = new StringBuilder(128); {
query.append("+PARENT:\"").append(webProjectRef).append("\" "); NodeService nodeService = WebProject.getServiceRegistry().getNodeService();
query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" ");
query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\""); NodeRef roleRef = findUserRoleNodeRef(webProjectRef, user);
query.append(currentUser.getUserName()); if (roleRef != null)
query.append("\""); {
userrole = (String)nodeService.getProperty(roleRef, WCMAppModel.PROP_WEBUSERROLE);
ResultSet resultSet = searchService.query( }
Repository.getStoreRef(), else
SearchService.LANGUAGE_LUCENE, {
query.toString()); LOGGER.warn("getWebProjectUserRole: user role not found for " + user);
List<NodeRef> nodes = resultSet.getNodeRefs(); }
}
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("getWebProjectUserRole: " + user.getUserName() + " " + userrole + " in " + (System.currentTimeMillis()-start) + " ms");
}
return userrole;
}
if (nodes.size() == 1) /**
{ * Perform a Lucene search to return a NodeRef to the node representing the the User Role
userrole = (String)nodeService.getProperty(nodes.get(0), WCMAppModel.PROP_WEBUSERROLE); * within the given WebProject.
} *
else if (nodes.size() == 0) * @param webProjectRef Web Project to search against
{ * @param user User to test against
LOGGER.warn("getWebProjectUserRole: user role not found for " + currentUser); *
} * @return NodeRef of the User Role node or null if none found
else */
{ public static NodeRef findUserRoleNodeRef(NodeRef webProjectRef, User user)
LOGGER.warn("getWebProjectUserRole: more than one user role found for " + currentUser); {
} SearchService searchService = WebProject.getServiceRegistry().getSearchService();
}
StringBuilder query = new StringBuilder(128);
if (LOGGER.isDebugEnabled()) query.append("+PARENT:\"").append(webProjectRef).append("\" ");
{ query.append("+TYPE:\"").append(WCMAppModel.TYPE_WEBUSER).append("\" ");
LOGGER.debug("getWebProjectUserRole: "+currentUser.getUserName()+" "+userrole+" in "+(System.currentTimeMillis()-start)+" ms"); query.append("+@").append(NamespaceService.WCMAPP_MODEL_PREFIX).append("\\:username:\"");
} query.append(user.getUserName());
query.append("\"");
return userrole;
} ResultSet resultSet = searchService.query(
Repository.getStoreRef(),
SearchService.LANGUAGE_LUCENE,
query.toString());
List<NodeRef> nodes = resultSet.getNodeRefs();
return (nodes.size() == 1 ? nodes.get(0) : null);
}
/** /**
* Returns the default webapp for this web project. * 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 * @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 // get the template from the special Content Templates folder
final FacesContext fc = FacesContext.getCurrentInstance(); final FacesContext fc = FacesContext.getCurrentInstance();
@@ -433,7 +484,7 @@ public class WebProject implements Serializable
final List<NodeRef> results = WebProject.getServiceRegistry().getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false); final List<NodeRef> results = WebProject.getServiceRegistry().getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false);
if (results.size() == 1) if (results.size() == 1)
{ {
WebProject.websitesFolderId = results.get(0).getId(); WebProject.websitesFolder = new NodeRef(Repository.getStoreRef(), results.get(0).getId());
} }
else else
{ {
@@ -441,7 +492,7 @@ public class WebProject implements Serializable
} }
} }
return new NodeRef(Repository.getStoreRef(), WebProject.websitesFolderId); return WebProject.websitesFolder;
} }
public static List<WebProject> getWebProjects() public static List<WebProject> getWebProjects()

View File

@@ -28,18 +28,17 @@ import java.io.IOException;
import java.util.List; import java.util.List;
import javax.faces.context.FacesContext; 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.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLock;
import org.alfresco.service.cmr.avm.locking.AVMLockingService; import org.alfresco.service.cmr.avm.locking.AVMLockingService;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.Application; 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.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.bean.wcm.WebProject;
import org.alfresco.web.ui.repo.component.UILockIcon; import org.alfresco.web.ui.repo.component.UILockIcon;
@@ -61,7 +60,6 @@ public class UIAVMLockIcon extends UILockIcon
return ALFRESCO_FACES_AVMLOCKICON; return ALFRESCO_FACES_AVMLOCKICON;
} }
/** /**
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext) * @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 // get the value and see if the image is locked
final AVMService avmService = Repository.getServiceRegistry(context).getAVMService(); final AVMService avmService = Repository.getServiceRegistry(context).getAVMService();
final AVMLockingService avmLockingService = Repository.getServiceRegistry(context).getAVMLockingService(); final AVMLockingService avmLockingService = Repository.getServiceRegistry(context).getAVMLockingService();
final AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME);
boolean locked = false; boolean locked = false;
boolean lockedOwner = false; boolean lockedOwner = false;
Object val = getValue(); Object val = getValue();
@@ -89,14 +88,21 @@ public class UIAVMLockIcon extends UILockIcon
{ {
if (avmService.lookup(-1, avmPath) != null) if (avmService.lookup(-1, avmPath) != null)
{ {
final WebProject webProject = new WebProject(avmPath); // optimization to reuse the current WebProject object if it represents the
final AVMLock lock = avmLockingService.getLock(webProject.getStoreId(), avmPath.substring(avmPath.indexOf("/"))); // 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) if (lock != null)
{ {
locked = true; locked = true;
final User currentUser = Application.getCurrentUser(context);
lockUsers = lock.getOwners(); lockUsers = lock.getOwners();
lockedOwner = (lockUsers.contains(currentUser.getUserName())); lockedOwner = (lockUsers.contains(Application.getCurrentUser(context).getUserName()));
} }
} }
} }

View File

@@ -303,6 +303,8 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
AVMService avmService = getAVMService(context); AVMService avmService = getAVMService(context);
NodeService nodeService = getNodeService(context); NodeService nodeService = getNodeService(context);
PermissionService permissionService = getPermissionService(context); PermissionService permissionService = getPermissionService(context);
AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, AVMBrowseBean.BEAN_NAME);
boolean showAllSandboxes = avmBrowseBean.getShowAllSandboxes();
UserTransaction tx = null; UserTransaction tx = null;
try try
{ {
@@ -317,19 +319,25 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
String storeRoot = (String)nodeService.getProperty(websiteRef, WCMAppModel.PROP_AVMSTORE); String storeRoot = (String)nodeService.getProperty(websiteRef, WCMAppModel.PROP_AVMSTORE);
// find out the current user role in the web project // find out the current user role in the web project
List<ChildAssociationRef> userInfoRefs = nodeService.getChildAssocs(
websiteRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
User currentUser = Application.getCurrentUser(context); User currentUser = Application.getCurrentUser(context);
String currentUserName = currentUser.getUserName(); String currentUserName = currentUser.getUserName();
String currentUserRole = WebProject.getWebProjectUserRole(websiteRef, currentUser); String currentUserRole = WebProject.getWebProjectUserRole(websiteRef, currentUser);
// sort the user list alphabetically and insert the current user at the top of the list // sort the user list alphabetically and insert the current user at the top of the list
List<UserRoleWrapper> userRoleWrappers = buildSortedUserRoles(nodeService, currentUserName, userInfoRefs); List<UserRoleWrapper> userRoleWrappers;
if (showAllSandboxes)
{
List<ChildAssociationRef> 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 // determine whether the check links action should be shown
boolean linkValidationEnabled = true; boolean linkValidationEnabled = true;
AVMBrowseBean avmBrowseBean = (AVMBrowseBean)FacesHelper.getManagedBean(context, "AVMBrowseBean");
if (avmBrowseBean != null) if (avmBrowseBean != null)
{ {
linkValidationEnabled = avmBrowseBean.isLinkValidationEnabled(); linkValidationEnabled = avmBrowseBean.isLinkValidationEnabled();
@@ -366,9 +374,12 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
// check the permissions on this store for the current user // check the permissions on this store for the current user
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Checking user role to view store: " + mainStore); logger.debug("Checking user role to view store: " + mainStore);
if (currentUserName.equals(username) ||
AVMUtil.ROLE_CONTENT_MANAGER.equals(currentUserRole) || if ((showAllSandboxes &&
AVMUtil.ROLE_CONTENT_PUBLISHER.equals(currentUserRole)) (currentUserName.equals(username) ||
AVMUtil.ROLE_CONTENT_MANAGER.equals(currentUserRole) ||
AVMUtil.ROLE_CONTENT_PUBLISHER.equals(currentUserRole))) ||
showAllSandboxes == false)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Building sandbox view for user store: " + mainStore); logger.debug("Building sandbox view for user store: " + mainStore);
@@ -584,7 +595,7 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
"innerwhite"); "innerwhite");
// spacer row // spacer row
if (index++ < userInfoRefs.size() - 1) if (index++ < userRoleWrappers.size() - 1)
{ {
out.write("<div style='padding:4px'></div>"); out.write("<div style='padding:4px'></div>");
} }
@@ -644,6 +655,29 @@ public class UIUserSandboxes extends SelfRenderingComponent implements Serializa
return wrappers; return wrappers;
} }
/**
* Build a list containing one item representing the current user role for the website.
*/
private static List<UserRoleWrapper> buildCurrentUserRole(
NodeService nodeService, NodeRef webProjectRef, User user)
{
// build a list of wrappers to hold the fields we need for each user and role
List<UserRoleWrapper> wrappers = new ArrayList<UserRoleWrapper>(0);
NodeRef userInfoRef = WebProject.findUserRoleNodeRef(webProjectRef, user);
if (userInfoRef != null)
{
wrappers = new ArrayList<UserRoleWrapper>(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. * Render the list of user modified files/folders in the layered sandbox area.

View File

@@ -230,7 +230,16 @@
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td> <td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width=4></td>
<td style="padding:4px"> <td style="padding:4px">
<a:panel id="sandboxes-panel" border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white" styleClass="mainSubTitle" label="#{msg.user_sandboxes}"> <%-- used by the panel to add additional component facets --%>
<h:panelGroup id="sandboxes-panel-facets">
<f:facet name="title">
<h:panelGroup id="sandboxes-panel-facets-wrapper">
<h:selectBooleanCheckbox id="showAllSandboxes" value="#{AVMBrowseBean.showAllSandboxes}" onchange="document.forms['website'].submit(); return true;" immediate="false" />
<h:outputText id="txtShowSandboxes" value="#{msg.website_showallsandboxes}" style="vertical-align:15%" />
</h:panelGroup>
</f:facet>
</h:panelGroup>
<a:panel id="sandboxes-panel" border="white" bgcolor="white" titleBorder="lbgrey" expandedTitleBorder="dotted" titleBgcolor="white" styleClass="mainSubTitle" facetsId="sandboxes-panel-facets" label="#{msg.user_sandboxes}">
<%-- User Sandboxes List --%> <%-- User Sandboxes List --%>
<w:userSandboxes id="sandboxes" binding="#{AVMBrowseBean.userSandboxes}" value="#{AVMBrowseBean.website.nodeRef}" webapp="#{AVMBrowseBean.webapp}" /> <w:userSandboxes id="sandboxes" binding="#{AVMBrowseBean.userSandboxes}" value="#{AVMBrowseBean.website.nodeRef}" webapp="#{AVMBrowseBean.webapp}" />