Work flow updates to Javs script

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10417 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2008-08-19 11:54:31 +00:00
parent 540755aeb4
commit dcc9ac128c
5 changed files with 430 additions and 203 deletions

View File

@@ -26,6 +26,9 @@
<property name="workflowPackageComponent" ref="workflowPackageImpl"/> <property name="workflowPackageComponent" ref="workflowPackageImpl"/>
<property name="nodeService" ref="nodeService"/> <property name="nodeService" ref="nodeService"/>
<property name="contentService" ref="contentService"/> <property name="contentService" ref="contentService"/>
<property name="avmSyncService" ref="AVMSyncService"/>
<property name="dictionaryService" ref="dictionaryService"/>
<property name="protectedNodeService" ref="NodeService"/>
</bean> </bean>
<bean id="workflowPackageImpl" class="org.alfresco.repo.workflow.WorkflowPackageImpl"> <bean id="workflowPackageImpl" class="org.alfresco.repo.workflow.WorkflowPackageImpl">

View File

@@ -43,6 +43,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
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.NodeService; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateImageResolver;
import org.alfresco.service.cmr.workflow.WorkflowService; import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
@@ -51,6 +52,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNameMap; import org.alfresco.service.namespace.QNameMap;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.Pair;
/** /**
* Workflow and task support in FreeMarker templates. * Workflow and task support in FreeMarker templates.
@@ -246,40 +248,22 @@ public class Workflow extends BaseTemplateProcessorExtension
public List<TemplateContent> getPackageResources() public List<TemplateContent> getPackageResources()
{ {
List<TemplateContent> resources = new ArrayList<TemplateContent>(); List<TemplateContent> resources = new ArrayList<TemplateContent>();
if (this.task.properties.get(PROP_FROM_PATH) != null) List<NodeRef> contents = this.services.getWorkflowService().getPackageContents(this.task.id);
NodeService nodeService = this.services.getNodeService();
DictionaryService ddService = this.services.getDictionaryService();
for(NodeRef nodeRef : contents)
{ {
AVMService avmService = this.services.getAVMService(); if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
NodeRef workflowPackage = getPackage();
NodeRef stagingNodeRef = (NodeRef)this.services.getNodeService().getProperty(
workflowPackage, WCMModel.PROP_AVM_DIR_INDIRECTION);
String stagingAvmPath = AVMNodeConverter.ToAVMVersionPath(stagingNodeRef).getSecond();
String packageAvmPath = AVMNodeConverter.ToAVMVersionPath(workflowPackage).getSecond();
for (AVMDifference d : this.services.getAVMSyncService().compare(
-1, packageAvmPath, -1, stagingAvmPath, null))
{
if (d.getDifferenceCode() == AVMDifference.NEWER ||
d.getDifferenceCode() == AVMDifference.CONFLICT)
{ {
Pair<Integer, String> vp = AVMNodeConverter.ToAVMVersionPath(nodeRef);
resources.add(new AVMTemplateNode( resources.add(new AVMTemplateNode(
d.getSourcePath(), d.getSourceVersion(), this.services, this.resolver)); vp.getSecond(), vp.getFirst(), this.services, this.resolver));
}
}
} }
else else
{ {
// get existing workflow package items
NodeService nodeService = this.services.getNodeService();
DictionaryService ddService = this.services.getDictionaryService();
List<ChildAssociationRef> childRefs = nodeService.getChildAssocs(
getPackage(), ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref: childRefs)
{
// create our Node representation from the NodeRef
NodeRef nodeRef = ref.getChildRef();
if (nodeService.exists(nodeRef))
{
// find it's type so we can see if it's a node we are interested in
QName type = nodeService.getType(nodeRef); QName type = nodeService.getType(nodeRef);
// make sure the type is defined in the data dictionary // make sure the type is defined in the data dictionary
@@ -295,7 +279,6 @@ public class Workflow extends BaseTemplateProcessorExtension
} }
} }
} }
}
return resources; return resources;
} }

View File

@@ -33,10 +33,18 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
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.StoreRef;
import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType; import org.alfresco.service.cmr.security.AuthorityType;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
@@ -51,6 +59,7 @@ import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
import org.alfresco.service.cmr.workflow.WorkflowTaskState; import org.alfresco.service.cmr.workflow.WorkflowTaskState;
import org.alfresco.service.cmr.workflow.WorkflowTimer; import org.alfresco.service.cmr.workflow.WorkflowTimer;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -72,6 +81,9 @@ public class WorkflowServiceImpl implements WorkflowService
private WorkflowPackageComponent workflowPackageComponent; private WorkflowPackageComponent workflowPackageComponent;
private NodeService nodeService; private NodeService nodeService;
private ContentService contentService; private ContentService contentService;
private AVMSyncService avmSyncService;
private DictionaryService dictionaryService;
private NodeService protectedNodeService;
/** /**
@@ -97,7 +109,7 @@ public class WorkflowServiceImpl implements WorkflowService
/** /**
* Sets the Workflow Package Component * Sets the Workflow Package Component
* *
* @param workflowPackage workflow package component * @param workflowPackageComponent workflow package component
*/ */
public void setWorkflowPackageComponent(WorkflowPackageComponent workflowPackageComponent) public void setWorkflowPackageComponent(WorkflowPackageComponent workflowPackageComponent)
{ {
@@ -124,6 +136,34 @@ public class WorkflowServiceImpl implements WorkflowService
this.contentService = contentService; this.contentService = contentService;
} }
/**
* Set the avm sync service
* @param avmSyncService
*/
public void setAvmSyncService(AVMSyncService avmSyncService)
{
this.avmSyncService = avmSyncService;
}
/**
* Set the dictionary service
*
* @param dictionaryService
*/
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Set the node service which applies permissions
* @param protectedNodeService
*/
public void setProtectedNodeService(NodeService protectedNodeService)
{
this.protectedNodeService = protectedNodeService;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(java.lang.String, java.io.InputStream, java.lang.String) * @see org.alfresco.service.cmr.workflow.WorkflowService#deployDefinition(java.lang.String, java.io.InputStream, java.lang.String)
@@ -573,4 +613,83 @@ public class WorkflowServiceImpl implements WorkflowService
return component; return component;
} }
public List<NodeRef> getPackageContents(String taskId)
{
WorkflowTask workflowTask = getTaskById(taskId);
List<NodeRef> contents = new ArrayList<NodeRef>();
if(workflowTask != null)
{
NodeRef workflowPackage = (NodeRef)workflowTask.properties.get(WorkflowModel.ASSOC_PACKAGE);
if (workflowPackage.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
{
if (protectedNodeService.exists(workflowPackage))
{
final NodeRef stagingNodeRef = (NodeRef)
protectedNodeService.getProperty(workflowPackage,
WCMModel.PROP_AVM_DIR_INDIRECTION);
final String stagingAvmPath = AVMNodeConverter.ToAVMVersionPath(stagingNodeRef).getSecond();
final String packageAvmPath = AVMNodeConverter.ToAVMVersionPath(workflowPackage).getSecond();
if (logger.isDebugEnabled())
logger.debug("comparing " + packageAvmPath + " with " + stagingAvmPath);
for (AVMDifference d : avmSyncService.compare(-1, packageAvmPath,
-1, stagingAvmPath,
null))
{
if (logger.isDebugEnabled())
logger.debug("got difference " + d);
if (d.getDifferenceCode() == AVMDifference.NEWER ||
d.getDifferenceCode() == AVMDifference.CONFLICT)
{
contents.add(AVMNodeConverter.ToNodeRef(d.getSourceVersion(), d.getSourcePath()));
}
}
}
}
else
{
// get existing workflow package items
List<ChildAssociationRef> childRefs = protectedNodeService.getChildAssocs(
workflowPackage, ContentModel.ASSOC_CONTAINS,
RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref: childRefs)
{
// create our Node representation from the NodeRef
NodeRef nodeRef = ref.getChildRef();
if (!protectedNodeService.exists(nodeRef))
{
if (logger.isDebugEnabled())
logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
}
else
{
// find it's type so we can see if it's a node we are interested in
QName type = protectedNodeService.getType(nodeRef);
// make sure the type is defined in the data dictionary
TypeDefinition typeDef = dictionaryService.getType(type);
if (typeDef == null)
{
if (logger.isWarnEnabled())
logger.warn("Found invalid object in database: id = " + nodeRef +
", type = " + type);
}
else
{
contents.add(nodeRef);
}
}
}
}
}
return contents;
}
} }

