Пример #1
0
  public void setup(org.dspace.content.Bitstream bitstream, String expand) throws SQLException {
    List<String> expandFields = new ArrayList<String>();
    if (expand != null) {
      expandFields = Arrays.asList(expand.split(","));
    }

    // A logo bitstream might not have a bundle...
    if (bitstream.getBundles() != null & bitstream.getBundles().length >= 0) {
      if (bitstream.getParentObject().getType() == Constants.ITEM) {
        bundleName = bitstream.getBundles()[0].getName();
      }
    }

    description = bitstream.getDescription();
    format = bitstream.getFormatDescription();
    sizeBytes = bitstream.getSize();
    retrieveLink = "/bitstreams/" + bitstream.getID() + "/retrieve";
    mimeType = bitstream.getFormat().getMIMEType();
    sequenceId = bitstream.getSequenceID();
    CheckSum checkSum = new CheckSum();
    checkSum.setCheckSumAlgorith(bitstream.getChecksumAlgorithm());
    checkSum.setValue(bitstream.getChecksum());
    this.setCheckSum(checkSum);

    if (expandFields.contains("parent") || expandFields.contains("all")) {
      parentObject = new DSpaceObject(bitstream.getParentObject());
    } else {
      this.addExpand("parent");
    }

    if (!expandFields.contains("all")) {
      this.addExpand("all");
    }
  }
Пример #2
0
  /**
   * Return this resource's children. Item's children are its bitstreams.
   *
   * @return the DAV resource[]
   * @throws SQLException the SQL exception
   */
  @Override
  protected DAVResource[] children() throws SQLException {
    // Check for overall read permission on Item
    if (!AuthorizeManager.authorizeActionBoolean(this.context, this.item, Constants.READ)) {
      return new DAVResource[0];
    }

    Vector result = new Vector();
    Bundle[] bundles = this.item.getBundles();
    for (Bundle element : bundles) {
      // check read permission on this Bundle
      if (!AuthorizeManager.authorizeActionBoolean(this.context, element, Constants.READ)) {
        continue;
      }

      Bitstream[] bitstreams = element.getBitstreams();
      for (Bitstream element0 : bitstreams) {
        String ext[] = element0.getFormat().getExtensions();
        result.add(
            new DAVBitstream(
                this.context,
                this.request,
                this.response,
                makeChildPath(
                    DAVBitstream.getPathElt(
                        element0.getSequenceID(), ext.length < 1 ? null : ext[0])),
                this.item,
                element0));
      }
    }
    return (DAVResource[]) result.toArray(new DAVResource[result.size()]);
  }
