From 88512cf711ae0021a0113916ffcae97c61764965 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Tue, 30 Jan 2007 12:06:19 +0000 Subject: [PATCH] . Added cm:name based path support to the UITemplate component - this component is generally used to render FreeMarker templates directly to the page - particularly useful for Dashlet pages - now supports an additional attribute 'templatePath' which should be set to a cm:name based path to a template for rendering - For example the simplest portable dashlet JSP page to render a template would look like this: <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> - Fixes http://issues.alfresco.com/browse/AWC-1091 . Additional helper override for resolving cm:name based webdav style paths to a NodeRef . ClipboardItem interface javadoc and removal of obsolete methods from implementing classes git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4963 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/web/app/servlet/BaseServlet.java | 13 ++ .../bean/clipboard/AbstractClipboardItem.java | 5 - .../web/bean/clipboard/ClipboardItem.java | 34 +++- .../clipboard/WorkspaceClipboardItem.java | 6 +- .../repo/component/template/UITemplate.java | 180 ++++++++++++------ .../alfresco/web/ui/repo/tag/TemplateTag.java | 15 ++ source/web/WEB-INF/repo.tld | 8 +- 7 files changed, 191 insertions(+), 70 deletions(-) diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index 9b7930af6d..9c96c18386 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -208,6 +208,19 @@ public abstract class BaseServlet extends HttpServlet return resolveWebDAVPath(wc, args, true); } + /** + * Resolves the given path elements to a NodeRef in the current repository + * + * @param context Faces context + * @param args The elements of the path to lookup + * @param decode True to decode the arg from UTF-8 format, false for no decoding + */ + public static NodeRef resolveWebDAVPath(FacesContext context, String[] args, boolean decode) + { + WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context); + return resolveWebDAVPath(wc, args, decode); + } + /** * Resolves the given path elements to a NodeRef in the current repository * diff --git a/source/java/org/alfresco/web/bean/clipboard/AbstractClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/AbstractClipboardItem.java index 54e324491b..0849a80ecb 100644 --- a/source/java/org/alfresco/web/bean/clipboard/AbstractClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/AbstractClipboardItem.java @@ -103,11 +103,6 @@ abstract class AbstractClipboardItem implements ClipboardItem return this.icon; } - public String getId() - { - return this.ref.getId(); - } - public NodeRef getNodeRef() { return this.ref; diff --git a/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java index 7e7d80d428..45130dff66 100644 --- a/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/ClipboardItem.java @@ -28,21 +28,51 @@ import org.alfresco.service.namespace.QName; */ public interface ClipboardItem { + /** + * @return the mode status of the clipboard item, the enum can be either Cut or Copy + */ public ClipboardStatus getMode(); + /** + * @return display label (cm:name) of the clipboard item + */ public String getName(); + /** + * @return QName type of the clipboard item + */ public QName getType(); + /** + * @return the app:icon property of the clipboard item + */ public String getIcon(); - public String getId(); - + /** + * @return the NodeRef of the clipboard item + */ public NodeRef getNodeRef(); + /** + * @return true if the item on the clipboard supports linking (.url) as a link type + */ public boolean supportsLink(); + /** + * @param viewId JSF View Id to check against + * + * @return true if the clipboard item can be pasted to the specified JSF view + */ public boolean canPasteToViewId(String viewId); + /** + * @param fc FacesContext + * @param viewId JSF View Id to paste into + * @param action Clipboard action constant (@see org.alfresco.web.ui.repo.component.shelf.UIClipboardShelfItem) + * + * @return true on successful paste, false otherwise + * + * @throws Throwable on fatal error during paste + */ public boolean paste(FacesContext fc, String viewId, int action) throws Throwable; } diff --git a/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java b/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java index 04a35597ae..1a254dd948 100644 --- a/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java +++ b/source/java/org/alfresco/web/bean/clipboard/WorkspaceClipboardItem.java @@ -127,7 +127,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem { // LINK operation if (logger.isDebugEnabled()) - logger.debug("Attempting to link node ID: " + getId() + " into node ID: " + destRef.getId()); + logger.debug("Attempting to link node ID: " + getNodeRef() + " into node: " + destRef.toString()); // we create a special Link Object node that has a property to reference the original // create the node using the nodeService (can only use FileFolderService for content) @@ -178,7 +178,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem { // COPY operation if (logger.isDebugEnabled()) - logger.debug("Attempting to copy node ID: " + getId() + " into node ID: " + destRef.getId()); + logger.debug("Attempting to copy node: " + getNodeRef() + " into node ID: " + destRef.toString()); if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) || dd.isSubClass(getType(), ContentModel.TYPE_FOLDER)) @@ -218,7 +218,7 @@ public class WorkspaceClipboardItem extends AbstractClipboardItem { // MOVE operation if (logger.isDebugEnabled()) - logger.debug("Attempting to move node ID: " + getId() + " into node ID: " + destRef.getId()); + logger.debug("Attempting to move node: " + getNodeRef() + " into node ID: " + destRef.toString()); if (dd.isSubClass(getType(), ContentModel.TYPE_CONTENT) || dd.isSubClass(getType(), ContentModel.TYPE_FOLDER)) diff --git a/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java b/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java index 0c362c3793..a0e53aebaa 100644 --- a/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java +++ b/source/java/org/alfresco/web/ui/repo/component/template/UITemplate.java @@ -18,6 +18,7 @@ package org.alfresco.web.ui.repo.component.template; import java.io.IOException; import java.util.Map; +import java.util.StringTokenizer; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; @@ -29,6 +30,7 @@ import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateService; import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.BaseServlet; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.User; import org.alfresco.web.ui.common.Utils; @@ -36,21 +38,30 @@ import org.alfresco.web.ui.common.component.SelfRenderingComponent; import org.apache.log4j.Logger; /** + * Component responsible for rendering the output of a FreeMarker template directly to the page. + *

