// Create workflow start provenance message
  protected void recordStart(Context context, Item myitem, Action action)
      throws SQLException, IOException, AuthorizeException {
    // get date
    DCDate now = DCDate.getCurrent();

    // Create provenance description
    String provmessage = "";

    if (myitem.getSubmitter() != null) {
      provmessage =
          "Submitted by "
              + myitem.getSubmitter().getFullName()
              + " ("
              + myitem.getSubmitter().getEmail()
              + ") on "
              + now.toString()
              + " workflow start="
              + action.getProvenanceStartId()
              + "\n";
    } else
    // null submitter
    {
      provmessage =
          "Submitted by unknown (probably automated) on"
              + now.toString()
              + " workflow start="
              + action.getProvenanceStartId()
              + "\n";
    }

    // add sizes and checksums of bitstreams
    provmessage += installItemService.getBitstreamProvenanceMessage(context, myitem);

    // Add message to the DC
    itemService.addMetadata(
        context, myitem, MetadataSchema.DC_SCHEMA, "description", "provenance", "en", provmessage);
    itemService.update(context, myitem);
  }
 protected void grantSubmitterReadPolicies(Context context, Item item)
     throws SQLException, AuthorizeException {
   // A list of policies the user has for this item
   List<Integer> userHasPolicies = new ArrayList<Integer>();
   List<ResourcePolicy> itempols = authorizeService.getPolicies(context, item);
   EPerson submitter = item.getSubmitter();
   for (ResourcePolicy resourcePolicy : itempols) {
     if (submitter.equals(resourcePolicy.getEPerson())) {
       // The user has already got this policy so add it to the list
       userHasPolicies.add(resourcePolicy.getAction());
     }
   }
   // Make sure we don't add duplicate policies
   if (!userHasPolicies.contains(Constants.READ))
     addPolicyToItem(context, item, Constants.READ, submitter);
 }
 protected void removeUserItemPolicies(Context context, Item item, EPerson e)
     throws SQLException, AuthorizeException {
   if (e != null) {
     // Also remove any lingering authorizations from this user
     authorizeService.removeEPersonPolicies(context, item, e);
     // Remove the bundle rights
     List<Bundle> bundles = item.getBundles();
     for (Bundle bundle : bundles) {
       authorizeService.removeEPersonPolicies(context, bundle, e);
       List<Bitstream> bitstreams = bundle.getBitstreams();
       for (Bitstream bitstream : bitstreams) {
         authorizeService.removeEPersonPolicies(context, bitstream, e);
       }
     }
     // Ensure that the submitter always retains his resource policies
     if (e.getID().equals(item.getSubmitter().getID())) {
       grantSubmitterReadPolicies(context, item);
     }
   }
 }
  /**
   * Return the workflow item to the workspace of the submitter. The workflow item is removed, and a
   * workspace item created.
   *
   * @param c Context
   * @param wfi WorkflowItem to be 'dismantled'
   * @return the workspace item
   * @throws java.io.IOException ...
   * @throws java.sql.SQLException ...
   * @throws org.dspace.authorize.AuthorizeException ...
   */
  protected WorkspaceItem returnToWorkspace(Context c, XmlWorkflowItem wfi)
      throws SQLException, IOException, AuthorizeException {
    // authorize a DSpaceActions.REJECT
    // stop workflow
    deleteAllTasks(c, wfi);

    c.turnOffAuthorisationSystem();
    // Also clear all info for this step
    workflowRequirementsService.clearInProgressUsers(c, wfi);

    // Remove (if any) the workflowItemroles for this item
    workflowItemRoleService.deleteForWorkflowItem(c, wfi);

    Item myitem = wfi.getItem();
    // Restore permissions for the submitter
    grantUserAllItemPolicies(c, myitem, myitem.getSubmitter());

    // FIXME: How should this interact with the workflow system?
    // FIXME: Remove license
    // FIXME: Provenance statement?
    // Create the new workspace item row
    WorkspaceItem workspaceItem = workspaceItemService.create(c, wfi);
    workspaceItem.setMultipleFiles(wfi.hasMultipleFiles());
    workspaceItem.setMultipleTitles(wfi.hasMultipleTitles());
    workspaceItem.setPublishedBefore(wfi.isPublishedBefore());
    workspaceItemService.update(c, workspaceItem);

    // myitem.update();
    log.info(
        LogManager.getHeader(
            c,
            "return_to_workspace",
            "workflow_item_id=" + wfi.getID() + "workspace_item_id=" + workspaceItem.getID()));

    // Now remove the workflow object manually from the database
    xmlWorkflowItemService.deleteWrapper(c, wfi);
    return workspaceItem;
  }
  /**
   * notify the submitter that the item is archived
   *
   * @param context The relevant DSpace Context.
   * @param item which item was archived
   * @param coll collection name to display in template
   * @throws SQLException An exception that provides information on a database access error or other
   *     errors.
   * @throws IOException A general class of exceptions produced by failed or interrupted I/O
   *     operations.
   */
  protected void notifyOfArchive(Context context, Item item, Collection coll)
      throws SQLException, IOException {
    try {
      // Get submitter
      EPerson ep = item.getSubmitter();
      // Get the Locale
      Locale supportedLocale = I18nUtil.getEPersonLocale(ep);
      Email email = Email.getEmail(I18nUtil.getEmailFilename(supportedLocale, "submit_archive"));

      // Get the item handle to email to user
      String handle = handleService.findHandle(context, item);

      // Get title
      List<MetadataValue> titles =
          itemService.getMetadata(item, MetadataSchema.DC_SCHEMA, "title", null, Item.ANY);
      String title = "";
      try {
        title = I18nUtil.getMessage("org.dspace.workflow.WorkflowManager.untitled");
      } catch (MissingResourceException e) {
        title = "Untitled";
      }
      if (titles.size() > 0) {
        title = titles.iterator().next().getValue();
      }

      email.addRecipient(ep.getEmail());
      email.addArgument(title);
      email.addArgument(coll.getName());
      email.addArgument(handleService.getCanonicalForm(handle));

      email.send();
    } catch (MessagingException e) {
      log.warn(
          LogManager.getHeader(
              context, "notifyOfArchive", "cannot email user" + " item_id=" + item.getID()));
    }
  }
  @Override
  public XmlWorkflowItem start(Context context, WorkspaceItem wsi)
      throws SQLException, AuthorizeException, IOException, WorkflowException {
    try {
      Item myitem = wsi.getItem();
      Collection collection = wsi.getCollection();
      Workflow wf = xmlWorkflowFactory.getWorkflow(collection);

      XmlWorkflowItem wfi = xmlWorkflowItemService.create(context, myitem, collection);
      wfi.setMultipleFiles(wsi.hasMultipleFiles());
      wfi.setMultipleTitles(wsi.hasMultipleTitles());
      wfi.setPublishedBefore(wsi.isPublishedBefore());
      xmlWorkflowItemService.update(context, wfi);
      removeUserItemPolicies(context, myitem, myitem.getSubmitter());
      grantSubmitterReadPolicies(context, myitem);

      context.turnOffAuthorisationSystem();
      Step firstStep = wf.getFirstStep();
      if (firstStep.isValidStep(context, wfi)) {
        activateFirstStep(context, wf, firstStep, wfi);
      } else {
        // Get our next step, if none is found, archive our item
        firstStep = wf.getNextStep(context, wfi, firstStep, ActionResult.OUTCOME_COMPLETE);
        if (firstStep == null) {
          archive(context, wfi);
        } else {
          activateFirstStep(context, wf, firstStep, wfi);
        }
      }
      // remove the WorkspaceItem
      workspaceItemService.deleteWrapper(context, wsi);
      context.restoreAuthSystemState();
      return wfi;
    } catch (WorkflowConfigurationException e) {
      throw new WorkflowException(e);
    }
  }