Пример #3
0
 /**
  * Returns canonical link to a bitstream in the item.
  *
  * @param item The DSpace Item that the bitstream is part of
  * @param bitstream The bitstream to link to
  * @returns a String link to the bitstream
  */
 private String makeBitstreamLink(Item item, Bitstream bitstream) {
   String name = bitstream.getName();
   StringBuilder result = new StringBuilder(contextPath);
   result.append("/bitstream/item/").append(String.valueOf(item.getID()));
   // append name although it isn't strictly necessary
   try {
     if (name != null) {
       result.append("/").append(Util.encodeBitstreamName(name, "UTF-8"));
     }
   } catch (UnsupportedEncodingException uee) {
     // just ignore it, we don't have to have a pretty
     // name on the end of the url because the sequence id will
     // locate it. However it means that links in this file might
     // not work....
   }
   result.append("?sequence=").append(String.valueOf(bitstream.getSequenceID()));
   return result.toString();
 }
  /** Write out a METS manifest. Mostly lifted from Rob Tansley's METS exporter. */
  private void writeManifest(Context context, Item item, PackageParameters params, OutputStream out)
      throws PackageValidationException, CrosswalkException, AuthorizeException, SQLException,
          IOException {
    try {
      // Create the METS file
      Mets mets = new Mets();

      // Top-level stuff
      mets.setID(gensym("mets"));
      mets.setOBJID("hdl:" + item.getHandle());
      mets.setLABEL("DSpace Item");
      mets.setPROFILE(getProfile());

      // MetsHdr
      MetsHdr metsHdr = new MetsHdr();
      metsHdr.setCREATEDATE(new Date()); // FIXME: CREATEDATE is now:
      // maybe should be item create
      // date?

      // Agent
      Agent agent = new Agent();
      agent.setROLE(Role.CUSTODIAN);
      agent.setTYPE(Type.ORGANIZATION);
      Name name = new Name();
      name.getContent().add(new PCData(ConfigurationManager.getProperty("dspace.name")));
      agent.getContent().add(name);
      metsHdr.getContent().add(agent);
      mets.getContent().add(metsHdr);

      // add DMD sections
      // Each type element MAY be either just a MODS-and-crosswalk name, OR
      // a combination "MODS-name:crosswalk-name" (e.g. "DC:qDC").
      String dmdTypes[] = getDmdTypes(params);

      // record of ID of each dmdsec to make DMDID in structmap.
      String dmdGroup = gensym("dmd_group");
      String dmdId[] = new String[dmdTypes.length];
      for (int i = 0; i < dmdTypes.length; ++i) {
        dmdId[i] = gensym("dmd");
        XmlData xmlData = new XmlData();
        String xwalkName, metsName;
        String parts[] = dmdTypes[i].split(":", 2);
        if (parts.length > 1) {
          metsName = parts[0];
          xwalkName = parts[1];
        } else xwalkName = metsName = dmdTypes[i];

        DisseminationCrosswalk xwalk =
            (DisseminationCrosswalk)
                PluginManager.getNamedPlugin(DisseminationCrosswalk.class, xwalkName);
        if (xwalk == null)
          throw new PackageValidationException("Cannot find " + dmdTypes[i] + " crosswalk plugin!");
        else crosswalkToMets(xwalk, item, xmlData);

        DmdSec dmdSec = new DmdSec();
        dmdSec.setID(dmdId[i]);
        dmdSec.setGROUPID(dmdGroup);
        MdWrap mdWrap = new MdWrap();
        setMdType(mdWrap, metsName);
        mdWrap.getContent().add(xmlData);
        dmdSec.getContent().add(mdWrap);
        mets.getContent().add(dmdSec);
      }

      // Only add license AMD section if there are any licenses.
      // Catch authorization failures accessing license bitstreams
      // only if we are skipping unauthorized bitstreams.
      String licenseID = null;
      try {
        AmdSec amdSec = new AmdSec();
        addRightsMd(context, item, amdSec);
        if (amdSec.getContent().size() > 0) {
          licenseID = gensym("license");
          amdSec.setID(licenseID);
          mets.getContent().add(amdSec);
        }
      } catch (AuthorizeException e) {
        String unauth = (params == null) ? null : params.getProperty("unauthorized");
        if (!(unauth != null && unauth.equalsIgnoreCase("skip"))) throw e;
        else log.warn("Skipping license metadata because of access failure: " + e.toString());
      }

      // FIXME: History data???? Nooooo!!!!

      // fileSec - all non-metadata bundles go into fileGrp,
      // and each bitstream therein into a file.
      // Create the bitstream-level techMd and div's for structmap
      // at the same time so we can connec the IDREFs to IDs.
      FileSec fileSec = new FileSec();

      String techMdType = getTechMdType(params);
      String parts[] = techMdType.split(":", 2);
      String xwalkName, metsName;
      if (parts.length > 1) {
        metsName = parts[0];
        xwalkName = parts[1];
      } else xwalkName = metsName = techMdType;

      DisseminationCrosswalk xwalk =
          (DisseminationCrosswalk)
              PluginManager.getNamedPlugin(DisseminationCrosswalk.class, xwalkName);
      if (xwalk == null)
        throw new PackageValidationException("Cannot find " + xwalkName + " crosswalk plugin!");

      // log the primary bitstream for structmap
      String primaryBitstreamFileID = null;

      // accumulate content DIV items to put in structMap later.
      List contentDivs = new ArrayList();

      // how to handle unauthorized bundle/bitstream:
      String unauth = (params == null) ? null : params.getProperty("unauthorized");

      Bundle[] bundles = item.getBundles();
      for (int i = 0; i < bundles.length; i++) {
        if (PackageUtils.isMetaInfoBundle(bundles[i])) continue;

        // unauthorized bundle?
        // NOTE: This must match the logic in disseminate()
        if (!AuthorizeManager.authorizeActionBoolean(context, bundles[i], Constants.READ)) {
          if (unauth != null && (unauth.equalsIgnoreCase("skip"))) continue;
          else
            throw new AuthorizeException(
                "Not authorized to read Bundle named \"" + bundles[i].getName() + "\"");
        }

        Bitstream[] bitstreams = bundles[i].getBitstreams();

        // Create a fileGrp
        FileGrp fileGrp = new FileGrp();

        // Bundle name for USE attribute
        String bName = bundles[i].getName();
        if ((bName != null) && !bName.equals("")) fileGrp.setUSE(bundleToFileGrp(bName));

        // watch for primary bitstream
        int primaryBitstreamID = -1;
        boolean isContentBundle = false;
        if ((bName != null) && bName.equals("ORIGINAL")) {
          isContentBundle = true;
          primaryBitstreamID = bundles[i].getPrimaryBitstreamID();
        }

        for (int bits = 0; bits < bitstreams.length; bits++) {
          // Check for authorization.  Handle unauthorized
          // bitstreams to match the logic in disseminate(),
          // i.e. "unauth=zero" means include a 0-length bitstream,
          // "unauth=skip" means to ignore it (and exclude from
          // manifest).
          boolean auth =
              AuthorizeManager.authorizeActionBoolean(context, bitstreams[bits], Constants.READ);
          if (!auth) {
            if (unauth != null && unauth.equalsIgnoreCase("skip")) continue;
            else if (!(unauth != null && unauth.equalsIgnoreCase("zero")))
              throw new AuthorizeException(
                  "Not authorized to read Bitstream, SID="
                      + String.valueOf(bitstreams[bits].getSequenceID()));
          }

          String sid = String.valueOf(bitstreams[bits].getSequenceID());

          edu.harvard.hul.ois.mets.File file = new edu.harvard.hul.ois.mets.File();

          String xmlIDstart = "bitstream_";
          String fileID = xmlIDstart + sid;

          file.setID(fileID);

          // log primary bitstream for later (structMap)
          if (bitstreams[bits].getID() == primaryBitstreamID) primaryBitstreamFileID = fileID;

          // if this is content, add to structmap too:
          if (isContentBundle) {
            Div div = new Div();
            div.setID(gensym("div"));
            div.setTYPE("DSpace Content Bitstream");
            Fptr fptr = new Fptr();
            fptr.setFILEID(fileID);
            div.getContent().add(fptr);
            contentDivs.add(div);
          }

          file.setSEQ(bitstreams[bits].getSequenceID());

          String groupID = "GROUP_" + xmlIDstart + sid;

          /*
           * If we're in THUMBNAIL or TEXT bundles, the bitstream is
           * extracted text or a thumbnail, so we use the name to work
           * out which bitstream to be in the same group as
           */
          if ((bundles[i].getName() != null)
              && (bundles[i].getName().equals("THUMBNAIL")
                  || bundles[i].getName().startsWith("TEXT"))) {
            // Try and find the original bitstream, and chuck the
            // derived bitstream in the same group
            Bitstream original = findOriginalBitstream(item, bitstreams[bits]);

            if (original != null) {
              groupID = "GROUP_" + xmlIDstart + original.getSequenceID();
            }
          }

          file.setGROUPID(groupID);
          file.setMIMETYPE(bitstreams[bits].getFormat().getMIMEType());

          // FIXME: CREATED: no date

          file.setSIZE(auth ? bitstreams[bits].getSize() : 0);

          // translate checksum and type to METS, if available.
          String csType = bitstreams[bits].getChecksumAlgorithm();
          String cs = bitstreams[bits].getChecksum();
          if (auth && cs != null && csType != null) {
            try {
              file.setCHECKSUMTYPE(Checksumtype.parse(csType));
              file.setCHECKSUM(cs);
            } catch (MetsException e) {
              log.warn("Cannot set bitstream checksum type=" + csType + " in METS.");
            }
          }

          // FLocat: filename is MD5 checksum
          FLocat flocat = new FLocat();
          flocat.setLOCTYPE(Loctype.URL);
          flocat.setXlinkHref(makeBitstreamName(bitstreams[bits]));

          // Make bitstream techMD metadata, add to file.
          String techID = "techMd_for_bitstream_" + bitstreams[bits].getSequenceID();
          AmdSec fAmdSec = new AmdSec();
          fAmdSec.setID(techID);
          TechMD techMd = new TechMD();
          techMd.setID(gensym("tech"));
          MdWrap mdWrap = new MdWrap();
          setMdType(mdWrap, metsName);
          XmlData xmlData = new XmlData();
          mdWrap.getContent().add(xmlData);
          techMd.getContent().add(mdWrap);
          fAmdSec.getContent().add(techMd);
          mets.getContent().add(fAmdSec);
          crosswalkToMets(xwalk, bitstreams[bits], xmlData);
          file.setADMID(techID);

          // Add FLocat to File, and File to FileGrp
          file.getContent().add(flocat);
          fileGrp.getContent().add(file);
        }

        // Add fileGrp to fileSec
        fileSec.getContent().add(fileGrp);
      }

      // Add fileSec to document
      mets.getContent().add(fileSec);

      // Create simple structMap: initial div represents the Item,
      // and user-visible content bitstreams are in its child divs.
      StringBuffer dmdIds = new StringBuffer();
      for (int i = 0; i < dmdId.length; ++i) dmdIds.append(" " + dmdId[i]);
      StructMap structMap = new StructMap();
      structMap.setID(gensym("struct"));
      structMap.setTYPE("LOGICAL");
      structMap.setLABEL("DSpace");
      Div div0 = new Div();
      div0.setID(gensym("div"));
      div0.setTYPE("DSpace Item");
      div0.setDMDID(dmdIds.substring(1));
      if (licenseID != null) div0.setADMID(licenseID);

      // if there is a primary bitstream, add FPTR to it.
      if (primaryBitstreamFileID != null) {
        Fptr fptr = new Fptr();
        fptr.setFILEID(primaryBitstreamFileID);
        div0.getContent().add(fptr);
      }

      // add DIV for each content bitstream
      div0.getContent().addAll(contentDivs);

      structMap.getContent().add(div0);

      // Does subclass have something to add to structMap?
      addStructMap(context, item, params, mets);

      mets.getContent().add(structMap);

      mets.validate(new MetsValidator());

      mets.write(new MetsWriter(out));
    } catch (MetsException e) {
      // We don't pass up a MetsException, so callers don't need to
      // know the details of the METS toolkit
      // e.printStackTrace();
      throw new PackageValidationException(e);
    }
  }
