64 Customizing Workflow

A WebCenter Sites workflow process is the series of states an asset moves through on its way to publication. The asset moves from one state to the next by taking a workflow step. You must create the workflow step condition elements which specify the conditions that an asset must meet to move on to the next state, and the workflow action elements which perform various actions as the asset moves from one state to the next.

Topics:

Workflow Step Conditions

A workflow process is composed of one or more workflow states. Workflow steps move the asset from one workflow state to the next. You can associate each workflow step that the asset takes with a timed action, such as sending an email to a user when an asset is assigned to them, or a workflow step condition, which prevents an asset from moving on to the next step if certain conditions are not fulfilled. Sometimes there are conditions under which the asset should not move on to the next workflow state. You need to create the element that defines the condition or conditions that prevent the asset from moving on to the next state.

This element receives the following data when it is called:

  • An IWorkflowable object called Object, which represents the asset whose state is being changed.

  • An IWorkflowStep object called Step, which represents the current workflow step.

  • The StepUser variable, which contains the ID of the user attempting the step.

  • Variables specified as name-value pairs when a StepCondition is defined in the WebCenter Sites user interface. See Setting Up the Actions and Conditions in Administering Oracle WebCenter Sites.

The workflow step condition element should check for a condition and return a Boolean value. If the value is false, then the step does not proceed.

The following example comes from a sample workflow step condition element:

<?xml version="1.0" ?>

<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

<FTCS Version="1.1">

<!-- OpenMarket/Xcelerate/Actions/Workflow/StepConditions/ExampleStepCondition

-

- INPUT

-

- OUTPUT

-

-->

<csvar NAME="This step condition will check if step can be taken"/><br/>

The first line in the following example sets an empty ReturnVal variable:

<setvar NAME="ReturnVal" VALUE="Variables.empty"/>

<!--change the value of ReturnVal to a non-empty string later on, if you want to stop the step --> <!-- most of the stuff below are debugging statements and also show you some items available to you to set up a condition for stopping the step-->

The second line in the following example uses the WORKFLOWABLEASSET.GETDISPLAYABLENAME tag to get the name of the asset that is in workflow:

<!-- get asset -->

<WORKFLOWABLEOBJECT.GETDISPLAYABLENAME OBJECT="Object" VARNAME="assetdisplayablename"/>

Object:<csvar NAME="Variables.assetdisplayablename"/><br/>

Line 2 in the following example creates a variable called StepUser which contains the ID of the user attempting to take the step. Line 3 uses the USERMANAGER.GETUSER tag to load the user's ID into the StepUser variable. Line 4 uses the CCUSER.GETNAME tag to retrieve a human-readable user name, and line 5 uses the csvar tag to display that user name:

<!-- get userid -->

Userid: <csvar NAME="Variables.StepUser"/><br/>

<USERMANAGER.GETUSER OBJVARNAME="myUserObj" USER="Variables.StepUser"/>

<CCUSER.GETNAME NAME="myUserObj" VARNAME="uname"/>

Username: <csvar NAME="Variables.uname"/><br/>

Line 2 in the following example uses the WORKFLOWSTEP.GETID tag to get the ID of the current workflow step. The WORKFLOWSTEP.GETNAME tag, used in line 4, loads the step with the specified name:

<!-- getstep -->

<WORKFLOWSTEP.GETID NAME="Step" VARNAME="sid"/>

Stepid: <csvar NAME="Variables.sid "/>

<WORKFLOWSTEP.GETNAME NAME="Step" VARNAME="sname"/>

Stepname: <csvar NAME="Variables.sname"/><br/><br/>

The following example defines the conditions that stop the change of step from taking place. The forcestop and notalloweduser variables that the conditionals check were set as arguments when the sample step condition was defined in the WebCenter Sites interface. In a real step condition, you would test for the condition of your choice here. For example, seeing whether an article asset has an associated image.

<!-- This is the actual condition to stop the step. The following is just an example. -->

<if COND="Variables.forcestop=true">

<then>

<setvar NAME="ReturnVal" VALUE="You can not take this step because forcestop=true"/>

</then>

<else>

<if COND="Variables.uname=Variables.notalloweduser">

<then>

<setvar NAME="ReturnVal" VALUE="You are not allowed to take this step"/>

</then>

</if>

</else>

</if>

</FTCS>