View File

@@ -25,23 +25,48 @@
package org.alfresco.repo.workflow.jscript; package org.alfresco.repo.workflow.jscript;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.jscript.ScriptableHashMap;
import org.alfresco.repo.jscript.ScriptableQNameMap; import org.alfresco.repo.jscript.ScriptableQNameMap;
import org.alfresco.repo.template.AVMTemplateNode;
import org.alfresco.repo.template.TemplateContent;
import org.alfresco.repo.template.TemplateNode;
import org.alfresco.repo.workflow.WorkflowModel;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.Pair;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.Scriptable;
/** /**
* This class represents a workflow task (an instance of a workflow * This class represents a workflow task (an instance of a workflow task definition)
* task definition)
* *
* @author glenj * @author glenj
*
*/ */
public class JscriptWorkflowTask implements Serializable public class JscriptWorkflowTask implements Serializable
{ {
private static final String WCM_WF_MODEL_1_0_URI = "http://www.alfresco.org/model/wcmworkflow/1.0";
private static final QName PROP_FROM_PATH = QName.createQName(WCM_WF_MODEL_1_0_URI, "fromPath");
static final long serialVersionUID = -8285971359421912313L; static final long serialVersionUID = -8285971359421912313L;
/** Unique ID for workflow task */ /** Unique ID for workflow task */
@@ -68,18 +93,31 @@ public class JscriptWorkflowTask implements Serializable
/** Service Registry object */ /** Service Registry object */
private ServiceRegistry serviceRegistry; private ServiceRegistry serviceRegistry;
/** Available transitions * */
private ScriptableHashMap<String, String> transitions;
/** Package resources * */
private Scriptable packageResources;
/** /**
* Creates a new instance of a workflow task (instance of a workflow task definition) * Creates a new instance of a workflow task (instance of a workflow task definition)
* *
* @param id workflow task ID * @param id
* @param name workflow task name * workflow task ID
* @param title workflow task title * @param name
* @param description workflow task description * workflow task name
* @param serviceRegistry Service Registry object * @param title
* workflow task title
* @param description
* workflow task description
* @param serviceRegistry
* Service Registry object
* @param properties
* @param transitions
* @param packageResources
*/ */
public JscriptWorkflowTask(final String id, final String name, final String title, public JscriptWorkflowTask(final String id, final String name, final String title, final String description, final ServiceRegistry serviceRegistry,
final String description, final ServiceRegistry serviceRegistry, final ScriptableQNameMap<String, Serializable> properties, final ScriptableHashMap<String, String> transitions, Scriptable packageResources)
final ScriptableQNameMap<String, Serializable> properties)
{ {
this.id = id; this.id = id;
this.name = name; this.name = name;
@@ -87,17 +125,19 @@ public class JscriptWorkflowTask implements Serializable
this.description = description; this.description = description;
this.serviceRegistry = serviceRegistry; this.serviceRegistry = serviceRegistry;
this.properties = properties; this.properties = properties;
this.transitions = transitions;
this.packageResources = packageResources;
} }
/** /**
* Creates a new instance of a workflow task from a WorkflowTask from the CMR * Creates a new instance of a workflow task from a WorkflowTask from the CMR workflow object model
* workflow object model
* *
* @param cmrWorkflowTask an instance of WorkflowTask from CMR workflow object model * @param cmrWorkflowTask
* @param serviceRegistry Service Registry object * an instance of WorkflowTask from CMR workflow object model
* @param serviceRegistry
* Service Registry object
*/ */
public JscriptWorkflowTask(final WorkflowTask cmrWorkflowTask, public JscriptWorkflowTask(final WorkflowTask cmrWorkflowTask, final ServiceRegistry serviceRegistry)
final ServiceRegistry serviceRegistry)
{ {
this.id = cmrWorkflowTask.id; this.id = cmrWorkflowTask.id;
this.name = cmrWorkflowTask.name; this.name = cmrWorkflowTask.name;
@@ -107,8 +147,7 @@ public class JscriptWorkflowTask implements Serializable
// instantiate ScriptableQNameMap<String, Serializable> properties // instantiate ScriptableQNameMap<String, Serializable> properties
// from WorkflowTasks's Map<QName, Serializable> properties // from WorkflowTasks's Map<QName, Serializable> properties
this.properties = new ScriptableQNameMap<String, Serializable>( this.properties = new ScriptableQNameMap<String, Serializable>(serviceRegistry.getNamespaceService());
serviceRegistry.getNamespaceService());
Set<QName> keys = cmrWorkflowTask.properties.keySet(); Set<QName> keys = cmrWorkflowTask.properties.keySet();
for (QName key : keys) for (QName key : keys)
@@ -116,6 +155,59 @@ public class JscriptWorkflowTask implements Serializable
Serializable value = cmrWorkflowTask.properties.get(key); Serializable value = cmrWorkflowTask.properties.get(key);
this.properties.put(key.toString(), value); this.properties.put(key.toString(), value);
} }
transitions = new ScriptableHashMap<String, String>();
for (WorkflowTransition transition : cmrWorkflowTask.path.node.transitions)
{
transitions.put(transition.id, transition.title);
}
// build package context .... should be centralised... YUK
// Needs to match org.alfresco.repo.template.Workflow.WorkflowTaskItem.getPackageResources
NodeRef workflowPackage = (NodeRef) cmrWorkflowTask.properties.get(WorkflowModel.ASSOC_PACKAGE);
List<NodeRef> contents = serviceRegistry.getWorkflowService().getPackageContents(cmrWorkflowTask.id);
List<NodeRef> resources = new ArrayList<NodeRef>(contents.size());
NodeService nodeService = serviceRegistry.getNodeService();
DictionaryService ddService = serviceRegistry.getDictionaryService();
for (NodeRef nodeRef : contents)
{
if (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
{
resources.add(nodeRef);
}
else
{
if (nodeService.exists(nodeRef))
{
// find it's type so we can see if it's a node we are interested in
QName type = nodeService.getType(nodeRef);
// make sure the type is defined in the data dictionary
if (ddService.getType(type) != null)
{
// look for content nodes or links to content
// NOTE: folders within workflow packages are ignored for now
if (ddService.isSubClass(type, ContentModel.TYPE_CONTENT) || ApplicationModel.TYPE_FILELINK.equals(type))
{
resources.add(nodeRef);
}
}
}
}
}
Object[] answer = new Object[resources.size()];
for (int i = 0; i < resources.size(); i++)
{
// create our Node representation from the NodeRef
answer[i] = new ScriptNode(resources.get(i), serviceRegistry, null);
}
packageResources = Context.getCurrentContext().newArray(null, answer);
} }
/** /**
@@ -171,7 +263,8 @@ public class JscriptWorkflowTask implements Serializable
/** /**
* Sets the value of the <code>properties</code> property * Sets the value of the <code>properties</code> property
* *
* @param properties the properties to set * @param properties
* the properties to set
*/ */
public void setProperties(ScriptableQNameMap<String, Serializable> properties) public void setProperties(ScriptableQNameMap<String, Serializable> properties)
{ {
@@ -179,8 +272,7 @@ public class JscriptWorkflowTask implements Serializable
} }
/** /**
* Returns whether the task is complete * Returns whether the task is complete 'true':complete, 'false':in-progress
* 'true':complete, 'false':in-progress
* *
* @return the complete * @return the complete
*/ */
@@ -202,7 +294,8 @@ public class JscriptWorkflowTask implements Serializable
/** /**
* Sets whether task is pooled('true') or not('false') * Sets whether task is pooled('true') or not('false')
* *
* @param pooled the pooled to set * @param pooled
* the pooled to set
*/ */
public void setPooled(boolean pooled) public void setPooled(boolean pooled)
{ {
@@ -212,10 +305,32 @@ public class JscriptWorkflowTask implements Serializable
/** /**
* End the task * End the task
* *
* @param transition transition to end the task for * @param transition
* transition to end the task for
*/ */
public void endTask(String transitionId) public void endTask(String transitionId)
{ {
serviceRegistry.getWorkflowService().endTask(this.id, transitionId); serviceRegistry.getWorkflowService().endTask(this.id, transitionId);
} }
/**
* Get the available transition ids.
*
* @return
*/
public ScriptableHashMap<String, String> getTransitions()
{
return transitions;
}
/**
* Get the packe resources (array of noderefs)
*
* @return
*/
public Scriptable getPackageResources()
{
return packageResources;
}
} }

View File

@@ -384,4 +384,11 @@ public interface WorkflowService
@Auditable(key = Auditable.Key.ARG_0, parameters = {"packageItem", "active"}) @Auditable(key = Auditable.Key.ARG_0, parameters = {"packageItem", "active"})
public List<WorkflowInstance> getWorkflowsForContent(NodeRef packageItem, boolean active); public List<WorkflowInstance> getWorkflowsForContent(NodeRef packageItem, boolean active);
/**
* Get a list of node refs to all the package contents for the given task id.
* @param taskId - the task id
* @return - A list of NodeRefs
*/
@Auditable(key = Auditable.Key.ARG_0, parameters = {"packageItem", "active"})
public List<NodeRef> getPackageContents(String taskId);
} }