Пример #5
0
  /**
   * Generate a METS file element for a given bitstream.
   *
   * @param context
   * @param item If the bitstream is associated with an item, provide the item, otherwise leave
   *     null.
   * @param bitstream The bitstream to build a file element for.
   * @param fileID The unique file id for this file.
   * @param groupID The group id for this file, if it is derived from another file then they should
   *     share the same groupID.
   * @param admID The IDs of the administrative metadata sections which pertain to this file
   * @throws org.xml.sax.SAXException passed through.
   * @throws java.sql.SQLException passed through.
   */
  protected final void renderFile(
      Context context, Item item, Bitstream bitstream, String fileID, String groupID, String admID)
      throws SAXException, SQLException {
    AttributeMap attributes;

    // //////////////////////////////
    // Determine the file attributes
    BitstreamFormat format = bitstream.getFormat(context);
    String mimeType = null;
    if (format != null) {
      mimeType = format.getMIMEType();
    }
    String checksumType = bitstream.getChecksumAlgorithm();
    String checksum = bitstream.getChecksum();
    long size = bitstream.getSize();

    // ////////////////////////////////
    // Start the actual file
    attributes = new AttributeMap();
    attributes.put("ID", fileID);
    attributes.put("GROUPID", groupID);
    if (admID != null && admID.length() > 0) {
      attributes.put("ADMID", admID);
    }
    if (mimeType != null && mimeType.length() > 0) {
      attributes.put("MIMETYPE", mimeType);
    }
    if (checksumType != null && checksum != null) {
      attributes.put("CHECKSUM", checksum);
      attributes.put("CHECKSUMTYPE", checksumType);
    }
    attributes.put("SIZE", String.valueOf(size));
    startElement(METS, "file", attributes);

    // ////////////////////////////////////
    // Determine the file location attributes
    String name = bitstream.getName();
    String description = bitstream.getDescription();

    // If possible, reference this bitstream via a handle, however this may
    // be null if a handle has not yet been assigned. In this case reference the
    // item its internal id. In the last case where the bitstream is not associated
    // with an item (such as a community logo) then reference the bitstreamID directly.
    String identifier = null;
    if (item != null && item.getHandle() != null) {
      identifier = "handle/" + item.getHandle();
    } else if (item != null) {
      identifier = "item/" + item.getID();
    } else {
      identifier = "id/" + bitstream.getID();
    }

    String url = contextPath + "/bitstream/" + identifier + "/";

    // If we can, append the pretty name of the bitstream to the URL
    try {
      if (bitstream.getName() != null) {
        url += Util.encodeBitstreamName(bitstream.getName(), "UTF-8");
      }
    } catch (UnsupportedEncodingException uee) {
      // just ignore it, we don't have to have a pretty
      // name at the end of the URL because the sequence id will
      // locate it. However it means that links in this file might
      // not work....
    }

    url += "?sequence=" + bitstream.getSequenceID();

    // //////////////////////
    // Start the file location
    attributes = new AttributeMap();
    AttributeMap attributesXLINK = new AttributeMap();
    attributesXLINK.setNamespace(XLINK);
    attributes.put("LOCTYPE", "URL");
    attributesXLINK.put("type", "locator");
    attributesXLINK.put("title", name);
    if (description != null) {
      attributesXLINK.put("label", description);
    }
    attributesXLINK.put("href", url);
    startElement(METS, "FLocat", attributes, attributesXLINK);

    // ///////////////////////
    // End file location
    endElement(METS, "FLocate");

    // ////////////////////////////////
    // End the file
    endElement(METS, "file");
  }