Workflow Actions

As an asset moves through workflow, it can trigger a workflow action. A workflow action can do anything from send an email to alert a user that he has a new asset to evaluate to breaking a deadlock after a specified period of time has elapsed.

There are five types of workflow actions:

  • Step actions, which are executed as part of a transition between workflow states.

  • Timed actions, which are triggered by deadlines when the asset is in a given state, thus associating the asset with a specific assignment.

  • Deadlock actions, which are executed when an asset needs a unanimous vote to move to the next state, but the voters differ on which step the asset should take. The deadlock action is run whenever users choose different steps for the asset to move to.

  • Group deadlock actions, which are executed when the assets in a workflow group need a unanimous vote to move to the next state, but the voters choose different steps, creating a deadlock.

  • Delegation actions, which are executed when an asset is delegated. The delegated asset remains in its current workflow state, but is assigned to a new user.

Your workflow administrator must first define workflow actions using the WebCenter Sites user interface. Then you must create the elements that accomplish these workflow actions. WebCenter Sites provides several sample workflow action definitions for you to look at. See Setting Up the Actions and Conditions in Administering Oracle WebCenter Sites.

The following topics describe sample workflow action elements:

Step Action Elements

A Step Action element receives the following data when it is called:

  • A WorkflowEngine object called WorkflowEngine.

  • An ObjectTotal variable, which represents the total number of assets whose state is being changed.

  • An IWorkflowable object called Objectnnn, which represents the assets whose state is being changed. nnn is a number between 0 and ObjectTotal -1.

  • An IWorkflowStep object called Step, which represents the workflow step being considered.

  • A StepTargetUser variable, which is a comma-separated list of the step's target users.

  • A StepUser variable, which contains the ID of the user attempting the step.

  • A Group variable, which contains the ID of the workflow group to which the assets belong (if you are using workflow groups).

  • Any variables that your workflow administrator has created in the definition for this Step Action.

In the following example, the Step Action element approves assets for publish; most other Step Action elements send an email to the assignees.

<?xml version="1.0" ?>

<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

<FTCS Version="1.1">

<!-- OpenMarket/Xcelerate/Actions/Workflow/StepActions/ApproveForPublish

-

- INPUT

- Variables.ObjectTotal - number of loaded workflowasset objects

- Object[n] - loaded workflowasset objects, where n = 0 - Variables.ObjectTotal

-targets - one or more comma separated names of PubTargets for which to approve the asset

-

- OUTPUT

-

-->

<!-- This is an action element called by step actions ApproveForPublish-->

This step action element will approve an asset for publish.<br/>

Line 2 in the following example uses the SETCOUNTER tag to create a counter which keeps track of the number of assets to approve. Lines 3 through 9 use the LOOP tag to loop through the assets and retrieve the asset types and IDs.

<!-- get the id and assettype of the asset(s) to approve -->

<SETCOUNTER NAME="count" VALUE="0"/>

<LOOP COUNT="Variables.ObjectTotal">

<WORKFLOWASSET.GETASSETTYPE OBJECT="ObjectCounters.count" VARNAME="assettype"/>

<WORKFLOWASSET.GETASSETID OBJECT="ObjectCounters.count" VARNAME="assetid"/>

<SETVAR NAME="idCounters.count" VALUE="Variables.assetid"/>

<SETVAR NAME="typeCounters.count" VALUE="Variables.assettype"/>

<INCCOUNTER NAME="count" VALUE="1"/>

</LOOP>

In the following example, the STRINGLIST tag is used to create a comma-separated list of publish target names. The PUBTARGET.LOAD and PUBTARGET.GET tags are used to load information about the publish targets from the PubTarget table. This information and information about the assets to be approved are passed to the ApprovePost element for further processing.

<!-- approve for each destination -->

<STRINGLIST NAME="publishTargets" STR="Variables.targets" DELIM=","/>

<if COND="IsList.publishTargets=true">

<then>

<LOOP LIST="publishTargets">

<PUBTARGET.LOAD NAME="pubtgt" FIELD="name" VALUE="publishTargets.ITEM"/>

<if COND="IsError.Variables.errno=false">

<then>

Approving for publish to <CSVAR NAME="publishTargets.ITEM"/><br/>

<PUBTARGET.GET NAME="pubtgt" FIELD="id" OUTPUT="pubtgt:id"/>

