From a67dce2f5ed083bc1847b3bf37dc694902989948 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Tue, 19 Dec 2006 17:12:47 +0000 Subject: [PATCH] Merged 1.4 to HEAD (Repository support for Records Management) svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4306 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4307 . svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4485 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4486 . svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4532 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4/root/projects/repository@4533 . svn resolved source\java\org\alfresco\repo\jscript\Node.java svn resolved config\alfresco\action-services-context.xml git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4664 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/action-services-context.xml | 18 ++ config/alfresco/script-services-context.xml | 36 +++ .../action/executer/MailActionExecuter.java | 6 +- .../action/executer/ScriptActionExecuter.java | 48 ++- ...arkerWithLuceneExtensionsModelFactory.java | 2 +- .../org/alfresco/repo/jscript/Actions.java | 274 +---------------- .../alfresco/repo/jscript/CategoryNode.java | 19 +- .../repo/jscript/CategoryTemplateNode.java | 14 +- .../alfresco/repo/jscript/Classification.java | 31 +- .../repo/jscript/ExecuteScriptJob.java | 72 +++++ .../java/org/alfresco/repo/jscript/Node.java | 94 +++--- .../org/alfresco/repo/jscript/People.java | 13 +- .../repo/jscript/RhinoScriptService.java | 49 +-- .../repo/jscript/RhinoScriptTest.java | 10 +- .../alfresco/repo/jscript/ScriptAction.java | 280 ++++++++++++++++++ .../alfresco/repo/jscript/ScriptUtils.java | 27 ++ .../org/alfresco/repo/jscript/Search.java | 62 ++-- .../org/alfresco/repo/jscript/Session.java | 31 +- .../alfresco/repo/jscript/ValueConverter.java | 2 +- .../repo/template/BasePathResultsMap.java | 4 +- .../repo/template/BaseSearchResultsMap.java | 2 +- .../repo/template/Classification.java | 2 +- .../repo/template/FreeMarkerProcessor.java | 8 +- .../template/TemplateServiceImplTest.java | 2 +- .../workflow/jbpm/AlfrescoJavaScript.java | 11 - .../service/cmr/repository/TemplateNode.java | 60 +--- 26 files changed, 633 insertions(+), 544 deletions(-) create mode 100644 source/java/org/alfresco/repo/jscript/ExecuteScriptJob.java create mode 100644 source/java/org/alfresco/repo/jscript/ScriptAction.java diff --git a/config/alfresco/action-services-context.xml b/config/alfresco/action-services-context.xml index 1125fa4c24..37c03ec642 100644 --- a/config/alfresco/action-services-context.xml +++ b/config/alfresco/action-services-context.xml @@ -465,4 +465,22 @@ false + + + + + + + + + + + + + + + + + + diff --git a/config/alfresco/script-services-context.xml b/config/alfresco/script-services-context.xml index 391f625782..fd310cf666 100644 --- a/config/alfresco/script-services-context.xml +++ b/config/alfresco/script-services-context.xml @@ -25,6 +25,9 @@ utils + + + @@ -36,6 +39,30 @@ + + + search + + + + + + ${spaces.store} + + + + + + classification + + + + + + ${spaces.store} + + + people @@ -44,6 +71,15 @@ + + + + session + + + + + diff --git a/source/java/org/alfresco/repo/action/executer/MailActionExecuter.java b/source/java/org/alfresco/repo/action/executer/MailActionExecuter.java index 02df2f1670..dce1a3a68f 100644 --- a/source/java/org/alfresco/repo/action/executer/MailActionExecuter.java +++ b/source/java/org/alfresco/repo/action/executer/MailActionExecuter.java @@ -333,10 +333,10 @@ public class MailActionExecuter extends ActionExecuterAbstractBase Map model = new HashMap(8, 1.0f); NodeRef person = personService.getPerson(authService.getCurrentUserName()); - model.put("person", new TemplateNode(person, serviceRegistry, null)); - model.put("document", new TemplateNode(ref, serviceRegistry, null)); + model.put("person", new TemplateNode(person, serviceRegistry)); + model.put("document", new TemplateNode(ref, serviceRegistry)); NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(ref).getParentRef(); - model.put("space", new TemplateNode(parent, serviceRegistry, null)); + model.put("space", new TemplateNode(parent, serviceRegistry)); // current date/time is useful to have and isn't supplied by FreeMarker by default model.put("date", new Date()); diff --git a/source/java/org/alfresco/repo/action/executer/ScriptActionExecuter.java b/source/java/org/alfresco/repo/action/executer/ScriptActionExecuter.java index 1505941515..d76eb0c585 100644 --- a/source/java/org/alfresco/repo/action/executer/ScriptActionExecuter.java +++ b/source/java/org/alfresco/repo/action/executer/ScriptActionExecuter.java @@ -22,12 +22,14 @@ import java.util.Map; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.jscript.RhinoScriptService; +import org.alfresco.repo.jscript.ScriptAction; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.ScriptLocation; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.PersonService; @@ -47,6 +49,7 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase private PersonService personService; private String companyHomePath; private StoreRef storeRef; + private ScriptLocation scriptLocation; /** * @param serviceRegistry The serviceRegistry to set. @@ -73,6 +76,26 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase { this.companyHomePath = companyHomePath; } + + /** + * Set the script location from Spring + * + * @param scriptLocation the script location + */ + public void setScriptLocation(ScriptLocation scriptLocation) + { + this.scriptLocation = scriptLocation; + } + + /** + * Allow adhoc properties to be passed to this action + * + * @see org.alfresco.repo.action.ParameterizedItemAbstractBase#getAdhocPropertiesAllowed() + */ + protected boolean getAdhocPropertiesAllowed() + { + return true; + } /** * @see org.alfresco.repo.action.executer.ActionExecuterAbstractBase#executeImpl(org.alfresco.service.cmr.action.Action, org.alfresco.service.cmr.repository.NodeRef) @@ -89,7 +112,7 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase spaceRef = nodeService.getPrimaryParent(actionedUponNodeRef).getParentRef(); } - if (nodeService.exists(scriptRef)) + if (this.scriptLocation != null || (scriptRef != null && nodeService.exists(scriptRef) == true)) { // get the references we need to build the default scripting data-model String userName = this.serviceRegistry.getAuthenticationService().getCurrentUserName(); @@ -107,11 +130,23 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase actionedUponNodeRef, spaceRef); - // execute the script against the default model - this.serviceRegistry.getScriptService().executeScript( + // Add the action to the default model + ScriptAction scriptAction = new ScriptAction(this.serviceRegistry, action, this.actionDefinition); + model.put("action", scriptAction); + + if (this.scriptLocation == null) + { + // execute the script against the default model + this.serviceRegistry.getScriptService().executeScript( scriptRef, ContentModel.PROP_CONTENT, model); + } + else + { + // execute the script at the specified script location + this.serviceRegistry.getScriptService().executeScript(this.scriptLocation, model); + } } } } @@ -121,9 +156,14 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase */ protected void addParameterDefinitions(List paramList) { - paramList.add(new ParameterDefinitionImpl(PARAM_SCRIPTREF, DataTypeDefinition.NODE_REF, true, getParamDisplayLabel(PARAM_SCRIPTREF))); + paramList.add(new ParameterDefinitionImpl(PARAM_SCRIPTREF, DataTypeDefinition.NODE_REF, false, getParamDisplayLabel(PARAM_SCRIPTREF))); } + /** + * Gets the company home node + * + * @return the company home node ref + */ private NodeRef getCompanyHome() { NodeRef companyHomeRef; diff --git a/source/java/org/alfresco/repo/action/scheduled/FreeMarkerWithLuceneExtensionsModelFactory.java b/source/java/org/alfresco/repo/action/scheduled/FreeMarkerWithLuceneExtensionsModelFactory.java index a38dd4d49a..e2f5f19edf 100644 --- a/source/java/org/alfresco/repo/action/scheduled/FreeMarkerWithLuceneExtensionsModelFactory.java +++ b/source/java/org/alfresco/repo/action/scheduled/FreeMarkerWithLuceneExtensionsModelFactory.java @@ -104,7 +104,7 @@ public class FreeMarkerWithLuceneExtensionsModelFactory implements TemplateActio { Map model = getModel(); - TemplateNode companyRootNode = new TemplateNode(nodeRef, serviceRegistry, null); + TemplateNode companyRootNode = new TemplateNode(nodeRef, serviceRegistry); model.put("node", companyRootNode); return model; diff --git a/source/java/org/alfresco/repo/jscript/Actions.java b/source/java/org/alfresco/repo/jscript/Actions.java index a0f4734e97..51d0f28989 100644 --- a/source/java/org/alfresco/repo/jscript/Actions.java +++ b/source/java/org/alfresco/repo/jscript/Actions.java @@ -16,19 +16,13 @@ */ package org.alfresco.repo.jscript; -import java.io.Serializable; import java.util.List; -import java.util.Map; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.action.ParameterDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.namespace.QName; import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.Wrapper; /** * Scripted Action service for describing and executing actions against Nodes. @@ -99,274 +93,10 @@ public final class Actions extends BaseScriptImplementation implements Scopeable if (actionDef != null) { Action action = actionService.createAction(actionName); - scriptAction = new ScriptAction(action, actionDef); + scriptAction = new ScriptAction(this.services, action, actionDef); scriptAction.setScope(scope); } return scriptAction; - } - - /** - * Scriptable Action - * - * @author davidc - */ - public final class ScriptAction implements Serializable, Scopeable - { - private static final long serialVersionUID = 5794161358406531996L; - - /** Root scope for this object */ - private Scriptable scope; - - /** Converter with knowledge of action parameter values */ - private ActionValueConverter converter; - - /** Action state */ - private Action action; - - private ActionDefinition actionDef; - - private ScriptableParameterMap parameters = null; - - /** - * Construct - * - * @param action - * Alfresco action - */ - public ScriptAction(Action action, ActionDefinition actionDef) - { - this.action = action; - this.actionDef = actionDef; - this.converter = new ActionValueConverter(); - } - - /** - * @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable) - */ - public void setScope(Scriptable scope) - { - this.scope = scope; - } - - /** - * Returns the action name - * - * @return action name - */ - public String getName() - { - return this.actionDef.getName(); - } - - public String jsGet_name() - { - return getName(); - } - - /** - * Return all the properties known about this node. The Map returned implements the Scriptable interface to allow access to the properties via JavaScript associative array - * access. This means properties of a node can be access thus: node.properties["name"] - * - * @return Map of properties for this Node. - */ - @SuppressWarnings("synthetic-access") - public Map getParameters() - { - if (this.parameters == null) - { - // this Map implements the Scriptable interface for native JS syntax property access - this.parameters = new ScriptableParameterMap(); - Map actionParams = this.action.getParameterValues(); - for (Map.Entry entry : actionParams.entrySet()) - { - String name = entry.getKey(); - this.parameters.put(name, converter.convertActionParamForScript(name, entry.getValue())); - } - this.parameters.setModified(false); - } - return this.parameters; - } - - public Map jsGet_parameters() - { - return getParameters(); - } - - /** - * Execute action - * - * @param node - * the node to execute action upon - */ - @SuppressWarnings("synthetic-access") - public void execute(Node node) - { - if (this.parameters != null && this.parameters.isModified()) - { - Map actionParams = action.getParameterValues(); - actionParams.clear(); - - for (Map.Entry entry : this.parameters.entrySet()) - { - // perform the conversion from script wrapper object to repo serializable values - String name = entry.getKey(); - Serializable value = converter.convertActionParamForRepo(name, entry.getValue()); - actionParams.put(name, value); - } - } - services.getActionService().executeAction(action, node.getNodeRef()); - - // Reset the actioned upon node - node.reset(); - } - - /** - * Value converter with specific knowledge of action parameters - * - * @author davidc - */ - private class ActionValueConverter extends ValueConverter - { - /** - * Convert Action Parameter for Script usage - * - * @param paramName - * parameter name - * @param value - * value to convert - * @return converted value - */ - @SuppressWarnings("synthetic-access") - public Serializable convertActionParamForScript(String paramName, Serializable value) - { - ParameterDefinition paramDef = actionDef.getParameterDefintion(paramName); - if (paramDef != null && paramDef.getType().equals(DataTypeDefinition.QNAME)) - { - return ((QName) value).toPrefixString(services.getNamespaceService()); - } - else - { - return convertValueForScript(services, scope, null, value); - } - } - - /** - * Convert Action Parameter for Java usage - * - * @param paramName - * parameter name - * @param value - * value to convert - * @return converted value - */ - @SuppressWarnings("synthetic-access") - public Serializable convertActionParamForRepo(String paramName, Serializable value) - { - ParameterDefinition paramDef = actionDef.getParameterDefintion(paramName); - - if (paramDef != null && paramDef.getType().equals(DataTypeDefinition.QNAME)) - { - if (value instanceof Wrapper) - { - // unwrap a Java object from a JavaScript wrapper - // recursively call this method to convert the unwrapped value - return convertActionParamForRepo(paramName, (Serializable) ((Wrapper) value).unwrap()); - } - else - { - if (value instanceof String) - { - String stringQName = (String) value; - if (stringQName.startsWith("{")) - { - return QName.createQName(stringQName); - - } - else - { - return QName.createQName(stringQName, services.getNamespaceService()); - } - } - else - { - return value; - } - } - } - else - { - return convertValueForRepo(value); - } - } - } - } - - /** - * Scripted Parameter map with modified flag. - * - * @author davidc - */ - public static final class ScriptableParameterMap extends ScriptableHashMap - { - private static final long serialVersionUID = 574661815973241554L; - - private boolean modified = false; - - /** - * Is this a modified parameter map? - * - * @return true => modified - */ - /* package */boolean isModified() - { - return modified; - } - - /** - * Set explicitly whether this map is modified - * - * @param modified - * true => modified, false => not modified - */ - /* package */void setModified(boolean modified) - { - this.modified = modified; - } - - /* - * (non-Javadoc) - * - * @see org.mozilla.javascript.Scriptable#getClassName() - */ - @Override - public String getClassName() - { - return "ScriptableParameterMap"; - } - - /* - * (non-Javadoc) - * - * @see org.mozilla.javascript.Scriptable#delete(java.lang.String) - */ - @Override - public void delete(String name) - { - super.delete(name); - setModified(true); - } - - /* - * (non-Javadoc) - * - * @see org.mozilla.javascript.Scriptable#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object) - */ - @Override - public void put(String name, Scriptable start, Object value) - { - super.put(name, start, value); - setModified(true); - } - } + } } diff --git a/source/java/org/alfresco/repo/jscript/CategoryNode.java b/source/java/org/alfresco/repo/jscript/CategoryNode.java index a22183ba61..6f76b5df7a 100644 --- a/source/java/org/alfresco/repo/jscript/CategoryNode.java +++ b/source/java/org/alfresco/repo/jscript/CategoryNode.java @@ -22,7 +22,6 @@ import org.alfresco.model.ContentModel; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.namespace.QName; import org.mozilla.javascript.Scriptable; @@ -41,9 +40,9 @@ public class CategoryNode extends Node * @param services * @param resolver */ - public CategoryNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver) + public CategoryNode(NodeRef nodeRef, ServiceRegistry services) { - super(nodeRef, services, resolver); + super(nodeRef, services); } /** @@ -54,9 +53,9 @@ public class CategoryNode extends Node * @param resolver * @param scope */ - public CategoryNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver, Scriptable scope) + public CategoryNode(NodeRef nodeRef, ServiceRegistry services, Scriptable scope) { - super(nodeRef, services, resolver, scope); + super(nodeRef, services, scope); } /** @@ -146,7 +145,7 @@ public class CategoryNode extends Node */ public CategoryNode createSubCategory(String name) { - return new CategoryNode(services.getCategoryService().createCategory(getNodeRef(), name), this.services, this.imageResolver, this.scope); + return new CategoryNode(services.getCategoryService().createCategory(getNodeRef(), name), this.services, this.scope); } /** @@ -169,7 +168,7 @@ public class CategoryNode extends Node int i = 0; for (ChildAssociationRef car : cars) { - categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.imageResolver, this.scope); + categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.scope); } return categoryNodes; } @@ -180,7 +179,7 @@ public class CategoryNode extends Node int i = 0; for (ChildAssociationRef car : cars) { - nodes[i++] = new Node(car.getChildRef(), this.services, this.imageResolver, this.scope); + nodes[i++] = new Node(car.getChildRef(), this.services, this.scope); } return nodes; } @@ -194,11 +193,11 @@ public class CategoryNode extends Node QName type = services.getNodeService().getType(car.getChildRef()); if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY)) { - nodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.imageResolver, this.scope); + nodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.scope); } else { - nodes[i++] = new Node(car.getChildRef(), this.services, this.imageResolver, this.scope); + nodes[i++] = new Node(car.getChildRef(), this.services, this.scope); } } return nodes; diff --git a/source/java/org/alfresco/repo/jscript/CategoryTemplateNode.java b/source/java/org/alfresco/repo/jscript/CategoryTemplateNode.java index 5f0efa84df..bf099ae3a0 100644 --- a/source/java/org/alfresco/repo/jscript/CategoryTemplateNode.java +++ b/source/java/org/alfresco/repo/jscript/CategoryTemplateNode.java @@ -25,7 +25,6 @@ import org.alfresco.model.ContentModel; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.namespace.QName; @@ -44,9 +43,9 @@ public class CategoryTemplateNode extends TemplateNode * @param services * @param resolver */ - public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver) + public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services) { - super(nodeRef, services, resolver); + super(nodeRef, services); } @Override @@ -165,7 +164,7 @@ public class CategoryTemplateNode extends TemplateNode for (ChildAssociationRef ref : childRefs) { // create our Node representation from the NodeRef - TemplateNode child = new TemplateNode(ref.getChildRef(), this.services, this.imageResolver); + TemplateNode child = new TemplateNode(ref.getChildRef(), this.services); answer.add(child); } return answer; @@ -177,7 +176,7 @@ public class CategoryTemplateNode extends TemplateNode for (ChildAssociationRef ref : childRefs) { // create our Node representation from the NodeRef - CategoryTemplateNode child = new CategoryTemplateNode(ref.getChildRef(), this.services, this.imageResolver); + CategoryTemplateNode child = new CategoryTemplateNode(ref.getChildRef(), this.services); answer.add(child); } return answer; @@ -186,17 +185,16 @@ public class CategoryTemplateNode extends TemplateNode private List buildMixedNodeList(Collection cars) { List nodes = new ArrayList(cars.size()); - int i = 0; for (ChildAssociationRef car : cars) { QName type = services.getNodeService().getType(car.getChildRef()); if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY)) { - nodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver)); + nodes.add(new CategoryTemplateNode(car.getChildRef(), this.services)); } else { - nodes.add(new TemplateNode(car.getChildRef(), this.services, this.imageResolver)); + nodes.add(new TemplateNode(car.getChildRef(), this.services)); } } return nodes; diff --git a/source/java/org/alfresco/repo/jscript/Classification.java b/source/java/org/alfresco/repo/jscript/Classification.java index c093bf630d..f8e044d711 100644 --- a/source/java/org/alfresco/repo/jscript/Classification.java +++ b/source/java/org/alfresco/repo/jscript/Classification.java @@ -21,11 +21,8 @@ import java.util.Collection; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.namespace.QName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.mozilla.javascript.Scriptable; /** @@ -33,23 +30,33 @@ import org.mozilla.javascript.Scriptable; * * @author Andy Hind */ -public final class Classification implements Scopeable +public final class Classification extends BaseScriptImplementation implements Scopeable { @SuppressWarnings("unused") private Scriptable scope; private ServiceRegistry services; - @SuppressWarnings("unused") - private TemplateImageResolver imageResolver; - private StoreRef storeRef; - - public Classification(ServiceRegistry services, StoreRef storeRef, TemplateImageResolver imageResolver) + + /** + * Set the default store reference + * + * @param storeRef the default store reference + */ + public void setStoreUrl(String storeRef) + { + this.storeRef = new StoreRef(storeRef); + } + + /** + * Set the service registry + * + * @param services the service registry + */ + public void setServiceRegistry(ServiceRegistry services) { this.services = services; - this.imageResolver = imageResolver; - this.storeRef = storeRef; } /** @@ -122,7 +129,7 @@ public final class Classification implements Scopeable int i = 0; for (ChildAssociationRef car : cars) { - categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.imageResolver, this.scope); + categoryNodes[i++] = new CategoryNode(car.getChildRef(), this.services, this.scope); } return categoryNodes; } diff --git a/source/java/org/alfresco/repo/jscript/ExecuteScriptJob.java b/source/java/org/alfresco/repo/jscript/ExecuteScriptJob.java new file mode 100644 index 0000000000..1688950952 --- /dev/null +++ b/source/java/org/alfresco/repo/jscript/ExecuteScriptJob.java @@ -0,0 +1,72 @@ +/** + * + */ +package org.alfresco.repo.jscript; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.repo.security.authentication.AuthenticationComponent; +import org.alfresco.service.cmr.repository.ScriptLocation; +import org.alfresco.service.cmr.repository.ScriptService; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; + +/** + * Quartz job that executes a scheduled JS script. + * + * @author Roy Wetherall + */ +public class ExecuteScriptJob implements Job +{ + private static final String PARAM_SCRIPT_LOCATION = "scriptLocation"; + private static final String PARAM_SCRIPT_SERVICE = "scriptService"; + private static final String PARAM_AUTHENTICATION_COMPONENT = "authenticationComponent"; + + /** + * Executes the scheduled script + * + * @see org.quartz.Job#execute(org.quartz.JobExecutionContext) + */ + public void execute(JobExecutionContext context) throws JobExecutionException + { + JobDataMap jobData = context.getJobDetail().getJobDataMap(); + + // Get the script service from the job map + Object scriptServiceObj = jobData.get(PARAM_SCRIPT_SERVICE); + if (scriptServiceObj == null || !(scriptServiceObj instanceof ScriptService)) + { + throw new AlfrescoRuntimeException( + "ExecuteScriptJob data must contain valid script service"); + } + + // Get the script location from the job map + Object scriptLocationObj = jobData.get(PARAM_SCRIPT_LOCATION); + if (scriptLocationObj == null || !(scriptLocationObj instanceof ScriptLocation)) + { + throw new AlfrescoRuntimeException( + "ExecuteScriptJob data must contain valid script location"); + } + + // Get the authentication component from the job map + Object authenticationComponentObj = jobData.get(PARAM_AUTHENTICATION_COMPONENT); + if (authenticationComponentObj == null || !(authenticationComponentObj instanceof AuthenticationComponent)) + { + throw new AlfrescoRuntimeException( + "ExecuteScriptJob data must contain valid authentication component"); + } + + + // Execute the script as the system user + ((AuthenticationComponent)authenticationComponentObj).setSystemUserAsCurrentUser(); + try + { + // Execute the script + ((ScriptService)scriptServiceObj).executeScript((ScriptLocation)scriptLocationObj, null); + } + finally + { + ((AuthenticationComponent)authenticationComponentObj).clearCurrentSecurityContext(); + } + } +} diff --git a/source/java/org/alfresco/repo/jscript/Node.java b/source/java/org/alfresco/repo/jscript/Node.java index 3b000ff2fc..2dafdffe01 100644 --- a/source/java/org/alfresco/repo/jscript/Node.java +++ b/source/java/org/alfresco/repo/jscript/Node.java @@ -49,7 +49,6 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NoTransformerException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.PermissionService; @@ -148,9 +147,9 @@ public class Node implements Serializable, Scopeable * @param resolver * Image resolver to use to retrieve icons */ - public Node(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver) + public Node(NodeRef nodeRef, ServiceRegistry services) { - this(nodeRef, services, resolver, null); + this(nodeRef, services, null); } /** @@ -165,7 +164,7 @@ public class Node implements Serializable, Scopeable * @param scope * Root scope for this Node */ - public Node(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver, Scriptable scope) + public Node(NodeRef nodeRef, ServiceRegistry services, Scriptable scope) { if (nodeRef == null) { @@ -181,7 +180,6 @@ public class Node implements Serializable, Scopeable this.id = nodeRef.getId(); this.services = services; this.nodeService = services.getNodeService(); - this.imageResolver = resolver; this.scope = scope; } @@ -404,6 +402,7 @@ public class Node implements Serializable, Scopeable * * @return associations as a Map of assoc name to an Array of Nodes. */ + @SuppressWarnings("unchecked") public Map getAssocs() { if (this.assocs == null) @@ -448,6 +447,7 @@ public class Node implements Serializable, Scopeable * * @return Map of properties for this Node. */ + @SuppressWarnings("unchecked") public Map getProperties() { if (this.properties == null) @@ -614,21 +614,7 @@ public class Node implements Serializable, Scopeable */ public String getIcon16() { - if (this.imageResolver != null) - { - if (getIsDocument()) - { - return this.imageResolver.resolveImagePathForName(getName(), true); - } - else - { - return "/images/icons/space_small.gif"; - } - } - else - { - return "/images/filetypes/_default.gif"; - } + return "/images/filetypes/_default.gif"; } public String jsGet_icon16() @@ -641,29 +627,7 @@ public class Node implements Serializable, Scopeable */ public String getIcon32() { - if (this.imageResolver != null) - { - if (getIsDocument()) - { - return this.imageResolver.resolveImagePathForName(getName(), false); - } - else - { - String icon = (String) getProperties().get("app:icon"); - if (icon != null) - { - return "/images/icons/" + icon + ".gif"; - } - else - { - return "/images/icons/space-icon-default.gif"; - } - } - } - else - { - return "/images/filetypes32/_default.gif"; - } + return "/images/filetypes32/_default.gif"; } public String jsGet_icon32() @@ -876,14 +840,6 @@ public class Node implements Serializable, Scopeable return getSize(); } - /** - * @return the image resolver instance used by this node - */ - public TemplateImageResolver getImageResolver() - { - return this.imageResolver; - } - // ------------------------------------------------------------------------------ // Security API @@ -1333,6 +1289,30 @@ public class Node implements Serializable, Scopeable return success; } + + /** + * Remove aspect from the node. + * + * @param type the aspect type + * @return true if successful, false otherwise + */ + public boolean removeAspect(String type) + { + boolean success = false; + + if (type != null && type.length() != 0) + { + QName aspectQName = createQName(type); + this.nodeService.removeAspect(this.nodeRef, aspectQName); + + // reset the relevant cached node members + reset(); + + success = true; + } + + return success; + } // ------------------------------------------------------------------------------ // Checkout/Checkin Services @@ -1679,19 +1659,17 @@ public class Node implements Serializable, Scopeable // build default model for the template processing Map model = FreeMarkerProcessor.buildDefaultModel(services, ((Node) ((Wrapper) scope.get( "person", scope)).unwrap()).getNodeRef(), ((Node) ((Wrapper) scope.get("companyhome", scope)).unwrap()) - .getNodeRef(), ((Node) ((Wrapper) scope.get("userhome", scope)).unwrap()).getNodeRef(), templateRef, - this.imageResolver); + .getNodeRef(), ((Node) ((Wrapper) scope.get("userhome", scope)).unwrap()).getNodeRef(), templateRef, null); // add the current node as either the document/space as appropriate if (this.getIsDocument()) { - model.put("document", new TemplateNode(this.nodeRef, this.services, this.imageResolver)); - model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services, - this.imageResolver)); + model.put("document", new TemplateNode(this.nodeRef, this.services)); + model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services)); } else { - model.put("space", new TemplateNode(this.nodeRef, this.services, this.imageResolver)); + model.put("space", new TemplateNode(this.nodeRef, this.services)); } // add the supplied args to the 'args' root object @@ -1935,6 +1913,8 @@ public class Node implements Serializable, Scopeable */ public class ScriptContentData implements Serializable { + private static final long serialVersionUID = -7819328543933312278L; + /** * Constructor * diff --git a/source/java/org/alfresco/repo/jscript/People.java b/source/java/org/alfresco/repo/jscript/People.java index 6f85360604..cd4ae29534 100644 --- a/source/java/org/alfresco/repo/jscript/People.java +++ b/source/java/org/alfresco/repo/jscript/People.java @@ -16,21 +16,10 @@ */ package org.alfresco.repo.jscript; -import java.io.Serializable; -import java.util.List; -import java.util.Map; - import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.action.Action; -import org.alfresco.service.cmr.action.ActionDefinition; -import org.alfresco.service.cmr.action.ActionService; -import org.alfresco.service.cmr.action.ParameterDefinition; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.namespace.QName; import org.mozilla.javascript.Scriptable; -import org.mozilla.javascript.Wrapper; /** * Scripted People service for describing and executing actions against People & Groups. @@ -75,7 +64,7 @@ public final class People extends BaseScriptImplementation implements Scopeable if (personService.personExists(username)) { NodeRef personRef = personService.getPerson(username); - person = new Node(personRef, services, null, scope); + person = new Node(personRef, services, scope); } return person; } diff --git a/source/java/org/alfresco/repo/jscript/RhinoScriptService.java b/source/java/org/alfresco/repo/jscript/RhinoScriptService.java index a0debb0b6f..0caeb8c352 100644 --- a/source/java/org/alfresco/repo/jscript/RhinoScriptService.java +++ b/source/java/org/alfresco/repo/jscript/RhinoScriptService.java @@ -36,7 +36,6 @@ import org.alfresco.service.cmr.repository.ScriptImplementation; import org.alfresco.service.cmr.repository.ScriptLocation; import org.alfresco.service.cmr.repository.ScriptImplementation; import org.alfresco.service.cmr.repository.ScriptService; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.namespace.QName; import org.alfresco.util.ParameterCheck; import org.apache.log4j.Logger; @@ -315,33 +314,6 @@ public class RhinoScriptService implements ScriptService } } - /** - * Create the default data-model available to scripts as global scope level objects: - *

