/**
   * GET implementation returns the contents of the Item as a package. The query arg "package" must
   * be specified.
   *
   * @throws SQLException the SQL exception
   * @throws AuthorizeException the authorize exception
   * @throws ServletException the servlet exception
   * @throws IOException Signals that an I/O exception has occurred.
   * @throws DAVStatusException the DAV status exception
   */
  @Override
  protected void get() throws SQLException, AuthorizeException, IOException, DAVStatusException {
    // Check for overall read permission on Item, because nothing else will
    AuthorizeManager.authorizeAction(this.context, this.item, Constants.READ);

    String packageType = this.request.getParameter("package");
    Bundle[] original = this.item.getBundles("ORIGINAL");
    int bsid;

    if (packageType == null) {
      packageType = "default";
    }
    PackageDisseminator dip =
        (PackageDisseminator) PluginManager.getNamedPlugin(PackageDisseminator.class, packageType);
    if (dip == null) {
      throw new DAVStatusException(
          HttpServletResponse.SC_BAD_REQUEST,
          "Cannot find a disseminate plugin for package=" + packageType);
    } else {
      try {
        PackageParameters pparams = PackageParameters.create(this.request);
        this.response.setContentType(dip.getMIMEType(pparams));
        dip.disseminate(this.context, this.item, pparams, this.response.getOutputStream());
      } catch (CrosswalkException pe) {
        throw new DAVStatusException(
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
            "Failed in crosswalk of metadata: " + pe.toString());
      } catch (PackageException pe) {
        pe.log(log);
        throw new DAVStatusException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, pe.toString());
      }
    }
  }
  /**
   * PUT ingests a package as a new Item. Package type (must match pluggable packager name) is in
   * either (a) "package" query arg in URI (b) content-type request header
   *
   * @throws SQLException the SQL exception
   * @throws AuthorizeException the authorize exception
   * @throws ServletException the servlet exception
   * @throws IOException Signals that an I/O exception has occurred.
   * @throws DAVStatusException the DAV status exception
   */
  @Override
  protected void put()
      throws SQLException, AuthorizeException, ServletException, IOException, DAVStatusException {
    try {
      String packageType = this.request.getParameter("package");
      if (packageType == null) {
        packageType = this.request.getContentType();
      }
      if (packageType == null) {
        throw new DAVStatusException(
            HttpServletResponse.SC_BAD_REQUEST,
            "Cannot determine package type,  need content-type header or package param");
      }

      PackageIngester sip =
          (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, packageType);
      if (sip == null) {
        throw new DAVStatusException(
            HttpServletResponse.SC_BAD_REQUEST,
            "Cannot find importer for package type: " + packageType);
      }

      /*
       * Ugh. Servlet container doesn't get end-of-file right on input
       * stream so we have to count it, when possible.
       */
      int contentLength = this.request.getIntHeader("Content-Length");
      InputStream pis = this.request.getInputStream();
      if (contentLength >= 0) {
        pis = new CountedInputStream(pis, contentLength);
        log.debug("put: Using CountedInputStream, length=" + String.valueOf(contentLength));
      }
      WorkspaceItem wi =
          sip.ingest(
              this.context, this.collection, pis, PackageParameters.create(this.request), null);
      WorkflowItem wfi = WorkflowManager.startWithoutNotify(this.context, wi);

      // get new item's location: if workflow completed, then look
      // for handle (but be ready for disappointment); otherwise,
      // return the workflow item's resource.
      int state = wfi.getState();
      String location = null;
      if (state == WorkflowManager.WFSTATE_ARCHIVE) {
        Item ni = wfi.getItem();

        // FIXME: I'm not sure this is what we want
        String handle = ni.getExternalIdentifier().getCanonicalForm();
        //                String handle = HandleManager.findHandle(this.context, ni);

        String end = (handle != null) ? DAVDSpaceObject.getPathElt(handle) : DAVItem.getPathElt(ni);
        DAVItem newItem =
            new DAVItem(this.context, this.request, this.response, makeChildPath(end), ni);
        location = newItem.hrefURL();
      } else if (state == WorkflowManager.WFSTATE_SUBMIT
          || state == WorkflowManager.WFSTATE_STEP1POOL) {
        location = hrefPrefix() + DAVWorkflow.getPath(wfi);
      } else {
        throw new DAVStatusException(
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
            "Workflow object in unexpected state, state="
                + String.valueOf(state)
                + ", aborting PUT.");
      }

      this.context.commit();
      log.info("Created new Item, location=" + location);
      this.response.setHeader("Location", location);
      this.response.setStatus(HttpServletResponse.SC_CREATED);
    } catch (PackageException pe) {
      pe.log(log);
      throw new DAVStatusException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, pe.toString());
    } catch (CrosswalkException ie) {
      String reason = "";
      if (ie.getCause() != null) {
        reason = ", Reason: " + ie.getCause().toString();
      }
      log.error(ie.toString() + reason);
      throw new DAVStatusException(
          HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ie.toString() + reason);
    }
  }