diff --git a/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.desc.xml new file mode 100644 index 0000000000..fe995ae216 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.desc.xml @@ -0,0 +1,8 @@ + + Apply AVM Custom View + Simple UI to help apply a WebScript based custom view to an AVM folder + /avm/applyavmcustomview + extension + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.html.ftl new file mode 100644 index 0000000000..2dcf2f349a --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.get.html.ftl @@ -0,0 +1,52 @@ + + + + + Apply AVM WebScript Custom View + + + + +
+ +
+ Store: +
e.g. website1--admin
+
+ +
+ Folder Path: +
e.g. /ROOT/images
+
+ +
+ WebScript URL: +
e.g. /utils/avmview
A well known token {path} can be used in the url and will be replaced by the current AVM folder path at runtime.
+
+ +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.desc.xml new file mode 100644 index 0000000000..f8b05a54a3 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.desc.xml @@ -0,0 +1,8 @@ + + Apply AVM Custom View POST + Simple UI to help apply a WebScript based custom view to an AVM folder + /avm/applyavmcustomview + extension + user + required + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.html.ftl b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.html.ftl new file mode 100644 index 0000000000..94508d81ae --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.html.ftl @@ -0,0 +1,19 @@ + + + + Apply AVM WebScript Custom View - Done + + + + <#if success> + Operation Complete. + <#else> + Operation FAILED. Unable to find store or node. + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.js b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.js new file mode 100644 index 0000000000..24ab94c6bd --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/avm/applyavmcustomview.post.js @@ -0,0 +1,27 @@ +// check that search term has been provided +if (args.store == undefined || args.store.length == 0 || + args.path == undefined || args.path.length == 0 || + args.view == undefined || args.view.length == 0) +{ + status.code = 400; + status.message = "Mandatory arguments not set - please complete all form fields."; + status.redirect = true; +} +else +{ + // lookup the root on the store + var storeRootNode = avm.lookupStoreRoot(args.store); + if (storeRootNode != null) + { + var path = storeRootNode.path + args.path; + var node = avm.lookupNode(path); + if (node != null) + { + // add the custom view aspect + node.addAspect("cm:webscriptable"); + node.properties["cm:webscript"] = "/wcs" + args.view; + node.save(); + model.success = true; + } + } +} \ 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 285159bbf8..771574ab66 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -45,6 +45,7 @@ import javax.transaction.UserTransaction; import org.alfresco.config.ConfigElement; import org.alfresco.config.ConfigService; import org.alfresco.linkvalidation.HrefValidationProgress; +import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeType; @@ -59,14 +60,19 @@ import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.service.cmr.repository.FileTypeImageSize; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.repository.TemplateImageResolver; +import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.service.cmr.search.LimitBy; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchParameters; 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.util.Pair; @@ -208,20 +214,23 @@ public class AVMBrowseBean implements IContextListener protected NavigationBean navigator; /** AVM service bean reference */ - transient private AVMService avmService; + transient protected AVMService avmService; /** AVM sync service bean reference */ - transient private AVMSyncService avmSyncService; + transient protected AVMSyncService avmSyncService; /** Action service bean reference */ - transient private ActionService actionService; + transient protected ActionService actionService; /** The FormsService reference */ - transient private FormsService formsService; + transient protected FormsService formsService; /** The SearchService reference */ transient private SearchService searchService; + /** The PermissionService reference */ + transient protected PermissionService permissionService; + /** * Default Constructor @@ -279,6 +288,20 @@ public class AVMBrowseBean implements IContextListener this.nodeService = nodeService; } + /** + * Getter used by the Inline Edit XML JSP + * + * @return The NodeService + */ + public NodeService getNodeService() + { + if (nodeService == null) + { + nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); + } + return nodeService; + } + /** * Set the workflow service * @param service The workflow service instance. @@ -320,17 +343,20 @@ public class AVMBrowseBean implements IContextListener /** - * Getter used by the Inline Edit XML JSP - * - * @return The NodeService + * @param permissionService The PermissionService to set. */ - public NodeService getNodeService() + public void setPermissionService(PermissionService permissionService) { - if (nodeService == null) + this.permissionService = permissionService; + } + + protected PermissionService getPermissionService() + { + if (permissionService == null) { - nodeService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNodeService(); + permissionService = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getPermissionService(); } - return nodeService; + return permissionService; } /** @@ -888,6 +914,90 @@ public class AVMBrowseBean implements IContextListener this.location = location; } + /** + * @return true if the current node has a custom view available + */ + public boolean getHasCustomView() + { + return getHasWebscriptView() || getHasTemplateView(); + } + + /** + * @return true if the current node has a Template based custom view available + */ + public boolean getHasTemplateView() + { + AVMNode node = getCurrentPathNode(); + if (node.hasAspect(ContentModel.ASPECT_TEMPLATABLE)) + { + NodeRef templateRef = (NodeRef)node.getProperties().get(ContentModel.PROP_TEMPLATE); + return (templateRef != null && this.getNodeService().exists(templateRef) && + getPermissionService().hasPermission(templateRef, PermissionService.READ) == AccessStatus.ALLOWED); + } + return false; + } + + /** + * @return true if the current node has a Webscript based custom view available + */ + public boolean getHasWebscriptView() + { + AVMNode node = getCurrentPathNode(); + if (node.hasAspect(ContentModel.ASPECT_WEBSCRIPTABLE)) + { + return (node.getProperties().get(ContentModel.PROP_WEBSCRIPT) != null); + } + return false; + } + + /** + * @return the NodeRef.toString() for the current node Template custom view if it has one + */ + public String getCurrentNodeTemplate() + { + NodeRef ref = (NodeRef)getCurrentPathNode().getProperties().get(ContentModel.PROP_TEMPLATE); + return ref != null ? ref.toString() : null; + } + + /** + * @return the service url for the current node Webscript custom view if it has one + */ + public String getCurrentNodeWebscript() + { + return (String)getCurrentPathNode().getProperties().get(ContentModel.PROP_WEBSCRIPT); + } + + /** + * Returns a model for use by a template on a space Dashboard page. + * + * @return model containing current current space info. + */ + @SuppressWarnings("unchecked") + public Map getTemplateModel() + { + HashMap model = new HashMap(4, 1.0f); + + model.put("space", getCurrentPathNode().getNodeRef()); + model.put("path", getCurrentPathNode().getPath()); + model.put(TemplateService.KEY_IMAGE_RESOLVER, + new TemplateImageResolver() + { + public String resolveImagePathForName(String filename, FileTypeImageSize size) + { + return Utils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size); + } + }); + + return model; + } + + public Map getCustomWebscriptContext() + { + HashMap model = new HashMap(2, 1.0f); + model.put("path", getCurrentPathNode().getPath()); + return model; + } + /** * @return true if the current user has the manager role in the current website */ @@ -915,7 +1025,7 @@ public class AVMBrowseBean implements IContextListener { // see if there are any deployment attempts for the staging area NodeRef webProjectRef = this.getWebsite().getNodeRef(); - String store = (String)nodeService.getProperty(webProjectRef, + String store = (String)getNodeService().getProperty(webProjectRef, WCMAppModel.PROP_AVMSTORE); List deployAttempts = DeploymentUtil.findDeploymentAttempts(store); diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 2dba46c78c..9b9960f16f 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -3395,6 +3395,10 @@ searchService #{SearchService} + + permissionService + #{PermissionService} + diff --git a/source/web/jsp/wcm/browse-sandbox.jsp b/source/web/jsp/wcm/browse-sandbox.jsp index 83d676d2aa..9f51805acb 100644 --- a/source/web/jsp/wcm/browse-sandbox.jsp +++ b/source/web/jsp/wcm/browse-sandbox.jsp @@ -188,6 +188,21 @@ + <%-- Custom Template View --%> + + + + + + + + + + + + + <%-- Details - Folders --%>