Merged 1.4 to HEAD (More workflow)

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4166 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4167 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4183 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4184 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4206 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4207 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4215 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4216 .
   svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4301 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4302 .


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4534 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-12-06 18:34:19 +00:00
parent c4e2cabb12
commit 6e7b8ad98e
11 changed files with 313 additions and 18 deletions

View File

@@ -23,6 +23,12 @@ ok> use
## Workflow Definition Commands ## Workflow Definition Commands
## ##
ok> show file <definitionClassPath>
Output the contents of the file located at <definitionClassPath>.
<definitionClassPath> class path to workflow definition file.
ok> deploy <definitionClassPath> ok> deploy <definitionClassPath>
Deploy workflow definition to Alfresco server. Deploy workflow definition to Alfresco server.
@@ -61,8 +67,8 @@ ok> var <varName>[*]=<varValue>
e.g. e.g.
set bpm:assignee*=admin,fred var bpm:assignee*=admin,fred
set wf:notifyMe=true var wf:notifyMe=true
ok> var <varName>[*] person <varValue> ok> var <varName>[*] person <varValue>
@@ -74,7 +80,17 @@ ok> var <varName>[*] person <varValue>
e.g. e.g.
set bpm:assignee* person admin,fred var bpm:assignee* person admin,fred
ok> var <varName> package <itemCount>
Define or update a (bpm:workflowPackage) node ref variable.
A new workflow package is created containing <itemCount> content items.
e.g.
var bpm:package package 4
ok> var <varName>= ok> var <varName>=
@@ -129,6 +145,10 @@ ok> end workflow <workflowId>
End (cancel) the specified <workflowId>. End (cancel) the specified <workflowId>.
ok> delete workflow <workflowId>
Force deletion of the specified <workflowId>.
## ##
## Task Commands ## Task Commands
## ##

View File

@@ -34,6 +34,7 @@
<property name="nodeService" ref="NodeService"/> <property name="nodeService" ref="NodeService"/>
<property name="namespaceService" ref="namespaceService"/> <property name="namespaceService" ref="namespaceService"/>
<property name="personService" ref="PersonService"/> <property name="personService" ref="PersonService"/>
<property name="fileFolderService" ref="FileFolderService"/>
</bean> </bean>
<bean id="workflowInterpreterHelp" class="org.alfresco.i18n.ResourceBundleBootstrapComponent"> <bean id="workflowInterpreterHelp" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
@@ -87,6 +88,8 @@
<property name="nodeService" ref="nodeService"/> <property name="nodeService" ref="nodeService"/>
<property name="personService" ref="personService"/> <property name="personService" ref="personService"/>
<property name="serviceRegistry" ref="ServiceRegistry"/> <property name="serviceRegistry" ref="ServiceRegistry"/>
<property name="companyHomeStore"><value>${spaces.store}</value></property>
<property name="companyHomePath"><value>/${spaces.company_home.childname}</value></property>
</bean> </bean>
</beans> </beans>

View File

