. Fix for AWC-555

- Space Selector now no longer attempts to disable spaces that a user cannot read
 - Was assuming Company Home was accessable
. Label change: "Content Templates" now reads "Presentation Templates"
. Fix for DownloadContentServlet to display normal error JSP page if content is deleted before viewing occurs
. Removal of erronous character in SystemErrorTag

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2459 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2006-02-21 19:25:01 +00:00
parent d50e2cf700
commit ad01ff846f
6 changed files with 190 additions and 155 deletions

View File

@@ -158,25 +158,25 @@ public class DownloadContentServlet extends BaseServlet
ContentService contentService = serviceRegistry.getContentService(); ContentService contentService = serviceRegistry.getContentService();
PermissionService permissionService = serviceRegistry.getPermissionService(); PermissionService permissionService = serviceRegistry.getPermissionService();
// check that the user has at least READ_CONTENT access - else redirect to the login page
if (permissionService.hasPermission(nodeRef, PermissionService.READ_CONTENT) == AccessStatus.DENIED)
{
if (logger.isDebugEnabled())
logger.debug("User does not have permissions to read content for NodeRef: " + nodeRef.toString());
redirectToLoginPage(req, res, getServletContext());
return;
}
if (attachment == true)
{
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
// this is better than the default response of the browse trying to display the contents!
// TODO: make this configurable - and check it does not prevent streaming of large files
res.setHeader("Content-Disposition", "attachment;filename=\"" + URLDecoder.decode(filename, "UTF-8") + '"');
}
try try
{ {
// check that the user has at least READ_CONTENT access - else redirect to the login page
if (permissionService.hasPermission(nodeRef, PermissionService.READ_CONTENT) == AccessStatus.DENIED)
{
if (logger.isDebugEnabled())
logger.debug("User does not have permissions to read content for NodeRef: " + nodeRef.toString());
redirectToLoginPage(req, res, getServletContext());
return;
}
if (attachment == true)
{
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
// this is better than the default response of the browse trying to display the contents!
// TODO: make this configurable - and check it does not prevent streaming of large files
res.setHeader("Content-Disposition", "attachment;filename=\"" + URLDecoder.decode(filename, "UTF-8") + '"');
}
// get the content reader // get the content reader
ContentReader reader = contentService.getReader(nodeRef, propertyQName); ContentReader reader = contentService.getReader(nodeRef, propertyQName);
// ensure that it is safe to use // ensure that it is safe to use

View File

@@ -82,9 +82,12 @@ public final class Repository
/** reference to System folder */ /** reference to System folder */
private static NodeRef systemRef = null; private static NodeRef systemRef = null;
/** reference to the namespace service */ /** reference to the NamespaceService */
private static NamespaceService namespaceService = null; private static NamespaceService namespaceService = null;
/** reference to the ServiceRegistry */
private static ServiceRegistry serviceRegistry = null;
/** /**
* Private constructor * Private constructor
*/ */
@@ -411,8 +414,12 @@ public final class Repository
*/ */
public static ServiceRegistry getServiceRegistry(FacesContext context) public static ServiceRegistry getServiceRegistry(FacesContext context)
{ {
return (ServiceRegistry)FacesContextUtils.getRequiredWebApplicationContext( if (serviceRegistry == null)
context).getBean(ServiceRegistry.SERVICE_REGISTRY); {
serviceRegistry = (ServiceRegistry)FacesContextUtils.getRequiredWebApplicationContext(
context).getBean(ServiceRegistry.SERVICE_REGISTRY);
}
return serviceRegistry;
} }
/** /**
@@ -423,8 +430,12 @@ public final class Repository
*/ */
public static ServiceRegistry getServiceRegistry(ServletContext context) public static ServiceRegistry getServiceRegistry(ServletContext context)
{ {
return (ServiceRegistry)WebApplicationContextUtils.getRequiredWebApplicationContext( if (serviceRegistry == null)
context).getBean(ServiceRegistry.SERVICE_REGISTRY); {
serviceRegistry = (ServiceRegistry)WebApplicationContextUtils.getRequiredWebApplicationContext(
context).getBean(ServiceRegistry.SERVICE_REGISTRY);
}
return serviceRegistry;
} }
/** /**

View File

@@ -33,7 +33,6 @@ import javax.faces.event.FacesEvent;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
@@ -79,6 +78,7 @@ public abstract class AbstractItemSelector extends UIInput
/** Flag to show whether the component is disabled */ /** Flag to show whether the component is disabled */
protected Boolean disabled; protected Boolean disabled;
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Component Impl // Component Impl
@@ -117,7 +117,7 @@ public abstract class AbstractItemSelector extends UIInput
* @param context The Faces context * @param context The Faces context
* @return The children * @return The children
*/ */
public abstract Collection<ChildAssociationRef> getChildrenForNode(FacesContext context); public abstract Collection<NodeRef> getChildrenForNode(FacesContext context);
/** /**
* Returns a collection of child associations of the root * Returns a collection of child associations of the root
@@ -125,7 +125,7 @@ public abstract class AbstractItemSelector extends UIInput
* @param context The Faces context * @param context The Faces context
* @return The root options * @return The root options
*/ */
public abstract Collection<ChildAssociationRef> getRootChildren(FacesContext context); public abstract Collection<NodeRef> getRootChildren(FacesContext context);
/** /**
* @return The icon image to display next to the item links, or null for no icon * @return The icon image to display next to the item links, or null for no icon
@@ -240,6 +240,8 @@ public abstract class AbstractItemSelector extends UIInput
return; return;
} }
NodeService service = getNodeService(context);
if (isDisabled()) if (isDisabled())
{ {
// render a read-only view of the selected category (if any) // render a read-only view of the selected category (if any)
@@ -263,13 +265,12 @@ public abstract class AbstractItemSelector extends UIInput
// if there is a value show it's name // if there is a value show it's name
if (nodeRef != null) if (nodeRef != null)
{ {
NodeService service = Repository.getServiceRegistry(context).getNodeService();
out.write(Repository.getNameForNode(service, nodeRef)); out.write(Repository.getNameForNode(service, nodeRef));
} }
} }
else else
{ {
// render an editable control for selecting categories // render an editable control for selecting items
String clientId = getClientId(context); String clientId = getClientId(context);
StringBuilder buf = new StringBuilder(512); StringBuilder buf = new StringBuilder(512);
@@ -327,7 +328,7 @@ public abstract class AbstractItemSelector extends UIInput
} }
else else
{ {
label = Repository.getNameForNode(getNodeService(context), value); label = Repository.getNameForNode(service, value);
showValueInHiddenField = true; showValueInHiddenField = true;
} }
@@ -400,122 +401,95 @@ public abstract class AbstractItemSelector extends UIInput
{ {
// show the picker list // show the picker list
// get the children of the node ref to show // get the children of the node ref to show
NodeService service = getNodeService(context); buf.append("<table border=0 cellspacing=1 cellpadding=1");
if (attrs.get("style") != null)
{
buf.append(" style=\"")
.append(attrs.get("style"))
.append('"');
}
if (attrs.get("styleClass") != null)
{
buf.append(" class=")
.append(attrs.get("styleClass"));
}
buf.append(">");
// if we are setting up the initial selection we need to get the
// parent id of the initial selection so the user can actually see
// the item when the list is rendered
if (this.mode == MODE_INITIAL_SELECTION)
{
this.navigationId = getParentNodeId(context);
}
// render "Go Up" link if not at the root level
if (this.navigationId != null)
{
// get the id of the parent node of the current navigation node,
// null indicates we are at the root level
String id = getParentNodeId(context);
buf.append("<tr><td></td><td>");
String upImage = Utils.buildImageTag(context, WebResources.IMAGE_GO_UP, null, "absmiddle");
// render a link to the parent node
renderNodeLink(context, id, Application.getMessage(context, MSG_GO_UP), upImage, buf);
buf.append("</td></tr>");
}
String okButtonId = clientId + OK_BUTTON;
boolean okButtonEnabled = false;
// display the children of the specified navigation node ID
Collection<NodeRef> childRefs;
if (this.navigationId != null)
{
// get a list of children for the current navigation node
childRefs = getChildrenForNode(context);
}
else
{
// no node set - special case to show the initial root items
childRefs = getRootChildren(context);
}
UserTransaction tx = null; UserTransaction tx = null;
try try
{ {
tx = Repository.getUserTransaction(context, true); tx = Repository.getUserTransaction(context, true);
tx.begin(); tx.begin();
buf.append("<table border=0 cellspacing=1 cellpadding=1"); for (NodeRef childRef : childRefs)
if (attrs.get("style") != null)
{ {
buf.append(" style=\"") // render each child found
.append(attrs.get("style")) String childId = childRef.getId();
.append('"'); buf.append("<tr><td><input type='radio' name='")
} .append(clientId).append(OPTION).append("' value='")
if (attrs.get("styleClass") != null) .append(childId).append("'");
{ if (childId.equals(this.initialSelectionId))
buf.append(" class=") {
.append(attrs.get("styleClass")); buf.append(" checked");
}
buf.append(">");
// if we are setting up the initial selection we need to get the // if any radio buttons are checked, the OK button must start enabled
// parent id of the initial selection so the user can actually see okButtonEnabled = true;
// the item when the list is rendered
if (this.mode == MODE_INITIAL_SELECTION)
{
this.navigationId = getParentNodeId(context);
}
// render "Go Up" link // now remove the initial selection as we only need it the first time
if (this.navigationId != null) this.initialSelectionId = null;
{ }
// get the id of the parent node of the current navigation node, buf.append(" onclick=\"javascript:document.getElementById('")
// null indicates we are at the root level .append(okButtonId)
String id = getParentNodeId(context); .append("').disabled=false;\"");
buf.append("/></td><td>");
buf.append("<tr><td></td><td>"); // get the name for the child and output as link
NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId);
String upImage = Utils.buildImageTag(context, WebResources.IMAGE_GO_UP, null, "absmiddle"); String name = Repository.getNameForNode(service, childNodeRef);
renderNodeLink(context, childId, name, image, buf);
// render a link to the parent node
renderNodeLink(context, id, Application.getMessage(context, MSG_GO_UP), upImage, buf);
buf.append("</td></tr>"); buf.append("</td></tr>");
} }
String okButtonId = clientId + OK_BUTTON;
boolean okButtonEnabled = false;
// display the children of the specified navigation node ID
if (this.navigationId != null)
{
// get a list of children for the current navigation node
Collection<ChildAssociationRef> childRefs = getChildrenForNode(context);
for (ChildAssociationRef childRef : childRefs)
{
// render each child found
String childId = childRef.getChildRef().getId();
buf.append("<tr><td><input type='radio' name='")
.append(clientId).append(OPTION).append("' value='")
.append(childId).append("'");
if (childId.equals(this.initialSelectionId))
{
buf.append(" checked");
// if any radio buttons are checked, the OK button must start enabled
okButtonEnabled = true;
// now remove the initial selection as we only need it the first time
this.initialSelectionId = null;
}
buf.append(" onclick=\"javascript:document.getElementById('")
.append(okButtonId)
.append("').disabled=false;\"");
buf.append("/></td><td>");
// get the name for the child and output as link
NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId);
String name = Repository.getNameForNode(service, childNodeRef);
renderNodeLink(context, childId, name, image, buf);
buf.append("</td></tr>");
}
}
else
{
// no node set - special case so show the root items
Collection<ChildAssociationRef> childRefs = getRootChildren(context);
for (ChildAssociationRef childRef : childRefs)
{
// render each root category found
String childId = childRef.getChildRef().getId();
buf.append("<tr><td><input type='radio' name='")
.append(clientId).append(OPTION).append("' value='")
.append(childId).append("'");
if (childId.equals(this.initialSelectionId))
{
buf.append(" checked");
// if any radio buttons are checked, the OK button must start enabled
okButtonEnabled = true;
// now remove the initial selection as we only need it the first time
this.initialSelectionId = null;
}
buf.append(" onclick=\"javascript:document.getElementById('")
.append(okButtonId)
.append("').disabled=false;\"");
buf.append("/></td><td>");
// get the name for the child (rather than association name)
NodeRef childNodeRef = new NodeRef(Repository.getStoreRef(), childId);
String name = Repository.getNameForNode(service, childNodeRef);
renderNodeLink(context, childId, name, image, buf);
buf.append("</td></tr>");
}
}
// render OK button // render OK button
String fieldValue = encodeFieldValues(MODE_CONFIRM_SELECTION, null); String fieldValue = encodeFieldValues(MODE_CONFIRM_SELECTION, null);
buf.append("<tr style='padding-top:4px'><td></td><td align=center>") buf.append("<tr style='padding-top:4px'><td></td><td align=center>")
@@ -680,6 +654,7 @@ public abstract class AbstractItemSelector extends UIInput
this.disabled = disabled; this.disabled = disabled;
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Protected helpers // Protected helpers

View File

@@ -16,6 +16,7 @@
*/ */
package org.alfresco.web.ui.repo.component; package org.alfresco.web.ui.repo.component;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
@@ -107,14 +108,19 @@ public class UICategorySelector extends AbstractItemSelector
* *
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext) * @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext)
*/ */
public Collection<ChildAssociationRef> getChildrenForNode(FacesContext context) public Collection<NodeRef> getChildrenForNode(FacesContext context)
{ {
NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId); NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId);
Collection<ChildAssociationRef> childRefs = getCategoryService(context).getChildren(nodeRef, Collection<ChildAssociationRef> childRefs = getCategoryService(context).getChildren(nodeRef,
CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE); CategoryService.Mode.SUB_CATEGORIES, CategoryService.Depth.IMMEDIATE);
Collection<NodeRef> refs = new ArrayList<NodeRef>(childRefs.size());
for (ChildAssociationRef childRef : childRefs)
{
refs.add(childRef.getChildRef());
}
return childRefs; return refs;
} }
/** /**
@@ -122,9 +128,17 @@ public class UICategorySelector extends AbstractItemSelector
* *
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext) * @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext)
*/ */
public Collection<ChildAssociationRef> getRootChildren(FacesContext context) public Collection<NodeRef> getRootChildren(FacesContext context)
{ {
return getCategoryService(context).getCategories(Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, Depth.IMMEDIATE); Collection<ChildAssociationRef> childRefs = getCategoryService(context).getCategories(
Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE, Depth.IMMEDIATE);
Collection<NodeRef> refs = new ArrayList<NodeRef>(childRefs.size());
for (ChildAssociationRef childRef : childRefs)
{
refs.add(childRef.getChildRef());
}
return refs;
} }
/** /**

View File

@@ -23,10 +23,13 @@ import java.util.List;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.Repository;
@@ -58,7 +61,8 @@ public class UISpaceSelector extends AbstractItemSelector
} }
/** /**
* Returns the parent id of the current space or null if the parent space is the company home space * Returns the parent id of the current space or null if the parent space is an immediate child
* of the repository root node or the parent is inaccessable due to permissions.
* *
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getParentNodeId(javax.faces.context.FacesContext) * @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getParentNodeId(javax.faces.context.FacesContext)
*/ */
@@ -68,20 +72,47 @@ public class UISpaceSelector extends AbstractItemSelector
if (this.navigationId != null && this.navigationId.equals(Application.getCompanyRootId()) == false) if (this.navigationId != null && this.navigationId.equals(Application.getCompanyRootId()) == false)
{ {
ChildAssociationRef parentRef = getNodeService(context).getPrimaryParent( try
new NodeRef(Repository.getStoreRef(), this.navigationId)); {
id = parentRef.getParentRef().getId(); ChildAssociationRef parentRef = getNodeService(context).getPrimaryParent(
new NodeRef(Repository.getStoreRef(), this.navigationId));
id = parentRef.getParentRef().getId();
}
catch (AccessDeniedException accessErr)
{
// cannot navigate to parent id will be null
}
} }
return id; return id;
} }
/**
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#parentAccessable()
*/
/*public boolean parentAccessable(FacesContext context)
{
boolean accessable = false;
try
{
ChildAssociationRef parentRef = getNodeService(context).getPrimaryParent(
new NodeRef(Repository.getStoreRef(), this.navigationId));
parentRef.getParentRef().getId();
accessable = true;
}
catch (AccessDeniedException accessErr)
{
// cannot navigate to parent id - not accessable
}
return accessable;
}*/
/** /**
* Returns the child spaces of the current space * Returns the child spaces of the current space
* *
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext) * @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getChildrenForNode(javax.faces.context.FacesContext)
*/ */
public Collection<ChildAssociationRef> getChildrenForNode(FacesContext context) public Collection<NodeRef> getChildrenForNode(FacesContext context)
{ {
NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId); NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId);
List<ChildAssociationRef> allKids = getNodeService(context).getChildAssocs(nodeRef, List<ChildAssociationRef> allKids = getNodeService(context).getChildAssocs(nodeRef,
@@ -90,13 +121,13 @@ public class UISpaceSelector extends AbstractItemSelector
NodeService service = getNodeService(context); NodeService service = getNodeService(context);
// filter out those children that are not spaces // filter out those children that are not spaces
List<ChildAssociationRef> spaceKids = new ArrayList<ChildAssociationRef>(); List<NodeRef> spaceKids = new ArrayList<NodeRef>();
for (ChildAssociationRef ref : allKids) for (ChildAssociationRef ref : allKids)
{ {
if (dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_FOLDER) && if (dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_FOLDER) &&
dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_SYSTEM_FOLDER) == false) dd.isSubClass(service.getType(ref.getChildRef()), ContentModel.TYPE_SYSTEM_FOLDER) == false)
{ {
spaceKids.add(ref); spaceKids.add(ref.getChildRef());
} }
} }
@@ -104,21 +135,25 @@ public class UISpaceSelector extends AbstractItemSelector
} }
/** /**
* Returns the current users home space * Returns the children of the initial root space
* *
* @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext) * @see org.alfresco.web.ui.repo.component.AbstractItemSelector#getRootChildren(javax.faces.context.FacesContext)
*/ */
public Collection<ChildAssociationRef> getRootChildren(FacesContext context) public Collection<NodeRef> getRootChildren(FacesContext context)
{ {
// get the root space from the current user
//String rootId = Application.getCurrentUser(context).getHomeSpaceId();
NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId()); NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
// get a child association reference back to the real repository root to satisfy // get a child association reference back from the parent node to satisfy
// the generic API we have in the abstract super class // the generic API we have in the abstract super class
ChildAssociationRef childRefFromRealRoot = getNodeService(context).getPrimaryParent(rootRef); PermissionService ps = Repository.getServiceRegistry(context).getPermissionService();
List<ChildAssociationRef> roots = new ArrayList<ChildAssociationRef>(1); if (ps.hasPermission(rootRef, PermissionService.READ) != AccessStatus.ALLOWED)
roots.add(childRefFromRealRoot); {
// get the root space from the current user home instead
String homeId = Application.getCurrentUser(context).getHomeSpaceId();
rootRef = new NodeRef(Repository.getStoreRef(), homeId);
}
List<NodeRef> roots = new ArrayList<NodeRef>(1);
roots.add(rootRef);
return roots; return roots;
} }

View File

@@ -171,7 +171,7 @@ public class SystemErrorTag extends TagSupport
out.write("} else {\n"); out.write("} else {\n");
out.write("document.getElementById('detailsTitle').innerHTML = '"); out.write("document.getElementById('detailsTitle').innerHTML = '");
out.write(bundle.getString(MSG_SHOW_DETAILS)); out.write(bundle.getString(MSG_SHOW_DETAILS));
out.write(")';\n"); out.write("';\n");
out.write("document.getElementById('details').style.display = 'none';\n"); out.write("document.getElementById('details').style.display = 'none';\n");
out.write("hidden = true;\n"); out.write("hidden = true;\n");
out.write("} } </script>\n"); out.write("} } </script>\n");