1. Steps, status and action
Workflows To describe steps (Step), steps of the step, the relationship between the steps, and the conditions and permissions to perform each step, each step may contain one or more action (anctions), the action will make The state of one step changes.
For an executive workflow, the switching handover is inevitable. A workflow has one or more current steps at a certain time, each of which has a status value, and the status value of the current step constitutes a status value of the workflow instance. Once a step is completed, then this step will no longer be the current step (but switching to a new step), usually a new current step will be established to ensure that the workflow continues. The final status value of the completed step is specified with the OLD-Status property, and the setting of this status value will occur before switching to other steps. The value of Old-Status can be arbitrary, but in general, we are set to finished.
Switch itself is an action result of an action. Each step can contain multiple actions, which action to load is determined by the ultimate user, external event, or TriggerD. As the action is completed, a specific step switch will also occur. The action can be limited to the user, user group, or current state. Each action must contain a Unconditional Result and 0 or more Conditional Results.
Therefore, in general, a workflow consists of multiple steps. Each step has a current state (for example: Queued, Underway, or finished), one step contains multiple actions. Each step contains multiple actions that can be performed. Each action has the conditions performed, and there is also a function to be executed. The action contains RESULTS that can change status and current workflow steps.
2. Results, Joins, And Splits
(1) UNCONDITIONAL RESULT
For each action, there must be a Unconditional Result. A Result is a series of instructions that will tell OSWORKFLOW what is going to do. This includes switching the workflow from one state to another.
(2) Conditional Result
Conditional Result is an extension of UNCONDITIONAL RESULT. It requires one or more Condition subtabs. The first CONDITIONAL (using the AND or OR type) indicates the step of switching, the occurrence of the switching step is caused by a user performs an action.
(3) Three different RESULTS (Conditional or Unconditional)
- A new, single step, and a combination of states.
- A combination split into two or more steps and states.
- Combine this and other switches into a new single step and a combination of states.
Each Different Result corresponds to a different XML description, you can read http://www.opensymphony.com/OSworkflow/workflow_2_6.dtd, get more information.
Note: Typically, a SPLIT or a JOIN will not cause a split or join to occur.
1 Single steps and status results can be described:
If the status is not queued, then the third essential condition is the owner of the new step. In addition to the information of the next state, Result can also specify validators and post-functions, which will be discussed below.
2 Split into multiple states from one state to describe:
...
Status = "underway" @ = "$ {someowner}" /> status = "underway" Owner = "$ {sometherowner}" />
3 Multiple status merge into a state described:
...
"Finished" .Equals (jn.getstep (6) .gedstatus ()
&& "finished" .equals (jn.getstep (8) .getStatus ())
The above description may be a bit vague, but you should pay attention to the condition tag, which uses a "JN" variable, using this variable, you can form an expression to determine the condition of the merge action. This expression means: "When the state of ID = 6 and ID = 8 turns into the state of Finished, the combined action happens when the switches they want are JOIN =" 1 ".
3. External functions
OsWorkflow defines a standard solution for external business logics to be defined and executed. This is achieved by using "functions". Osworkflow has two function, pre and post step functions.
The preunctions is performed before the process of steps occur. An example is a function of acquiring the name of the caller name, and the name of the acquired caller is used as a result to switch to the state. Another example is the most recent caller of the pre-function to update most of the actions. These two functions are provided as a standard tool function, which is very practical in actual workflows.
Post Functions has the same scope of application with Pre functions, and the POST Functions is performed after the state changes. An example of a typical Post Functions is: After an action is executed, send someone to someone email. For example: When a document is in the 'Research' step, and execute the 'MarkReadyforreView' action, you want to send an email to all Reviewers.
There may be many reasons for using Post Functions and Pre functions. One is if the user clicks the completion button twice and sends two execution of the action, and the PRE function of this action will perform a long time, then this long period of execution may be executed multiple times, because the switching action is not yet At this time, OSWORKFLOW will consider the second execution action is reasonable. So to change this function into a Post function. Under normal circumstances, the pre function should be simple and can perform quickly.
Functions can be defined in two separate locations: Step (STEP) and Action.
Typically, Post Functions and Pre Functions are defined in an action. Pre-functions defined in the action refers to the function to be executed before the action occurs. When the workflow is switched, the function is used to do something, whether it is sending E_mail, or for future use setting variables.
When post functions and pre functions are defined in STEP, the use is a bit different. Pre-functions defined in stepp refers to execution before switching to this STEP
The function. Note: These functions will be applied to all switches of this step, even because this step itself is switched, for example, in the same step, all preunctions will also be called when transferred by the Queued state to the underway state. Similarly, Post Functions in Step will leave this step before the process leaves this step. 4. Trigger Functions
Trigger Functions is the same as other functions, and the difference is that they are not linked to an action. They also logo through a unique ID. These functions are usually in an environment running in a system-level user or an informal user. Trigger Functions is used through the API of OsWorkflow.
5. Validators
Validator is the validity used to check the input of an action. This action will be executed if you enter the eligible condition. If you do not meet the conditions, you will throw an invalidInputException exception.
6. Registers
A Register is an auxiliary function that can return an object, which can be used to access other common objects in the function, especially in the entity in Workflow. The registered object can be any type, an example of a typical registration object is: Document, Metadata, Issue, and Task.
Here is an example of registers:
...
Owner = "$ {availableManager}" />
...
7. Conditions
Conditions can be implemented in different languages, like Validators, Registers, and Functions. Conditions can be organized with an AND or OR logic operator. Conditions is usually in contact with Conditional Results, and RESULT will only be executed when the condition is established.
Conditions is very similar to the function, the only difference is that the conditiones return is the boolean value, not the void.
8. Variable Interpolation
In all functions, conditions, validators, and registers, you may have to provide a range of parameters. These parameters will be converted to parameter map, which will be discussed later. Similarly, Status, Old-Status, and Owner tags in the Workflow descriptor will also be dynamically parsing into variables. A variable is identified: $ {foo}. When OSWORKFLOW identifies this format, it first goes to transientvars to find the keyword for foo, if not found, then go to the propertyset, if you have not found, the variable foo will be converted to an empty String.
One thing of particular importance is that in the case of args, if the variable is the only argument, the argument will not be of type String, but instead whatever the variable type is. However, if the arg is a mix of characters and variables The entire argument is converted to string no matter what. That Means The Two Arguments Below Are Very Different In That Foo Is A Date Object and Bar Is A String:
$ {somedate} $ {somedate}
9. Permissions and Restrictions
Permissions can be assigned to users and / or groups based on the state of the workflow instance. These permissions are unrelated to the functionality of the workflow engine, but they are useful to have for applications that implement OSWorkflow. For example, a document management system might have the permission name "file-write-permission" enabled for a particular group only during the "Document Edit" stage of the workflow. That way your application can use the API to determine if files can be modified or not. This is useful as there could be a number of states within the workflow where the "file-write-permission" is applicable, so instead of checking for specific steps or conditions, the check can simply be made for a particular permission.
10. Auto Actions
Sometimes, we need some actions to be automatically performed based on some conditions. To achieve this, you can join the auto = "true" attribute in the Action. The process will examine the conditions and limitations of this action. If the condition is in line, this action will be executed. Auto action is performed by the current caller, so the caller of the action will perform permission check.
11. Integrating with Abstract Entities
It is recommended to create a new attribute within your core entity, such as "Document" or "Order". Create a new property inside: WorkflowID. This way, when new "document" or "ORDER" is created, it can associate with a Workflow instance. So, your code can find this Workflow instance through the OsWorkflow API and get the information and action of this Workflow.
12. Workflow Instance State
Sometimes, specify a state for the entire Workflow instance is very helpful, it is independent of the process of executing the process. OsWorkflow provides "meta-states" that can be included in some Workflow instances. These "meta-states" can be created, activated, suspended, killed, and completed. When a workflow instance is created, it will be in the CREATED state. Then, as long as one action is executed, it will automatically become an Activated state. If the caller does not clearly change the status of the instance, the workflow will keep this state until the workflow is over. When the workflow is not possible to perform any other actions, the workflow will automatically become the Completed status.
However, when the workflow is in the Activated state, the caller can terminate or suspend this workflow (set the status of the workflow as killed or suspended). A termination workflow will not perform any action, and will always be terminated. A hangned workflow will be frozen, and he cannot perform any action unless it turns into Activated. Second, the function in the workflow
OsWorkflow supports the following functions:
1. Java-based functions (based on Java-based function)
Java-based functions must be implemented in a com.opensymphony.workflow.functionProvider interface. This interface has only one function --execute, this function has three parameters
--Transientvars Map
TransientVars Map: It is called when the client code calls workflow.doAction (). This parameter can make functions of different behavior based on different inputs of users.
This parameter also contains some special variables, which is very helpful for access to Workflow. It also contains all the variables configured in Registers and the following two special variables: entry (com.opensymphony.workflow.spi.workflowntry) and context (com.opensymphony.workflow.workflowcontext).
--The Args Map
ARGS MAP is included in all
Tag
Label's Map. These parameters are String types. this means
this is $ {somevar}
The parameters defined in the label will be mapped to the "This IS [Contents of Somevar]" string in the Arg Map.
--Propertyset
The propertyset contains all persistent variables in the Workflow instance.
Java-based function is suitable for the following types:
(1) Class
For a class of functions, the class loader must know the name of the class to which your function belongs. This can be accomplished by class.name parameters:
com.acme.foofunction
The message is $ {message}
(2) JNDI
JNDI functions are like classifiers. The only difference between JNDI functions must be existed in the JNDI tree, here you need JNDI.Location parameters:
Java: / foofunction
The message is $ {message}
(3) Remote-EJB
Remote EJBS can be used as a function in OSWORKFLOW. EJB's remote interface must expand com.opensymphony.workflow.functionProviderRemote, here you need EJB.Location parameters:
Java: / comp / env / fooejb
The message is $ {message}
(4) Local-EJB
The local EJBS is different from the remote EJBS that local EJBS is to expand the com.opensymphony.workflow.functionProvider interface, for example:
Java: / comp / env / fooejb
The message is $ {message}
2. Beanshell Functions
OsWorkflow supports Beanshell as a scripting language. To http://www.beanshell.org/, you can get more beanshell information.
The type of Beanshell function must be specified as beanshell, but also a parameter, the name is Script. The value of this parameter is actually the Script to be executed, for example: system.out.println ("Hello, World!");
There is always three variables, entry, context, and store in the expression. The Entry variable is an object that implements the com.opensymphony.workflow.spi.workflowntry interface, which represents the Workflow instance. The Context variable is an object of the com.opensymphony.workflow.workflowcontext type, which allows the beanshell function to roll back the transaction or determine the name of the caller. The Store variable is an object of the com.opensymphony.workflow.workflowstore type, which allows the function to access the Workflow persistent storage area.
Like the Java-based function above, use three variables TransientVars, Args, and PropertySet, for example:
PropertySet.SetString ("World", "Earth");
System.out.println ("Hello," PropertySet.getstring ("world"));
The output of these two Scripts is "Hello, Earth". This is because the variables stored in the Propertyset are persisted to use the function in the Workflow later.
3. BSF Functions (Perlscript, Vbscript, JavaScript)
OsWorkflow also supports a function of Bean Scripting Framework. BSF is an IBM AlphaWorks team project that allows common Script language, such as VBScript, Perlscript, Python, and JavaScript run in a generic environment. This means that in OSWORKFLOW you can use any language supported by BSF to write your function:
FOO.PL
0
0
Print $ bsf-> lookupbean ("propertyset"). GetString ("foo");
The above code will get PropertySet, then printed the value of the object of Key as FOO. The same variable in the BEANSHELL function can be obtained in your BSF SCRIPT code. For how to get variables in your own language, please read the BSF user manual.
4. Utility Functions
OsWorkflow itself comes with some very practical tool functions, which implements the com.opensymphony.workflow.functionProvider interface. For more detailed information, read the Javadoc documentation of these tools. Below is a brief description of each function, you can find all classes in the com.opensymphony.workflow.util package.
(1) Caller
Set the persistent variable Caller with the executor name of the current action.
(2) Webworchxecutor
Perform a webwork function and store an old ActionContext at the end of the action.
(3) EJBINVOKER
Call an EJB Session Bean method.
(4) JMSMessage
Send a TextMessage to a JMStopic or Queue.
(5) MOSTRECENTOWNER
Set the persistent variable MOSTRECENTOWNER with the name of the owner of the recently specified steps. Optional feature can set the variable to Nothing when there is any person, or return an internal error. (6) Schedulejob
You can schedule a TRIGGER function to perform at a certain time. At the same time support CRON expressions and simple repeat / delay counts.
(7) UnschduleJob
Delete a ScheduleJob and all Triggers functions with it. It turns very useful in the status of Workflow and you no longer want ScheduleJob to perform it.
(8) Sendemail
Send an email to one or more users.
Third, Osworkflow Validators
Like OsWorkflow function, OsWorkflow's Validators has three different forms: java-based, beanshell, and BSF. Java-based Validators must implement the com.Opensymphony.Workflow.valiDator interface (or if you want to implement the com.opensymphony.workflow.valiDatorRemote interface) if you via remote EJB. In all java-based validators, you have to throw an InvalidInputException.
However, in the implementation of Beanshell and BSF, the situation is slightly different because the exception thrown in Scripts cannot spread out in the Java runtime environment. In order to achieve this purpose, the value returned by Beanshell or BSF is returned as an error message, and the logic is like this:
- If returned is an InvalidInputException object, then this object will be immediately thrown to the client.
- If returned is a map, then this MAP is used in an error / error message pair in InvalInotInputException.
- If the returned is a string [], the even value is used as a keyword (key), the odd value is used to be used, so that the above MAP can be constructed.
- If it is not the three situations, the return value will be converted to a String object and as an error message.
Four, OSWORKFLOW Registers
The Register in OSWORKFLOW is a runtime variable that can be dynamically registered in the definition file of Workflow. Registers is very useful in many occasions. For example: You want to provide a way to get Workflow to access an entity in its descriptor file. At this time, you can define a register to encapject this entity. If this entity is a local session ejb, you have to use the com.opensymphony.workflow.util.ejb.local.localeJbregister registration class. For example, in the back post-function, you can access this entity and can call the method in this entity by Beanshell Script.
Registers also have three implementations: java-based, beanshell and bsf.
Java-based
Java-based Registers must implement the com.roencyysymphony.workflow.register interface (or if it is remote EJB, you have to implement the com.opensymphony.workflow.registerRemote interface).
2. Beanshell and bsf registers
The values returned by Script or objects will be the object you registered.
Note: In the interface of Registers, you only need an Args Map parameter, which is because registers calls at all regardless of the user's input.
3. Example:
The following example will illustrate the functionality and use of the Register. Here REGISTER is used in a simple log Register, which has an accessible variable "log", which can be accessed within the life of the entire workflow. The logger can do a lot of useful jobs, such as adding an instance ID of the workflow to the logging. We define the REGISTER in the top layer of the descriptor file of Workflow.
com.opensymphony.workflow.util.logregister
True
As can be seen from the code, we created a logRegister called log, and also specified a value of TRUE to address the addressIDID.
We can use this variable anywhere in the Workflow descriptor file. E.g:
Transientvars.get ("log"). INFO ("Function Called");
The above function will output "Function Called" and add an instance ID of Workflow before output.
V. Conditions
Among the Script of BSF and Beanshell, there is a special object called "JN". This variable is an instance of the com.opensymphony.workflow.joinNodes class, which is used in Join-Conditions. In addition, the differences between Conditions and Functions is that Conditions must return a TRUE or FALSE value. This value can be a string of "true" or "false", or a "true" or "false" Boolean, or even a function containing the toString (), its return value is "true" or " False "object.
Each Condition must be defined as a subtab as a conditions. When you use the "and" type, all the value of all the Condition tags must be "true", and the entire Conditions can be True. Otherwise, the entire Conditions will return "false". If you use the "OR" type, as long as there is a CONDition tag value "true", the entire Conditions is True, and only when all the Condition tags must be "false", the entire Conditions can be false. If you want more complex logical judgment, then you have to consider using the Condition or ConditionRemote interface, Beanshell or BSF. Note: If only one condition is included in the Conditions tab, the type can be omitted.
Here is some standards of OsWorkflow comes with the standard Conditions:
--OSuserGroupCondition - Use OSuse to determine if the caller is in the parameter "group".
--Statuscondition - Judging whether the status of the current step is the same as the parameter "status".
--Allowowneronlycondition - If the caller is the owner of the specified step, only Return true if you do not specify the step, return the current step.
- Denyownercondition - Contrary to the AllowowNeronlyCondition function.
6. Use OsWorkflow's API
Interface selection
OsWorkflow provides multiple implementations of the com.opensymphony.workflow.workflow interface, you can use them directly in your program. (1) BasicWorkflow
BasicWorkflow does not support transaction processing, but it is possible to support transactions by overcrowding BasicWorkflow, which has been achieved in your persistence. BasicWorkflow is created in the following manner:
Workflow WF = New BasicWorkflow (UserName);
UserName is the username of the current request.
(2) EJBWORKFLOW
EJBWORKFlow uses EJB containers to manage transactions. This is configured in the ejb-jar.xml file. It is built like this:
Workflow wf = new ejbworkflow ();
You don't need to specify the username here because once the user is authorized, it automatically loads the username from the EJB container.
(3) OFBIZWORKFLOW
The only different parts of OFBIZWORKFLOW and BasicWorkflow are to support transaction processing through the TransactionUtIL call for OFBIZ.
2. Create a new workflow
The following briefly describes how to create a new workflow with an OSWORKFLOW API. First, you should create a file that defines a workflow. Then, your program must know the value of the initialization step to perform the initialization of the process instance. Before you initialize a workflow, you have to create it, this, you can get the reference to this workflow. Below is routine code:
Workflow WF = New BasicWorkflow (UserName);
HashMap INPUTS = New hashMap ();
Inputs.put ("DOCTITLE", Request.getParameter ("Title");
Wf.initialize ("WorkflowName", 1, Inputs);
Note: Under normal circumstances, you should use a reference to a Workflow type, and should not be a reference to BasicWorkflow.
3. Executive action
In OSWORKFLOW, it is very simple to perform an action:
Workflow WF = New BasicWorkflow (UserName);
HashMap INPUTS = New hashMap ();
Inputs.put ("DOCTITLE", Request.getParameter ("Title");
Long id = long.parselong (Request.GetParameter ("WorkflowID"));
Wf.doAction (ID, 1, INPUTS);
4. Query
In OSWORKFLOW 2.6, a new ExpressionQuery API is introduced.
Note: Not all Workflow storage supports query. Currently, all Hibernate, JDBC and memory storage support queries. However, Hibernate stores not supporting the mixed type query (for example: a query of the query information of a history and current step). To perform a query, create a WorkflowExpressionQuery object and call the query method in the WorkflowExpressionQuery object.
Below is an example of a query:
// Get All Workflow Entry ID's for Which the Owner IS 'Testuser'
New WorkflowExpressionQuery
New FieldExpression (FieldExpression.Owner, // Check the Owner Field
FieldExpression.current_steps, // Look in The Current Steps Context
FieldExpression.equals, // check equality
"Testuser"); // the equality value is 'testuser'
// Get All Workflow Entry ID's That Have the name 'myworkflow'
New WorkflowExpressionQuery
New FieldExpression (FieldExpression.name, // Check The Name Field
FieldExpression.Entry, // Look in The Entries Context
FieldExpression.equals, // check equality
'myworkflow')) // Equality value is 'myworkflow'
Here is an example of nested query:
// Get All finished Workflow Entries Where The Current Owner IS 'Testuser'
Expression Queryleft = New FieldExpression
FieldExpression.Owner,
FieldExpression.current_steps,
FieldExpression.equals, 'Testuser');
Expression Queryright = New FieldExpression
FieldExpression.status,
FieldExpression.current_steps,
FieldExpression.equals,
"Finished",
True);
WorkflowExpressionQuery Query = New WorkflowExpressionQuery
New NestedExpression (new expression [] {queryft, queryright},
NestedExpression.and));
.
// Get All Workflow Entries That Were finished in the Past
// OR are currently marked finished
Expression Queryleft = New FieldExpression
FieldExpression.finish_date, FieldExpression.history_steps,
FieldExpression.lt, new date ());
Expression Queryright = New FieldExpression
FieldExpression.status,
FieldExpression.current_steps,
FieldExpression.equals, "finished");
WorkflowExpressionQuery Query = New WorkflowExpressionQuery
New NestedExpression (new expression [] {queryft, queryright},
NestedExpression.or);