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 launch them from workflow subscriptions.

This topic provides code examples for the following workflow-related operations:

For an overview of workflows on the Content Engine, see Workflow Concepts. For additional 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". Note that the folder.file call specifies a null value for the document name. This results in the default name of the WorkflowDefinition object being used, which is the name set in the DocumentTitle property.

You can optionally set permissions when you create a WorkflowDefinition object. For a code sample, see Setting Permissions .

Java Example

...
// Create WorkflowDefinition and set properties
WorkflowDefinition wdNew = Factory.WorkflowDefinition.createInstance(os, 
   (GuidConstants.Class_WorkflowDefinition).toString());
wdNew.getProperties().putValue("DocumentTitle", "Submit Timecards");

// Create input stream and set it on ContentTransfer object
FileInputStream inputStream = new FileInputStream("c:\\WorkflowDefinition.pep");
ContentTransfer ctNew = Factory.ContentTransfer.createInstance();
ContentTransferList contentList = Factory.ContentTransfer.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);

// 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

...
// 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
Stream fileStream = File.OpenRead(@"C:\\WorkflowDefinition.pep");
IContentTransfer ctNew = Factory.ContentTransfer.CreateInstance();
IContentTransferList contentList = Factory.ContentTransfer.CreateList();
ctNew.SetCaptureSource(fileStream);
ctNew.ContentType="application/x-filenet-workflowdefinition";
contentList.Add(ctNew);
wdNew.ContentElements=contentList;

// 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 only work 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, 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.

On the returned VWSession object, the getWorkFlowDefinitionDocument method calls the checkWorkflowIdentifier method, which indicates whether or not the workflow is on Process Engine, based on the specified workflow identifier. This call provides an additional check because it's possible that a workflow definition was previously transferred, but, for 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. See Transferring a Workflow Definition to the Process Engine for a code example.

Java Example

public WorkflowDefinition getWorkFlowDefinitionDocument(ObjectStore os, String conn_point, String ceUri, 
      String workflowDefinitionId ) throws Exception
{
   // Get the Workflow Definition document object.
   WorkflowDefinition wfdDocument = Factory.WorkflowDefinition.fetchInstance( os, new Id(workflowDefinitionId), null );

   // Get the current VW version number to test its validity.
   String vwCurrentVersion = wfdDocument.get_VWVersion();
   // Get the VWSession object for testing the VW version number.
   VWSession vwSession = getVWSession(conn_point, ceUri);
   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;
}

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.");
   }
   // Cannot get the vwSession object
   if (vwSession == null)
      throw new Exception("Cannot create a VWSession object.");
   return vwSession;
}

C# Example

public IWorkflowDefinition GetWorkFlowDefinitionDocument(IObjectStore os, String workflowDefinitionId )
{
   // Get the Workflow Definition document object.
   IWorkflowDefinition wfdDocument = Factory.WorkflowDefinition.FetchInstance( os, new Id(workflowDefinitionId), null );

   // 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 PE.\n" +
         "Use Process Designer to transfer the workflow.");
   }
   // Return the Workflow Definition document
   return wfdDocument;
}

Transferring a Workflow Definition to the Process Engine

This section shows you 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 following code example shows two methods. The first, transferWorkflowDefinition, transfers a specified workflow definition to Process Engine. This method calls the second method listed, getContents.

The transferWorkflowDefinition method uses the following objects from the Process Engine Java API:

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.
   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;
}

