예제 #1
0
  /**
   * Process the input from the CC license page
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by doPostProcessing() below! (if
   *     STATUS_COMPLETE or 0 is returned, no errors occurred!)
   */
  protected int processCC(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    String buttonPressed = Util.getSubmitButton(request, NEXT_BUTTON);

    // RLR hack - need to distinguish between progress bar real submission
    // (if cc_license_url exists, then users has accepted the CC License)
    String ccLicenseUrl = request.getParameter("cc_license_url");

    if (buttonPressed.equals("submit_no_cc")) {
      // Skipping the CC license - remove any existing license selection
      creativeCommonsService.removeLicense(context, subInfo.getSubmissionItem().getItem());
    } else if ((ccLicenseUrl != null) && (ccLicenseUrl.length() > 0)) {
      Item item = subInfo.getSubmissionItem().getItem();

      // save the CC license
      creativeCommonsService.setLicense(context, item, ccLicenseUrl);
    }

    // commit changes
    context.dispatchEvents();

    // completed without errors
    return STATUS_COMPLETE;
  }
예제 #2
0
  /**
   * Do any processing of the information input by the user, and/or perform step processing (if no
   * user interaction required)
   *
   * <p>It is this method's job to save any data to the underlying database, as necessary, and
   * return error messages (if any) which can then be processed by the appropriate user interface
   * (JSP-UI or XML-UI)
   *
   * <p>NOTE: If this step is a non-interactive step (i.e. requires no UI), then it should perform
   * *all* of its processing in this method!
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by doPostProcessing() below! (if
   *     STATUS_COMPLETE or 0 is returned, no errors occurred!)
   */
  public int doProcessing(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    // The Submission is COMPLETE!!
    log.info(
        LogManager.getHeader(
            context,
            "submission_complete",
            "Completed submission with id=" + subInfo.getSubmissionItem().getID()));

    // Start the workflow for this Submission
    boolean success = false;
    try {
      WorkflowManager.start(context, (WorkspaceItem) subInfo.getSubmissionItem());
      success = true;
    } catch (Exception e) {
      log.error("Caught exception in submission step: ", e);
      throw new ServletException(e);
    } finally {
      // commit changes to database
      if (success) {
        context.commit();
      } else {
        context.getDBConnection().rollback();
      }
    }
    return STATUS_COMPLETE;
  }
예제 #3
0
  /**
   * Process input from get file type page
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by UI-related code! (if STATUS_COMPLETE or
   *     0 is returned, no errors occurred!)
   */
  protected int processSaveFileFormat(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    if (subInfo.getBitstream() != null) {
      // Did the user select a format?
      int typeID = Util.getIntParameter(request, "format");

      BitstreamFormat format = BitstreamFormat.find(context, typeID);

      if (format != null) {
        subInfo.getBitstream().setFormat(format);
      } else {
        String userDesc = request.getParameter("format_description");

        subInfo.getBitstream().setUserFormatDescription(userDesc);
      }

      // update database
      subInfo.getBitstream().update();
    } else {
      return STATUS_INTEGRITY_ERROR;
    }

    return STATUS_COMPLETE;
  }
예제 #4
0
  /**
   * Retrieves a list of all steps and pages within the current submission process.
   *
   * <p>This list may differ from the list of steps in the progress bar if the current submission
   * process includes non-interactive steps which do not appear in the progress bar!
   *
   * <p>This method is used by the Manakin submission flowscript (submission.js) to step
   * forward/backward between steps.
   *
   * @param request The HTTP Servlet Request object
   * @param subInfo the current SubmissionInfo object
   */
  public static StepAndPage[] getListOfAllSteps(
      HttpServletRequest request, SubmissionInfo subInfo) {
    ArrayList<StepAndPage> listStepNumbers = new ArrayList<StepAndPage>();

    // loop through all steps
    for (int i = 0; i < subInfo.getSubmissionConfig().getNumberOfSteps(); i++) {
      // get the current step info
      SubmissionStepConfig currentStep = subInfo.getSubmissionConfig().getStep(i);
      int stepNumber = currentStep.getStepNumber();

      // Skip over the "Select Collection" step, since
      // a user is never allowed to return to that step or jump from that step
      if (currentStep.getId() != null
          && currentStep.getId().equals(SubmissionStepConfig.SELECT_COLLECTION_STEP)) {
        continue;
      }

      // default to just one page in this step
      int numPages = 1;

      try {
        // load the processing class for this step
        ClassLoader loader = subInfo.getClass().getClassLoader();
        Class<?> stepClass = loader.loadClass(currentStep.getProcessingClassName());

        // call the "getNumberOfPages()" method of the class
        // to get it's number of pages
        AbstractProcessingStep step = (AbstractProcessingStep) stepClass.newInstance();

        // get number of pages from servlet
        numPages = step.getNumberOfPages(request, subInfo);
      } catch (Exception e) {
        log.error(
            "Error loading step information from Step Class '"
                + currentStep.getProcessingClassName()
                + "' Error:",
            e);
      }

      // save each of the step's pages to the progress bar
      for (int j = 1; j <= numPages; j++) {
        StepAndPage stepAndPageNum = new StepAndPage(stepNumber, j);

        listStepNumbers.add(stepAndPageNum);
      } // end for each page
    } // end for each step

    // convert into an array and return that
    return listStepNumbers.toArray(new StepAndPage[listStepNumbers.size()]);
  }
