@Override
  public WorkspaceItem abort(Context context, BasicWorkflowItem workflowItem, EPerson e)
      throws SQLException, AuthorizeException, IOException {
    // authorize a DSpaceActions.ABORT
    if (!authorizeService.isAdmin(context)) {
      throw new AuthorizeException("You must be an admin to abort a workflow");
    }

    // stop workflow regardless of its state
    taskListItemService.deleteByWorkflowItem(context, workflowItem);

    log.info(
        LogManager.getHeader(
            context,
            "abort_workflow",
            "workflow_item_id="
                + workflowItem.getID()
                + "item_id="
                + workflowItem.getItem().getID()
                + "collection_id="
                + workflowItem.getCollection().getID()
                + "eperson_id="
                + e.getID()));

    // convert into personal workspace
    return returnToWorkspace(context, workflowItem);
  }
 // creates workflow tasklist entries for a workflow
 // for all the given EPeople
 protected void createTasks(Context c, BasicWorkflowItem wi, List<EPerson> epa)
     throws SQLException {
   // create a tasklist entry for each eperson
   for (EPerson anEpa : epa) {
     // can we get away without creating a tasklistitem class?
     // do we want to?
     taskListItemService.create(c, wi, anEpa);
   }
 }
 @Override
 public List<String> getEPersonDeleteConstraints(Context context, EPerson ePerson)
     throws SQLException {
   List<String> resultList = new ArrayList<>();
   List<BasicWorkflowItem> workflowItems = workflowItemService.findByOwner(context, ePerson);
   if (CollectionUtils.isNotEmpty(workflowItems)) {
     resultList.add("workflowitem");
   }
   List<TaskListItem> taskListItems = taskListItemService.findByEPerson(context, ePerson);
   if (CollectionUtils.isNotEmpty(taskListItems)) {
     resultList.add("tasklistitem");
   }
   return resultList;
 }
  @Override
  public WorkspaceItem sendWorkflowItemBackSubmission(
      Context context,
      BasicWorkflowItem workflowItem,
      EPerson ePerson,
      String provenancePrefix,
      String rejection_message)
      throws SQLException, AuthorizeException, IOException {

    int oldState = workflowItem.getState();
    // authorize a DSpaceActions.REJECT
    // stop workflow
    taskListItemService.deleteByWorkflowItem(context, workflowItem);

    // rejection provenance
    Item myitem = workflowItem.getItem();

    // Get current date
    String now = DCDate.getCurrent().toString();

    // Get user's name + email address
    String usersName = getEPersonName(ePerson);

    // Here's what happened
    String provDescription =
        "Rejected by " + usersName + ", reason: " + rejection_message + " on " + now + " (GMT) ";

    // Add to item as a DC field
    itemService.addMetadata(
        context,
        myitem,
        MetadataSchema.DC_SCHEMA,
        "description",
        "provenance",
        "en",
        provDescription);
    itemService.update(context, myitem);

    // convert into personal workspace
    WorkspaceItem wsi = returnToWorkspace(context, workflowItem);

    // notify that it's been rejected
    notifyOfReject(context, workflowItem, ePerson, rejection_message);

    log.info(
        LogManager.getHeader(
            context,
            "reject_workflow",
            "workflow_item_id="
                + workflowItem.getID()
                + "item_id="
                + workflowItem.getItem().getID()
                + "collection_id="
                + workflowItem.getCollection().getID()
                + "eperson_id="
                + ePerson.getID()));

    logWorkflowEvent(
        context,
        wsi.getItem(),
        workflowItem,
        ePerson,
        WFSTATE_SUBMIT,
        null,
        wsi.getCollection(),
        oldState,
        null);

    return wsi;
  }
  // returns true if archived
  protected boolean doState(
      Context context, BasicWorkflowItem workflowItem, int newstate, EPerson newowner)
      throws SQLException, IOException, AuthorizeException {
    Collection mycollection = workflowItem.getCollection();
    Group mygroup = null;
    boolean archived = false;

    // Gather our old data for launching the workflow event
    int oldState = workflowItem.getState();

    workflowItem.setState(newstate);

    switch (newstate) {
      case WFSTATE_STEP1POOL:

        // any reviewers?
        // if so, add them to the tasklist
        workflowItem.setOwner(null);

        // get reviewers (group 1 )
        mygroup = collectionService.getWorkflowGroup(mycollection, 1);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were reviewers, change the state
          //  and add them to the list
          createTasks(context, workflowItem, epa);
          workflowItemService.update(context, workflowItem);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no reviewers, skip ahead
          workflowItem.setState(WFSTATE_STEP1);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP1:

        // remove reviewers from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_STEP2POOL:

        // clear owner
        // any approvers?
        // if so, add them to tasklist
        // if not, skip to next state
        workflowItem.setOwner(null);

        // get approvers (group 2)
        mygroup = collectionService.getWorkflowGroup(mycollection, 2);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were approvers, change the state
          //  timestamp, and add them to the list
          createTasks(context, workflowItem, epa);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no reviewers, skip ahead
          workflowItem.setState(WFSTATE_STEP2);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP2:

        // remove admins from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_STEP3POOL:

        // any editors?
        // if so, add them to tasklist
        workflowItem.setOwner(null);
        mygroup = collectionService.getWorkflowGroup(mycollection, 3);

        if ((mygroup != null) && !(groupService.isEmpty(mygroup))) {
          // get a list of all epeople in group (or any subgroups)
          List<EPerson> epa = groupService.allMembers(context, mygroup);

          // there were editors, change the state
          //  timestamp, and add them to the list
          createTasks(context, workflowItem, epa);

          // email notification
          notifyGroupOfTask(context, workflowItem, mygroup, epa);
        } else {
          // no editors, skip ahead
          workflowItem.setState(WFSTATE_STEP3);
          archived = advance(context, workflowItem, null, true, false);
        }

        break;

      case WFSTATE_STEP3:

        // remove editors from tasklist
        // assign owner
        taskListItemService.deleteByWorkflowItem(context, workflowItem);
        workflowItem.setOwner(newowner);

        break;

      case WFSTATE_ARCHIVE:

        // put in archive in one transaction
        // remove workflow tasks
        taskListItemService.deleteByWorkflowItem(context, workflowItem);

        mycollection = workflowItem.getCollection();

        Item myitem = archive(context, workflowItem);

        // now email notification
        notifyOfArchive(context, myitem, mycollection);
        archived = true;

        break;
    }

    logWorkflowEvent(
        context,
        workflowItem.getItem(),
        workflowItem,
        context.getCurrentUser(),
        newstate,
        newowner,
        mycollection,
        oldState,
        mygroup);

    if (!archived) {
      workflowItemService.update(context, workflowItem);
    }

    return archived;
  }