public InputStream getContents(String objectStoreName, WorkflowDefinition workflowDocCE) throws Exception
{
   InputStream inStream = null;
   ContentElementList contentList = Factory.ContentTransfer.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

This section shows you how to create an instance workflow subscription and a class workflow subscription. The code examples are nearly identical except that for an instance workflow subscription, an InstanceWorkflowSubscription object is created, and the object's subscription target is a specific object instance of type Document. For a class workflow subscription, a ClassWorkflowSubscription object is created, and the object's subscription target is a class object of type DocumentClassDefinition. For both the instance workflow subscription and class workflow subscription examples, the Factory class is used to create the workflow subscription object. Next, objects to be used in the subscription are retrieved, and a list of events to be used in the subscription is created. The required subscription properties are set and the subscription is saved. Content Engine automatically places a workflow subscription in its system "Subscriptions" folder.

Note that the getWorkflowDefinition method is called to retrieve the WorkflowDefinition object. For a code example, see Retrieving a WorkflowDefinition Object.

You can optionally set permissions when you create a workflow subscription. For a code sample, see Setting Permissions .

Instance Workflow Subscription

Java Example

public void addInstanceWorkflowSubscription(ObjectStore os, String conn_point, String ceUri, String workflowDefinitionId, 
      String targetDocId, String eventActionGuid) throws Exception
{
   // Create an instance workflow subscription
   InstanceWorkflowSubscription instanceWfSubscription =
      Factory.InstanceWorkflowSubscription.createInstance(os, ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION);

   // Get the target document, the workflow definition document, and the event action
   Document targetDocument = Factory.Document.getInstance( os, "Document", new Id(targetDocId) );
   WorkflowDefinition workflowDefDocument = getWorkFlowDefinitionDocument(os, conn_point, ceURI, workflowDefinitionId);
   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
   instanceWfSubscription.set_SubscribedEvents(subEventList);
   instanceWfSubscription.set_SubscriptionTarget(targetDocument);
   instanceWfSubscription.set_WorkflowDefinition(workflowDefDocument);
   instanceWfSubscription.set_EventAction(eventAction);

   instanceWfSubscription.set_DisplayName("InstanceWorkflowSubscriptionJava");
   instanceWfSubscription.set_VWVersion(workflowDefDocument.get_VWVersion());
   PEConnectionPoint peConnPoint = Factory.PEConnectionPoint.fetchInstance(domain, conn_point, null);
   instanceWfSubscription.set_IsolatedRegionNumber(peConnPoint.get_IsolatedRegion().get_IsolatedRegionNumber());

   // Save the subscription
   instanceWfSubscription.save(RefreshMode.REFRESH);
}

C# Example

public void AddInstanceWorkflowSubscription(IObjectStore os, String workflowDefinitionId, String targetDocId,
      String eventActionGuid, IDomain domain, String connPoint)
{

   // Create an instance workflow subscription
   IInstanceWorkflowSubscription instanceWfSubscription =
     Factory.InstanceWorkflowSubscription.CreateInstance(os, ClassNames.INSTANCE_WORKFLOW_SUBSCRIPTION);

   // Get the target document, the workflow definition document, and the event action
   IDocument targetDocument = Factory.Document.GetInstance(os, ClassNames.DOCUMENT, new Id(targetDocId));
   IWorkflowDefinition workflowDefDocument = GetWorkFlowDefinitionDocument(os, workflowDefinitionId);
   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
   instanceWfSubscription.SubscribedEvents = subEventList;
   instanceWfSubscription.SubscriptionTarget = targetDocument;
   instanceWfSubscription.WorkflowDefinition = workflowDefDocument;
   instanceWfSubscription.EventAction = eventAction;

   instanceWfSubscription.DisplayName = "InstanceWorkflowSubscriptionCSharp";
   instanceWfSubscription.VWVersion = workflowDefDocument.VWVersion;
   IPEConnectionPoint peConnPoint = Factory.PEConnectionPoint.FetchInstance(domain, connPoint, null);
   instanceWfSubscription.IsolatedRegionNumber = peConnPoint.IsolatedRegion.IsolatedRegionNumber; 

   // Save the subscription
   instanceWfSubscription.Save(RefreshMode.REFRESH);
}

Class Workflow Subscription

Java Example

public void addClassWorkflowSubscription(ObjectStore os, String conn_point, String ceUri,
   String workflowDefinitionId, String targetClassGuid, String eventActionGuid) throws Exception
{
   // Create a class workflow subscription
   ClassWorkflowSubscription classWfSubscription =
      Factory.ClassWorkflowSubscription.createInstance(os, ClassNames.CLASS_WORKFLOW_SUBSCRIPTION);

   // Get the target class, the workflow definition document, and the event action
   DocumentClassDefinition targetClass = Factory.DocumentClassDefinition.getInstance(
      os, new Id(targetClassGuid) );
   WorkflowDefinition workflowDefDocument = getWorkFlowDefinitionDocument(os, conn_point, ceURI, workflowDefinitionId);
   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
   classWfSubscription.set_SubscribedEvents(subEventList);
   classWfSubscription.set_SubscriptionTarget(targetClass);
   classWfSubscription.set_WorkflowDefinition(workflowDefDocument);
   classWfSubscription.set_EventAction(eventAction);

   classWfSubscription.set_DisplayName("ClassWorkflowSubscriptionJava");
   classWfSubscription.set_VWVersion(workflowDefDocument.get_VWVersion());
   PEConnectionPoint peConnPoint = Factory.PEConnectionPoint.fetchInstance(domain, conn_point, null);
   classWfSubscription.set_IsolatedRegionNumber(peConnPoint.get_IsolatedRegion().get_IsolatedRegionNumber());

   // Save the subscription
   classWfSubscription.save(RefreshMode.REFRESH);
}

C# Example

public void AddClassWorkflowSubscription(IObjectStore os, String workflowDefinitionId, String targetClassGuid,
      String eventActionGuid, IDomain domain, String connPoint)
{
   // Create a class workflow subscription
   IClassWorkflowSubscription classWfSubscription =
      Factory.ClassWorkflowSubscription.CreateInstance(os, ClassNames.CLASS_WORKFLOW_SUBSCRIPTION);

   // Get the target class, the workflow definition document, and the event action
   ISubscribableClassDefinition targetClass = Factory.SubscribableClassDefinition.GetInstance(
      os, new Id(targetClassGuid) );
   IWorkflowDefinition workflowDefDocument = GetWorkFlowDefinitionDocument(os, workflowDefinitionId);
   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
   classWfSubscription.SubscribedEvents = subEventList;
   classWfSubscription.SubscriptionTarget = targetClass;
   classWfSubscription.WorkflowDefinition = workflowDefDocument;
   classWfSubscription.EventAction = eventAction;

   classWfSubscription.DisplayName = "ClassWorkflowSubscriptionCSharp";
   classWfSubscription.VWVersion = workflowDefDocument.VWVersion;
   IPEConnectionPoint peConnPoint = Factory.PEConnectionPoint.FetchInstance(domain, connPoint, null);
   classWfSubscription.IsolatedRegionNumber = peConnPoint.IsolatedRegion.IsolatedRegionNumber;

   // Save the subscription
   classWfSubscription.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);
}