您的位置:首页 > 数据库 > Oracle

Oracle BPM: Working with Tasks Programmatically (Part II)

2014-10-27 01:38 295 查看

Oracle BPM: Working with Tasks Programmatically (Part II)

This article is going to cover how to query tasks from Oracle BPM Programmatically.

In the previous
article we looked at the Oracle BPM Worklist Application, and started explaining how to call the Oracle BPM API to create
a custom interaction with the engine. Specifically, we looked at how to get a task given its ID, and how to execute an outcome on it.

In most cases, when you are going to be calling the Oracle BPM APIs you are going to need to execute different queries to retrieve the tasks that are relevant to your business need.

Please, don’t query all the Oracle BPM tasks, and then filter them in a for loop.You might be surprised, but I found one time a developer who was “prototyping” and learning how to use the API,
that did just that. Then the code was left in the repository untouched for a long time. Everyone forgot. But you can be sure, when it was time for regression testing, that piece of functionality was a performance bottleneck that no one was able to explain,
until a code review was performed…

You should always construct a predicate that describes precisely what Oracle BPM tasks you want to retrieve.

For that we are going to use the same objects we did in the previous article.

ITaskService taskService = null;
ITaskQueryService queryService = null;
IWorkflowContext workflowContext = null;

java.util.logging.Logger logger = Logger.getLogger("oracle.apps");
WorkflowServicesClientConfigurationType workflowServicesClientConfigurationType =
getWorkflowClientConfigObject("FIN_SOA_RMI);
IWorkflowServiceClient workflowServiceClientt =
WorkflowServiceClientFactory.getWorkflowServiceClient(workflowServicesClientConfigurationType, logger);
taskService = workflowServiceClient.getTaskService();
queryService = workflowServiceClient.getTaskQueryService();
workflowContext = queryService.getWorkflowContextForAuthenticatedUser();

Remember to keep your copy of the workflow context, as it is time consuming to get it.

Beyond authentication, all methods require the Oracle BPM worklist context as the first argument. The worklist context helps the worklist service determine the user requesting the action, whether
the user has permission to perform the requested action on the task and so forth. The context also contains information about the user’s locale and timezone information.

Now we are ready to construct our “predicate” object.

There are many constructors for the Oracle BPM Predicate class.

The most important ones are the following:

Predicate(Column column, int operation, java.lang.Object value)
Predicate(Predicate pred1, int logical, Predicate pred2)

In the column parameter you specify which column you want to filter by. The operation is what type of comparison you want to apply to that column, and lastly the value is the value you want to compare against.

Column objects are defined in oracle.bpel.services.workflow.repos.TableConstants, and they can also be obtained by passing the column name to the static method getColumn() on oracle.bpel.services.workflow.repos.Column. My personal preference, is
to just use the Constant. In that way, you will have no surprises at run time.

Per the Oracle BPM API, the operation parameter is an int. However, you should never pass directly an int. Instead use a constant from the class PredicateConstants. The class Predicate
extends PredicateConstants. So you can just use Predicate to access those operations. All of those constants start with the OP prefix. From JDeveloper, just use the autocomplete feature (CTRL-SPACE) after typeing
Predicate.OP and you will find them self descriptive.

The last parameter is just a value. You can pass a Java Object that represent the value you want to compare against.

The second constructor that I am bringing up, is the one that allows you to connect multiple Predicates with a logical operator. Using this constructor, you can connect the Predicates with logical AND, OR, and others.

Here is a simple example of these constructors in action:

Predicate statePredicate = new Predicate(TableConstants.WFTASK_STATE_COLUMN, Predicate.OP_NEQ, IWorkflowConstants.TASK_STATE_ASSIGNED);
Predicate datePredicate = new Predicate(TableConstants.WFTASK_ENDDATE_COLUMN, Predicate.OP_ON, new Date());
Predicate predicate = new Predicate(statePredicate, Predicate.AND, datePredicate);

That Predicate will query all the tasks that have a status not equal to assigned, and have an End Date of today.

Another way to connect different predicates, is to use the 
addClause
 method.
It is pretty straight forward after you understand how to construct Predicates from the explanation above.

There is the option to specify a specific order for the tasks that you are querying from theOracle BPM engine. This feature works similar to an ORDER BY in a database query.

Ordering ordering = new Ordering(TableConstants.WFTASK_TITLE_COLUMN, true, true);

In this example we will receive the Tasks order by the Title column.

By default the Oracle BPM query service result will include only a list of Tasks Ids, then you can use the technique in the prior article to retrieve the information of that specific
Task Id. However, most of the time, you will want not only the task Id. You will want some other attributes to be able to show to the user the results.

The Oracle BPM API allows you to specify which attributes you want to have for each Task that meets the criteria you have given.

For that, just create a regular Java List and include in it the names of the columns you want back, like the following:

List queryColumns = new ArrayList();
queryColumns.add("TASKNUMBER");
queryColumns.add("TITLE");
queryColumns.add("PRIORITY");
queryColumns.add("STATE");
queryColumns.add("ENDDATE");

You can even retrieve what the Oracle BPM API calls Optional Info as part of the response from the query:

List optionalInfo = new ArrayList();
optionalInfo.add("Actions");
optionalInfo.add("GroupActions");
optionalInfo.add("CustomActions");
optionalInfo.add("ShortHistory");

According to the documentation of the query service, the following are reserved for future use. If you need them, please use getTaskDetailsById (or) getTaskDetailsByNumber, which will fetch all information related to a task, which includes these:

//optionalInfo.add("Attachments");
//optionalInfo.add("Comments");
//optionalInfo.add("Payload");

If you are going to display the results to the user, please always specify which attributes you need, in this call. Don’t just get the default result set (task ID) and fetch individually task by task. You might be surprised that I am pointing this
out, as this should perhaps be considered a
4000
trivial thing. However, I have seen in some code reviews, developers that have done just that.

Now we are ready to call the following API to query the Tasks:

queryTasks(IWorkflowContext ctx, java.util.List displayColumns,
java.util.List optionalInformation,
ITaskQueryService.AssignmentFilter assignmentFilter,
java.lang.String keywords,
Predicate predicate,
Ordering ordering,
int startRow,
int endRow)

The last 2 parameters allow you to do “paging”. You can choose how many records to retrieve at a time for a specific call.

In this way, you can retrieve in batches only the Tasks that your user will be able to deal with at the same time. This should help with the memory consumption of the overall solution.

If you just want all the results, and not use paging, you can just pass zero for the start row, and zero for the end row, as it is show in the following code:

List tasksList = queryService.queryTasks(workflowContext,
queryColumns,
optionalInfo,
ITaskQueryService.ASSIGNMENT_FILTER_MY_AND_GROUP,
keyword,
predicate,
ordering,
0,0);

We reviewed all the parameters with the exception of keyword. That parameter is just a java.lang.String.

If this keyword is null, it will be ignored. If it is not null, then the following predicates will be added to the query performing SQL ‘like’ operations:  task title, identification key, all textAttributes in task, and task number (only if the
keyword is a number.)

The keyword will be surrounded by wild cards, the equivalent to the % in a sql query, the following way: %keyword%.

As you can see in the example above, the result from the call returns a regular Java List.

In it, you will see 
Task
 objects.

You can do anything with it, here a simple example of how to extract the information from the tasks and print them to the standard output:

for (Task task : tasksList) {
System.out.println("Task Number: " + task.getSystemAttributes().getTaskNumber());
System.out.println("Task Id: " + task.getSystemAttributes().getTaskId());
System.out.println("Title: " + task.getTitle());
System.out.println("Priority: " + task.getPriority());
System.out.println("State: " + task.getSystemAttributes().getState());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: