63 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:
63.1 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 calledObject
, which represents the asset whose state is being changed. -
An
IWorkflowStep
object calledStep
, 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>
63.2 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:
63.2.1 Step Action Elements
A Step Action element receives the following data when it is called:
-
A
WorkflowEngine
object calledWorkflowEngine
. -
An
ObjectTotal
variable, which represents the total number of assets whose state is being changed. -
An
IWorkflowable
object calledObjectnnn
, which represents the assets whose state is being changed. nnn is a number between 0 and ObjectTotal -1. -
An
IWorkflowStep
object calledStep
, 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>
63.2.2 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 theAction 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&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>
63.2.3 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 calledObjectnnn
, which represents the deadlocked assets. -
An
IWorkflowStep
object calledStep
, 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&header=Variables.Header&message=Variables.Message&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>
63.2.4 Group Deadlock Action Elements
Group Deadlock action elements receive the following data when they are called:
-
A
WorkflowEngine
object calledWorkflowEngine
-
An
ObjectTotal
variable, which represents the total number of deadlocked assets -
An
IWorkflowable
object calledObject
nnn, which represents the deadlocked asset. nnn is a number greater than zero -
An
IWorkflowStep
object calledStep
, 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&header=Variables.Header&message=Variables.Message&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>
63.2.5 Delegation Action Elements
Delegation action elements receive the following data when they are called:
-
A
WorkflowEngine
object calledWorkflowEngine
-
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 theDelegateUser
variable -
An
ObjectTotal
variable, which represents the total number of assets being delegated -
An
IWorkflowable
object calledObject
nnn, which represents the assets being delegated. nnn represents a number greater than zero
Delegation action elements should be coded like other Workflow Action elements.