This topic applies only to the IBM Business Process Manager Advanced configuration.

使用 StaffQueryResultPostProcessorPlugin2 接口开发插件

StaffQueryResultPostProcessorPlugin2 接口为如下情况提供更佳的性能:后处理将对基于同一任务模板的所有任务实例或升级实例间的特定任务角色或升级角色生成同一结果。

在实施 StaffQueryResultPostProcessorPlugin2 接口时,一个重要的性能考虑事项为布尔方法 isInstanceSpecific,该方法控制如何处理每个任务模板和升级模板的人员查询结果后处理。
特定于模板
对于每种角色,将为所有实例均返回同一人员列表,因此可以为模板计算一次后处理结果,并将这些结果供所有实例使用。基于角色的替换是符合如下情况的示例:所有任务实例均可以共享同一人员查询后处理结果。该选项提供比特定于实例的后处理更佳的性能。
特定于实例
对于每种角色,不同的实例需要返回不同的人员列表。工作负载均衡是对每个任务实例都需要不同人员查询结果后处理的示例。 出于性能原因,请勿对可通过特定于模板的后处理进行处理的模板使用特定于实例的后处理。
注: 如果要从此类调用 HumanTaskManagerService 接口,请勿调用更新已生成事件的任务的方法。此操作可能会导致数据库中的任务数据不一致。

的值

StaffQueryResultPostProcessorPlugin2 接口向插件提供以下输入参数:
originalStaffQueryResult
您可以使用此 Map 对象来获取关于内建人员解析和替换所计算的用户的信息。
peopleQuerySpec
这是 Map 对象,包含为当前人员分配所考虑的人员分配条件 (PAC) 描述。它包含为任务或升级角色所指定的名称、参数名和值(全都为 String 类型)。要访问人员分配条件名称,请使用键 HTM_VERB_NAME。 要访问参数的值,请将参数名用作键,例如 groupName
peopleQueryVariables
Map 对象包含已在人员分配条件中指定的替换变量及其已解析值。要访问为替换变量所解析的值,请将变量的名称用作键,例如 htm:task.originator。 结果的类型为 String 或 String[]。
usersRemovedByPeopleQuery
该字符串数组用于标识通过人员分配条件排除了哪些用户标识。如果这些排除具有强制性,那么您的插件可以使用该列表来避免添加任何已经排除的用户标识。
pppContext
您可以使用该 postProcessingContext 对象来访问关于所考虑的应用程序上下文的信息。 请使用在类 Javadoc 中定义并说明的对应 getter 方法。例如,分配原因以及当前任务或升级的相应模板或实例的标识。 根据后处理是特定于模板还是特定于实例,该对象向每个可能上下文的后处理程序提供不同信息:
特定于模板的上下文:
这些上下文中的每一个都提供不同信息。
任务模板
  • 任务模板。
  • 以下工作项分配原因之一:实例创建者、管理员、阅读者、编辑者、潜在启动者或潜在所有者。
升级模板
  • 升级模板。
  • 工作项分配原因:升级接收者。
特定于实例的上下文:
这些上下文中的每一个都提供不同信息。
非特别任务实例
  • 任务模板。
  • 任务实例。
  • 以下工作项分配原因之一:管理员、阅读者、编辑者、潜在启动者或潜在所有者。
特别任务实例
  • 任务实例。
  • 与任务实例关联的应用程序组件。
  • 以下工作项分配原因之一:管理员、阅读者、编辑者、潜在启动者或潜在所有者。
非特别升级实例
  • 任务模板。
  • 任务实例。
  • 升级模板。
  • 升级实例。
  • 工作项分配原因:升级接收者。
特别升级实例
  • 升级实例。
  • 与升级关联的任务实例。
  • 与升级实例关联的应用程序组件。
  • 工作项分配原因:升级接收者。
特殊案例上下文:
在创建特别任务模板或实例以及在没有实例创建者人员分配条件的情况下创建任务模板时,授权基于关联的应用程序组件的实例创建者角色。
应用程序组件
  • 应用程序组件。
  • 工作项分配原因:实例创建者。
注: 分配原因通过对应的角色来指示。

示例:StaffQueryResultPostProcessorPlugin2 实施

以下示例说明了具有用户替换(取决于任务角色)的 StaffQueryResultPostProcessorPlugin2 接口的实施。
package com.ibm.task.spi.ppp;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.ibm.task.api.WorkItem;
import com.ibm.task.spi.StaffQueryResult;
import com.ibm.task.spi.StaffQueryResultFactory;
import com.ibm.task.spi.UserData;

public class MyStaffResultProcessor implements
        StaffQueryResultPostProcessorPlugin2
{
    public boolean isInstanceSpecific(PostProcessingContext pppContext)
    {
        // post processing logic is not depending on task/escalation
        // instance specifics
        return false;
    }

    // post processing method providing for user substitution that are
    // in the Potential Owner role
    public StaffQueryResult processStaffQueryResult(
            StaffQueryResult originalStaffQueryResult,
            Map peopleQuerySpec,
            Map peopleQueryVariable,
            String[] usersRemovedByPeopleQuery,
            PostProcessingContext pppContext)
    {

        StaffQueryResult newStaffQueryResult = null;
        int assignmentReason = pppContext.getAssignmentReason();

        // apply people substitution for potential owners
        switch (assignmentReason)
        {
        case WorkItem.REASON_POTENTIAL_OWNER:
            newStaffQueryResult = substitutePotentialOwners(originalStaffQueryResult);
            break;
        default:
            newStaffQueryResult = originalStaffQueryResult;
        }

        return newStaffQueryResult;
    }

    // method providing for substitution logic for users in the Potential Owner
    // role
    private StaffQueryResult substitutePotentialOwners(
            StaffQueryResult originalStaffQueryResult)
    {
        StaffQueryResult newStaffQueryResult = originalStaffQueryResult;
        StaffQueryResultFactory staffResultFactory = StaffQueryResultFactory
                .newInstance();

        Map userDataMap = originalStaffQueryResult.getUserDataMap();
        Map newUserDataMap = new HashMap();
        Iterator iterator = userDataMap.keySet().iterator();

        while (iterator.hasNext())
        {
            String originalUserId = (String) iterator.next();

            // a real substitution logic would contain a lookup, for example in a database,
            // an LDAP directory
            String substituteUserId = null;
            if (originalUserId.equals("Edward"))
            {
                substituteUserId = "Bob";
            }
            else if (originalUserId.equals("Jack"))
            {
                substituteUserId = "John";
            }

            UserData substituteUserData = staffResultFactory.newUserData(
                    substituteUserId,
                    null,
                    null);

            // include the substitute
            newUserDataMap.put(substituteUserId, substituteUserData);
        }

        if (newUserDataMap.size() > 0)
        {
            // create a new StaffQueryResult including the map
            newStaffQueryResult = StaffQueryResultFactory.newInstance()
                    .newStaffQueryResult(newUserDataMap);
        }

        return newStaffQueryResult;
    }

}

有关此接口的更多信息,请参阅 Javadoc。