+ * FreeMarker templates can be specified as a NodeRef or classpath location. The template output + * will be processed against the default model merged with any custom model reference supplied to + * the component as a value binding attribute. The output of the template is the output of the + * component tag. + * * @author Kevin Roast */ public class UITemplate extends SelfRenderingComponent { private final static String ENGINE_DEFAULT = "freemarker"; - private final static String TEMPLATE_KEY = "_template_"; private static Logger logger = Logger.getLogger(UITemplate.class); /** Template engine name */ private String engine = null; - /** Template name/path */ + /** Template name/classpath */ private String template = null; + /** Template cm:name based path */ + private String templatePath = null; + /** Data model reference */ private Object model = null; @@ -76,7 +87,8 @@ public class UITemplate extends SelfRenderingComponent super.restoreState(context, values[0]); this.engine = (String)values[1]; this.template = (String)values[2]; - this.model = (Object)values[3]; + this.templatePath = (String)values[3]; + this.model = (Object)values[4]; } /** @@ -84,12 +96,8 @@ public class UITemplate extends SelfRenderingComponent */ public Object saveState(FacesContext context) { - Object values[] = new Object[4]; - // standard component attributes are saved by the super class - values[0] = super.saveState(context); - values[1] = this.engine; - values[2] = this.template; - values[3] = this.model; + Object values[] = new Object[] { + super.saveState(context), this.engine, this.template, this.templatePath, this.model}; return (values); } @@ -104,8 +112,30 @@ public class UITemplate extends SelfRenderingComponent } // get the template to process - String template = getTemplate(); - if (template != null && template.length() != 0) + String templateRef = getTemplate(); + if (templateRef == null || templateRef.length() == 0) + { + // no noderef/classpath template found - try a name based path + String path = getTemplatePath(); + if (path != null && path.length() != 0) + { + // convert cm:name based path to a NodeRef + StringTokenizer t = new StringTokenizer(path, "/"); + int tokenCount = t.countTokens(); + String[] elements = new String[tokenCount]; + for (int i=0; i - * By default we return a Map model containing root references to the Company Home Space, - * the users Home Space and the Person Node for the current user. + * Return the custom data model to bind template against. * - * @return Returns the data model to bind template against. + * @return Returns the custom data model to bind template against. */ public Object getModel() { if (this.model == null) { - Object model = null; ValueBinding vb = getValueBinding("model"); if (vb != null) { - model = vb.getValue(getFacesContext()); + this.model = vb.getValue(getFacesContext()); } - - if (getEngine().equals(ENGINE_DEFAULT)) - { - // create an instance of the default FreeMarker template object model - FacesContext fc = FacesContext.getCurrentInstance(); - ServiceRegistry services = Repository.getServiceRegistry(fc); - User user = Application.getCurrentUser(fc); - - // add the template itself to the model - NodeRef templateRef = null; - if (getTemplate().indexOf(StoreRef.URI_FILLER) != -1) - { - // found a noderef template - templateRef = new NodeRef(getTemplate()); - } - - Map root = DefaultModelHelper.buildDefaultModel(services, user, templateRef); - - // merge models - if (model instanceof Map) - { - if (logger.isDebugEnabled()) - logger.debug("Found valid Map model to merge with FreeMarker: " + model); - - root.putAll((Map)model); - } - - model = root; - } - - return model; - } - else - { - return this.model; } + return this.model; } - + /** * @param model The model to set. */ @@ -230,7 +265,7 @@ public class UITemplate extends SelfRenderingComponent } /** - * @return Returns the template name. + * @return Returns the template NodeRef/classpath. */ public String getTemplate() { @@ -249,13 +284,40 @@ public class UITemplate extends SelfRenderingComponent } /** - * @param template The template name to set. + * @param template The template NodeRef/classpath to set. */ public void setTemplate(String template) { this.template = template; } + /** + * @return Returns the template path. + */ + public String getTemplatePath() + { + ValueBinding vb = getValueBinding("templatePath"); + if (vb != null) + { + String val = (String)vb.getValue(getFacesContext()); + if (val != null) + { + this.templatePath = val.toString(); + } + } + + return this.templatePath; + } + + /** + * @param templatePath The template cm:name based path to set. + */ + public void setTemplatePath(String templatePath) + { + this.templatePath = templatePath; + } + + /** Template Image resolver helper */ private TemplateImageResolver imageResolver = new TemplateImageResolver() { diff --git a/source/java/org/alfresco/web/ui/repo/tag/TemplateTag.java b/source/java/org/alfresco/web/ui/repo/tag/TemplateTag.java index a86cff0a95..794d7137f0 100644 --- a/source/java/org/alfresco/web/ui/repo/tag/TemplateTag.java +++ b/source/java/org/alfresco/web/ui/repo/tag/TemplateTag.java @@ -52,6 +52,7 @@ public class TemplateTag extends BaseComponentTag setStringProperty(component, "engine", this.engine); setStringProperty(component, "template", this.template); + setStringProperty(component, "templatePath", this.templatePath); setStringBindingProperty(component, "model", this.model); } @@ -64,6 +65,7 @@ public class TemplateTag extends BaseComponentTag this.engine = null; this.template = null; + this.templatePath = null; this.model = null; } @@ -86,6 +88,16 @@ public class TemplateTag extends BaseComponentTag { this.template = template; } + + /** + * Set the template name based path + * + * @param templatePath the template name based path + */ + public void setTemplatePath(String templatePath) + { + this.templatePath = templatePath; + } /** * Set the data model @@ -98,6 +110,9 @@ public class TemplateTag extends BaseComponentTag } + /** the template name based path */ + private String templatePath; + /** the engine name */ private String engine; diff --git a/source/web/WEB-INF/repo.tld b/source/web/WEB-INF/repo.tld index 49f3b28145..6796c54c5c 100644 --- a/source/web/WEB-INF/repo.tld +++ b/source/web/WEB-INF/repo.tld @@ -1292,7 +1292,13 @@ template - true + false + true + + + + templatePath + false true