private void populateTableRowFromItem(Item item, TableRow row) {
    EPerson submitter = item.getSubmitter();
    Collection owningCollection = item.getOwningCollection();

    row.setColumn("item_id", item.getID());
    row.setColumn("in_archive", item.isArchived());
    row.setColumn("withdrawn", item.isWithdrawn());
    row.setColumn("last_modified", item.getLastModified());

    if (submitter != null) {
      row.setColumn("submitter_id", submitter.getID());
    }

    if (owningCollection != null) {
      row.setColumn("owning_collection", owningCollection.getID());
    }
  }
  /**
   * Show an item page
   *
   * @param context Context object
   * @param request the HTTP request
   * @param response the HTTP response
   * @param item the item
   * @param identifier a persistent identifier that belongs to the item
   */
  private void displayItem(
      Context context, HttpServletRequest request, HttpServletResponse response, Item item)
      throws ServletException, IOException, SQLException, AuthorizeException {
    // Tombstone?
    if (item.isWithdrawn()) {
      JSPManager.showJSP(request, response, "/tombstone.jsp");

      return;
    }

    // Ensure the user has authorisation
    AuthorizeManager.authorizeAction(context, item, Constants.READ);

    log.info(
        LogManager.getHeader(
            context, "view_item", "uri=" + item.getIdentifier().getCanonicalForm()));

    // show edit link
    if (item.canEdit()) {
      // set a variable to create an edit button
      request.setAttribute("admin_button", new Boolean(true));
    }

    // Get the collections
    Collection[] collections = (Collection[]) item.getCollections().toArray();

    // For the breadcrumbs, get the first collection and the first community
    // that is in. FIXME: Not multiple-inclusion friendly--should be
    // smarter, context-sensitive
    request.setAttribute("dspace.collection", item.getOwningCollection());

    Collection collection = item.getOwningCollection();
    if (collection != null) {
      Community[] comms = (Community[]) collection.getCommunities().toArray();
      if (comms.length > 0) {
        request.setAttribute("dspace.community", comms[0]);

        /*
         * Find all the "parent" communities for the collection
         */
        request.setAttribute("dspace.communities", getParents(comms[0], true));
      }
    }

    // Full or simple display?
    boolean displayAll = false;
    String modeParam = request.getParameter("mode");

    if ((modeParam != null) && modeParam.equalsIgnoreCase("full")) {
      displayAll = true;
    }

    // Enable suggest link or not
    boolean suggestEnable = false;
    if (!ConfigurationManager.getBooleanProperty("webui.suggest.enable")) {
      // do nothing, the suggestLink is allready set to false
    } else {
      // it is in general enabled
      suggestEnable = true;

      // check for the enable only for logged in users option
      if (!ConfigurationManager.getBooleanProperty("webui.suggest.loggedinusers.only")) {
        // do nothing, the suggestLink stays as it is
      } else {
        // check whether there is a logged in user
        suggestEnable = (context.getCurrentUser() == null ? false : true);
      }
    }

    // Set attributes and display
    request.setAttribute("suggest.enable", new Boolean(suggestEnable));
    request.setAttribute("display.all", new Boolean(displayAll));
    request.setAttribute("item", item);
    request.setAttribute("collections", collections);
    JSPManager.showJSP(request, response, "/display-item.jsp");
  }
  @Override
  protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException, SQLException, AuthorizeException {
    Item item = null;
    Bitstream bitstream = null;

    // Get the ID from the URL
    String idString = request.getPathInfo();
    String handle = "";
    String sequenceText = "";
    String filename = null;
    int sequenceID;

    // Parse 'handle' and 'sequence' (bitstream seq. number) out
    // of remaining URL path, which is typically of the format:
    // {handle}/{sequence}/{bitstream-name}
    // But since the bitstream name MAY have any number of "/"s in
    // it, and the handle is guaranteed to have one slash, we
    // scan from the start to pick out handle and sequence:

    // Remove leading slash if any:
    if (idString.startsWith("/")) {
      idString = idString.substring(1);
    }

    // skip first slash within handle
    int slashIndex = idString.indexOf('/');
    if (slashIndex != -1) {
      slashIndex = idString.indexOf('/', slashIndex + 1);
      if (slashIndex != -1) {
        handle = idString.substring(0, slashIndex);
        int slash2 = idString.indexOf('/', slashIndex + 1);
        if (slash2 != -1) {
          sequenceText = idString.substring(slashIndex + 1, slash2);
          filename = idString.substring(slash2 + 1);
        }
      }
    }

    try {
      sequenceID = Integer.parseInt(sequenceText);
    } catch (NumberFormatException nfe) {
      sequenceID = -1;
    }

    // Now try and retrieve the item
    DSpaceObject dso = HandleManager.resolveToObject(context, handle);

    // Make sure we have valid item and sequence number
    if (dso != null && dso.getType() == Constants.ITEM && sequenceID >= 0) {
      item = (Item) dso;

      if (item.isWithdrawn()) {
        log.info(
            LogManager.getHeader(
                context, "view_bitstream", "handle=" + handle + ",withdrawn=true"));
        JSPManager.showJSP(request, response, "/tombstone.jsp");
        return;
      }

      boolean found = false;

      Bundle[] bundles = item.getBundles();

      for (int i = 0; (i < bundles.length) && !found; i++) {
        Bitstream[] bitstreams = bundles[i].getBitstreams();

        for (int k = 0; (k < bitstreams.length) && !found; k++) {
          if (sequenceID == bitstreams[k].getSequenceID()) {
            bitstream = bitstreams[k];
            found = true;
          }
        }
      }
    }

    if (bitstream == null || filename == null || !filename.equals(bitstream.getName())) {
      // No bitstream found or filename was wrong -- ID invalid
      log.info(LogManager.getHeader(context, "invalid_id", "path=" + idString));
      JSPManager.showInvalidIDError(request, response, idString, Constants.BITSTREAM);

      return;
    }

    log.info(LogManager.getHeader(context, "view_bitstream", "bitstream_id=" + bitstream.getID()));

    // Modification date
    // Only use last-modified if this is an anonymous access
    // - caching content that may be generated under authorisation
    //   is a security problem
    if (context.getCurrentUser() == null) {
      // TODO: Currently the date of the item, since we don't have dates
      // for files
      response.setDateHeader("Last-Modified", item.getLastModified().getTime());

      // Check for if-modified-since header
      long modSince = request.getDateHeader("If-Modified-Since");

      if (modSince != -1 && item.getLastModified().getTime() < modSince) {
        // Item has not been modified since requested date,
        // hence bitstream has not; return 304
        response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        return;
      }
    }

    // Pipe the bits
    InputStream is = bitstream.retrieve();

    // Set the response MIME type
    response.setContentType(bitstream.getFormat().getMIMEType());

    // Response length
    response.setHeader("Content-Length", String.valueOf(bitstream.getSize()));

    if (threshold != -1 && bitstream.getSize() >= threshold) {
      setBitstreamDisposition(bitstream.getName(), request, response);
    }

    Utils.bufferedCopy(is, response.getOutputStream());
    is.close();
    response.getOutputStream().flush();
  }