- * 'companyhome' - the Company Home node
- * 'userhome' - the current user home space node
- * 'person' - the node representing the current user Person
- * 'document' - document context node (may not be available)
- * 'space' - space context node (may not be available) - * - * @param services ServiceRegistry - * @param person The current user Person Node - * @param companyHome The CompanyHome ref - * @param userHome The User home space ref - * @param script Optional ref to the script itself - * @param document Optional ref to a document Node - * @param space Optional ref to a space Node - * - * @return A Map of global scope scriptable Node objects - */ - public static Map buildDefaultModel( - ServiceRegistry services, - NodeRef person, NodeRef companyHome, NodeRef userHome, - NodeRef script, NodeRef document, NodeRef space) - { - return buildDefaultModel(services, person, companyHome, userHome, script, document, space, null); - } - /** * Create the default data-model available to scripts as global scope level objects: *

@@ -366,34 +338,27 @@ public class RhinoScriptService implements ScriptService public static Map buildDefaultModel( ServiceRegistry services, NodeRef person, NodeRef companyHome, NodeRef userHome, - NodeRef script, NodeRef document, NodeRef space, - TemplateImageResolver resolver) + NodeRef script, NodeRef document, NodeRef space) { Map model = new HashMap(); // add the well known node wrapper objects - model.put("companyhome", new Node(companyHome, services, resolver)); - model.put("userhome", new Node(userHome, services, resolver)); - model.put("person", new Node(person, services, resolver)); + model.put("companyhome", new Node(companyHome, services)); + model.put("userhome", new Node(userHome, services)); + model.put("person", new Node(person, services)); if (script != null) { - model.put("script", new Node(script, services, resolver)); + model.put("script", new Node(script, services)); } if (document != null) { - model.put("document", new Node(document, services, resolver)); + model.put("document", new Node(document, services)); } if (space != null) { - model.put("space", new Node(space, services, resolver)); + model.put("space", new Node(space, services)); } - model.put("search", new Search(services, companyHome.getStoreRef(), resolver)); - - model.put("session", new Session(services, resolver)); - - model.put("classification", new Classification(services, companyHome.getStoreRef(), resolver)); - return model; } } diff --git a/source/java/org/alfresco/repo/jscript/RhinoScriptTest.java b/source/java/org/alfresco/repo/jscript/RhinoScriptTest.java index 76f26d93af..98e57597ee 100644 --- a/source/java/org/alfresco/repo/jscript/RhinoScriptTest.java +++ b/source/java/org/alfresco/repo/jscript/RhinoScriptTest.java @@ -67,11 +67,11 @@ public class RhinoScriptTest extends TestCase { super.setUp(); - transactionService = (TransactionService)this.ctx.getBean("transactionComponent"); - contentService = (ContentService)this.ctx.getBean("contentService"); - nodeService = (NodeService)this.ctx.getBean("nodeService"); - scriptService = (ScriptService)this.ctx.getBean("scriptService"); - serviceRegistry = (ServiceRegistry)this.ctx.getBean("ServiceRegistry"); + transactionService = (TransactionService)ctx.getBean("transactionComponent"); + contentService = (ContentService)ctx.getBean("contentService"); + nodeService = (NodeService)ctx.getBean("nodeService"); + scriptService = (ScriptService)ctx.getBean("scriptService"); + serviceRegistry = (ServiceRegistry)ctx.getBean("ServiceRegistry"); this.authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent"); this.authenticationComponent.setSystemUserAsCurrentUser(); diff --git a/source/java/org/alfresco/repo/jscript/ScriptAction.java b/source/java/org/alfresco/repo/jscript/ScriptAction.java new file mode 100644 index 0000000000..43b8d246f2 --- /dev/null +++ b/source/java/org/alfresco/repo/jscript/ScriptAction.java @@ -0,0 +1,280 @@ +package org.alfresco.repo.jscript; + +import java.io.Serializable; +import java.util.Map; + +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.action.ActionDefinition; +import org.alfresco.service.cmr.action.ParameterDefinition; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.namespace.QName; +import org.mozilla.javascript.Scriptable; +import org.mozilla.javascript.Wrapper; + +/** + * Scriptable Action + * + * @author davidc + */ +public final class ScriptAction implements Serializable, Scopeable +{ + private static final long serialVersionUID = 5794161358406531996L; + + /** Root scope for this object */ + private Scriptable scope; + + /** Converter with knowledge of action parameter values */ + private ActionValueConverter converter; + + private ServiceRegistry services; + + /** Action state */ + private Action action; + + private ActionDefinition actionDef; + + private ScriptableParameterMap parameters = null; + + /** + * Construct + * + * @param action + * Alfresco action + */ + public ScriptAction(ServiceRegistry services, Action action, ActionDefinition actionDef) + { + this.services = services; + this.action = action; + this.actionDef = actionDef; + this.converter = new ActionValueConverter(); + } + + /** + * @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable) + */ + public void setScope(Scriptable scope) + { + this.scope = scope; + } + + /** + * Returns the action name + * + * @return action name + */ + public String getName() + { + return this.actionDef.getName(); + } + + public String jsGet_name() + { + return getName(); + } + + /** + * Return all the properties known about this node. The Map returned implements the Scriptable interface to allow access to the properties via JavaScript associative array + * access. This means properties of a node can be access thus: node.properties["name"] + * + * @return Map of properties for this Node. + */ + @SuppressWarnings("synthetic-access") + public Map getParameters() + { + if (this.parameters == null) + { + // this Map implements the Scriptable interface for native JS syntax property access + this.parameters = new ScriptableParameterMap(); + Map actionParams = this.action.getParameterValues(); + for (Map.Entry entry : actionParams.entrySet()) + { + String name = entry.getKey(); + this.parameters.put(name, converter.convertActionParamForScript(name, entry.getValue())); + } + this.parameters.setModified(false); + } + return this.parameters; + } + + public Map jsGet_parameters() + { + return getParameters(); + } + + /** + * Execute action + * + * @param node + * the node to execute action upon + */ + @SuppressWarnings("synthetic-access") + public void execute(Node node) + { + if (this.parameters != null && this.parameters.isModified()) + { + Map actionParams = action.getParameterValues(); + actionParams.clear(); + + for (Map.Entry entry : this.parameters.entrySet()) + { + // perform the conversion from script wrapper object to repo serializable values + String name = entry.getKey(); + Serializable value = converter.convertActionParamForRepo(name, entry.getValue()); + actionParams.put(name, value); + } + } + services.getActionService().executeAction(action, node.getNodeRef()); + + // Reset the actioned upon node + node.reset(); + } + + /** + * Value converter with specific knowledge of action parameters + * + * @author davidc + */ + private class ActionValueConverter extends ValueConverter + { + /** + * Convert Action Parameter for Script usage + * + * @param paramName + * parameter name + * @param value + * value to convert + * @return converted value + */ + @SuppressWarnings("synthetic-access") + public Serializable convertActionParamForScript(String paramName, Serializable value) + { + ParameterDefinition paramDef = actionDef.getParameterDefintion(paramName); + if (paramDef != null && paramDef.getType().equals(DataTypeDefinition.QNAME)) + { + return ((QName) value).toPrefixString(services.getNamespaceService()); + } + else + { + return convertValueForScript(services, scope, null, value); + } + } + + /** + * Convert Action Parameter for Java usage + * + * @param paramName + * parameter name + * @param value + * value to convert + * @return converted value + */ + @SuppressWarnings("synthetic-access") + public Serializable convertActionParamForRepo(String paramName, Serializable value) + { + ParameterDefinition paramDef = actionDef.getParameterDefintion(paramName); + + if (paramDef != null && paramDef.getType().equals(DataTypeDefinition.QNAME)) + { + if (value instanceof Wrapper) + { + // unwrap a Java object from a JavaScript wrapper + // recursively call this method to convert the unwrapped value + return convertActionParamForRepo(paramName, (Serializable) ((Wrapper) value).unwrap()); + } + else + { + if (value instanceof String) + { + String stringQName = (String) value; + if (stringQName.startsWith("{")) + { + return QName.createQName(stringQName); + + } + else + { + return QName.createQName(stringQName, services.getNamespaceService()); + } + } + else + { + return value; + } + } + } + else + { + return convertValueForRepo(value); + } + } + } + + /** + * Scripted Parameter map with modified flag. + * + * @author davidc + */ + public static final class ScriptableParameterMap extends ScriptableHashMap + { + private static final long serialVersionUID = 574661815973241554L; + + private boolean modified = false; + + /** + * Is this a modified parameter map? + * + * @return true => modified + */ + /* package */boolean isModified() + { + return modified; + } + + /** + * Set explicitly whether this map is modified + * + * @param modified + * true => modified, false => not modified + */ + /* package */void setModified(boolean modified) + { + this.modified = modified; + } + + /* + * (non-Javadoc) + * + * @see org.mozilla.javascript.Scriptable#getClassName() + */ + @Override + public String getClassName() + { + return "ScriptableParameterMap"; + } + + /* + * (non-Javadoc) + * + * @see org.mozilla.javascript.Scriptable#delete(java.lang.String) + */ + @Override + public void delete(String name) + { + super.delete(name); + setModified(true); + } + + /* + * (non-Javadoc) + * + * @see org.mozilla.javascript.Scriptable#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object) + */ + @Override + public void put(String name, Scriptable start, Object value) + { + super.put(name, start, value); + setModified(true); + } + } +} diff --git a/source/java/org/alfresco/repo/jscript/ScriptUtils.java b/source/java/org/alfresco/repo/jscript/ScriptUtils.java index a96d3288e7..6db5661024 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptUtils.java +++ b/source/java/org/alfresco/repo/jscript/ScriptUtils.java @@ -16,6 +16,8 @@ */ package org.alfresco.repo.jscript; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.NodeRef; import org.mozilla.javascript.Scriptable; /** @@ -28,6 +30,9 @@ public final class ScriptUtils extends BaseScriptImplementation implements Scope /** Root scope for this object */ private Scriptable scope; + /** Services */ + private ServiceRegistry services; + /** * @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable) */ @@ -36,6 +41,16 @@ public final class ScriptUtils extends BaseScriptImplementation implements Scope this.scope = scope; } + /** + * Sets the service registry + * + * @param services the service registry + */ + public void setServiceRegistry(ServiceRegistry services) + { + this.services = services; + } + /** * Function to pad a string with zero '0' characters to the required length * @@ -53,4 +68,16 @@ public final class ScriptUtils extends BaseScriptImplementation implements Scope } return result; } + + /** + * Gets a JS node object from a string noderef + * + * @param nodeRefString string reference to a node + * @return a JS node object + */ + public Node getNodeFromString(String nodeRefString) + { + NodeRef nodeRef = new NodeRef(nodeRefString); + return (Node)new ValueConverter().convertValueForScript(this.services, this.scope, null, nodeRef); + } } diff --git a/source/java/org/alfresco/repo/jscript/Search.java b/source/java/org/alfresco/repo/jscript/Search.java index 59b767aac2..952d45fccd 100644 --- a/source/java/org/alfresco/repo/jscript/Search.java +++ b/source/java/org/alfresco/repo/jscript/Search.java @@ -17,7 +17,6 @@ package org.alfresco.repo.jscript; import java.io.StringReader; -import java.util.Collections; import java.util.LinkedHashSet; import org.alfresco.error.AlfrescoRuntimeException; @@ -27,12 +26,9 @@ import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.search.ResultSet; import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchService; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; @@ -51,28 +47,35 @@ import org.mozilla.javascript.Scriptable; * * @author Kevin Roast */ -public final class Search implements Scopeable +public final class Search extends BaseScriptImplementation implements Scopeable { - private static Log logger = LogFactory.getLog(Search.class); - + /** Service registry */ private ServiceRegistry services; + + /** Default store reference */ private StoreRef storeRef; - private TemplateImageResolver imageResolver; /** Root scope for this object */ private Scriptable scope; + /** + * Set the default store reference + * + * @param storeRef the default store reference + */ + public void setStoreUrl(String storeRef) + { + this.storeRef = new StoreRef(storeRef); + } /** - * Constructor + * Set the service registry * - * @param services The ServiceRegistry to use + * @param services the service registry */ - public Search(ServiceRegistry services, StoreRef storeRef, TemplateImageResolver imageResolver) + public void setServiceRegistry(ServiceRegistry services) { this.services = services; - this.storeRef = storeRef; - this.imageResolver = imageResolver; } /** @@ -105,7 +108,7 @@ public final class Search implements Scopeable public Node findNode(String ref) { String query = "ID:" + LuceneQueryParser.escape(ref); - Node[] result = query(query); + Node[] result = query(query, SearchService.LANGUAGE_LUCENE); if (result.length == 1) { return result[0]; @@ -116,6 +119,25 @@ public final class Search implements Scopeable } } + /** + * Execute a XPath search + * + * @param search XPath search string to execute + * + * @return Node[] of results from the search - can be empty but not null + */ + public Node[] xpathSearch(String search) + { + if (search != null && search.length() != 0) + { + return query(search, SearchService.LANGUAGE_XPATH); + } + else + { + return new Node[0]; + } + } + /** * Execute a Lucene search * @@ -127,7 +149,7 @@ public final class Search implements Scopeable { if (search != null && search.length() != 0) { - return query(search); + return query(search, SearchService.LANGUAGE_LUCENE); } else { @@ -173,7 +195,7 @@ public final class Search implements Scopeable throw new AlfrescoRuntimeException("Failed to find or load saved Search: " + savedSearch.getNodeRef(), err); } - return search != null ? query(search) : new Node[0]; + return search != null ? query(search, SearchService.LANGUAGE_LUCENE) : new Node[0]; } /** @@ -194,7 +216,7 @@ public final class Search implements Scopeable return new Node[0]; } } - + /** * Execute the query * @@ -203,7 +225,7 @@ public final class Search implements Scopeable * @param search * @return */ - private Node[] query(String search) + private Node[] query(String search, String language) { LinkedHashSet set = new LinkedHashSet (); @@ -213,7 +235,7 @@ public final class Search implements Scopeable { results = this.services.getSearchService().query( this.storeRef, - SearchService.LANGUAGE_LUCENE, + language, search); if (results.length() != 0) @@ -221,7 +243,7 @@ public final class Search implements Scopeable for (ResultSetRow row: results) { NodeRef nodeRef = row.getNodeRef(); - set.add(new Node(nodeRef, services, this.imageResolver, this.scope)); + set.add(new Node(nodeRef, services, this.scope)); } } } diff --git a/source/java/org/alfresco/repo/jscript/Session.java b/source/java/org/alfresco/repo/jscript/Session.java index de54dfab33..4ed3254fcf 100644 --- a/source/java/org/alfresco/repo/jscript/Session.java +++ b/source/java/org/alfresco/repo/jscript/Session.java @@ -17,10 +17,6 @@ package org.alfresco.repo.jscript; import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.TemplateImageResolver; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.mozilla.javascript.Scriptable; /** * Support object for session level properties etc. @@ -29,32 +25,19 @@ import org.mozilla.javascript.Scriptable; * * @author Andy Hind */ -public class Session implements Scopeable +public class Session extends BaseScriptImplementation { - - @SuppressWarnings("unused") - private static Log logger = LogFactory.getLog(Session.class); - - @SuppressWarnings("unused") - private Scriptable scope; - + /** Service registry */ private ServiceRegistry services; - - @SuppressWarnings("unused") - private TemplateImageResolver imageResolver; - - public Session(ServiceRegistry services, TemplateImageResolver imageResolver) - { - this.services = services; - this.imageResolver = imageResolver; - } /** - * @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable) + * Set the service registry + * + * @param services the service registry */ - public void setScope(Scriptable scope) + public void setServiceRegistry(ServiceRegistry services) { - this.scope = scope; + this.services = services; } /** diff --git a/source/java/org/alfresco/repo/jscript/ValueConverter.java b/source/java/org/alfresco/repo/jscript/ValueConverter.java index d535758d19..8567e7d0fa 100644 --- a/source/java/org/alfresco/repo/jscript/ValueConverter.java +++ b/source/java/org/alfresco/repo/jscript/ValueConverter.java @@ -63,7 +63,7 @@ public class ValueConverter { // NodeRef object properties are converted to new Node objects // so they can be used as objects within a template - value = new Node(((NodeRef)value), services, null, scope); + value = new Node(((NodeRef)value), services, scope); } else if (value instanceof QName || value instanceof StoreRef) { diff --git a/source/java/org/alfresco/repo/template/BasePathResultsMap.java b/source/java/org/alfresco/repo/template/BasePathResultsMap.java index 74e0d98bc1..5c73676cce 100644 --- a/source/java/org/alfresco/repo/template/BasePathResultsMap.java +++ b/source/java/org/alfresco/repo/template/BasePathResultsMap.java @@ -77,7 +77,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap if (nodes.size() != 0) { result = new ArrayList(1); - result.add(new TemplateNode(nodes.get(0), this.services, this.parent.getImageResolver())); + result.add(new TemplateNode(nodes.get(0), this.services)); } } // or all the results @@ -86,7 +86,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap result = new ArrayList(nodes.size()); for (NodeRef ref : nodes) { - result.add(new TemplateNode(ref, this.services, this.parent.getImageResolver())); + result.add(new TemplateNode(ref, this.services)); } } } diff --git a/source/java/org/alfresco/repo/template/BaseSearchResultsMap.java b/source/java/org/alfresco/repo/template/BaseSearchResultsMap.java index 06442f47b7..10f5f7fa84 100644 --- a/source/java/org/alfresco/repo/template/BaseSearchResultsMap.java +++ b/source/java/org/alfresco/repo/template/BaseSearchResultsMap.java @@ -75,7 +75,7 @@ public abstract class BaseSearchResultsMap extends BaseTemplateMap NodeRef nodeRef = row.getNodeRef(); if (!nodeRefs.contains(nodeRef)) { - nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver())); + nodes.add(new TemplateNode(nodeRef, services)); nodeRefs.add(nodeRef); } } diff --git a/source/java/org/alfresco/repo/template/Classification.java b/source/java/org/alfresco/repo/template/Classification.java index 3c55a5d0f6..75a8be74f9 100644 --- a/source/java/org/alfresco/repo/template/Classification.java +++ b/source/java/org/alfresco/repo/template/Classification.java @@ -102,7 +102,7 @@ public final class Classification ArrayList categoryNodes = new ArrayList(cars.size()); for (ChildAssociationRef car : cars) { - categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver)); + categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services)); } return categoryNodes; } diff --git a/source/java/org/alfresco/repo/template/FreeMarkerProcessor.java b/source/java/org/alfresco/repo/template/FreeMarkerProcessor.java index 8b90581768..8dc891a504 100644 --- a/source/java/org/alfresco/repo/template/FreeMarkerProcessor.java +++ b/source/java/org/alfresco/repo/template/FreeMarkerProcessor.java @@ -309,18 +309,18 @@ public class FreeMarkerProcessor implements TemplateProcessor Map model = new HashMap(16, 1.0f); // supply the Company Home space as "companyhome" - model.put("companyhome", new TemplateNode(companyHome, services, imageResolver)); + model.put("companyhome", new TemplateNode(companyHome, services)); // supply the users Home Space as "userhome" - model.put("userhome", new TemplateNode(userHome, services, imageResolver)); + model.put("userhome", new TemplateNode(userHome, services)); // supply the current user Node as "person" - model.put("person", new TemplateNode(person, services, imageResolver)); + model.put("person", new TemplateNode(person, services)); // add the template itself as "template" if it comes from content on a node if (template != null) { - model.put("template", new TemplateNode(template, services, imageResolver)); + model.put("template", new TemplateNode(template, services)); } // current date/time is useful to have and isn't supplied by FreeMarker by default diff --git a/source/java/org/alfresco/repo/template/TemplateServiceImplTest.java b/source/java/org/alfresco/repo/template/TemplateServiceImplTest.java index 1880a39162..699a564598 100644 --- a/source/java/org/alfresco/repo/template/TemplateServiceImplTest.java +++ b/source/java/org/alfresco/repo/template/TemplateServiceImplTest.java @@ -116,7 +116,7 @@ public class TemplateServiceImplTest extends TestCase // create test model Map model = new HashMap(7, 1.0f); - model.put("root", new TemplateNode(root, serviceRegistry, null)); + model.put("root", new TemplateNode(root, serviceRegistry)); // execute on test template String output = templateService.processTemplate("freemarker", TEMPLATE_1, model); diff --git a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java index 41f03c209e..5a630ccb5c 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/AlfrescoJavaScript.java @@ -22,9 +22,6 @@ import java.util.List; import java.util.Map; import org.alfresco.model.ContentModel; -import org.alfresco.repo.jscript.Classification; -import org.alfresco.repo.jscript.Search; -import org.alfresco.repo.jscript.Session; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; @@ -149,14 +146,6 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler Map inputMap = new HashMap(); // initialise global script variables - JBPMNode companyHome = (JBPMNode)executionContext.getContextInstance().getVariable("companyhome"); - if (companyHome != null) - { - NodeRef companyHomeRef = companyHome.getNodeRef(); - inputMap.put("search", new Search(services, companyHomeRef.getStoreRef(), null)); - inputMap.put("session", new Session(services, null)); - inputMap.put("classification", new Classification(services, companyHomeRef.getStoreRef(), null)); - } String userName = AuthenticationUtil.getCurrentUserName(); NodeRef person = services.getPersonService().getPerson(userName); if (person != null) diff --git a/source/java/org/alfresco/service/cmr/repository/TemplateNode.java b/source/java/org/alfresco/service/cmr/repository/TemplateNode.java index e225972963..b9bc47a232 100644 --- a/source/java/org/alfresco/service/cmr/repository/TemplateNode.java +++ b/source/java/org/alfresco/service/cmr/repository/TemplateNode.java @@ -93,7 +93,6 @@ public class TemplateNode implements Serializable private String displayPath = null; private String mimetype = null; private Long size = null; - protected TemplateImageResolver imageResolver = null; private TemplateNode parent = null; private ChildAssociationRef primaryParentAssoc = null; private Boolean isCategory = null; @@ -109,7 +108,7 @@ public class TemplateNode implements Serializable * @param services The ServiceRegistry the TemplateNode can use to access services * @param resolver Image resolver to use to retrieve icons */ - public TemplateNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver) + public TemplateNode(NodeRef nodeRef, ServiceRegistry services) { if (nodeRef == null) { @@ -124,7 +123,6 @@ public class TemplateNode implements Serializable this.nodeRef = nodeRef; this.id = nodeRef.getId(); this.services = services; - this.imageResolver = resolver; this.properties = new QNameMap(this.services.getNamespaceService()); } @@ -210,7 +208,7 @@ public class TemplateNode implements Serializable for (ChildAssociationRef ref : childRefs) { // create our Node representation from the NodeRef - TemplateNode child = new TemplateNode(ref.getChildRef(), this.services, this.imageResolver); + TemplateNode child = new TemplateNode(ref.getChildRef(), this.services); this.children.add(child); } } @@ -237,7 +235,7 @@ public class TemplateNode implements Serializable nodes = new ArrayList(4); this.assocs.put(ref.getTypeQName().toString(), nodes); } - nodes.add( new TemplateNode(ref.getTargetRef(), this.services, this.imageResolver) ); + nodes.add( new TemplateNode(ref.getTargetRef(), this.services) ); } } @@ -260,7 +258,7 @@ public class TemplateNode implements Serializable { // NodeRef object properties are converted to new TemplateNode objects // so they can be used as objects within a template - propValue = new TemplateNode(((NodeRef)propValue), this.services, this.imageResolver); + propValue = new TemplateNode(((NodeRef)propValue), this.services); } else if (propValue instanceof ContentData) { @@ -394,7 +392,7 @@ public class TemplateNode implements Serializable // handle root node (no parent!) if (parentRef != null) { - parent = new TemplateNode(parentRef, this.services, this.imageResolver); + parent = new TemplateNode(parentRef, this.services); } } @@ -551,21 +549,7 @@ public class TemplateNode implements Serializable */ public String getIcon16() { - if (this.imageResolver != null) - { - if (getIsDocument()) - { - return this.imageResolver.resolveImagePathForName(getName(), true); - } - else - { - return "/images/icons/space_small.gif"; - } - } - else - { - return "/images/filetypes/_default.gif"; - } + return "/images/filetypes/_default.gif"; } /** @@ -573,29 +557,7 @@ public class TemplateNode implements Serializable */ public String getIcon32() { - if (this.imageResolver != null) - { - if (getIsDocument()) - { - return this.imageResolver.resolveImagePathForName(getName(), false); - } - else - { - String icon = (String)getProperties().get("app:icon"); - if (icon != null) - { - return "/images/icons/" + icon + ".gif"; - } - else - { - return "/images/icons/space-icon-default.gif"; - } - } - } - else - { - return "/images/filetypes32/_default.gif"; - } + return "/images/filetypes32/_default.gif"; } @@ -699,14 +661,6 @@ public class TemplateNode implements Serializable // ------------------------------------------------------------------------------ // Misc helpers - /** - * @return the image resolver instance used by this node - */ - public TemplateImageResolver getImageResolver() - { - return this.imageResolver; - } - /** * Override Object.toString() to provide useful debug output */