@@ -21,6 +21,7 @@ import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.service.Auditable;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
import org.alfresco.service.cmr.workflow.WorkflowDeployment; import org.alfresco.service.cmr.workflow.WorkflowDeployment;
import org.alfresco.service.cmr.workflow.WorkflowInstance; import org.alfresco.service.cmr.workflow.WorkflowInstance;
@@ -95,6 +96,15 @@ public interface WorkflowComponent
*/ */
public WorkflowDefinition getDefinitionByName(String workflowName); public WorkflowDefinition getDefinitionByName(String workflowName);
/**
* Gets a graphical view of the Workflow Definition
*
* @param workflowDefinitionId the workflow definition id
* @return graphical image of workflow definition
*/
@Auditable(parameters = {"workflowDefinitionId"})
public byte[] getDefinitionImage(String workflowDefinitionId);
// //
// Workflow Instance Support // Workflow Instance Support
@@ -142,6 +152,14 @@ public interface WorkflowComponent
*/ */
public WorkflowInstance cancelWorkflow(String workflowId); public WorkflowInstance cancelWorkflow(String workflowId);
/**
* Delete an "in-fligth" Workflow instance
*
* @param workflowId the workflow instance to cancel
* @return an updated representation of the workflow instance
*/
public WorkflowInstance deleteWorkflow(String workflowId);
/** /**
* Signal the transition from one Workflow Node to another within an "in-flight" * Signal the transition from one Workflow Node to another within an "in-flight"
* process. * process.

View File

@@ -30,12 +30,16 @@ import java.util.Map;
import org.alfresco.i18n.I18NUtil; import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncService; import org.alfresco.service.cmr.avmsync.AVMSyncService;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.repository.ContentWriter;
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.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
@@ -68,6 +72,8 @@ public class WorkflowInterpreter
private AVMService avmService; private AVMService avmService;
private AVMSyncService avmSyncService; private AVMSyncService avmSyncService;
private PersonService personService; private PersonService personService;
private FileFolderService fileFolderService;
/** /**
* The reader for interaction. * The reader for interaction.
@@ -162,6 +168,14 @@ public class WorkflowInterpreter
this.personService = personService; this.personService = personService;
} }
/**
* @param fileFolderService fileFolderService
*/
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
/** /**
* A Read-Eval-Print loop. * A Read-Eval-Print loop.
*/ */
@@ -250,6 +264,31 @@ public class WorkflowInterpreter
return "Syntax Error.\n"; return "Syntax Error.\n";
} }
else if (command[1].equals("file"))
{
if (command.length != 3)
{
return "Syntax Error.\n";
}
ClassPathResource file = new ClassPathResource(command[2]);
InputStream fileStream = file.getInputStream();
byte[] fileBytes = new byte[500];
try
{
int read = fileStream.read(fileBytes);
while (read != -1)
{
bout.write(fileBytes, 0, read);
read = fileStream.read(fileBytes);
}
}
finally
{
fileStream.close();
}
out.println();
}
else if (command[1].equals("definitions")) else if (command[1].equals("definitions"))
{ {
List<WorkflowDefinition> defs = workflowService.getDefinitions(); List<WorkflowDefinition> defs = workflowService.getDefinitions();
@@ -610,6 +649,28 @@ public class WorkflowInterpreter
} }
} }
else if (command[0].equals("delete"))
{
if (command.length < 3)
{
return "Syntax Error.\n";
}
else if (command[1].equals("workflow"))
{
String workflowId = (command.length == 3) ? command[2] : (currentPath == null) ? null : currentPath.instance.id;
if (workflowId == null)
{
return "Syntax Error. Workflow Id not specified.\n";
}
workflowService.deleteWorkflow(workflowId);
out.println("workflow " + workflowId + " deleted.");
}
else
{
return "Syntax Error.\n";
}
}
else if (command[0].equals("var")) else if (command[0].equals("var"))
{ {
if (command.length == 1) if (command.length == 1)
@@ -699,7 +760,6 @@ public class WorkflowInterpreter
} }
out.println("set var " + qname + " = " + vars.get(qname)); out.println("set var " + qname + " = " + vars.get(qname));
} }
else if (command[2].equals("avmpackage")) else if (command[2].equals("avmpackage"))
{ {
// lookup source folder of changes // lookup source folder of changes
@@ -741,7 +801,20 @@ public class WorkflowInterpreter
vars.put(qname, packageNodeRef); vars.put(qname, packageNodeRef);
out.println("set var " + qname + " = " + vars.get(qname)); out.println("set var " + qname + " = " + vars.get(qname));
} }
else if (command[2].equals("package"))
{
QName qname = QName.createQName(command[1], namespaceService);
int number = new Integer(command[3]);
NodeRef packageNodeRef = workflowService.createPackage(null);
for (int i = 0; i < number; i++)
{
FileInfo fileInfo = fileFolderService.create(packageNodeRef, "Content" + i, ContentModel.TYPE_CONTENT);
ContentWriter writer = fileFolderService.getWriter(fileInfo.getNodeRef());
writer.putContent("Content" + i);
}
vars.put(qname, packageNodeRef);
out.println("set var " + qname + " = " + vars.get(qname));
}
else else
{ {
return "Syntax Error.\n"; return "Syntax Error.\n";

View File

@@ -156,6 +156,21 @@ public class WorkflowServiceImpl implements WorkflowService
return component.getDefinitionByName(workflowName); return component.getDefinitionByName(workflowName);
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#getDefinitionImage(java.lang.String)
*/
public byte[] getDefinitionImage(String workflowDefinitionId)
{
String engineId = BPMEngineRegistry.getEngineId(workflowDefinitionId);
WorkflowComponent component = getWorkflowComponent(engineId);
byte[] definitionImage = component.getDefinitionImage(workflowDefinitionId);
if (definitionImage == null)
{
definitionImage = new byte[0];
}
return definitionImage;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#startWorkflow(java.lang.String, java.util.Map) * @see org.alfresco.service.cmr.workflow.WorkflowService#startWorkflow(java.lang.String, java.util.Map)
*/ */
@@ -217,6 +232,20 @@ public class WorkflowServiceImpl implements WorkflowService
return component.cancelWorkflow(workflowId); return component.cancelWorkflow(workflowId);
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#deleteWorkflow(java.lang.String)
*/
public WorkflowInstance deleteWorkflow(String workflowId)
{
String engineId = BPMEngineRegistry.getEngineId(workflowId);
WorkflowComponent component = getWorkflowComponent(engineId);
WorkflowInstance instance = component.deleteWorkflow(workflowId);
// NOTE: Delete workflow package after deleting workflow, so it's still available
// in process-end events of workflow definition
workflowPackageComponent.deletePackage(instance.workflowPackage);
return instance;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.workflow.WorkflowService#signal(java.lang.String, java.lang.String) * @see org.alfresco.service.cmr.workflow.WorkflowService#signal(java.lang.String, java.lang.String)
*/ */

View File

@@ -47,6 +47,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
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.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.PersonService; import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.cmr.workflow.WorkflowDefinition; import org.alfresco.service.cmr.workflow.WorkflowDefinition;
@@ -71,6 +72,7 @@ import org.jbpm.context.exe.ContextInstance;
import org.jbpm.context.exe.TokenVariableMap; import org.jbpm.context.exe.TokenVariableMap;
import org.jbpm.db.GraphSession; import org.jbpm.db.GraphSession;
import org.jbpm.db.TaskMgmtSession; import org.jbpm.db.TaskMgmtSession;
import org.jbpm.file.def.FileDefinition;
import org.jbpm.graph.def.Node; import org.jbpm.graph.def.Node;
import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.def.Transition; import org.jbpm.graph.def.Transition;
@@ -107,6 +109,10 @@ public class JBPMEngine extends BPMEngine
protected PersonService personService; protected PersonService personService;
protected JbpmTemplate jbpmTemplate; protected JbpmTemplate jbpmTemplate;
// Company Home
protected StoreRef companyHomeStore;
protected String companyHomePath;
// Note: jBPM query which is not provided out-of-the-box // Note: jBPM query which is not provided out-of-the-box
// TODO: Check jBPM 3.2 and get this implemented in jBPM // TODO: Check jBPM 3.2 and get this implemented in jBPM
private final static String COMPLETED_TASKS_QUERY = private final static String COMPLETED_TASKS_QUERY =
@@ -186,6 +192,26 @@ public class JBPMEngine extends BPMEngine
this.serviceRegistry = serviceRegistry; this.serviceRegistry = serviceRegistry;
} }
/**
* Sets the Company Home Path
*
* @param companyHomePath
*/
public void setCompanyHomePath(String companyHomePath)
{
this.companyHomePath = companyHomePath;
}
/**
* Sets the Company Home Store
*
* @param companyHomeStore
*/
public void setCompanyHomeStore(String companyHomeStore)
{
this.companyHomeStore = new StoreRef(companyHomeStore);
}
// //
// Workflow Definition... // Workflow Definition...
@@ -357,6 +383,31 @@ public class JBPMEngine extends BPMEngine
} }
} }
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#getDefinitionImage(java.lang.String)
*/
public byte[] getDefinitionImage(final String workflowDefinitionId)
{
try
{
return (byte[])jbpmTemplate.execute(new JbpmCallback()
{
@SuppressWarnings("synthetic-access")
public Object doInJbpm(JbpmContext context)
{
GraphSession graphSession = context.getGraphSession();
ProcessDefinition processDefinition = getProcessDefinition(graphSession, workflowDefinitionId);
FileDefinition fileDefinition = processDefinition.getFileDefinition();
return (fileDefinition == null) ? null : fileDefinition.getBytes("processimage.jpg");
}
});
}
catch(JbpmException e)
{
throw new WorkflowException("Failed to retrieve workflow definition image for '" + workflowDefinitionId + "'", e);
}
}
/** /**
* Gets a jBPM process definition * Gets a jBPM process definition
* *
@@ -404,10 +455,18 @@ public class JBPMEngine extends BPMEngine
// assign initial process context // assign initial process context
ContextInstance processContext = processInstance.getContextInstance(); ContextInstance processContext = processInstance.getContextInstance();
processContext.setVariable("cancelled", false);
NodeRef companyHome = getCompanyHome();
processContext.setVariable("companyhome", new JBPMNode(companyHome, serviceRegistry));
NodeRef initiatorPerson = mapNameToAuthority(currentUserName); NodeRef initiatorPerson = mapNameToAuthority(currentUserName);
if (initiatorPerson != null) if (initiatorPerson != null)
{ {
processContext.setVariable("initiator", new JBPMNode(initiatorPerson, serviceRegistry)); processContext.setVariable("initiator", new JBPMNode(initiatorPerson, serviceRegistry));
NodeRef initiatorHome = (NodeRef)nodeService.getProperty(initiatorPerson, ContentModel.PROP_HOMEFOLDER);
if (initiatorHome != null)
{
processContext.setVariable("initiatorhome", new JBPMNode(initiatorHome, serviceRegistry));
}
} }
// create the start task if one exists // create the start task if one exists
@@ -558,10 +617,41 @@ public class JBPMEngine extends BPMEngine
// retrieve and cancel process instance // retrieve and cancel process instance
GraphSession graphSession = context.getGraphSession(); GraphSession graphSession = context.getGraphSession();
ProcessInstance processInstance = getProcessInstance(graphSession, workflowId); ProcessInstance processInstance = getProcessInstance(graphSession, workflowId);
processInstance.getContextInstance().setVariable("cancelled", true);
processInstance.end();
// TODO: Determine if this is the most appropriate way to cancel workflow... // TODO: Determine if this is the most appropriate way to cancel workflow...
// It might be useful to record point at which it was cancelled etc // It might be useful to record point at which it was cancelled etc
WorkflowInstance workflowInstance = createWorkflowInstance(processInstance); WorkflowInstance workflowInstance = createWorkflowInstance(processInstance);
// delete the process instance
graphSession.deleteProcessInstance(processInstance, true, true, true);
return workflowInstance;
}
});
}
catch(JbpmException e)
{
throw new WorkflowException("Failed to cancel workflow instance '" + workflowId + "'", e);
}
}
/* (non-Javadoc)
* @see org.alfresco.repo.workflow.WorkflowComponent#cancelWorkflow(java.lang.String)
*/
public WorkflowInstance deleteWorkflow(final String workflowId)
{
try
{
return (WorkflowInstance) jbpmTemplate.execute(new JbpmCallback()
{
@SuppressWarnings("unchecked")
public Object doInJbpm(JbpmContext context)
{
// retrieve and cancel process instance
GraphSession graphSession = context.getGraphSession();
ProcessInstance processInstance = getProcessInstance(graphSession, workflowId);
WorkflowInstance workflowInstance = createWorkflowInstance(processInstance);
// delete the process instance // delete the process instance
graphSession.deleteProcessInstance(processInstance, true, true, true); graphSession.deleteProcessInstance(processInstance, true, true, true);
workflowInstance.active = false; workflowInstance.active = false;
@@ -1755,6 +1845,21 @@ public class JBPMEngine extends BPMEngine
return (label == null) ? defaultLabel : label; return (label == null) ? defaultLabel : label;
} }
/**
* Gets the Company Home
*
* @return company home node ref
*/
private NodeRef getCompanyHome()
{
// TODO: Determine if caching is required
List<NodeRef> refs = serviceRegistry.getSearchService().selectNodes(nodeService.getRootNode(companyHomeStore), companyHomePath, null, namespaceService, false);
if (refs.size() != 1)
{
throw new IllegalStateException("Invalid company home path: " + companyHomePath + " - found: " + refs.size());
}
return refs.get(0);
}
// //
// Workflow Data Object Creation... // Workflow Data Object Creation...
@@ -1888,7 +1993,7 @@ public class JBPMEngine extends BPMEngine
final String title = getLabel(name + ".workflow", TITLE_LABEL, name); final String title = getLabel(name + ".workflow", TITLE_LABEL, name);
final String description = getLabel(name + ".workflow", DESC_LABEL, title); final String description = getLabel(name + ".workflow", DESC_LABEL, title);
return new WorkflowDefinition(createGlobalId(new Long(definition.getId()).toString()), return new WorkflowDefinition(createGlobalId(new Long(definition.getId()).toString()),
name, createGlobalId(name),
new Integer(definition.getVersion()).toString(), new Integer(definition.getVersion()).toString(),
title, title,
description, description,

View File

@@ -87,7 +87,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML); WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
testWorkflowDef = deployment.definition; testWorkflowDef = deployment.definition;
assertNotNull(testWorkflowDef); assertNotNull(testWorkflowDef);
assertEquals("test", testWorkflowDef.name); assertEquals("jbpm$test", testWorkflowDef.name);
assertEquals("1", testWorkflowDef.version); assertEquals("1", testWorkflowDef.version);
assertTrue(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML)); assertTrue(workflowComponent.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML));
@@ -119,7 +119,7 @@ public class JBPMEngineTest extends BaseSpringTest
WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML); WorkflowDeployment deployment = workflowComponent.deployDefinition(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML);
testWorkflowDef = deployment.definition; testWorkflowDef = deployment.definition;
assertNotNull(testWorkflowDef); assertNotNull(testWorkflowDef);
assertEquals("test", testWorkflowDef.name); assertEquals("jbpm$test", testWorkflowDef.name);
assertEquals("2", testWorkflowDef.version); assertEquals("2", testWorkflowDef.version);
} }