예제 #5
0
  /**
   * Process input from the "change file description" page
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by UI-related code! (if STATUS_COMPLETE or
   *     0 is returned, no errors occurred!)
   */
  protected int processSaveFileDescription(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    if (subInfo.getBitstream() != null) {
      subInfo.getBitstream().setDescription(request.getParameter("description"));
      subInfo.getBitstream().update();

      context.commit();
    } else {
      return STATUS_INTEGRITY_ERROR;
    }

    return STATUS_COMPLETE;
  }
예제 #6
0
  /**
   * Obtains the submission info for the current submission process. If a submissionInfo object has
   * already been created for this HTTP request, it is re-used, otherwise it is created.
   *
   * @param objectModel the cocoon Objectmodel
   * @param workspaceID the workspaceID of the submission info to obtain
   * @return a SubmissionInfo object
   */
  public static SubmissionInfo obtainSubmissionInfo(Map objectModel, String workspaceID)
      throws SQLException, IOException, AuthorizeException {
    Request request = ObjectModelHelper.getRequest(objectModel);
    Context context = ContextUtil.obtainContext(objectModel);

    // try loading subInfo from HTTP request
    SubmissionInfo subInfo = (SubmissionInfo) request.getAttribute(DSPACE_SUBMISSION_INFO);

    // get the submission represented by the WorkspaceID
    InProgressSubmission submission = findSubmission(context, workspaceID);

    // if no submission info, or wrong submission info, reload it!
    if ((subInfo == null && submission != null)
        || (subInfo != null
            && submission != null
            && subInfo.getSubmissionItem().getID() != submission.getID())) {
      try {
        final HttpServletRequest httpRequest =
            (HttpServletRequest) objectModel.get(HttpEnvironment.HTTP_REQUEST_OBJECT);

        // load submission info
        subInfo = SubmissionInfo.load(httpRequest, submission);

        // Set the session ID
        context.setExtraLogInfo("session_id=" + request.getSession().getId());

        // Store the submissionInfo in the request
        request.setAttribute(DSPACE_SUBMISSION_INFO, subInfo);
      } catch (Exception e) {
        throw new SQLException("Error loading Submission Info: " + e.getMessage(), e);
      }
    } else if (subInfo == null && submission == null) {
      throw new SQLException(
          "Unable to load Submission Information, since WorkspaceID (ID:"
              + workspaceID
              + ") is not a valid in-process submission.");
    }

    return subInfo;
  }
예제 #7
0
  /*
   If we created a new Bitstream but now realised there is a problem then remove it.
  */
  private void backoutBitstream(SubmissionInfo subInfo, Bitstream b, Item item)
      throws SQLException, AuthorizeException, IOException {
    // remove bitstream from bundle..
    // delete bundle if it's now empty
    Bundle[] bnd = b.getBundles();

    bnd[0].removeBitstream(b);

    Bitstream[] bitstreams = bnd[0].getBitstreams();

    // remove bundle if it's now empty
    if (bitstreams.length < 1) {
      item.removeBundle(bnd[0]);
      item.update();
    }

    subInfo.setBitstream(null);
  }
