Working with Workflow-related Objects
You can create and retrieve WorkflowDefinition objects, set and
retrieve properties and permissions for them, transfer them to Process Engine, and start them from workflow
subscriptions.
The following code examples demonstrate workflow-related operations. For an overview of workflows on the Content Engine, see Workflows. For more subscription code examples, see Working with Subscriptions.
Creating a WorkflowDefinition Object
The following Java™ and C# examples illustrate how to create
a WorkflowDefinition object, persist it to an object
store, and file it into a specified folder. To start, the Factory class
is used to create a new WorkflowDefinition object.
Two properties are set on the object, a document title and the object's
content elements, represented by a ContentTransfer class. Note that
a ContentTransfer object is set with the content
of the WorkflowDefinition.pep file and with the
content type. When a WorkflowDefinition object is
checked in and saved, the Content Engine automatically
places the object in its system Workflow Definitions folder.
The code also files the WorkflowDefinition object
in a specified folder, Payroll. Because the folder.file call
specifies a null value for the document name, the default name, which
is the name set in the DocumentTitle property, of the WorkflowDefinition object
is used.
You can optionally set permissions when you
create a WorkflowDefinition object. For a code sample,
see Setting Permissions.
Java Example
public void createWorkflowDefinition(ObjectStore os) throws Exception
{
// Create WorkflowDefinition and set properties.
WorkflowDefinition wdNew = Factory.WorkflowDefinition.createInstance(os,
(GuidConstants.Class_WorkflowDefinition).toString());
wdNew.getProperties().putValue("DocumentTitle", "Submit Timecards");
try
{
// Create input stream and set it on ContentTransfer object.
FileInputStream inputStream = new FileInputStream("c:\\WorkflowDefinition.pep");
// non-Windows: FileInputStream inputStream = new FileInputStream("/tmp/WorkflowDefinition.pep");
ContentTransfer ctNew = Factory.ContentTransfer.createInstance();
ContentElementList contentList = Factory.ContentElement.createList();
ctNew.setCaptureSource(inputStream);
ctNew.set_ContentType("application/x-filenet-workflowdefinition");
contentList.add(ctNew);
// Set list of ContentTransfer objects on workflow definition.
wdNew.set_ContentElements(contentList);
}
catch (Exception e)
{
throw new Exception(e);
}
// Check in workflow definition.
wdNew.checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);
wdNew.save(RefreshMode.REFRESH);
// File workflow definition into a folder.
Folder folder=Factory.Folder.getInstance(os, ClassNames.FOLDER, "/Payroll");
DynamicReferentialContainmentRelationship drcr =
(DynamicReferentialContainmentRelationship)folder.file((IndependentlyPersistableObject)wdNew,
AutoUniqueName.AUTO_UNIQUE,
null,
DefineSecurityParentage.DO_NOT_DEFINE_SECURITY_PARENTAGE);
drcr.save(RefreshMode.NO_REFRESH);
}
C# Example
public void CreateWorkflowDefinition(IObjectStore os)
{
// Create WorkflowDefinition and set properties.
IWorkflowDefinition wdNew = Factory.WorkflowDefinition.CreateInstance(os,
(GuidConstants.Class_WorkflowDefinition).ToString());
wdNew.Properties["DocumentTitle"] = "Submit Timecards";
// Create input stream and set it on ContentTransfer object.
try
{
Stream fileStream = File.OpenRead(@"C:\\WorkflowDefinition.pep");
IContentTransfer ctNew = Factory.ContentTransfer.CreateInstance();
IContentElementList contentList = Factory.ContentElement.CreateList();
ctNew.SetCaptureSource(fileStream);
ctNew.ContentType="application/x-filenet-workflowdefinition";
contentList.Add(ctNew);
wdNew.ContentElements=contentList;
}
catch (Exception e)
{
throw new Exception("Error getting content from workflow", e);
}
// Check in workflow definition.
wdNew.Checkin(AutoClassify.DO_NOT_AUTO_CLASSIFY, CheckinType.MAJOR_VERSION);
wdNew.Save(RefreshMode.REFRESH);
// File workflow definition into a folder.
IFolder folder=Factory.Folder.GetInstance(os, ClassNames.FOLDER, "/Payroll");
IDynamicReferentialContainmentRelationship drcr =
(IDynamicReferentialContainmentRelationship)folder.File((IIndependentlyPersistableObject)wdNew,
AutoUniqueName.AUTO_UNIQUE,
null,
DefineSecurityParentage.DO_NOT_DEFINE_SECURITY_PARENTAGE);
drcr.Save(RefreshMode.NO_REFRESH);
}
Retrieving a WorkflowDefinition Object
The following Java and C# examples show how to retrieve a
workflow definition that is to be used in a workflow subscription. Because
a workflow subscription can work only with a workflow definition that
exists on Process Engine, the
examples test the workflow definition's VWVersion property, which
is the identifier of a transferred workflow definition. Note that
in the Java example, the test
involves the use of the VWSession object in the Process Java API, whereas the C# example
does not. That's because Process Engine does
not include a .NET API.
The Java example
shows two methods. The first method, getWorkFlowDefinitionDocument,
uses the VWSession object to test the validity of
the workflow definition. This first method calls the second method, getVWSession,
which uses the Process Java API
to create and return the VWSession object. To create
a VWSession object, the Process Engine connection point identifier
and the Content Engine URI are
required.
When the VWSession object
is returned, its checkWorkflowIdentifier method is
called, indicating whether the workflow is on Process Engine, based on the specified
workflow identifier. This call provides an extra check because it
is possible that a workflow definition was previously transferred,
but, because of some unforeseen event, no longer exists on Process Engine. If there is no workflow
on Process Engine, then the transferWorkflowDefinition method
is called, which performs the transfer and returns an identifier that
is set on the VWVersion property of the workflow definition.
Java Example
public WorkflowDefinition getWorkFlowDefinitionDocument(ObjectStore os, String conn_point, String ceUri,
String workflowDefinitionId ) throws Exception
{
// Get the Workflow Definition document object.
PropertyFilter pf = new PropertyFilter();
pf.addIncludeProperty(new FilterElement(null, null, null, PropertyNames.VWVERSION, null));
WorkflowDefinition wfdDocument = Factory.WorkflowDefinition.fetchInstance( os, new Id(workflowDefinitionId), pf );
// Get the current VW version number.
String vwCurrentVersion = wfdDocument.get_VWVersion();
// Calls method getVWSession to get the VWSession object, which represents the Process Engine session.
VWSession vwSession = getVWSession(conn_point, ceUri);
// Test validity of current VW version number. If it's invalid,
// call the transferWorkflowDefinition.
if ( vwCurrentVersion == null || !vwSession.checkWorkflowIdentifier(vwCurrentVersion) )
{
String vwNewVersion;
System.out.println("Workflow definition does not have a VW version number, or it is not up to date");
vwNewVersion = transferWorkflowDefinition(os, vwSession, wfdDocument);
wfdDocument.set_VWVersion(vwNewVersion);
wfdDocument.save(RefreshMode.REFRESH);
}
return wfdDocument;
}
//Returns the Process Engine session.
public VWSession getVWSession(String conn_point, String ceUri) throws Exception
{
VWSession vwSession=new VWSession();
vwSession.setBootstrapCEURI(ceUri);
try
{
vwSession.logon(conn_point);
}
catch (VWException vwe)
{
throw new Exception("Cannot connect to the connection point.");
}
return vwSession;
}
C# Example
public IWorkflowDefinition GetWorkFlowDefinitionDocument(IObjectStore os, String workflowDefinitionId )
{
// Get the Workflow Definition document object.
PropertyFilter pf = new PropertyFilter();
pf.AddIncludeProperty(new FilterElement(null, null, null, PropertyNames.VWVERSION, null));
IWorkflowDefinition wfdDocument = Factory.WorkflowDefinition.FetchInstance( os, new Id(workflowDefinitionId), pf );
// To determine if the workflow definition has previously been transferred to Process Engine,
// get and test the VW version number.
String vwCurrentVersion = wfdDocument.VWVersion;
if (vwCurrentVersion == null)
{
throw new Exception("Workflow definition has not been transferred to Process Engine.\n" +
"Use Process Designer to transfer the workflow.");
}
// Return the Workflow Definition document.
return wfdDocument;
}
Transferring a Workflow Definition to the Process Engine
The following Java example shows how to programmatically transfer a workflow definition with the Content Engine Java API and the Process Java API. There is no .NET API for Process Engine. If you are using the Content Engine .NET API, you must use the Process Designer application to manually transfer a workflow definition.
The example
consists of two methods. The first, transferWorkflowDefinition,
transfers a specified Content Engine workflow
definition to Process Engine.
This method calls the second method, getContents,
which retrieves the content of the workflow definition and returns
it in the form of an InputStream object.
The transferWorkflowDefinition method uses the
following objects from the Process Engine Java API:
VWWorkflowDefinitionobject represents a workflow definition to be transferred to Process Engine and compiled as a workflow. The object is created from the content of the workflow definition on Content Engine.VWSessionrepresents a Process Engine session. It is used to transfer theVWWorkflowDefinitionobject to Process Engine.VWTransferResultobject is returned by thevwSession.transfercall, and is used to assess the result of the call.
Java Example
public String transferWorkflowDefinition(ObjectStore os, VWSession vwSession,
WorkflowDefinition workflowDocCE) throws Exception
{
String workflowVersion = null;
// In addition to the VWSession object, the following Process Java API objects are used.
VWWorkflowDefinition workflowDocPE = new VWWorkflowDefinition();
VWTransferResult transferResult = null;
// Get the definition content from the Content Engine object store to be transferred to Process Engine.
// Calls getContents method.
workflowDocPE = VWWorkflowDefinition.read( getContents(os.get_Name(), workflowDocCE) );
// Get the current version series id and use it to create a unique name for the transferred workflow.
String verSerId = workflowDocCE.get_VersionSeries().get_Id().toString();
String canonicalName = "document" + ":" + os.get_Name() + ":" + verSerId + ":" + workflowDocCE.get_Id().toString();
// Transfer the workflow.
try {
transferResult = vwSession.transfer(workflowDocPE, canonicalName, false, false);
}
catch (VWException e)
{
throw new Exception (e.getCauseDescription());
}
if ( ! transferResult.success() )
throw new Exception("Failed to transfer workflow definition");
else
workflowVersion = transferResult.getVersion();
// Return identifier of transferred workflow definition.
return workflowVersion;
}
// Returns the workflow definition content.
public InputStream getContents(String objectStoreName, WorkflowDefinition workflowDocCE) throws Exception
{
InputStream inStream = null;
ContentElementList contentList = Factory.ContentElement.createList();
ContentTransfer ctObject;
contentList = workflowDocCE.get_ContentElements();
try {
ctObject = (ContentTransfer) contentList.get(0);
}
catch (Exception e)
{
throw new Exception("Failed to retrieve document content.");
}
inStream = ctObject.accessContentStream();
return inStream;
}
Creating a Workflow Subscription Object
The following Java and C# examples show you how
to create an InstanceWorkflowSubscription object
for a target Document object and a ClassWorkflowSubscription for
the target DocumentClassDefinition class. The code
for creating these two types of workflow subscriptions is nearly identical.
In the examples, the code specific to creating a class workflow subscription
is commented out.
You can optionally set permissions when you create a workflow subscription. For a code sample, see Setting Permissions .
Java Example
public void addWorkflowSubscription(ObjectStore os, Domain domain, String conn_point, String ceUri,
String workflowDefinitionId, String targetObjectId, String eventActionGuid) throws Exception
{
// Create an instance workflow subscription.
InstanceWorkflowSubscription wfSubscription =
Factory.InstanceWorkflowSubscription.createInstance(os, ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION);
// Create a class workflow subscription.
/* ClassWorkflowSubscription wfSubscription =
Factory.ClassWorkflowSubscription.createInstance(os, ClassNames.CLASS_WORKFLOW_SUBSCRIPTION);*/
// Get the target document.
Document targetObject = Factory.Document.getInstance( os, "Document", new Id(targetObjectId) );
// Get the target class.
// DocumentClassDefinition targetObject = Factory.DocumentClassDefinition.getInstance(os, new Id(targetObjectId) );
// Get the workflow definition document. Calls method getWorkFlowDefinitionDocument.
WorkflowDefinition workflowDefDocument = getWorkFlowDefinitionDocument(os, conn_point, uri, workflowDefinitionId);
// Get the event action.
WorkflowEventAction eventAction = Factory.WorkflowEventAction.getInstance(os, ClassNames.WORKFLOW_EVENT_ACTION, new Id(eventActionGuid) );
// Create a list of subscribed events.
Id subscribedEventId = GuidConstants.Class_CheckoutEvent;
EventClassDefinition evDef = Factory.EventClassDefinition.getInstance(
os, subscribedEventId);
SubscribedEvent subEvent = Factory.SubscribedEvent.createInstance();
subEvent.set_EventClass(evDef);
SubscribedEventList subEventList = Factory.SubscribedEvent.createList();
subEventList.add(subEvent);
// Set subscription properties.
wfSubscription.set_SubscribedEvents(subEventList);
wfSubscription.set_SubscriptionTarget(targetObject);
wfSubscription.set_WorkflowDefinition(workflowDefDocument);
wfSubscription.set_EventAction(eventAction);
wfSubscription.set_DisplayName("InstanceWorkflowSubscriptionJava");
//wfSubscription.set_DisplayName("ClassWorkflowSubscriptionJava");
wfSubscription.set_VWVersion(workflowDefDocument.get_VWVersion());
PEConnectionPoint peConnPoint = Factory.PEConnectionPoint.fetchInstance(domain, conn_point, null);
wfSubscription.set_IsolatedRegionNumber(peConnPoint.get_IsolatedRegion().get_IsolatedRegionNumber());
// Save the subscription.
wfSubscription.save(RefreshMode.REFRESH);
}
C# Example
public void AddInstanceWorkflowSubscription(IObjectStore os, IDomain domain, String connPoint, String ceUri,
String workflowDefinitionId, String targetObjectId, String eventActionGuid)
{
// Create an instance workflow subscription.
IInstanceWorkflowSubscription wfSubscription =
Factory.InstanceWorkflowSubscription.CreateInstance(os, ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION);
// Create a class workflow subscription.
/* IClassWorkflowSubscription wfSubscription =
Factory.ClassWorkflowSubscription.CreateInstance(os, ClassNames.CLASS_WORKFLOW_SUBSCRIPTION);*/
// Get the target document.
IDocument targetDocument = Factory.Document.GetInstance(os, ClassNames.DOCUMENT, new Id(targetObjectId));
// Get the target class.
// IDocumentClassDefinition targetObject = Factory.DocumentClassDefinition.GetInstance(os, new Id(targetObjectId));
// Get the the workflow definition document. Calls method GetWorkFlowDefinitionDocument.
IWorkflowDefinition workflowDefDocument = GetWorkFlowDefinitionDocument(os, workflowDefinitionId);
// Get the event action.
IWorkflowEventAction eventAction = Factory.WorkflowEventAction.GetInstance(os, ClassNames.WORKFLOW_EVENT_ACTION, new Id(eventActionGuid));
// Create a list of subscribed events.
Id subscribedEventId = GuidConstants.Class_CheckoutEvent;
IEventClassDefinition evDef = Factory.EventClassDefinition.GetInstance(
os, subscribedEventId);
ISubscribedEvent subEvent = Factory.SubscribedEvent.CreateInstance();
subEvent.EventClass = evDef;
ISubscribedEventList subEventList = Factory.SubscribedEvent.CreateList();
subEventList.Add(subEvent);
// Set subscription properties.
wfSubscription.SubscribedEvents = subEventList;
wfSubscription.SubscriptionTarget = targetObject;
wfSubscription.WorkflowDefinition = workflowDefDocument;
wfSubscription.EventAction = eventAction;
wfSubscription.DisplayName = "InstanceWorkflowSubscriptionCSharp";
// wfSubscription.DisplayName = "ClassWorkflowSubscriptionCSharp";
wfSubscription.VWVersion = workflowDefDocument.VWVersion;
IPEConnectionPoint peConnPoint = Factory.PEConnectionPoint.FetchInstance(domain, connPoint, null);
wfSubscription.IsolatedRegionNumber = peConnPoint.IsolatedRegion.IsolatedRegionNumber;
// Save the subscription.
instanceWfSubscription.Save(RefreshMode.REFRESH);
}
Retrieving Workflow Subscriptions
You can retrieve a
single InstanceWorkflowSubscription or ClassWorkflowSubscription object
with a Factory method. You can also retrieve InstanceWorkflowSubscription and ClassWorkflowSubscription objects
from subscription-related collections as follows.
From SubscriptionSet Object
Get a SubscriptionSet object,
as described in Retrieving
Subscriptions. You can iterate a SubscriptionSet object
and filter for InstanceWorkflowSubscription and ClassWorkflowSubscription objects,
as shown in the Java and C#
code snippets.
Java Example
...
Iterator subscriptionsIter = subscriptions.iterator();
while (subscriptionsIter.hasNext())
{
Subscription subscription = (Subscription) subscriptionsIter.next();
String className = subscription.getClassName();
if ( className.equals(ClassNames.CLASS_WORKFLOW_SUBSCRIPTION) ) ||
( className.equals(ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION) )
{
System.out.println(className + " is " + subscription.get_DisplayName());
}
}
C# Example
...
foreach (ISubscription subscription in subscriptions)
{
String className = subscription.GetClassName();
if ( className.Equals(ClassNames.CLASS_WORKFLOW_SUBSCRIPTION) ||
className.Equals(ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION) )
{
System.Console.WriteLine(className + " is " + subscription.DisplayName);
}
}
From InstanceWorkflowSubscriptionSet Object
Get an InstanceWorkflowSubscriptionSet object
from these Subscribable subobjects: VersionSeries, Folder, Document,
and CustomObject. In the following Java and C# code snippets, an InstanceWorkflowSubscriptionSet object
is returned from a Document object's WorkflowSubscriptions
property. The code then iterates the collection for InstanceWorkflowSubscription objects.
Java Example
...
Document doc = Factory.Document.fetchInstance( os, new Id(targetDocId), null );
InstanceWorkflowSubscriptionSet instanceWfSubscriptions = doc.get_WorkflowSubscriptions();
subscriptionsIter = instanceWfSubscriptions.iterator();
while (subscriptionsIter.hasNext())
{
Subscription instanceWfSubscription = (Subscription) subscriptionsIter.next();
System.out.println(instanceWfSubscription.get_DisplayName());
}
C# Example
...
IDocument doc = Factory.Document.FetchInstance( os, new Id(targetDocId), null );
IInstanceWorkflowSubscriptionSet instanceWfSubscriptions = doc.WorkflowSubscriptions;
foreach (ISubscription subscription in instanceWfSubscriptions)
{
System.Console.WriteLine(subscription.DisplayName);
}
From a ClassWorkflowSubscriptionSet Object
Get a ClassWorkflowSubscriptionSet object
from a ClassDefinition subobject. In the following Java and C# code snippets, a ClassWorkflowSubscriptionSet object
is returned from a SubscribableClassDefinition object's
WorkflowSubscriptions property. The code then iterates the collection
for ClassWorkflowSubscription objects.
Java Example
...
SubscribableClassDefinition docClass = Factory.SubscribableClassDefinition.fetchInstance(os, targetClassGuid, null);
ClassWorkflowSubscriptionSet classWfSubscriptions = docClass.get_WorkflowSubscriptions();
subscriptionsIter = classWfSubscriptions.iterator();
while (subscriptionsIter.hasNext())
{
Subscription classWfSubscription = (Subscription) subscriptionsIter.next();
System.out.println(classWfSubscription.get_DisplayName());
}
C# Example
...
ISubscribableClassDefinition docClass = Factory.SubscribableClassDefinition.FetchInstance(os, targetClassGuid, null );
IClassWorkflowSubscriptionSet classWfSubscriptions = docClass.WorkflowSubscriptions;
foreach (ISubscription subscription in classWfSubscriptions)
{
System.Console.WriteLine(subscription.DisplayName);
}