View File

@@ -34,6 +34,8 @@
<task-node name="review"> <task-node name="review">
<event type="node-enter"> <event type="node-enter">
<script> <script>
System.out.println("company home: " + companyhome.name);
System.out.println("initiator home: " + initiatorhome.name);
System.out.println("the reviewer is " + reviewer); System.out.println("the reviewer is " + reviewer);
System.out.println("node " + testNode.name + " contains " + testNode.children.length + " children"); System.out.println("node " + testNode.name + " contains " + testNode.children.length + " children");
System.out.println("scriptResult = " + scriptResult); System.out.println("scriptResult = " + scriptResult);

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1" name="test_processevents">
<event type="process-start">
<script>
System.out.println("Process start");
</script>
</event>
<start-state name="start">
<transition to="end"/>
</start-state>
<end-state name="end"/>
<event type="process-end">
<script>
if (cancelled) { System.out.println("cancelled"); }
System.out.println("Process end: " + cancelled);
</script>
</event>
</process-definition>

View File

@@ -89,6 +89,6 @@ public class WorkflowDefinition
*/ */
public String toString() public String toString()
{ {
return "WorkflowDefinition[id=" + id + ",version=" + version + ",title=" + title + ",startTask=" + startTaskDefinition.toString() + "]"; return "WorkflowDefinition[id=" + id + ",name=" + name + ",version=" + version + ",title=" + title + ",startTask=" + ((startTaskDefinition == null) ? "undefined" : startTaskDefinition.toString()) + "]";
} }
} }

