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

@@ -465,4 +465,22 @@
<value>false</value> <value>false</value>
</property> </property>
</bean> </bean>
<!-- Scheduled action helper beans -->
<!-- Base template action definition -->
<bean id="baseTemplateActionDefintion" abstract="true" class="org.alfresco.repo.action.scheduled.SimpleTemplateActionDefinition">
<property name="templateActionModelFactory">
<ref bean="templateActionModelFactory"/>
</property>
<property name="dictionaryService">
<ref bean="DictionaryService"/>
</property>
<property name="actionService">
<ref bean="ActionService"/>
</property>
<property name="templateService">
<ref bean="TemplateService"/>
</property>
</bean>
</beans> </beans>

View File

@@ -25,6 +25,9 @@
<property name="scriptName"> <property name="scriptName">
<value>utils</value> <value>utils</value>
</property> </property>
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
</bean> </bean>
<bean id="actionsScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.Actions"> <bean id="actionsScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.Actions">
@@ -36,6 +39,30 @@
</property> </property>
</bean> </bean>
<bean id="searchScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.Search">
<property name="scriptName">
<value>search</value>
</property>
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
</bean>
<bean id="classificationScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.Classification">
<property name="scriptName">
<value>classification</value>
</property>
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
<property name="storeUrl">
<value>${spaces.store}</value>
</property>
</bean>
<bean id="peopleScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.People"> <bean id="peopleScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.People">
<property name="scriptName"> <property name="scriptName">
<value>people</value> <value>people</value>
@@ -44,6 +71,15 @@
<ref bean="ServiceRegistry"/> <ref bean="ServiceRegistry"/>
</property> </property>
</bean> </bean>
<bean id="sessionScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.Session">
<property name="scriptName">
<value>session</value>
</property>
<property name="serviceRegistry">
<ref bean="ServiceRegistry"/>
</property>
</bean>
<bean id="avmScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.AVM"> <bean id="avmScript" parent="baseScriptImplementation" class="org.alfresco.repo.jscript.AVM">
<property name="scriptName"> <property name="scriptName">

View File

@@ -333,10 +333,10 @@ public class MailActionExecuter extends ActionExecuterAbstractBase
Map<String, Object> model = new HashMap<String, Object>(8, 1.0f); Map<String, Object> model = new HashMap<String, Object>(8, 1.0f);
NodeRef person = personService.getPerson(authService.getCurrentUserName()); NodeRef person = personService.getPerson(authService.getCurrentUserName());
model.put("person", new TemplateNode(person, serviceRegistry, null)); model.put("person", new TemplateNode(person, serviceRegistry));
model.put("document", new TemplateNode(ref, serviceRegistry, null)); model.put("document", new TemplateNode(ref, serviceRegistry));
NodeRef parent = serviceRegistry.getNodeService().getPrimaryParent(ref).getParentRef(); 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 // current date/time is useful to have and isn't supplied by FreeMarker by default
model.put("date", new Date()); model.put("date", new Date());

View File