<CALLELEMENT NAME="OpenMarket/Xcelerate/PrologActions/ApprovePost">

<ARGUMENT NAME="targetid" VALUE="Variables.pubtgt:id"/>

<ARGUMENT NAME="assetTotal" VALUE="Counters.count"/>

</CALLELEMENT>

</then>

<else>

Cannot approve for publish to destination: <CSVAR NAME="publishTargets.ITEM"/>, Error: <CSVAR NAME="Variables.errno"/>

</else>

</if>

</LOOP>

</then>

<else>

Cannot approve for publish. This step action requires a targets argument with one or more comma separated publishing destination names.

</else>

</if>

</FTCS>

Timed Action Elements

Timed Action elements receive the following data when they are called:

  • A WorkflowEngine object called WorkflowEngine.

  • A WorkflowAssignmentTotal variable, which contains the total number of assignments for which this action applies.

  • An IWorkflowAssignment object called WorkflowAssignmentnnn, which represents assignments to apply the action to. nnn is a number greater than zero.

  • An optional Group variable, which contains the ID of the workflow group to which the assets belong (if you are using workflow groups).

  • Any variables that your workflow administrator has created in the definition for this Timed Action.

The following excerpt is from a Timed Action element that sends an email. The text of the subject and body of this email are set in the Workflow Email forms that you access from the Admin node in the Admin interface. The body text expects the following variables:

  • Variables.assetname, which contains the name of the current asset

  • Variables.assigner, which is the name of the user who completed the previous state in the workflow process

  • Variables.instruction, which is the text that the assigner puts in the Action to Take text box as he or she completes an assignment

In the following example, the variables in the email object, subject and body, are replaced by their values:

<!-- translate subject -->
<EMAIL.TRANSLATESUBJECT NAME="emailobject" PARAMS="assetname=Variables.assetname" VARNAME="subject"/>
<!-- translate body -->
<EMAIL.TRANSLATEBODY NAME="emailobject" PARAMS="assetname=Variables.assetname&#38;time=Variables.time" VARNAME="body"/>
<!-- send mail -->
<sendmail TO="Variables.EmailAddress" SUBJECT="Variables.subject" BODY="Variables.body"/>
</THEN>
<ELSE>
Email address: None<br/>
</ELSE>
</IF>
<inccounter NAME="COUNT" VALUE="1"/>
</loop>
</then>
</if>
</FTCS>

Deadlock Action Elements

Deadlock Action elements receive the following data when they are called:

  • A WorkflowEngine object.

  • An ObjectTotal variable, which represents the total number of deadlocked assets.

  • An IWorkflowable object called Objectnnn, which represents the deadlocked assets.

  • An IWorkflowStep object called Step, which represents the workflow step.

  • A StepTotal variable, which contains the number of steps chosen by individual users.

  • A StepUser variable, which contains the ID of the user attempting the step.

  • An optional Group variable, which contains the ID of the workflow group to which the assets belong (if you are using workflow groups).

  • Any variables that your workflow administrator has created in the definition for this Deadlock Action.

The following Deadlock Action element sends an email to the users who approve the asset.

The text of the subject and body of this email are set in the Workflow Email forms in the administrative user interface. The body text expects the following variables:

<?xml version="1.0" ?>

<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

<FTCS Version="1.1">

<!-- OpenMarket/Xcelerate/Actions/Workflow/DeadlockActions/SendEmailToAssignees

-

- INPUT

-

- OUTPUT

-

-->

<!-- This is an action element called by step actions SendAssignmentEmail and SendRejectionEmail-->

<csvar NAME="This deadlock action element will send emails"/><br/>

Line 2 in the following example uses the EMAILMANAGER.LOAD tag to load an email object.

<!-- load email object -->

<EMAILMANAGER.LOAD NAME="Variables.emailname" OBJVARNAME="emailobject"/>

Lines 1 through 9 in the following example create a NumOfSteps variable, which contains either the total number of assets being delegated or zero.

<!-- get total steps -->

<if COND="IsVariable.StepTotal=true">

<then>

<setvar NAME="NumOfSteps" VALUE="Variables.StepTotal"/>

</then>

<else>

<setvar NAME="NumOfSteps" VALUE="0"/>

</else>

</if>

<removevar NAME="Step"/>

