Ejemplo n.º 1
0
  public ActionForward processPayment(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws AppException {
    String forwardPage = "";
    Inform inf = new Inform();

    Workflow workflow = (Workflow) form;

    JbpmContext jbpmContext = JbpmUtil.getJbpmContext();
    try {
      long taskInstanceId = workflow.getTaskInstanceId();
      TaskInstance taskInstance = jbpmContext.getTaskInstance(taskInstanceId);
      // String isSubmit 结束/总经理处理 此处省略
      taskInstance.end();
      inf.setMessage("处理完成");
      inf.setForwardPage("../workflow/workflowList.do?thisAction=listTask");
    } catch (Exception e) {
      e.printStackTrace();
      inf.setMessage("异常信息:" + e.getMessage());
    } finally {
      jbpmContext.close();
    }
    return forwardInformPage(inf, mapping, request);
  }
Ejemplo n.º 2
0
  /** Start Process Definition */
  public static ProcessInstance runProcessDefinition(
      String user, long processDefinitionId, String uuid, List<FormElement> variables)
      throws WorkflowException {
    log.debug(
        "runProcessDefinition({}, {}, {}, {})",
        new Object[] {user, processDefinitionId, uuid, variables});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();
    ProcessInstance vo = new ProcessInstance();

    if (Config.SYSTEM_READONLY) {
      throw new WorkflowException("System is in read-only mode");
    }

    try {
      jbpmContext.setActorId(user);
      GraphSession graphSession = jbpmContext.getGraphSession();
      Map<String, Object> hm = new HashMap<String, Object>();
      hm.put(Config.WORKFLOW_PROCESS_INSTANCE_VARIABLE_UUID, uuid);

      for (FormElement fe : variables) {
        hm.put(fe.getName(), fe);
      }

      org.jbpm.graph.def.ProcessDefinition pd =
          graphSession.getProcessDefinition(processDefinitionId);
      org.jbpm.graph.exe.ProcessInstance pi = pd.createProcessInstance(hm);

      if (pi != null) {
        org.jbpm.taskmgmt.exe.TaskMgmtInstance tmi = pi.getTaskMgmtInstance();

        // http://community.jboss.org/thread/115182
        if (tmi.getTaskMgmtDefinition().getStartTask() != null) {
          org.jbpm.taskmgmt.exe.TaskInstance ti = tmi.createStartTaskInstance();

          if (Config.WORKFLOW_START_TASK_AUTO_RUN) {
            ti.start();
            ti.end();
          }
        } else {
          pi.getRootToken().signal();
        }

        jbpmContext.save(pi);
        vo = WorkflowUtils.copy(pi);
      }
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("runProcessDefinition: {}", vo);
    return vo;
  }
Ejemplo n.º 3
0
  public void deleteTaskInstanceExtensions(long processInstanceId) {
    List<TaskInstance> taskInstances =
        findTaskInstances(
            processInstanceId, 1, null, false, null, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);

    for (TaskInstance taskInstance : taskInstances) {
      TaskInstanceExtensionImpl taskInstanceExtensionImpl =
          findTaskInstanceExtension(taskInstance.getId());

      _session.delete(taskInstanceExtensionImpl);
    }
  }
Ejemplo n.º 4
0
  protected List<TaskInstance> getTasksInstancesBySubmittingUser(
      long companyId,
      long userId,
      Boolean completed,
      int start,
      int end,
      OrderByComparator orderByComparator) {

    List<TaskInstance> taskInstances = new ArrayList<TaskInstance>();

    try {
      Criteria criteria = _session.createCriteria(TaskInstance.class);

      criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

      if (completed != null) {
        if (completed.booleanValue()) {
          criteria.add(Restrictions.isNotNull("end"));
        } else {
          criteria.add(Restrictions.isNull("end"));
        }
      }

      addOrder(criteria, orderByComparator);

      for (TaskInstance taskInstance : (List<TaskInstance>) criteria.list()) {

        ProcessInstance processInstance = taskInstance.getProcessInstance();

        ContextInstance contextInstance = processInstance.getContextInstance();

        long taskInstanceUserId =
            GetterUtil.getLong((String) contextInstance.getVariable("userId"));

        if (userId == taskInstanceUserId) {
          taskInstances.add(taskInstance);
        }
      }
    } catch (Exception e) {
      throw new JbpmException(e);
    }

    if ((end != QueryUtil.ALL_POS) && (taskInstances.size() > end)) {
      taskInstances = ListUtil.subList(taskInstances, start, end);
    }

    return taskInstances;
  }
 public void testNextTermGroup() {
   expressionAssignmentHandler.expression = "user(john) --> group(hierarchy)";
   expressionAssignmentHandler.assign(assignable, executionContext);
   Set pooledActors = assignable.getPooledActors();
   PooledActor pooledActor = (PooledActor) pooledActors.iterator().next();
   assertEquals("hellsangels", pooledActor.getActorId());
 }
  @Override
  public void end(Transition transition) {
    // Force assignment of task if transition is taken, but no owner has yet
    // been assigned
    if (actorId == null) {
      actorId = AuthenticationUtil.getFullyAuthenticatedUser();
    }

    // Set task properties on completion of task
    // NOTE: Set properties first, so they're available during the
    // submission of
    // task variables to the process context
    Map<QName, Serializable> taskProperties = new HashMap<QName, Serializable>();
    Transition outcome =
        (transition == null) ? token.getNode().getDefaultLeavingTransition() : transition;
    if (outcome != null) {
      taskProperties.put(WorkflowModel.PROP_OUTCOME, outcome.getName());
    }
    taskProperties.put(WorkflowModel.PROP_STATUS, "Completed");
    getJBPMEngine().setTaskProperties(this, taskProperties);

    // perform transition
    super.end(transition);

    if (getTask().getStartState() != null) {
      // if ending a start task, push start task properties to process
      // context, if not
      // already done
      getJBPMEngine().setDefaultWorkflowProperties(this);

      // set task description
      getJBPMEngine().setDefaultStartTaskDescription(this);
    }
  }
Ejemplo n.º 7
0
  /** Add Task Instance Comment */
  public static void addTaskInstanceComment(String user, long taskInstanceId, String message)
      throws WorkflowException {
    log.debug("addTaskInstanceComment({}, {}, {})", new Object[] {user, taskInstanceId, message});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
      org.jbpm.taskmgmt.exe.TaskInstance ti = taskMgmtSession.getTaskInstance(taskInstanceId);
      ti.addComment(new org.jbpm.graph.exe.Comment(user, message));
      jbpmContext.getSession().flush();
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }
  }
 public void testFirstTermVariableUser() {
   expressionAssignmentHandler.expression = "variable(uservariable)";
   User john = identitySession.getUserByName("john");
   processInstance.getContextInstance().setVariable("uservariable", john);
   expressionAssignmentHandler.assign(assignable, executionContext);
   assertEquals("john", assignable.getActorId());
 }
Ejemplo n.º 9
0
  public void deleteWorkflowLogs(long processInstanceId) {
    List<TaskInstance> taskInstances =
        findTaskInstances(
            processInstanceId, 1, null, false, null, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);

    for (TaskInstance taskInstance : taskInstances) {
      Criteria criteria = _session.createCriteria(WorkflowLogImpl.class);

      criteria.add(Restrictions.eq("taskInstance.id", taskInstance.getId()));

      List<WorkflowLog> workflowLogs = criteria.list();

      for (WorkflowLog workflowLog : workflowLogs) {
        _session.delete(workflowLog);
      }
    }
  }
Ejemplo n.º 10
0
  public void execute(ExecutionContext executionContext) throws Exception {
    TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();

    // 取得当前流程实例所有的子Token上的任务实例

    Token rootToken = executionContext.getProcessInstance().getRootToken();
    Collection childTokeList = rootToken.getChildren().values();

    for (Iterator iterator = childTokeList.iterator(); iterator.hasNext(); ) {
      Token childToken = (Token) iterator.next();
      Collection c = tmi.getUnfinishedTasks(childToken);
      for (Iterator iterator2 = c.iterator(); iterator2.hasNext(); ) {
        TaskInstance ti = (TaskInstance) iterator2.next();
        ti.cancel();
      }
    }
  }
Ejemplo n.º 11
0
  /** Set Task Instance Actor Id */
  public static void setTaskInstanceActorId(long taskInstanceId, String actorId)
      throws WorkflowException {
    log.debug("setTaskInstanceActorId({}, {})", new Object[] {taskInstanceId, actorId});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      org.jbpm.taskmgmt.exe.TaskInstance ti = jbpmContext.getTaskInstance(taskInstanceId);
      ti.setActorId(actorId);
      jbpmContext.getSession().flush();
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("setTaskInstanceActorId: void");
  }
Ejemplo n.º 12
0
  /** Delete Task Instance Variable */
  public static void deleteTaskInstanceVariable(long taskInstanceId, String name)
      throws WorkflowException {
    log.debug("deleteTaskInstanceVariable({}, {})", new Object[] {taskInstanceId, name});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      org.jbpm.taskmgmt.exe.TaskInstance ti = jbpmContext.getTaskInstance(taskInstanceId);
      ti.deleteVariable(name);
      jbpmContext.getSession().flush();
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("deleteTaskInstanceVariable: void");
  }
Ejemplo n.º 13
0
  /** Resume Task Instance */
  public static void resumeTaskInstance(long taskInstanceId) throws WorkflowException {
    log.debug("resumeTaskInstance({})", taskInstanceId);
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
      org.jbpm.taskmgmt.exe.TaskInstance ti = taskMgmtSession.getTaskInstance(taskInstanceId);
      ti.resume();
      jbpmContext.getSession().flush();
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("resumeTaskInstance: void");
  }
 public void testFirstTermSwimlane() {
   expressionAssignmentHandler.expression = "swimlane(boss)";
   SwimlaneInstance swimlaneInstance = new SwimlaneInstance(new Swimlane("boss"));
   swimlaneInstance.setActorId("john");
   processInstance.getTaskMgmtInstance().addSwimlaneInstance(swimlaneInstance);
   expressionAssignmentHandler.assign(assignable, executionContext);
   assertEquals("john", assignable.getActorId());
 }
Ejemplo n.º 15
0
  public ActionForward insertPayment(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws AppException {
    String forwardPage = "";
    Inform inf = new Inform();

    Workflow workflow = (Workflow) form;

    JbpmContext jbpmContext = JbpmUtil.getJbpmContext();
    try {
      String issueperson = "user1";
      // 设置当前用户为user1
      jbpmContext.setActorId(issueperson);

      ProcessDefinition pd = jbpmContext.getGraphSession().findLatestProcessDefinition("payment");

      ProcessInstance processInstance = pd.createProcessInstance();
      ContextInstance contextInstance = processInstance.getContextInstance();

      //
      contextInstance.setVariable("issueperson", issueperson);

      // 创建开始节点的TaskInstance
      TaskInstance taskInstance = processInstance.getTaskMgmtInstance().createStartTaskInstance();

      // 向任务实例当中写入相关变量
      taskInstance.setVariable("title", workflow.getTitle());
      taskInstance.setVariable("moneyCount", workflow.getMoneyCount());
      taskInstance.setVariable("remark", workflow.getRemark());

      // 结束任务实例,token进入部门经理审批
      taskInstance.end();

      inf.setMessage("报销申请提交成功");
    } catch (Exception e) {
      e.printStackTrace();
      inf.setMessage("异常信息:" + e.getMessage());
    } finally {
      jbpmContext.close();
    }
    return forwardInformPage(inf, mapping, request);
  }
Ejemplo n.º 16
0
  /** End Task Instance */
  public static void endTaskInstance(long taskInstanceId, String transitionName)
      throws WorkflowException {
    log.debug("endTaskInstance({}, {})", new Object[] {taskInstanceId, transitionName});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
      org.jbpm.taskmgmt.exe.TaskInstance ti = taskMgmtSession.getTaskInstance(taskInstanceId);

      if (transitionName != null && !transitionName.equals("")) {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end(transitionName);
      } else {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end();
      }

      jbpmContext.getSession().flush();
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }

    log.debug("endTaskInstance: void");
  }
 public void testFirstTermVariableGroup() {
   expressionAssignmentHandler.expression = "variable(groupvariable)";
   Group hellsangels = identitySession.getGroupByName("hellsangels");
   processInstance.getContextInstance().setVariable("groupvariable", hellsangels);
   expressionAssignmentHandler.assign(assignable, executionContext);
   Set pooledActors = assignable.getPooledActors();
   PooledActor pooledActor = (PooledActor) pooledActors.iterator().next();
   assertEquals("hellsangels", pooledActor.getActorId());
 }
Ejemplo n.º 18
0
  /**
   * Retorna a lista de tarefas em ordem decrescente de criação.
   *
   * @return
   */
  public static List<TaskInstance> ordenarTarefas(TaskInstance taskInstance) {
    TaskInstance[] lista =
        new TaskInstance[taskInstance.getTaskMgmtInstance().getTaskInstances().size()];
    taskInstance.getTaskMgmtInstance().getTaskInstances().toArray(lista);

    Arrays.sort(
        lista,
        new Comparator<TaskInstance>() {

          public int compare(TaskInstance o1, TaskInstance o2) {
            if (o1.getCreate().getTime() < o2.getCreate().getTime()) {
              return 1;
            }
            if (o1.getCreate().getTime() > o2.getCreate().getTime()) {
              return -1;
            }
            return 0;
          }
        });

    return Arrays.asList(lista);
  }
Ejemplo n.º 19
0
  /**
   * Retorna a lista de tarefas em ordem decrescente de criação.
   *
   * @return
   */
  public static List<Comment> ordenarComentarios(TaskInstance taskInstance) {
    if (taskInstance.getComments() == null) return new ArrayList(0);
    Comment[] lista = new Comment[taskInstance.getComments().size()];
    taskInstance.getComments().toArray(lista);

    Arrays.sort(
        lista,
        new Comparator<Comment>() {

          public int compare(Comment o1, Comment o2) {
            if (o1.getTime().getTime() < o2.getTime().getTime()) {
              return 1;
            }
            if (o1.getTime().getTime() > o2.getTime().getTime()) {
              return -1;
            }
            return 0;
          }
        });

    return Arrays.asList(lista);
  }
Ejemplo n.º 20
0
  /**
   * Retorna as transições disponíveis em ordem alfabética.
   *
   * @param taskInstance
   * @return
   */
  public static List<Transition> ordenarTransicoes(TaskInstance taskInstance) {

    Transition[] lista = new Transition[taskInstance.getAvailableTransitions().size()];
    taskInstance.getAvailableTransitions().toArray(lista);

    Arrays.sort(
        lista,
        new Comparator<Transition>() {

          public int compare(Transition o1, Transition o2) {
            if (o1.getName() == null) {
              return 1;
            }
            if (o2.getName() == null) {
              return -1;
            }

            return o1.getName().compareToIgnoreCase(o2.getName());
          }
        });

    return Arrays.asList(lista);
  }
Ejemplo n.º 21
0
  /** Set Task Instance Values */
  public static void setTaskInstanceValues(
      long taskInstanceId, String transitionName, List<FormElement> values)
      throws WorkflowException {
    log.debug(
        "setTaskInstanceValues({}, {}, {})", new Object[] {taskInstanceId, transitionName, values});
    JbpmContext jbpmContext = JBPMUtils.getConfig().createJbpmContext();

    try {
      TaskMgmtSession taskMgmtSession = jbpmContext.getTaskMgmtSession();
      Map<String, FormElement> hm = new HashMap<String, FormElement>();

      for (FormElement fe : values) {
        hm.put(fe.getName(), fe);
      }

      org.jbpm.taskmgmt.exe.TaskInstance ti = taskMgmtSession.getTaskInstance(taskInstanceId);
      ti.setVariables(hm);

      if (transitionName != null && !transitionName.equals("")) {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end(transitionName);
      } else {
        if (ti.getStart() == null) {
          ti.start();
        }

        ti.end();
      }

      jbpmContext.save(ti);
    } catch (JbpmException e) {
      throw new WorkflowException(e.getMessage(), e);
    } finally {
      jbpmContext.close();
    }
  }
 @Override
 public void create(ExecutionContext executionContext) {
   super.create(executionContext);
   getJBPMEngine().setDefaultTaskProperties(this);
 }
 public void testNextTermMember() {
   expressionAssignmentHandler.expression = "group(hellsangels) --> member(leaderofthegang)";
   expressionAssignmentHandler.assign(assignable, executionContext);
   assertEquals("john", assignable.getActorId());
 }
  /**
   * extract the list of information from the process variables and make them available locally.
   * Note that if no task instance variables are specified, the full process variables scope will be
   * visible (that means that the user did not specify a special task instance scope).
   */
  public void initializeVariables(TaskInstance taskInstance) {
    ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
    try {
      // set context class loader correctly for delegation class
      // (https://jira.jboss.org/jira/browse/JBPM-1448)
      Thread.currentThread()
          .setContextClassLoader(
              JbpmConfiguration.getProcessClassLoader(
                  taskInstance.getTask().getProcessDefinition()));

      if (taskControllerDelegation != null) {
        TaskControllerHandler taskControllerHandler =
            (TaskControllerHandler) taskControllerDelegation.instantiate();
        ProcessInstance processInstance = taskInstance.getTaskMgmtInstance().getProcessInstance();
        ContextInstance contextInstance =
            (processInstance != null ? processInstance.getContextInstance() : null);
        Token token = taskInstance.getToken();

        if (UserCodeInterceptorConfig.userCodeInterceptor != null) {
          UserCodeInterceptorConfig.userCodeInterceptor.executeTaskControllerInitialization(
              taskControllerHandler, taskInstance, contextInstance, token);
        } else {
          taskControllerHandler.initializeTaskVariables(taskInstance, contextInstance, token);
        }

      } else {
        Token token = taskInstance.getToken();
        ProcessInstance processInstance = token.getProcessInstance();
        ContextInstance contextInstance = processInstance.getContextInstance();

        if (variableAccesses != null) {
          Iterator iter = variableAccesses.iterator();
          while (iter.hasNext()) {
            VariableAccess variableAccess = (VariableAccess) iter.next();
            String mappedName = variableAccess.getMappedName();
            if (variableAccess.isReadable()) {
              String variableName = variableAccess.getVariableName();
              Object value = contextInstance.getVariable(variableName, token);
              log.debug(
                  "creating task instance variable '"
                      + mappedName
                      + "' from process variable '"
                      + variableName
                      + "', value '"
                      + value
                      + "'");
              taskInstance.setVariableLocally(mappedName, value);
            } else {
              log.debug(
                  "creating task instance local variable '"
                      + mappedName
                      + "'. initializing with null value.");
              taskInstance.setVariableLocally(mappedName, null);
            }
          }
        }
      }
    } finally {
      Thread.currentThread().setContextClassLoader(surroundingClassLoader);
    }
  }
  /** update the process variables from the the task-instance variables. */
  public void submitParameters(TaskInstance taskInstance) {
    ClassLoader surroundingClassLoader = Thread.currentThread().getContextClassLoader();
    try {
      // set context class loader correctly for delegation class
      // (https://jira.jboss.org/jira/browse/JBPM-1448)
      Thread.currentThread()
          .setContextClassLoader(
              JbpmConfiguration.getProcessClassLoader(
                  taskInstance.getTask().getProcessDefinition()));

      if (taskControllerDelegation != null) {
        TaskControllerHandler taskControllerHandler =
            (TaskControllerHandler) taskControllerDelegation.instantiate();
        ProcessInstance processInstance = taskInstance.getTaskMgmtInstance().getProcessInstance();
        ContextInstance contextInstance =
            (processInstance != null ? processInstance.getContextInstance() : null);
        Token token = taskInstance.getToken();

        if (UserCodeInterceptorConfig.userCodeInterceptor != null) {
          UserCodeInterceptorConfig.userCodeInterceptor.executeTaskControllerSubmission(
              taskControllerHandler, taskInstance, contextInstance, token);
        } else {
          taskControllerHandler.submitTaskVariables(taskInstance, contextInstance, token);
        }

      } else {

        Token token = taskInstance.getToken();
        ProcessInstance processInstance = token.getProcessInstance();
        ContextInstance contextInstance = processInstance.getContextInstance();

        if (variableAccesses != null) {
          String missingTaskVariables = null;
          Iterator iter = variableAccesses.iterator();
          while (iter.hasNext()) {
            VariableAccess variableAccess = (VariableAccess) iter.next();
            String mappedName = variableAccess.getMappedName();
            // first check if the required variableInstances are present
            if ((variableAccess.isRequired()) && (!taskInstance.hasVariableLocally(mappedName))) {
              if (missingTaskVariables == null) {
                missingTaskVariables = mappedName;
              } else {
                missingTaskVariables += ", " + mappedName;
              }
            }
          }

          // if there are missing, required parameters, throw an
          // IllegalArgumentException
          if (missingTaskVariables != null) {
            throw new IllegalArgumentException("missing task variables: " + missingTaskVariables);
          }

          iter = variableAccesses.iterator();
          while (iter.hasNext()) {
            VariableAccess variableAccess = (VariableAccess) iter.next();
            String mappedName = variableAccess.getMappedName();
            String variableName = variableAccess.getVariableName();
            if (variableAccess.isWritable()) {
              Object value = taskInstance.getVariable(mappedName);
              if (value != null) {
                log.debug(
                    "submitting task variable '"
                        + mappedName
                        + "' to process variable '"
                        + variableName
                        + "', value '"
                        + value
                        + "'");
                contextInstance.setVariable(variableName, value, token);
              }
            }
          }
        }
      }
    } finally {
      Thread.currentThread().setContextClassLoader(surroundingClassLoader);
    }
  }
 public void testFirstTermPrevious() {
   expressionAssignmentHandler.expression = "previous";
   expressionAssignmentHandler.assign(assignable, executionContext);
   assertEquals("bill", assignable.getActorId());
 }
 public void testFirstTermVariableString() {
   expressionAssignmentHandler.expression = "variable(actoridstringvariable)";
   processInstance.getContextInstance().setVariable("actoridstringvariable", "john");
   expressionAssignmentHandler.assign(assignable, executionContext);
   assertEquals("john", assignable.getActorId());
 }
 public Object execute(JbpmContext jbpmContext) throws Exception {
   TaskInstance ti = jbpmContext.getTaskInstance(taskInstanceId);
   ti.setActorId(null);
   ti.setStart(null);
   return null;
 }
  public void testTimerInCombinationWithAsyncNode() throws Throwable {
    ProcessDefinition subDefinition =
        ProcessDefinition.parseXmlString(
            "<process-definition name='sub'>"
                + "  <start-state name='start'>"
                + "    <transition to='decision'/>"
                + "  </start-state>"
                + "  <decision name='decision'>"
                + "    <handler class='org.jbpm.scenarios.AsyncTimerAndSubProcessDbTest$ToTimedDecisionHandler' />"
                + "    <transition name='default' to='task' />"
                + "  </decision>"
                + "  <task-node name='task'>"
                + "    <task name='do stuff'>"
                + "      <controller>"
                + "        <variable name='a' access='read' />"
                + "      </controller>"
                + "      <assignment actor-id='victim' />"
                + "    </task>"
                + "    <transition to='end'/>"
                + "  </task-node>"
                + "  <end-state name='end' />"
                + "</process-definition>");
    jbpmContext.deployProcessDefinition(subDefinition);
    newTransaction();

    ProcessDefinition superDefinition =
        ProcessDefinition.parseXmlString(
            "<process-definition name='super'>"
                + "  <start-state name='start'>"
                + "    <transition to='decision'/>"
                + "  </start-state>"
                + "  <decision name='decision'>"
                + "    <handler class='org.jbpm.scenarios.AsyncTimerAndSubProcessDbTest$ToTimedDecisionHandler' />"
                + "    <transition name='default' to='timed' />"
                + "  </decision>"
                + "  <state name='timed'>"
                + "    <timer name='reminder' "
                + "           duedate='0 seconds' "
                + "           transition='timer fires' />"
                + "    <transition name='timer fires' to='async'/>"
                + "    <transition name='normal continuation' to='end'/>"
                + "  </state>"
                + "  <node name='async' async='true'>"
                + "    <transition to='subprocess'/>"
                + "  </node>"
                + "  <process-state name='subprocess'>"
                + "    <sub-process name='sub' />"
                + "    <variable name='a'/>"
                + "    <variable name='b'/>"
                + "    <transition to='decision' />"
                + "  </process-state>"
                + "  <end-state name='end' />"
                + "</process-definition>");
    jbpmContext.deployProcessDefinition(superDefinition);
    newTransaction();

    ProcessInstance superInstance = jbpmContext.newProcessInstanceForUpdate("super");
    ContextInstance superContext = superInstance.getContextInstance();
    superContext.setVariable("a", "value a");
    superContext.setVariable("b", "value b");
    superInstance.signal();

    processJobs(5000);

    superInstance = jbpmContext.loadProcessInstance(superInstance.getId());
    assertEquals("subprocess", superInstance.getRootToken().getNode().getName());

    List taskInstances = taskMgmtSession.findTaskInstances("victim");
    assertEquals(1, taskInstances.size());
    TaskInstance taskInstance = (TaskInstance) taskInstances.get(0);
    taskInstance.setVariable("a", "value a updated");
    taskInstance.setVariable("b", "value b updated");
    taskInstance.end();

    jbpmContext.save(taskInstance);
    long taskInstanceId = taskInstance.getId();
    long tokenId = taskInstance.getToken().getId();
    newTransaction();

    taskInstance = jbpmContext.loadTaskInstance(taskInstanceId);
    assertEquals("value a updated", taskInstance.getVariable("a"));
    assertEquals("value b updated", taskInstance.getVariable("b"));

    Token token = jbpmContext.loadToken(tokenId);
    ContextInstance subContextInstance = token.getProcessInstance().getContextInstance();
    assertEquals("value a", subContextInstance.getVariable("a"));
    assertEquals("value b updated", subContextInstance.getVariable("b"));
  }
 public static void endOneTask(Token token) {
   TaskMgmtInstance tmi = token.getProcessInstance().getTaskMgmtInstance();
   TaskInstance taskInstance = (TaskInstance) tmi.getUnfinishedTasks(token).iterator().next();
   taskInstance.end();
 }