@@ -22,12 +22,14 @@ import java.util.Map;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl; import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.jscript.RhinoScriptService; import org.alfresco.repo.jscript.RhinoScriptService;
import org.alfresco.repo.jscript.ScriptAction;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition; import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.ScriptLocation;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
@@ -47,6 +49,7 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase
private PersonService personService; private PersonService personService;
private String companyHomePath; private String companyHomePath;
private StoreRef storeRef; private StoreRef storeRef;
private ScriptLocation scriptLocation;
/** /**
* @param serviceRegistry The serviceRegistry to set. * @param serviceRegistry The serviceRegistry to set.
@@ -73,6 +76,26 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase
{ {
this.companyHomePath = companyHomePath; 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) * @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(); 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 // get the references we need to build the default scripting data-model
String userName = this.serviceRegistry.getAuthenticationService().getCurrentUserName(); String userName = this.serviceRegistry.getAuthenticationService().getCurrentUserName();
@@ -107,11 +130,23 @@ public class ScriptActionExecuter extends ActionExecuterAbstractBase
actionedUponNodeRef, actionedUponNodeRef,
spaceRef); spaceRef);
// execute the script against the default model // Add the action to the default model
this.serviceRegistry.getScriptService().executeScript( 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, scriptRef,
ContentModel.PROP_CONTENT, ContentModel.PROP_CONTENT,
model); 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) 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() private NodeRef getCompanyHome()
{ {
NodeRef companyHomeRef; NodeRef companyHomeRef;

View File

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

View File

@@ -16,19 +16,13 @@
*/ */
package org.alfresco.repo.jscript; package org.alfresco.repo.jscript;
import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ActionDefinition; import org.alfresco.service.cmr.action.ActionDefinition;
import org.alfresco.service.cmr.action.ActionService; 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.Scriptable;
import org.mozilla.javascript.Wrapper;
/** /**
* Scripted Action service for describing and executing actions against Nodes. * 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) if (actionDef != null)
{ {
Action action = actionService.createAction(actionName); Action action = actionService.createAction(actionName);
scriptAction = new ScriptAction(action, actionDef); scriptAction = new ScriptAction(this.services, action, actionDef);
scriptAction.setScope(scope); scriptAction.setScope(scope);
} }
return scriptAction; 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.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
@@ -41,9 +40,9 @@ public class CategoryNode extends Node
* @param services * @param services
* @param resolver * @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 resolver
* @param scope * @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) 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; int i = 0;
for (ChildAssociationRef car : cars) 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; return categoryNodes;
} }
@@ -180,7 +179,7 @@ public class CategoryNode extends Node
int i = 0; int i = 0;
for (ChildAssociationRef car : cars) 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; return nodes;
} }
@@ -194,11 +193,11 @@ public class CategoryNode extends Node
QName type = services.getNodeService().getType(car.getChildRef()); QName type = services.getNodeService().getType(car.getChildRef());
if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY)) 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 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; return nodes;

View File

@@ -25,7 +25,6 @@ import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.search.CategoryService; import org.alfresco.service.cmr.search.CategoryService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -44,9 +43,9 @@ public class CategoryTemplateNode extends TemplateNode
* @param services * @param services
* @param resolver * @param resolver
*/ */
public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services, TemplateImageResolver resolver) public CategoryTemplateNode(NodeRef nodeRef, ServiceRegistry services)
{ {
super(nodeRef, services, resolver); super(nodeRef, services);
} }
@Override @Override
@@ -165,7 +164,7 @@ public class CategoryTemplateNode extends TemplateNode
for (ChildAssociationRef ref : childRefs) for (ChildAssociationRef ref : childRefs)
{ {
// create our Node representation from the NodeRef // 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); answer.add(child);
} }
return answer; return answer;
@@ -177,7 +176,7 @@ public class CategoryTemplateNode extends TemplateNode
for (ChildAssociationRef ref : childRefs) for (ChildAssociationRef ref : childRefs)
{ {
// create our Node representation from the NodeRef // 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); answer.add(child);
} }
return answer; return answer;
@@ -186,17 +185,16 @@ public class CategoryTemplateNode extends TemplateNode
private List<TemplateNode> buildMixedNodeList(Collection<ChildAssociationRef> cars) private List<TemplateNode> buildMixedNodeList(Collection<ChildAssociationRef> cars)
{ {
List<TemplateNode> nodes = new ArrayList<TemplateNode>(cars.size()); List<TemplateNode> nodes = new ArrayList<TemplateNode>(cars.size());
int i = 0;
for (ChildAssociationRef car : cars) for (ChildAssociationRef car : cars)
{ {
QName type = services.getNodeService().getType(car.getChildRef()); QName type = services.getNodeService().getType(car.getChildRef());
if (services.getDictionaryService().isSubClass(type, ContentModel.TYPE_CATEGORY)) 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 else
{ {
nodes.add(new TemplateNode(car.getChildRef(), this.services, this.imageResolver)); nodes.add(new TemplateNode(car.getChildRef(), this.services));
} }
} }
return nodes; return nodes;

View File

@@ -21,11 +21,8 @@ import java.util.Collection;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.StoreRef; 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.cmr.search.CategoryService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
/** /**
@@ -33,23 +30,33 @@ import org.mozilla.javascript.Scriptable;
* *
* @author Andy Hind * @author Andy Hind
*/ */
public final class Classification implements Scopeable public final class Classification extends BaseScriptImplementation implements Scopeable
{ {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Scriptable scope; private Scriptable scope;
private ServiceRegistry services; private ServiceRegistry services;
@SuppressWarnings("unused")
private TemplateImageResolver imageResolver;
private StoreRef storeRef; 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.services = services;
this.imageResolver = imageResolver;
this.storeRef = storeRef;
} }
/** /**
@@ -122,7 +129,7 @@ public final class Classification implements Scopeable
int i = 0; int i = 0;
for (ChildAssociationRef car : cars) 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; 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.NoTransformerException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
@@ -148,9 +147,9 @@ public class Node implements Serializable, Scopeable
* @param resolver * @param resolver
* Image resolver to use to retrieve icons * 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 * @param scope
* Root scope for this Node * 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) if (nodeRef == null)
{ {
@@ -181,7 +180,6 @@ public class Node implements Serializable, Scopeable
this.id = nodeRef.getId(); this.id = nodeRef.getId();
this.services = services; this.services = services;
this.nodeService = services.getNodeService(); this.nodeService = services.getNodeService();
this.imageResolver = resolver;
this.scope = scope; 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. * @return associations as a Map of assoc name to an Array of Nodes.
*/ */
@SuppressWarnings("unchecked")
public Map<String, Node[]> getAssocs() public Map<String, Node[]> getAssocs()
{ {
if (this.assocs == null) if (this.assocs == null)
@@ -448,6 +447,7 @@ public class Node implements Serializable, Scopeable
* *
* @return Map of properties for this Node. * @return Map of properties for this Node.
*/ */
@SuppressWarnings("unchecked")
public Map<String, Object> getProperties() public Map<String, Object> getProperties()
{ {
if (this.properties == null) if (this.properties == null)
@@ -614,21 +614,7 @@ public class Node implements Serializable, Scopeable
*/ */
public String getIcon16() public String getIcon16()
{ {
if (this.imageResolver != null) return "/images/filetypes/_default.gif";
{
if (getIsDocument())
{
return this.imageResolver.resolveImagePathForName(getName(), true);
}
else
{
return "/images/icons/space_small.gif";
}
}
else
{
return "/images/filetypes/_default.gif";
}
} }
public String jsGet_icon16() public String jsGet_icon16()
@@ -641,29 +627,7 @@ public class Node implements Serializable, Scopeable
*/ */
public String getIcon32() public String getIcon32()
{ {
if (this.imageResolver != null) return "/images/filetypes32/_default.gif";
{
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";
}
} }
public String jsGet_icon32() public String jsGet_icon32()
@@ -876,14 +840,6 @@ public class Node implements Serializable, Scopeable
return getSize(); return getSize();
} }
/**
* @return the image resolver instance used by this node
*/
public TemplateImageResolver getImageResolver()
{
return this.imageResolver;
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Security API // Security API
@@ -1333,6 +1289,30 @@ public class Node implements Serializable, Scopeable
return success; 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 // Checkout/Checkin Services
@@ -1679,19 +1659,17 @@ public class Node implements Serializable, Scopeable
// build default model for the template processing // build default model for the template processing
Map<String, Object> model = FreeMarkerProcessor.buildDefaultModel(services, ((Node) ((Wrapper) scope.get( Map<String, Object> model = FreeMarkerProcessor.buildDefaultModel(services, ((Node) ((Wrapper) scope.get(
"person", scope)).unwrap()).getNodeRef(), ((Node) ((Wrapper) scope.get("companyhome", scope)).unwrap()) "person", scope)).unwrap()).getNodeRef(), ((Node) ((Wrapper) scope.get("companyhome", scope)).unwrap())
.getNodeRef(), ((Node) ((Wrapper) scope.get("userhome", scope)).unwrap()).getNodeRef(), templateRef, .getNodeRef(), ((Node) ((Wrapper) scope.get("userhome", scope)).unwrap()).getNodeRef(), templateRef, null);
this.imageResolver);
// add the current node as either the document/space as appropriate // add the current node as either the document/space as appropriate
if (this.getIsDocument()) if (this.getIsDocument())
{ {
model.put("document", new TemplateNode(this.nodeRef, this.services, this.imageResolver)); model.put("document", new TemplateNode(this.nodeRef, this.services));
model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services, model.put("space", new TemplateNode(getPrimaryParentAssoc().getParentRef(), this.services));
this.imageResolver));
} }
else 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 // add the supplied args to the 'args' root object
@@ -1935,6 +1913,8 @@ public class Node implements Serializable, Scopeable
*/ */
public class ScriptContentData implements Serializable public class ScriptContentData implements Serializable
{ {
private static final long serialVersionUID = -7819328543933312278L;
/** /**
* Constructor * Constructor
* *

View File

@@ -16,21 +16,10 @@
*/ */
package org.alfresco.repo.jscript; 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.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.repository.NodeRef;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Wrapper;
/** /**
* Scripted People service for describing and executing actions against People & Groups. * 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)) if (personService.personExists(username))
{ {
NodeRef personRef = personService.getPerson(username); NodeRef personRef = personService.getPerson(username);
person = new Node(personRef, services, null, scope); person = new Node(personRef, services, scope);
} }
return person; 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.ScriptLocation;
import org.alfresco.service.cmr.repository.ScriptImplementation; import org.alfresco.service.cmr.repository.ScriptImplementation;
import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.ScriptService;
import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck; import org.alfresco.util.ParameterCheck;
import org.apache.log4j.Logger; 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: * Create the default data-model available to scripts as global scope level objects:
* <p> * <p>
@@ -366,34 +338,27 @@ public class RhinoScriptService implements ScriptService
public static Map<String, Object> buildDefaultModel( public static Map<String, Object> buildDefaultModel(
ServiceRegistry services, ServiceRegistry services,
NodeRef person, NodeRef companyHome, NodeRef userHome, NodeRef person, NodeRef companyHome, NodeRef userHome,
NodeRef script, NodeRef document, NodeRef space, NodeRef script, NodeRef document, NodeRef space)
TemplateImageResolver resolver)
{ {
Map<String, Object> model = new HashMap<String, Object>(); Map<String, Object> model = new HashMap<String, Object>();
// add the well known node wrapper objects // add the well known node wrapper objects
model.put("companyhome", new Node(companyHome, services, resolver)); model.put("companyhome", new Node(companyHome, services));
model.put("userhome", new Node(userHome, services, resolver)); model.put("userhome", new Node(userHome, services));
model.put("person", new Node(person, services, resolver)); model.put("person", new Node(person, services));
if (script != null) if (script != null)
{ {
model.put("script", new Node(script, services, resolver)); model.put("script", new Node(script, services));
} }
if (document != null) if (document != null)
{ {
model.put("document", new Node(document, services, resolver)); model.put("document", new Node(document, services));
} }
if (space != null) 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; return model;
} }
} }

View File

@@ -67,11 +67,11 @@ public class RhinoScriptTest extends TestCase
{ {
super.setUp(); super.setUp();
transactionService = (TransactionService)this.ctx.getBean("transactionComponent"); transactionService = (TransactionService)ctx.getBean("transactionComponent");
contentService = (ContentService)this.ctx.getBean("contentService"); contentService = (ContentService)ctx.getBean("contentService");
nodeService = (NodeService)this.ctx.getBean("nodeService"); nodeService = (NodeService)ctx.getBean("nodeService");
scriptService = (ScriptService)this.ctx.getBean("scriptService"); scriptService = (ScriptService)ctx.getBean("scriptService");
serviceRegistry = (ServiceRegistry)this.ctx.getBean("ServiceRegistry"); serviceRegistry = (ServiceRegistry)ctx.getBean("ServiceRegistry");
this.authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent"); this.authenticationComponent = (AuthenticationComponent)ctx.getBean("authenticationComponent");
this.authenticationComponent.setSystemUserAsCurrentUser(); 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; package org.alfresco.repo.jscript;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
/** /**
@@ -28,6 +30,9 @@ public final class ScriptUtils extends BaseScriptImplementation implements Scope
/** Root scope for this object */ /** Root scope for this object */
private Scriptable scope; private Scriptable scope;
/** Services */
private ServiceRegistry services;
/** /**
* @see org.alfresco.repo.jscript.Scopeable#setScope(org.mozilla.javascript.Scriptable) * @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; 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 * 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; 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; package org.alfresco.repo.jscript;
import java.io.StringReader; import java.io.StringReader;
import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import org.alfresco.error.AlfrescoRuntimeException; 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.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef; 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.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchService; 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.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
@@ -51,28 +47,35 @@ import org.mozilla.javascript.Scriptable;
* *
* @author Kevin Roast * @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; private ServiceRegistry services;
/** Default store reference */
private StoreRef storeRef; private StoreRef storeRef;
private TemplateImageResolver imageResolver;
/** Root scope for this object */ /** Root scope for this object */
private Scriptable scope; 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.services = services;
this.storeRef = storeRef;
this.imageResolver = imageResolver;
} }
/** /**
@@ -105,7 +108,7 @@ public final class Search implements Scopeable
public Node findNode(String ref) public Node findNode(String ref)
{ {
String query = "ID:" + LuceneQueryParser.escape(ref); String query = "ID:" + LuceneQueryParser.escape(ref);
Node[] result = query(query); Node[] result = query(query, SearchService.LANGUAGE_LUCENE);
if (result.length == 1) if (result.length == 1)
{ {
return result[0]; 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 * Execute a Lucene search
* *
@@ -127,7 +149,7 @@ public final class Search implements Scopeable
{ {
if (search != null && search.length() != 0) if (search != null && search.length() != 0)
{ {
return query(search); return query(search, SearchService.LANGUAGE_LUCENE);
} }
else else
{ {
@@ -173,7 +195,7 @@ public final class Search implements Scopeable
throw new AlfrescoRuntimeException("Failed to find or load saved Search: " + savedSearch.getNodeRef(), err); 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]; return new Node[0];
} }
} }
/** /**
* Execute the query * Execute the query
* *
@@ -203,7 +225,7 @@ public final class Search implements Scopeable
* @param search * @param search
* @return * @return
*/ */
private Node[] query(String search) private Node[] query(String search, String language)
{ {
LinkedHashSet<Node> set = new LinkedHashSet<Node> (); LinkedHashSet<Node> set = new LinkedHashSet<Node> ();
@@ -213,7 +235,7 @@ public final class Search implements Scopeable
{ {
results = this.services.getSearchService().query( results = this.services.getSearchService().query(
this.storeRef, this.storeRef,
SearchService.LANGUAGE_LUCENE, language,
search); search);
if (results.length() != 0) if (results.length() != 0)
@@ -221,7 +243,7 @@ public final class Search implements Scopeable
for (ResultSetRow row: results) for (ResultSetRow row: results)
{ {
NodeRef nodeRef = row.getNodeRef(); 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; package org.alfresco.repo.jscript;
import org.alfresco.service.ServiceRegistry; 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. * Support object for session level properties etc.
@@ -29,32 +25,19 @@ import org.mozilla.javascript.Scriptable;
* *
* @author Andy Hind * @author Andy Hind
*/ */
public class Session implements Scopeable public class Session extends BaseScriptImplementation
{ {
/** Service registry */
@SuppressWarnings("unused")
private static Log logger = LogFactory.getLog(Session.class);
@SuppressWarnings("unused")
private Scriptable scope;
private ServiceRegistry services; 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 // NodeRef object properties are converted to new Node objects
// so they can be used as objects within a template // 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) else if (value instanceof QName || value instanceof StoreRef)
{ {

View File

@@ -77,7 +77,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap
if (nodes.size() != 0) if (nodes.size() != 0)
{ {
result = new ArrayList<TemplateNode>(1); 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 // or all the results
@@ -86,7 +86,7 @@ public abstract class BasePathResultsMap extends BaseTemplateMap
result = new ArrayList<TemplateNode>(nodes.size()); result = new ArrayList<TemplateNode>(nodes.size());
for (NodeRef ref : nodes) 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(); NodeRef nodeRef = row.getNodeRef();
if (!nodeRefs.contains(nodeRef)) if (!nodeRefs.contains(nodeRef))
{ {
nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver())); nodes.add(new TemplateNode(nodeRef, services));
nodeRefs.add(nodeRef); nodeRefs.add(nodeRef);
} }
} }

View File

@@ -102,7 +102,7 @@ public final class Classification
ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(cars.size()); ArrayList<CategoryTemplateNode> categoryNodes = new ArrayList<CategoryTemplateNode>(cars.size());
for (ChildAssociationRef car : cars) for (ChildAssociationRef car : cars)
{ {
categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services, this.imageResolver)); categoryNodes.add(new CategoryTemplateNode(car.getChildRef(), this.services));
} }
return categoryNodes; return categoryNodes;
} }

View File

@@ -309,18 +309,18 @@ public class FreeMarkerProcessor implements TemplateProcessor
Map<String, Object> model = new HashMap<String, Object>(16, 1.0f); Map<String, Object> model = new HashMap<String, Object>(16, 1.0f);
// supply the Company Home space as "companyhome" // 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" // 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" // 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 // add the template itself as "template" if it comes from content on a node
if (template != null) 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 // 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 // create test model
Map model = new HashMap(7, 1.0f); 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 // execute on test template
String output = templateService.processTemplate("freemarker", TEMPLATE_1, model); String output = templateService.processTemplate("freemarker", TEMPLATE_1, model);

View File

@@ -22,9 +22,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.model.ContentModel; 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.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
@@ -149,14 +146,6 @@ public class AlfrescoJavaScript extends JBPMSpringActionHandler
Map<String, Object> inputMap = new HashMap<String, Object>(); Map<String, Object> inputMap = new HashMap<String, Object>();
// initialise global script variables // 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(); String userName = AuthenticationUtil.getCurrentUserName();
NodeRef person = services.getPersonService().getPerson(userName); NodeRef person = services.getPersonService().getPerson(userName);
if (person != null) if (person != null)

View File

@@ -93,7 +93,6 @@ public class TemplateNode implements Serializable
private String displayPath = null; private String displayPath = null;
private String mimetype = null; private String mimetype = null;
private Long size = null; private Long size = null;
protected TemplateImageResolver imageResolver = null;
private TemplateNode parent = null; private TemplateNode parent = null;
private ChildAssociationRef primaryParentAssoc = null; private ChildAssociationRef primaryParentAssoc = null;
private Boolean isCategory = 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 services The ServiceRegistry the TemplateNode can use to access services
* @param resolver Image resolver to use to retrieve icons * @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) if (nodeRef == null)
{ {
@@ -124,7 +123,6 @@ public class TemplateNode implements Serializable
this.nodeRef = nodeRef; this.nodeRef = nodeRef;
this.id = nodeRef.getId(); this.id = nodeRef.getId();
this.services = services; this.services = services;
this.imageResolver = resolver;
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService()); this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
} }
@@ -210,7 +208,7 @@ public class TemplateNode implements Serializable
for (ChildAssociationRef ref : childRefs) for (ChildAssociationRef ref : childRefs)
{ {
// create our Node representation from the NodeRef // 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); this.children.add(child);
} }
} }
@@ -237,7 +235,7 @@ public class TemplateNode implements Serializable
nodes = new ArrayList<TemplateNode>(4); nodes = new ArrayList<TemplateNode>(4);
this.assocs.put(ref.getTypeQName().toString(), nodes); 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 // NodeRef object properties are converted to new TemplateNode objects
// so they can be used as objects within a template // 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) else if (propValue instanceof ContentData)
{ {
@@ -394,7 +392,7 @@ public class TemplateNode implements Serializable
// handle root node (no parent!) // handle root node (no parent!)
if (parentRef != null) 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() public String getIcon16()
{ {
if (this.imageResolver != null) return "/images/filetypes/_default.gif";
{
if (getIsDocument())
{
return this.imageResolver.resolveImagePathForName(getName(), true);
}
else
{
return "/images/icons/space_small.gif";
}
}
else
{
return "/images/filetypes/_default.gif";
}
} }
/** /**
@@ -573,29 +557,7 @@ public class TemplateNode implements Serializable
*/ */
public String getIcon32() public String getIcon32()
{ {
if (this.imageResolver != null) return "/images/filetypes32/_default.gif";
{
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";
}
} }
@@ -699,14 +661,6 @@ public class TemplateNode implements Serializable
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Misc helpers // 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 * Override Object.toString() to provide useful debug output
*/ */