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

@@ -43,6 +43,7 @@ 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.repository.TemplateImageResolver;
import org.alfresco.service.cmr.workflow.WorkflowService;
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.QNameMap;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.Pair;
/**
* Workflow and task support in FreeMarker templates.
@@ -246,52 +248,33 @@ public class Workflow extends BaseTemplateProcessorExtension
public List<TemplateContent> getPackageResources()
{
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();
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 (nodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM))
{
if (d.getDifferenceCode() == AVMDifference.NEWER ||
d.getDifferenceCode() == AVMDifference.CONFLICT)
{
resources.add(new AVMTemplateNode(
d.getSourcePath(), d.getSourceVersion(), this.services, this.resolver));
}
Pair<Integer, String> vp = AVMNodeConverter.ToAVMVersionPath(nodeRef);
resources.add(new AVMTemplateNode(
vp.getSecond(), vp.getFirst(), this.services, this.resolver));
}
}
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)
else
{
// 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
if (ddService.getType(type) != null)
// 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))
{
// 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(new TemplateNode(nodeRef, this.services, this.resolver));
}
resources.add(new TemplateNode(nodeRef, this.services, this.resolver));
}
}
}

View File

@@ -33,10 +33,18 @@ import java.util.Map;
import java.util.Set;
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.ContentService;
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.security.AuthorityService;
import org.alfresco.service.cmr.security.AuthorityType;
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.WorkflowTimer;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -72,6 +81,9 @@ public class WorkflowServiceImpl implements WorkflowService
private WorkflowPackageComponent workflowPackageComponent;
private NodeService nodeService;
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
*
* @param workflowPackage workflow package component
* @param workflowPackageComponent workflow package component
*/
public void setWorkflowPackageComponent(WorkflowPackageComponent workflowPackageComponent)
{
@@ -124,7 +136,35 @@ public class WorkflowServiceImpl implements WorkflowService
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)
* @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;
}
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,197 +25,312 @@
package org.alfresco.repo.workflow.jscript;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
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.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.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.WorkflowTransition;
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;
/**
* This class represents a workflow task (an instance of a workflow
* task definition)
* This class represents a workflow task (an instance of a workflow task definition)
*
* @author glenj
*
*/
public class JscriptWorkflowTask implements Serializable
{
static final long serialVersionUID = -8285971359421912313L;
/** Unique ID for workflow task */
private final String id;
/** Name for workflow task */
private final String name;
/** Title for workflow task */
private final String title;
/** Description of workflow task */
private final String description;
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;
/** Unique ID for workflow task */
private final String id;
/** Name for workflow task */
private final String name;
/** Title for workflow task */
private final String title;
/** Description of workflow task */
private final String description;
/** Properties (key/value pairs) for this Workflow Task */
private ScriptableQNameMap<String, Serializable> properties;
/** Whether task is complete or not - 'true':complete, 'false':in-progress */
private boolean complete = false;
/** Whether task is pooled or not */
private boolean pooled = false;
/** Service Registry object */
private ServiceRegistry serviceRegistry;
/**
* Creates a new instance of a workflow task (instance of a workflow task definition)
*
* @param id workflow task ID
* @param name workflow task name
* @param title workflow task title
* @param description workflow task description
* @param serviceRegistry Service Registry object
*/
public JscriptWorkflowTask(final String id, final String name, final String title,
final String description, final ServiceRegistry serviceRegistry,
final ScriptableQNameMap<String, Serializable> properties)
{
this.id = id;
this.name = name;
this.title = title;
this.description = description;
this.serviceRegistry = serviceRegistry;
this.properties = properties;
}
/**
* Creates a new instance of a workflow task from a WorkflowTask from the CMR
* workflow object model
*
* @param cmrWorkflowTask an instance of WorkflowTask from CMR workflow object model
* @param serviceRegistry Service Registry object
*/
public JscriptWorkflowTask(final WorkflowTask cmrWorkflowTask,
final ServiceRegistry serviceRegistry)
{
this.id = cmrWorkflowTask.id;
this.name = cmrWorkflowTask.name;
this.title = cmrWorkflowTask.title;
this.description = cmrWorkflowTask.description;
this.serviceRegistry = serviceRegistry;
// instantiate ScriptableQNameMap<String, Serializable> properties
// from WorkflowTasks's Map<QName, Serializable> properties
this.properties = new ScriptableQNameMap<String, Serializable>(
serviceRegistry.getNamespaceService());
Set<QName> keys = cmrWorkflowTask.properties.keySet();
for (QName key : keys)
{
Serializable value = cmrWorkflowTask.properties.get(key);
this.properties.put(key.toString(), value);
}
}
/**
* Gets the value of the <code>id</code> property
*
* @return the id
*/
public String getId()
{
return id;
}
/** Available transitions * */
private ScriptableHashMap<String, String> transitions;
/**
* Gets the value of the <code>name</code> property
*
* @return the name
*/
public String getName()
{
return name;
}
/** Package resources * */
private Scriptable packageResources;
/**
* Gets the value of the <code>title</code> property
*
* @return the title
*/
public String getTitle()
{
return title;
}
/**
* Creates a new instance of a workflow task (instance of a workflow task definition)
*
* @param id
* workflow task ID
* @param name
* workflow task name
* @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, final String description, final ServiceRegistry serviceRegistry,
final ScriptableQNameMap<String, Serializable> properties, final ScriptableHashMap<String, String> transitions, Scriptable packageResources)
{
this.id = id;
this.name = name;
this.title = title;
this.description = description;
this.serviceRegistry = serviceRegistry;
this.properties = properties;
this.transitions = transitions;
this.packageResources = packageResources;
}
/**
* Gets the value of the <code>description</code> property
*
* @return the description
*/
public String getDescription()
{
return description;
}
/**
* Creates a new instance of a workflow task from a WorkflowTask from the CMR workflow object model
*
* @param cmrWorkflowTask
* an instance of WorkflowTask from CMR workflow object model
* @param serviceRegistry
* Service Registry object
*/
public JscriptWorkflowTask(final WorkflowTask cmrWorkflowTask, final ServiceRegistry serviceRegistry)
{
this.id = cmrWorkflowTask.id;
this.name = cmrWorkflowTask.name;
this.title = cmrWorkflowTask.title;
this.description = cmrWorkflowTask.description;
this.serviceRegistry = serviceRegistry;
/**
* Gets the value of the <code>properties</code> property
*
* @return the properties
*/
public Scriptable getProperties()
{
return properties;
}
// instantiate ScriptableQNameMap<String, Serializable> properties
// from WorkflowTasks's Map<QName, Serializable> properties
this.properties = new ScriptableQNameMap<String, Serializable>(serviceRegistry.getNamespaceService());
/**
* Sets the value of the <code>properties</code> property
*
* @param properties the properties to set
*/
public void setProperties(ScriptableQNameMap<String, Serializable> properties)
{
this.properties = properties;
}
Set<QName> keys = cmrWorkflowTask.properties.keySet();
for (QName key : keys)
{
Serializable value = cmrWorkflowTask.properties.get(key);
this.properties.put(key.toString(), value);
}
/**
* Returns whether the task is complete
* 'true':complete, 'false':in-progress
*
* @return the complete
*/
public boolean isComplete()
{
return complete;
}
transitions = new ScriptableHashMap<String, String>();
for (WorkflowTransition transition : cmrWorkflowTask.path.node.transitions)
{
transitions.put(transition.id, transition.title);
}
/**
* Returns whether this task is pooled or not
*
* @return 'true': task is pooled, 'false': task is not pooled
*/
public boolean isPooled()
{
return pooled;
}
// 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);
}
/**
* Gets the value of the <code>id</code> property
*
* @return the id
*/
public String getId()
{
return id;
}
/**
* Gets the value of the <code>name</code> property
*
* @return the name
*/
public String getName()
{
return name;
}
/**
* Gets the value of the <code>title</code> property
*
* @return the title
*/
public String getTitle()
{
return title;
}
/**
* Gets the value of the <code>description</code> property
*
* @return the description
*/
public String getDescription()
{
return description;
}
/**
* Gets the value of the <code>properties</code> property
*
* @return the properties
*/
public Scriptable getProperties()
{
return properties;
}
/**
* Sets the value of the <code>properties</code> property
*
* @param properties
* the properties to set
*/
public void setProperties(ScriptableQNameMap<String, Serializable> properties)
{
this.properties = properties;
}
/**
* Returns whether the task is complete 'true':complete, 'false':in-progress
*
* @return the complete
*/
public boolean isComplete()
{
return complete;
}
/**
* Returns whether this task is pooled or not
*
* @return 'true': task is pooled, 'false': task is not pooled
*/
public boolean isPooled()
{
return pooled;
}
/**
* Sets whether task is pooled('true') or not('false')
*
* @param pooled
* the pooled to set
*/
public void setPooled(boolean pooled)
{
this.pooled = pooled;
}
/**
* End the task
*
* @param transition
* transition to end the task for
*/
public void endTask(String 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;
}
/**
* Sets whether task is pooled('true') or not('false')
*
* @param pooled the pooled to set
*/
public void setPooled(boolean pooled)
{
this.pooled = pooled;
}
/**
* End the task
*
* @param transition transition to end the task for
*/
public void endTask(String transitionId)
{
serviceRegistry.getWorkflowService().endTask(this.id, transitionId);
}
}

View File

@@ -384,4 +384,11 @@ public interface WorkflowService
@Auditable(key = Auditable.Key.ARG_0, parameters = {"packageItem", "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);
}