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
This commit is contained in:
Derek Hulley
2006-12-19 17:12:47 +00:00
parent ae7c03d291
commit a67dce2f5e
26 changed files with 633 additions and 544 deletions

View File

@@ -333,10 +333,10 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
Map<String, Object> model = new HashMap<String, Object>(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());

View File

@@ -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<ParameterDefinition> 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;

View File

@@ -104,7 +104,7 @@ public class FreeMarkerWithLuceneExtensionsModelFactory implements TemplateActio
{
Map<String, Object> model = getModel();
TemplateNode companyRootNode = new TemplateNode(nodeRef, serviceRegistry, null);
TemplateNode companyRootNode = new TemplateNode(nodeRef, serviceRegistry);
model.put("node", companyRootNode);
return model;

View File

@@ -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<String, Serializable> 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: <code>node.properties["name"]</code>
*
* @return Map of properties for this Node.
*/
@SuppressWarnings("synthetic-access")
public Map<String, Serializable> getParameters()
{
if (this.parameters == null)
{
// this Map implements the Scriptable interface for native JS syntax property access
this.parameters = new ScriptableParameterMap<String, Serializable>();
Map<String, Serializable> actionParams = this.action.getParameterValues();
for (Map.Entry<String, Serializable> 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<String, Serializable> 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<String, Serializable> actionParams = action.getParameterValues();
actionParams.clear();
for (Map.Entry<String, Serializable> 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<K, V> extends ScriptableHashMap<K, V>
{
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);
}
}
}
}

View File

@@ -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;

View File

@@ -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<TemplateNode> buildMixedNodeList(Collection<ChildAssociationRef> cars)
{
List<TemplateNode> nodes = new ArrayList<TemplateNode>(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;

View File

@@ -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;
}

View File

@@ -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();
}
}
}

View File

@@ -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<String, Node[]> 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<String, Object> 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<String, Object> 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
*

View File

@@ -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;
}

View File

@@ -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:
* <p>
* 'companyhome' - the Company Home node<br>
* 'userhome' - the current user home space node<br>
* 'person' - the node representing the current user Person<br>
* 'document' - document context node (may not be available)<br>
* '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<String, Object> 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:
* <p>
@@ -366,34 +338,27 @@ public class RhinoScriptService implements ScriptService
public static Map<String, Object> buildDefaultModel(
ServiceRegistry services,
NodeRef person, NodeRef companyHome, NodeRef userHome,
NodeRef script, NodeRef document, NodeRef space,
TemplateImageResolver resolver)
NodeRef script, NodeRef document, NodeRef space)
{
Map<String, Object> model = new HashMap<String, Object>();
// 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;
}
}

View File

@@ -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();

View File

@@ -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<String, Serializable> 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: <code>node.properties["name"]</code>
*
* @return Map of properties for this Node.
*/
@SuppressWarnings("synthetic-access")
public Map<String, Serializable> getParameters()
{
if (this.parameters == null)
{
// this Map implements the Scriptable interface for native JS syntax property access
this.parameters = new ScriptableParameterMap<String, Serializable>();
Map<String, Serializable> actionParams = this.action.getParameterValues();
for (Map.Entry<String, Serializable> 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<String, Serializable> 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<String, Serializable> actionParams = action.getParameterValues();
actionParams.clear();
for (Map.Entry<String, Serializable> 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<K, V> extends ScriptableHashMap<K, V>
{
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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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<Node> set = new LinkedHashSet<Node> ();
@@ -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));
}
}
}

View File

@@ -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;
}
/**

View File

@@ -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)
{

View File

@@ -77,7 +77,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap
if (nodes.size() != 0)
{
result = new ArrayList<TemplateNode>(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<TemplateNode>(nodes.size());
for (NodeRef ref : nodes)
{
result.add(new TemplateNode(ref, this.services, this.parent.getImageResolver()));
result.add(new TemplateNode(ref, this.services));
}
}
}

View File

@@ -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);
}
}

View File

@@ -102,7 +102,7 @@ public final class Classification
ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(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;
}

View File

@@ -309,18 +309,18 @@ public class FreeMarkerProcessor implements TemplateProcessor
Map<String, Object> model = new HashMap<String, Object>(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

View File

@@ -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);

View File

@@ -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<String, Object> inputMap = new HashMap<String, Object>();
// 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)