/** Removes a task. */
  @Override
  public void unAssignTask(Task task) throws WorkflowException {
    String componentId = task.getProcessInstance().getModelId();
    ComponentInst compoInst = null;

    try {
      compoInst = AdminReference.getAdminService().getComponentInst(componentId);
    } catch (AdminException e) {
      throw new WorkflowException(
          "TaskManagerImpl.unassignTask", "workflowEngine.EX_GET_COMPONENT_INST", e);
    }

    TodoBackboneAccess todoBBA = new TodoBackboneAccess();

    if (task.getUser() != null) {
      todoBBA.removeEntriesFromExternal(
          compoInst.getDomainFatherId(), componentId, getExternalId(task));
    } else {
      String role = task.getUserRoleName();
      List<User> usersInRole = task.getProcessInstance().getUsersInRole(role);
      for (User userInRole : usersInRole) {
        TaskImpl taskImpl =
            new TaskImpl(userInRole, role, task.getProcessInstance(), task.getState());
        todoBBA.removeEntriesFromExternal(
            compoInst.getDomainFatherId(),
            componentId,
            getExternalId(taskImpl, userInRole.getUserId()));
      }
    }
  }
  /**
   * Adds a new task in the user's todos. Returns the external id given by the external todo system.
   */
  @Override
  public void assignTask(Task task, User delegator) throws WorkflowException {
    String componentId = task.getProcessInstance().getModelId();
    ComponentInst compoInst = null;

    try {
      compoInst = AdminReference.getAdminService().getComponentInst(componentId);
    } catch (AdminException e) {
      throw new WorkflowException(
          "TaskManagerImpl.assignTask", "workflowEngine.EX_GET_COMPONENT_INST", e);
    }

    TodoDetail todo = new TodoDetail();
    todo.setId(task.getProcessInstance().getInstanceId());
    todo.setSpaceId(compoInst.getDomainFatherId());
    todo.setComponentId(componentId);
    todo.setName("activite : " + task.getState().getLabel(task.getUserRoleName(), "fr"));
    if (delegator != null) {
      todo.setDelegatorId(delegator.getUserId());
    } else {
      SilverTrace.error(
          "workflowEngine",
          "TaskManagerImpl.assignTask",
          "root.MSG_GEN_PARAM_VALUE",
          "Undefined delegator for new task : " + todo.getName());
    }

    TodoBackboneAccess todoBBA = new TodoBackboneAccess();
    Vector<Attendee> attendees = new Vector<Attendee>();
    if (task.getUser() != null) {
      // add todo to specified user
      attendees.add(new Attendee(task.getUser().getUserId()));
      todo.setAttendees(attendees);
      todo.setExternalId(getExternalId(task));
      todoBBA.addEntry(todo);
    } else {
      List<User> users = null;
      if (StringUtil.isDefined(task.getGroupId())) {
        // get users according to group
        users = task.getProcessInstance().getUsersInGroup(task.getGroupId());
      } else {
        // get users according to role
        users = task.getProcessInstance().getUsersInRole(task.getUserRoleName());
      }
      for (User user : users) {
        attendees.clear();
        attendees.add(new Attendee(user.getUserId()));
        todo.setAttendees(attendees);
        todo.setExternalId(getExternalId(task, user.getUserId()));
        todoBBA.addEntry(todo);
      }
    }
  }
 private String getExternalId(Task task, String userId) {
   return task.getProcessInstance().getInstanceId()
       + "##"
       + userId
       + "##"
       + task.getState().getName()
       + "##"
       + task.getUserRoleName();
 }
 /**
  * A QuestionEventImpl is built from a resolved task, a choosen target state and a filled form.
  */
 public QuestionEventImpl(Task resolvedTask, String stepId, DataRecord data) {
   this.user = resolvedTask.getUser();
   this.processModel = resolvedTask.getProcessModel();
   this.processInstance = resolvedTask.getProcessInstance();
   this.resolvedState = resolvedTask.getState();
   this.actionName = "#question#";
   this.actionDate = new Date();
   this.userRoleName = resolvedTask.getUserRoleName();
   this.data = data;
   this.stepId = stepId;
 }
  /**
   * Notify user that an action has been done
   *
   * @throws WorkflowException
   */
  @Override
  public void notifyActor(Task task, User sender, User user, String text) throws WorkflowException {
    String componentId = task.getProcessInstance().getModelId();
    List<String> userIds = new ArrayList<String>();
    if (user != null) {
      userIds.add(user.getUserId());
    } else if (StringUtil.isDefined(task.getGroupId())) {
      List<User> usersInGroup = task.getProcessInstance().getUsersInGroup(task.getGroupId());
      for (User userInGroup : usersInGroup) {
        userIds.add(userInGroup.getUserId());
      }
    } else {
      String role = task.getUserRoleName();
      List<User> usersInRole = task.getProcessInstance().getUsersInRole(role);
      for (User userInRole : usersInRole) {
        userIds.add(userInRole.getUserId());
      }
    }

    NotificationSender notifSender = notificationSenders.get(componentId);
    if (notifSender == null) {
      notifSender = new NotificationSender(componentId);
      notificationSenders.put(componentId, notifSender);
    }

    for (String userId : userIds) {
      try {
        String title = task.getProcessInstance().getTitle(task.getUserRoleName(), "");

        DataRecord data = task.getProcessInstance().getAllDataRecord(task.getUserRoleName(), "");
        text = DataRecordUtil.applySubstitution(text, data, "");

        NotificationMetaData notifMetaData =
            new NotificationMetaData(NotificationParameters.NORMAL, title, text);
        if (sender != null) {
          notifMetaData.setSender(sender.getUserId());
        } else {
          notifMetaData.setSender(userId);
        }
        notifMetaData.addUserRecipient(new UserRecipient(userId));
        String link =
            "/RprocessManager/"
                + componentId
                + "/searchResult?Type=ProcessInstance&Id="
                + task.getProcessInstance().getInstanceId()
                + "&role="
                + task.getUserRoleName();
        notifMetaData.setLink(link);
        notifSender.notifyUser(notifMetaData);
      } catch (WorkflowException e) {
        SilverTrace.warn(
            "workflowEngine",
            "TaskManagerImpl.notifyUser()",
            "workflowEngine.EX_ERR_NOTIFY",
            "user = "******"workflowEngine",
            "TaskManagerImpl.notifyUser()",
            "workflowEngine.EX_ERR_NOTIFY",
            "user = " + userId,
            e);
      }
    }
  }