<setvar NAME="Header" VALUE="The following users have chosen the corresponding steps that has resulted in a deadlock. Please take appropriate actions to resolve deadlock:"/>

<setvar NAME="Message" VALUE="Variables.empty"/>

The code in the following three examples loop through the list of users who have put the asset in deadlock, creating an email for each one. Line 10 in the following code uses the USERMANAGER.GETUSER tag to load the user information of the user specified in the ID. Lines 11 and 12 use CCUSER tags to get the user's name and email address.

<!-- For each assignment object, get asignee -->

<setcounter NAME="COUNT" VALUE="0"/>

<if COND="Variables.NumOfSteps!=0">

<then>

<loop FROM="0" COUNT="Variables.NumOfSteps">

<!-- get assigner -->

<setvar NAME="userid" VALUE="Variables.StepUserCounters.COUNT"/>

<!-- get email address --->

<USERMANAGER.GETUSER USER="Variables.userid" OBJVARNAME="userobj"/>

<CCUSER.GETNAME NAME="userobj" VARNAME="user_name"/>

<CCUSER.GETEMAIL NAME="userobj" VARNAME="EmailAddress"/>

Lines 1 through 6 in the following example use the WORKFLOWSTEP and WORKFLOWSTATE tags to retrieve the asset's starting and ending steps and states.

<WORKFLOWSTEP.GETNAME NAME="StepCounters.COUNT" VARNAME="stepname"/>

<WORKFLOWSTEP.GETSTARTSTATE NAME="StepCounters.COUNT" VARNAME="startstate"/>

<WORKFLOWSTEP.GETENDSTATE NAME="StepCounters.COUNT" VARNAME="endstate"/>

<WORKFLOWSTATE.GETSTATENAME NAME="Variables.startstate" VARNAME="startstatename"/>

<WORKFLOWSTATE.GETSTATENAME NAME="Variables.endstate" VARNAME="endstatename"/>

<setvar NAME="Message" VALUE="Variables.Message Variables.user_name: Variables.stepname - "/>

<!--

user:<csvar NAME="Variables.user_name"/><br/>

step name:<csvar NAME="Variables.stepname"/><br/>

startstate name:<csvar NAME="Variables.startstate"/><br/>

endstate name:<csvar NAME="Variables.endstate"/><br/>

-->

<!-- get asset -->

<WORKFLOWABLEOBJECT.GETDISPLAYABLENAME NAME="Variables.ObjectCounters.COUNT" VARNAME="assetname"/>

In lines 3 and 6 in the following example, the variables in the email object, subject and body, are replaced by their values.

<!-- translate subject -->

<SETVAR NAME="params" VALUE="username=Variables.user_name&#38;header=Variables.Header&#38;message=Variables.Message&#38;assetname=Variables.assetname"/>

<EMAIL.TRANSLATESUBJECT NAME="emailobject" PARAMS="Variables.params" VARNAME="subject"/>

<!-- translate body -->

<EMAIL.TRANSLATEBODY NAME="emailobject" PARAMS="Variables.params" VARNAME="body"/>

<!-- send mail -->

<sendmail TO="Variables.EmailAddress" SUBJECT="Variables.subject" BODY="Variables.body"/>

<inccounter NAME="COUNT" VALUE="1"/>

</loop>

</then>

</if>

email message:<csvar NAME="Variables.Header Variables.Message"/><br/>

</FTCS>

Group Deadlock Action Elements

Group Deadlock action elements receive the following data when they are called:

  • A WorkflowEngine object called WorkflowEngine

  • An ObjectTotal variable, which represents the total number of deadlocked assets

  • An IWorkflowable object called Objectnnn, which represents the deadlocked asset. nnn is a number greater than zero

  • An IWorkflowStep object called Step, which represents the workflow step

  • A StepTotal variable, which contains the number of steps chosen by individual users

  • A StepUser variable, which contains the ID of the user attempting the step

  • A Group variable, which contains the ID of the workflow group that is deadlocked

  • Any variables that your workflow administrator has created in the definition for this Group Deadlock Action

The following Group Deadlock Action element sends an email to the users who approve the asset.

The text of the subject and body of this email are set in the Workflow Email forms in the administrative user interface. The body text expects the following variables:

<?xml version="1.0" ?>

<!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

<FTCS Version="1.1">

