35 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. Each step that the asset takes can be associated 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.

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. This chapter describes these elements in greater detail and provide sample code for each element type.

This chapter contains the following sections:

35.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. Sometimes, however, there are conditions under which the asset should not move on to the next workflow state. You must 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. For more information about defining StepConditions, see the Oracle Fusion Middleware WebCenter Sites Administrator's Guide.

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

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

Example 35-1

  1. <?xml version="1.0" ?>

  2. <!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

  3. <FTCS Version="1.1">

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

  5. -

  6. - INPUT

  7. -

  8. - OUTPUT

  9. -

  10. -->

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

Line 1 in the following code sets an empty ReturnVal variable. In lines 4 and 9 of Example 35-6, this variable will be set with the reasons why the step cannot proceed.

Example 35-2

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

  2. <!--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-->

Line 2 in the following code uses the WORKFLOWABLEASSET.GETDISPLAYABLENAME tag to get the name of the asset that is in workflow.

Example 35-3

  1. <!-- get asset -->

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

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

Line 2 in the following code creates a variable called StepUser which will contain 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.

Example 35-4

  1. <!-- get userid -->

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

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

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

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

Line 2 in the following code 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.

Example 35-5

  1. <!-- getstep -->

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

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

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

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

The following code defines the conditions that will 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.

Example 35-6

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

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

  3. <then>

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

  5. </then>

  6. <else>

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

  8. <then>

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

  10. </then>

  11. </if>

  12. </else>

  13. </if>

  14. </FTCS>

35.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 in order to move to the next state, but the voters differ on which step the asset should take. The deadlock action will be executed 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 in order 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. For more information about defining workflow actions, see the Oracle Fusion Middleware WebCenter Sites Administrator's Guide.

The following sections describe sample workflow action elements:

35.2.1 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.

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

Example 35-7

  1. <?xml version="1.0" ?>

  2. <!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

  3. <FTCS Version="1.1">

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

  5. -

  6. - INPUT

  7. - Variables.ObjectTotal - number of loaded workflowasset objects

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

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

  10. -

  11. - OUTPUT

  12. -

  13. -->

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

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

Line 2 in the following code 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.

Example 35-8

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

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

  3. <LOOP COUNT="Variables.ObjectTotal">

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

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

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

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

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

  9. </LOOP>

Line 2 in the following code uses the STRINGLIST tag to create a comma-separated list of publish target names. Lines 6 through 21 loop through this list, using the PUBTARGET.LOAD and PUBTARGET.GET tags 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 in line 12.

Example 35-9

  1. <!-- approve for each destination -->

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

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

  4. <then>

  5. <LOOP LIST="publishTargets">

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

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

  8. <then>

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

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

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

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

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

  14. </CALLELEMENT>

  15. </then>

  16. <else>

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

  18. </else>

  19. </if>

  20. </LOOP>

  21. </then>

  22. <else>

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

  24. </else>

  25. </if>

  26. </FTCS>

35.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 tab in the WebCenter Sites user 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 lines 2 and 5 of the following code, the variables in the email object, subject and body, are replaced by their values.

Example 35-10

  1. <!-- translate subject -->

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

  3. <!-- translate body -->

  4. <EMAIL.TRANSLATEBODY NAME="emailobject" PARAMS="assetname=Variables.assetname&#38;time=Variables.time" VARNAME="body"/>

  5. <!-- send mail -->

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

  7. </THEN>

  8. <ELSE>

  9. Email address: None<br/>

  10. </ELSE>

  11. </IF>

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

  13. </loop>

  14. </then>

  15. </if>

  16. </FTCS>

35.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 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 WebCenter Sites administrative user interface. The body text expects the following variables:

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

  • Variables.header and Variables.message, which contain the text of the email's body

Example 35-11

  1. <?xml version="1.0" ?>

  2. <!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

  3. <FTCS Version="1.1">

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

  5. -

  6. - INPUT

  7. -

  8. - OUTPUT

  9. -

  10. -->

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

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

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

Example 35-12

  1. <!-- load email object -->

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

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

Example 35-13

  1. <!-- get total steps -->

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

  3. <then>

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

  5. </then>

  6. <else>

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

  8. </else>

  9. </if>

  10. <removevar NAME="Step"/>

  11. <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:"/>

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

The code in the following three examples (Example 35-14, Example 35-15, and Example 35-16) 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.

Example 35-14

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

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

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

  4. <then>

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

  6. <!-- get assigner -->

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

  8. <!-- get email address --->

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

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

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

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

Example 35-15

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

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

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

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

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

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

  7. <!--

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

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

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

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

  12. -->

  13. <!-- get asset -->

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

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

Example 35-16

  1. <!-- translate subject -->

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

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

  4. <!-- translate body -->

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

  6. <!-- send mail -->

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

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

  9. </loop>

  10. </then>

  11. </if>

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

  13. </FTCS>

35.2.4 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 WebCenter Sites administrative user interface. The body text expects the following variables:

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

  • Variables.header and Variables.message, which contain the text of the email's body

Example 35-17

  1. <?xml version="1.0" ?>

  2. <!DOCTYPE FTCS SYSTEM "futuretense_cs.dtd">

  3. <FTCS Version="1.1">

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

  5. -

  6. - INPUT

  7. -

  8. - OUTPUT

  9. -

  10. -->

  11. <!-- user code goes here -->

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

  13. <!-- load email object -->

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

  15. <!-- get group -->

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

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

  18. <!-- get total steps -->

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

  20. <then>

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

  22. </then>

  23. <else>

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

  25. </else>

  26. </if>

  27. <removevar NAME="Step"/>

  28. <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:"/>

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

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

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

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

  33. <then>

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

  35. <!-- get assigner -->

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

  37. <!-- get email address --->

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

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

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

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

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

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

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

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

  46. <!-- get asset -->

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

  48. <!-- set message -->

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

  50. <!-- translate subject -->

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

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

  53. <!-- translate body -->

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

  55. <!-- send mail -->

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

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

  58. </loop>

  59. </then>

  60. </if>

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

  62. </FTCS>

35.2.5 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.

  • 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.