Пример #6
0
  private int scan(Bitstream bitstream, InputStream inputstream, String itemHandle) {
    try {
      dataOutputStream.write(INSTREAM);
    } catch (IOException e) {
      log.error("Error writing INSTREAM command . . .");
      return Curator.CURATE_ERROR;
    }
    int read = DEFAULT_CHUNK_SIZE;
    while (read == DEFAULT_CHUNK_SIZE) {
      try {
        read = inputstream.read(buffer);
      } catch (IOException e) {
        log.error("Failed attempting to read the InputStream . . . ");
        return Curator.CURATE_ERROR;
      }
      if (read == -1) {
        break;
      }
      try {
        dataOutputStream.writeInt(read);
        dataOutputStream.write(buffer, 0, read);
      } catch (IOException e) {
        log.error("Could not write to the socket . . . ");
        return Curator.CURATE_ERROR;
      }
    }
    try {
      dataOutputStream.writeInt(0);
      dataOutputStream.flush();
    } catch (IOException e) {
      log.error("Error writing zero-length chunk to socket");
      return Curator.CURATE_ERROR;
    }
    try {
      read = socket.getInputStream().read(buffer);

    } catch (IOException e) {
      log.error("Error reading result from socket");
      return Curator.CURATE_ERROR;
    }

    if (read > 0) {
      String response = new String(buffer, 0, read);
      logDebugMessage("Response: " + response);
      if (response.indexOf("FOUND") != -1) {
        String itemMsg = "item - " + itemHandle + ": ";
        String bsMsg =
            "bitstream - "
                + bitstream.getName()
                + ": SequenceId - "
                + bitstream.getSequenceID()
                + ": infected";
        report(itemMsg + bsMsg);
        results.add(bsMsg);
        return Curator.CURATE_FAIL;
      } else {
        return Curator.CURATE_SUCCESS;
      }
    }
    return Curator.CURATE_ERROR;
  }