예제 #8
0
  /**
   * Show the page which displays all the Initial Questions to the user
   *
   * @param context current DSpace context
   * @param request the request object
   * @param response the response object
   * @param subInfo the SubmissionInfo object
   */
  private void showInitialQuestions(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws SQLException, ServletException, IOException {
    // determine collection
    Collection c = subInfo.getSubmissionItem().getCollection();

    try {
      // read configurable submissions forms data
      DCInputsReader inputsReader = new DCInputsReader();

      // load the proper submission inputs to be used by the JSP
      request.setAttribute("submission.inputs", inputsReader.getInputs(c.getHandle()));
    } catch (DCInputsReaderException e) {
      throw new ServletException(e);
    }

    // forward to initial questions JSP
    JSPStepManager.showJSP(request, response, subInfo, INITIAL_QUESTIONS_JSP);
  }
예제 #9
0
 /**
  * Do any processing of the information input by the user, and/or perform step processing (if no
  * user interaction required)
  *
  * <p>It is this method's job to save any data to the underlying database, as necessary, and
  * return error messages (if any) which can then be processed by the appropriate user interface
  * (JSP-UI or XML-UI)
  *
  * <p>NOTE: If this step is a non-interactive step (i.e. requires no UI), then it should perform
  * *all* of its processing in this method!
  *
  * @param context current DSpace context
  * @param request current servlet request object
  * @param response current servlet response object
  * @param subInfo submission info object
  * @return Status or error flag which will be processed by doPostProcessing() below! (if
  *     STATUS_COMPLETE or 0 is returned, no errors occurred!)
  */
 @Override
 public int doProcessing(
     Context context,
     HttpServletRequest request,
     HttpServletResponse response,
     SubmissionInfo subInfo)
     throws ServletException, IOException, SQLException, AuthorizeException, java.io.IOException {
   HttpSession session = request.getSession();
   session.setAttribute("inProgress", "TRUE");
   // check what submit button was pressed in User Interface
   String buttonPressed = Util.getSubmitButton(request, NEXT_BUTTON);
   if ("submit_grant".equalsIgnoreCase(buttonPressed)
       || "submit_no_cc".equalsIgnoreCase(buttonPressed)) {
     return processCC(context, request, response, subInfo);
   }
   String choiceButton = Util.getSubmitButton(request, SELECT_CHANGE);
   Enumeration e = request.getParameterNames();
   String isFieldRequired = "FALSE";
   while (e.hasMoreElements()) {
     String parameterName = (String) e.nextElement();
     if (parameterName.equals("button_required")) {
       isFieldRequired = "TRUE";
       break;
     }
   }
   session.setAttribute("isFieldRequired", isFieldRequired);
   if (choiceButton.equals(SELECT_CHANGE)) {
     Item item = subInfo.getSubmissionItem().getItem();
     LicenseMetadataValue uriField = creativeCommonsService.getCCField("uri");
     LicenseMetadataValue nameField = creativeCommonsService.getCCField("name");
     String licenseUri = uriField.ccItemValue(item);
     if (licenseUri != null)
     // if (CreativeCommons.hasLicense(item, "dc", "rights", "uri", Item.ANY)
     //	&& !CreativeCommons.getRightsURI(item, "dc", "rights", "uri", Item.ANY).equals(""))
     {
       // CreativeCommons.setItemMetadata(item, licenseURI, "dc", "rights", "uri",
       // ConfigurationManager.getProperty("default.locale"));
       uriField.removeItemValue(context, item, licenseUri);
       if (ConfigurationManager.getBooleanProperty("cc.submit.setname")) {
         String licenseName = nameField.keyedItemValue(item, licenseUri);
         nameField.removeItemValue(context, item, licenseName);
         // CreativeCommons.setItemMetadata(item, CreativeCommons.getRightsName(item, "dc",
         // "rights", null, Item.ANY), "dc", "rights", null,
         // ConfigurationManager.getProperty("default.locale"));
       }
       if (ConfigurationManager.getBooleanProperty("cc.submit.addBitstream")) {
         creativeCommonsService.removeLicense(context, item);
       }
       removeRequiredAttributes(session);
       itemService.update(context, item);
       context.dispatchEvents();
     }
     return STATUS_COMPLETE;
   } else if (buttonPressed.startsWith(PROGRESS_BAR_PREFIX)
       || buttonPressed.equals(PREVIOUS_BUTTON)) {
     removeRequiredAttributes(session);
   }
   if (buttonPressed.equals(NEXT_BUTTON) || buttonPressed.equals(CANCEL_BUTTON)) {
     return processCCWS(context, request, response, subInfo);
   } else {
     removeRequiredAttributes(session);
     session.removeAttribute("inProgress");
     return STATUS_COMPLETE;
   }
 }
예제 #10
0
  /**
   * Process the input from the CC license page using CC Web service
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by doPostProcessing() below! (if
   *     STATUS_COMPLETE or 0 is returned, no errors occurred!)
   */
  protected int processCCWS(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {

    HttpSession session = request.getSession();
    Map<String, String> map = new HashMap<String, String>();
    String licenseclass =
        (request.getParameter("licenseclass_chooser") != null)
            ? request.getParameter("licenseclass_chooser")
            : "";
    String jurisdiction =
        (ConfigurationManager.getProperty("cc.license.jurisdiction") != null)
            ? ConfigurationManager.getProperty("cc.license.jurisdiction")
            : "";
    if (licenseclass.equals("standard")) {
      map.put("commercial", request.getParameter("commercial_chooser"));
      map.put("derivatives", request.getParameter("derivatives_chooser"));
    } else if (licenseclass.equals("recombo")) {
      map.put("sampling", request.getParameter("sampling_chooser"));
    }
    map.put("jurisdiction", jurisdiction);
    CCLookup ccLookup = new CCLookup();
    LicenseMetadataValue uriField = creativeCommonsService.getCCField("uri");
    LicenseMetadataValue nameField = creativeCommonsService.getCCField("name");
    ccLookup.issue(licenseclass, map, ConfigurationManager.getProperty("cc.license.locale"));
    Item item = subInfo.getSubmissionItem().getItem();
    if (licenseclass.equals("xmlui.Submission.submit.CCLicenseStep.no_license")) {
      // only remove any previous licenses
      String licenseUri = uriField.ccItemValue(item);
      if (licenseUri != null) {
        uriField.removeItemValue(context, item, licenseUri);
        if (ConfigurationManager.getBooleanProperty("cc.submit.setname")) {
          String licenseName = nameField.keyedItemValue(item, licenseUri);
          nameField.removeItemValue(context, item, licenseName);
        }
        if (ConfigurationManager.getBooleanProperty("cc.submit.addBitstream")) {
          creativeCommonsService.removeLicense(context, item);
        }
        itemService.update(context, item);
        context.dispatchEvents();
        removeRequiredAttributes(session);
      }
      return STATUS_COMPLETE;
    } else if (licenseclass.equals("xmlui.Submission.submit.CCLicenseStep.select_change")) {
      removeRequiredAttributes(session);
      return STATUS_COMPLETE;
    } else if (ccLookup.isSuccess()) {
      uriField.addItemValue(context, item, ccLookup.getLicenseUrl());
      if (ConfigurationManager.getBooleanProperty("cc.submit.addbitstream")) {
        creativeCommonsService.setLicenseRDF(context, item, ccLookup.getRdf());
      }
      if (ConfigurationManager.getBooleanProperty("cc.submit.setname")) {
        nameField.addItemValue(context, item, ccLookup.getLicenseName());
      }
      itemService.update(context, item);
      context.dispatchEvents();
      removeRequiredAttributes(session);
      session.removeAttribute("inProgress");
    } else {
      request.getSession().setAttribute("ccError", ccLookup.getErrorMessage());
      String licenseUri = uriField.ccItemValue(item);
      if (licenseUri != null) {
        uriField.removeItemValue(context, item, licenseUri);
      }
      return STATUS_LICENSE_REJECTED;
    }
    return STATUS_COMPLETE;
  }
예제 #11
0
  /**
   * Process the upload of a new file!
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by UI-related code! (if STATUS_COMPLETE or
   *     0 is returned, no errors occurred!)
   */
  protected int processUploadFile(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    boolean formatKnown = true;
    boolean fileOK = false;
    BitstreamFormat bf = null;
    Bitstream b = null;

    // NOTE: File should already be uploaded.
    // Manakin does this automatically via Cocoon.
    // For JSP-UI, the SubmissionController.uploadFiles() does the actual upload

    Enumeration attNames = request.getAttributeNames();

    // loop through our request attributes
    while (attNames.hasMoreElements()) {
      String attr = (String) attNames.nextElement();

      // if this ends with "-path", this attribute
      // represents a newly uploaded file
      if (attr.endsWith("-path")) {
        // strip off the -path to get the actual parameter
        // that the file was uploaded as
        String param = attr.replace("-path", "");

        // Load the file's path and input stream and description
        String filePath = (String) request.getAttribute(param + "-path");
        InputStream fileInputStream = (InputStream) request.getAttribute(param + "-inputstream");

        // attempt to get description from attribute first, then direct from a parameter
        String fileDescription = (String) request.getAttribute(param + "-description");
        if (fileDescription == null || fileDescription.length() == 0) {
          fileDescription = request.getParameter("description");
        }

        // if information wasn't passed by User Interface, we had a problem
        // with the upload
        if (filePath == null || fileInputStream == null) {
          return STATUS_UPLOAD_ERROR;
        }

        if (subInfo == null) {
          // In any event, if we don't have the submission info, the request
          // was malformed
          return STATUS_INTEGRITY_ERROR;
        }

        // Create the bitstream
        Item item = subInfo.getSubmissionItem().getItem();

        // do we already have a bundle?
        Bundle[] bundles = item.getBundles("ORIGINAL");

        if (bundles.length < 1) {
          // set bundle's name to ORIGINAL
          b = item.createSingleBitstream(fileInputStream, "ORIGINAL");
        } else {
          // we have a bundle already, just add bitstream
          b = bundles[0].createBitstream(fileInputStream);
        }

        // Strip all but the last filename. It would be nice
        // to know which OS the file came from.
        String noPath = filePath;

        while (noPath.indexOf('/') > -1) {
          noPath = noPath.substring(noPath.indexOf('/') + 1);
        }

        while (noPath.indexOf('\\') > -1) {
          noPath = noPath.substring(noPath.indexOf('\\') + 1);
        }

        b.setName(noPath);
        b.setSource(filePath);
        b.setDescription(fileDescription);

        // Identify the format
        bf = FormatIdentifier.guessFormat(context, b);
        b.setFormat(bf);

        // Update to DB
        b.update();
        item.update();

        if ((bf != null) && (bf.isInternal())) {
          log.warn("Attempt to upload file format marked as internal system use only");
          backoutBitstream(subInfo, b, item);
          return STATUS_UPLOAD_ERROR;
        }

        // Check for virus
        if (ConfigurationManager.getBooleanProperty("submission-curation", "virus-scan")) {
          Curator curator = new Curator();
          curator.addTask("vscan").curate(item);
          int status = curator.getStatus("vscan");
          if (status == Curator.CURATE_ERROR) {
            backoutBitstream(subInfo, b, item);
            return STATUS_VIRUS_CHECKER_UNAVAILABLE;
          } else if (status == Curator.CURATE_FAIL) {
            backoutBitstream(subInfo, b, item);
            return STATUS_CONTAINS_VIRUS;
          }
        }

        // If we got this far then everything is more or less ok.

        // Comment - not sure if this is the right place for a commit here
        // but I'm not brave enough to remove it - Robin.
        context.commit();

        // save this bitstream to the submission info, as the
        // bitstream we're currently working with
        subInfo.setBitstream(b);

        // if format was not identified
        if (bf == null) {
          return STATUS_UNKNOWN_FORMAT;
        }
      } // end if attribute ends with "-path"
    } // end while

    return STATUS_COMPLETE;
  }
예제 #12
0
  /**
   * Do any processing of the information input by the user, and/or perform step processing (if no
   * user interaction required)
   *
   * <p>It is this method's job to save any data to the underlying database, as necessary, and
   * return error messages (if any) which can then be processed by the appropriate user interface
   * (JSP-UI or XML-UI)
   *
   * <p>NOTE: If this step is a non-interactive step (i.e. requires no UI), then it should perform
   * *all* of its processing in this method!
   *
   * @param context current DSpace context
   * @param request current servlet request object
   * @param response current servlet response object
   * @param subInfo submission info object
   * @return Status or error flag which will be processed by doPostProcessing() below! (if
   *     STATUS_COMPLETE or 0 is returned, no errors occurred!)
   */
  public int doProcessing(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      SubmissionInfo subInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    // get button user pressed
    String buttonPressed = Util.getSubmitButton(request, NEXT_BUTTON);

    // get reference to item
    Item item = subInfo.getSubmissionItem().getItem();

    // -----------------------------------
    // Step #0: Upload new files (if any)
    // -----------------------------------
    String contentType = request.getContentType();

    // if multipart form, then we are uploading a file
    if ((contentType != null) && (contentType.indexOf("multipart/form-data") != -1)) {
      // This is a multipart request, so it's a file upload
      // (return any status messages or errors reported)
      int status = processUploadFile(context, request, response, subInfo);

      // if error occurred, return immediately
      if (status != STATUS_COMPLETE) {
        return status;
      }
    }

    // if user pressed jump-to button in process bar,
    // return success (so that jump will occur)
    if (buttonPressed.startsWith(PROGRESS_BAR_PREFIX)) {
      // check if a file is required to be uploaded
      if (fileRequired && !item.hasUploadedFiles()) {
        return STATUS_NO_FILES_ERROR;
      } else {
        return STATUS_COMPLETE;
      }
    }

    // ---------------------------------------------
    // Step #1: Check if this was just a request to
    // edit file information.
    // (or canceled editing information)
    // ---------------------------------------------
    // check if we're already editing a specific bitstream
    if (request.getParameter("bitstream_id") != null) {
      if (buttonPressed.equals(CANCEL_EDIT_BUTTON)) {
        // canceled an edit bitstream request
        subInfo.setBitstream(null);

        // this flag will just return us to the normal upload screen
        return STATUS_EDIT_COMPLETE;
      } else {
        // load info for bitstream we are editing
        Bitstream b =
            Bitstream.find(context, Integer.parseInt(request.getParameter("bitstream_id")));

        // save bitstream to submission info
        subInfo.setBitstream(b);
      }
    } else if (buttonPressed.startsWith("submit_edit_")) {
      // get ID of bitstream that was requested for editing
      String bitstreamID = buttonPressed.substring("submit_edit_".length());

      Bitstream b = Bitstream.find(context, Integer.parseInt(bitstreamID));

      // save bitstream to submission info
      subInfo.setBitstream(b);

      // return appropriate status flag to say we are now editing the
      // bitstream
      return STATUS_EDIT_BITSTREAM;
    }

    // ---------------------------------------------
    // Step #2: Process any remove file request(s)
    // ---------------------------------------------
    // Remove-selected requests come from Manakin
    if (buttonPressed.equalsIgnoreCase("submit_remove_selected")) {
      // this is a remove multiple request!

      if (request.getParameter("remove") != null) {
        // get all files to be removed
        String[] removeIDs = request.getParameterValues("remove");

        // remove each file in the list
        for (int i = 0; i < removeIDs.length; i++) {
          int id = Integer.parseInt(removeIDs[i]);

          int status = processRemoveFile(context, item, id);

          // if error occurred, return immediately
          if (status != STATUS_COMPLETE) {
            return status;
          }
        }

        // remove current bitstream from Submission Info
        subInfo.setBitstream(null);
      }
    } else if (buttonPressed.startsWith("submit_remove_")) {
      // A single file "remove" button must have been pressed

      int id = Integer.parseInt(buttonPressed.substring(14));
      int status = processRemoveFile(context, item, id);

      // if error occurred, return immediately
      if (status != STATUS_COMPLETE) {
        return status;
      }

      // remove current bitstream from Submission Info
      subInfo.setBitstream(null);
    }

    // -------------------------------------------------
    // Step #3: Check for a change in file description
    // -------------------------------------------------
    String fileDescription = request.getParameter("description");

    if (fileDescription != null && fileDescription.length() > 0) {
      // save this file description
      int status = processSaveFileDescription(context, request, response, subInfo);

      // if error occurred, return immediately
      if (status != STATUS_COMPLETE) {
        return status;
      }
    }

    // ------------------------------------------
    // Step #4: Check for a file format change
    // (if user had to manually specify format)
    // ------------------------------------------
    int formatTypeID = Util.getIntParameter(request, "format");
    String formatDesc = request.getParameter("format_description");

    // if a format id or description was found, then save this format!
    if (formatTypeID >= 0 || (formatDesc != null && formatDesc.length() > 0)) {
      // save this specified format
      int status = processSaveFileFormat(context, request, response, subInfo);

      // if error occurred, return immediately
      if (status != STATUS_COMPLETE) {
        return status;
      }
    }

    // ---------------------------------------------------
    // Step #5: Check if primary bitstream has changed
    // -------------------------------------------------
    if (request.getParameter("primary_bitstream_id") != null) {
      Bundle[] bundles = item.getBundles("ORIGINAL");
      if (bundles.length > 0) {
        bundles[0].setPrimaryBitstreamID(
            Integer.valueOf(request.getParameter("primary_bitstream_id")).intValue());
        bundles[0].update();
      }
    }

    // ---------------------------------------------------
    // Step #6: Determine if there is an error because no
    // files have been uploaded.
    // ---------------------------------------------------
    // check if a file is required to be uploaded
    if (fileRequired && !item.hasUploadedFiles()) {
      return STATUS_NO_FILES_ERROR;
    }

    // commit all changes to database
    context.commit();

    return STATUS_COMPLETE;
  }