View File

@@ -114,6 +114,15 @@ public interface WorkflowService
@Auditable(parameters = {"workflowName"}) @Auditable(parameters = {"workflowName"})
public WorkflowDefinition getDefinitionByName(String workflowName); public WorkflowDefinition getDefinitionByName(String workflowName);
/**
* Gets a graphical view of the Workflow Definition
*
* @param workflowDefinitionId the workflow definition id
* @return image view of the workflow definition
*/
@Auditable(parameters = {"workflowDefinitionId"})
public byte[] getDefinitionImage(String workflowDefinitionId);
// //
// Workflow Instance Management // Workflow Instance Management
@@ -176,6 +185,18 @@ public interface WorkflowService
@Auditable(parameters = {"workflowId"}) @Auditable(parameters = {"workflowId"})
public WorkflowInstance cancelWorkflow(String workflowId); public WorkflowInstance cancelWorkflow(String workflowId);
/**
* Delete an "in-fligth" Workflow instance
*
* NOTE: This will force a delete, meaning that the workflow instance may not
* go through all the appropriate cancel events.
*
* @param workflowId the workflow instance to cancel
* @return an updated representation of the workflow instance
*/
@Auditable(parameters = {"workflowId"})
public WorkflowInstance deleteWorkflow(String workflowId);
/** /**
* Signal the transition from one Workflow Node to another * Signal the transition from one Workflow Node to another
* *