<!-- OpenMarket/Xcelerate/Actions/Workflow/GroupActions/SendEmailToAssignees

-

- INPUT

-

- OUTPUT

-

-->

<!-- user code goes here -->

<csvar NAME="This group deadlock action element will send emails"/><br/>

<!-- load email object -->

<EMAILMANAGER.LOAD NAME="Variables.emailname" OBJVARNAME="emailobject"/>

<!-- get group -->

<WORKFLOWENGINE.GETGROUPID ID="Variables.Group" OBJVARNAME="grpobj"/>

<WORKFLOWGROUP.GETNAME NAME="grpobj" VARNAME="GroupName"/>

<!-- get total steps -->

<if COND="IsVariable.StepTotal=true">

<then>

<setvar NAME="NumOfSteps" VALUE="Variables.StepTotal"/>

</then>

<else>

<setvar NAME="NumOfSteps" VALUE="0"/>

</else>

</if>

<removevar NAME="Step"/>

<setvar NAME="Header" VALUE="The following users have chosen the corresponding steps that has resulted in a deadlock for the group: Variables.GroupName. Please take appropriate actions to resolve deadlock:"/>

<setvar NAME="Message" VALUE="Variables.empty"/>

<!-- For each assignment object, get asignee -->

<setcounter NAME="COUNT" VALUE="0"/>

<if COND="Variables.NumOfSteps!=0">

<then>

<loop FROM="0" COUNT="Variables.NumOfSteps">

<!-- get assigner -->

<setvar NAME="userid" VALUE="Variables.StepUserCounters.COUNT"/>

<!-- get email address --->

<USERMANAGER.GETUSER USER="Variables.userid" OBJVARNAME="userobj"/>

<CCUSER.GETNAME NAME="userobj" VARNAME="user_name"/>

<CCUSER.GETEMAIL NAME="userobj" VARNAME="EmailAddress"/>

<WORKFLOWSTEP.GETNAME NAME="StepCounters.COUNT" VARNAME="stepname"/>

<WORKFLOWSTEP.GETSTARTSTATE NAME="StepCounters.COUNT" VARNAME="startstate"/>

<WORKFLOWSTEP.GETENDSTATE NAME="StepCounters.COUNT" VARNAME="endstate"/>

<WORKFLOWSTATE.GETSTATENAME NAME="Variables.startstate" VARNAME="startstatename"/>

<WORKFLOWSTATE.GETSTATENAME NAME="Variables.endstate" VARNAME="endstatename"/>

<!-- get asset -->

<WORKFLOWABLEOBJECT.GETDISPLAYABLENAME NAME="Variables.ObjectCounters.COUNT" VARNAME="assetname"/>

<!-- set message -->

<setvar NAME="Message" VALUE="Variables.Message Asset: Variables.assetname, User: Variables.user_name, Step: Variables.stepname -- "/>

<!-- translate subject -->

<SETVAR NAME="params" VALUE="username=Variables.user_name&#38;header=Variables.Header&#38;message=Variables.Message&#38;assetname=Variables.assetname"/>

<EMAIL.TRANSLATESUBJECT NAME="emailobject" PARAMS="Variables.params" VARNAME="subject"/>

<!-- translate body -->

<EMAIL.TRANSLATEBODY NAME="emailobject" PARAMS="Variables.params" VARNAME="body"/>

<!-- send mail -->

<sendmail TO="Variables.EmailAddress" SUBJECT="Variables.subject" BODY="Variables.body"/>

<inccounter NAME="COUNT" VALUE="1"/>

</loop>

</then>

</if>

email message:<csvar NAME="Variables.Header Variables.Message"/><br/>

</FTCS>

Delegation Action Elements

Delegation action elements receive the following data when they are called:

  • A WorkflowEngine object called WorkflowEngine

  • A CurrentUser variable, which contains the ID of the user who is delegating the asset

  • An optional Group variable, which contains the ID of the workflow group. All objects to be delegated must be in the same workflow group

  • A DelegateUser variable, which contains the ID of the user to whom the asset was delegated

  • A DelegateComment variable, which contains a comment addressed to the user ID contained in the DelegateUser variable

  • An ObjectTotal variable, which represents the total number of assets being delegated

  • An IWorkflowable object called Objectnnn, which represents the assets being delegated. nnn represents a number greater than zero

Delegation action elements should be coded like other Workflow Action elements.