/**
   * Process Item, correcting CC-License if encountered.
   *
   * @param item
   * @throws SQLException
   * @throws AuthorizeException
   * @throws IOException
   */
  protected static void handleItem(Item item) throws SQLException, AuthorizeException, IOException {
    Bundle[] bundles = item.getBundles("CC-LICENSE");

    if (bundles == null || bundles.length == 0) return;

    Bundle bundle = bundles[0];

    Bitstream bitstream = bundle.getBitstreamByName("license_rdf");

    String license_rdf = new String(copy(bitstream));

    /* quickly fix xml by ripping out offensive parts */
    license_rdf = license_rdf.replaceFirst("<license", "");
    license_rdf = license_rdf.replaceFirst("</license>", "");

    StringWriter result = new StringWriter();

    try {
      templates
          .newTransformer()
          .transform(
              new StreamSource(new ByteArrayInputStream(license_rdf.getBytes())),
              new StreamResult(result));
    } catch (TransformerException e) {
      throw new RuntimeException(e.getMessage(), e);
    }

    StringBuffer buffer = result.getBuffer();

    Bitstream newBitstream =
        bundle.createBitstream(new ByteArrayInputStream(buffer.toString().getBytes()));

    newBitstream.setName(bitstream.getName());
    newBitstream.setDescription(bitstream.getDescription());
    newBitstream.setFormat(bitstream.getFormat());
    newBitstream.setSource(bitstream.getSource());
    newBitstream.setUserFormatDescription(bitstream.getUserFormatDescription());
    newBitstream.update();

    bundle.removeBitstream(bitstream);

    bundle.update();
  }
Пример #2
0
  /**
   * Perform a deposit, using the supplied SWORD Deposit object.
   *
   * @param deposit
   * @throws SWORDErrorException
   * @throws DSpaceSWORDException
   */
  public DepositResult doDeposit(Deposit deposit) throws SWORDErrorException, DSpaceSWORDException {
    // get the things out of the service that we need
    Context context = swordService.getContext();
    SWORDConfiguration swordConfig = swordService.getSwordConfig();
    SWORDUrlManager urlManager = swordService.getUrlManager();

    // FIXME: the spec is unclear what to do in this situation.  I'm going
    // the throw a 415 (ERROR_CONTENT) until further notice
    //
    // determine if this is an acceptable file format
    if (!swordConfig.isAcceptableContentType(context, deposit.getContentType(), collection)) {
      log.error(
          "Unacceptable content type detected: "
              + deposit.getContentType()
              + " for collection "
              + collection.getID());
      throw new SWORDErrorException(
          ErrorCodes.ERROR_CONTENT,
          "Unacceptable content type in deposit request: " + deposit.getContentType());
    }

    // determine if this is an acceptable packaging type for the deposit
    // if not, we throw a 415 HTTP error (Unsupported Media Type, ERROR_CONTENT)
    if (!swordConfig.isSupportedMediaType(deposit.getPackaging(), this.collection)) {
      log.error(
          "Unacceptable packaging type detected: "
              + deposit.getPackaging()
              + "for collection"
              + collection.getID());
      throw new SWORDErrorException(
          ErrorCodes.ERROR_CONTENT,
          "Unacceptable packaging type in deposit request: " + deposit.getPackaging());
    }

    // Obtain the relevant ingester from the factory
    SWORDIngester si = SWORDIngesterFactory.getInstance(context, deposit, collection);
    swordService.message("Loaded ingester: " + si.getClass().getName());

    // do the deposit
    DepositResult result = si.ingest(swordService, deposit, collection);
    swordService.message("Archive ingest completed successfully");

    // if there's an item availalble, and we want to keep the original
    // then do that
    try {
      if (swordConfig.isKeepOriginal()) {
        swordService.message(
            "DSpace will store an original copy of the deposit, "
                + "as well as ingesting the item into the archive");

        // in order to be allowed to add the file back to the item, we need to ignore authorisations
        // for a moment
        boolean ignoreAuth = context.ignoreAuthorization();
        context.setIgnoreAuthorization(true);

        String bundleName = ConfigurationManager.getProperty("sword-server", "bundle.name");
        if (bundleName == null || "".equals(bundleName)) {
          bundleName = "SWORD";
        }
        Item item = result.getItem();
        Bundle[] bundles = item.getBundles(bundleName);
        Bundle swordBundle = null;
        if (bundles.length > 0) {
          swordBundle = bundles[0];
        }
        if (swordBundle == null) {
          swordBundle = item.createBundle(bundleName);
        }

        String fn = swordService.getFilename(context, deposit, true);

        Bitstream bitstream;
        FileInputStream fis = null;
        try {
          fis = new FileInputStream(deposit.getFile());
          bitstream = swordBundle.createBitstream(fis);
        } finally {
          if (fis != null) {
            fis.close();
          }
        }

        bitstream.setName(fn);
        bitstream.setDescription("SWORD deposit package");

        BitstreamFormat bf = BitstreamFormat.findByMIMEType(context, deposit.getContentType());
        if (bf != null) {
          bitstream.setFormat(bf);
        }

        bitstream.update();

        swordBundle.update();
        item.update();

        swordService.message(
            "Original package stored as " + fn + ", in item bundle " + swordBundle);

        // now reset the context ignore authorisation
        context.setIgnoreAuthorization(ignoreAuth);

        // set the media link for the created item
        result.setMediaLink(urlManager.getMediaLink(bitstream));
      } else {
        // set the vanilla media link, which doesn't resolve to anything
        result.setMediaLink(urlManager.getBaseMediaLinkUrl());
      }
    } catch (SQLException e) {
      log.error("caught exception: ", e);
      throw new DSpaceSWORDException(e);
    } catch (AuthorizeException e) {
      log.error("caught exception: ", e);
      throw new DSpaceSWORDException(e);
    } catch (FileNotFoundException e) {
      log.error("caught exception: ", e);
      throw new DSpaceSWORDException(e);
    } catch (IOException e) {
      log.error("caught exception: ", e);
      throw new DSpaceSWORDException(e);
    }

    return result;
  }
Пример #3
0
  /**
   * Process the Options to apply to the Item. The options are tab delimited
   *
   * <p>Options: 48217870-MIT.pdf permissions: -r 'MIT Users' description: Full printable version
   * (MIT only) permissions:[r|w]-['group name'] description: 'the description of the file'
   *
   * <p>where: [r|w] (meaning: read|write) ['MIT Users'] (the group name)
   *
   * @param c
   * @param myItem
   * @param options
   * @throws SQLException
   * @throws AuthorizeException
   */
  private void processOptions(Context c, Item myItem, List<String> options)
      throws SQLException, AuthorizeException {
    for (String line : options) {
      System.out.println("\tprocessing " + line);

      boolean permissionsExist = false;
      boolean descriptionExists = false;

      String permissionsMarker = "\tpermissions:";
      int pMarkerIndex = line.indexOf(permissionsMarker);
      int pEndIndex = 0;
      if (pMarkerIndex > 0) {
        pEndIndex = line.indexOf("\t", pMarkerIndex + 1);
        if (pEndIndex == -1) {
          pEndIndex = line.length();
        }
        permissionsExist = true;
      }

      String descriptionMarker = "\tdescription:";
      int dMarkerIndex = line.indexOf(descriptionMarker);
      int dEndIndex = 0;
      if (dMarkerIndex > 0) {
        dEndIndex = line.indexOf("\t", dMarkerIndex + 1);
        if (dEndIndex == -1) {
          dEndIndex = line.length();
        }
        descriptionExists = true;
      }

      int bsEndIndex = line.indexOf("\t");
      String bitstreamName = line.substring(0, bsEndIndex);

      int actionID = -1;
      String groupName = "";
      Group myGroup = null;
      if (permissionsExist) {
        String thisPermission =
            line.substring(pMarkerIndex + permissionsMarker.length(), pEndIndex);

        // get permission type ("read" or "write")
        int pTypeIndex = thisPermission.indexOf('-');

        // get permission group (should be in single quotes)
        int groupIndex = thisPermission.indexOf('\'', pTypeIndex);
        int groupEndIndex = thisPermission.indexOf('\'', groupIndex + 1);

        // if not in single quotes, assume everything after type flag is
        // group name
        if (groupIndex == -1) {
          groupIndex = thisPermission.indexOf(' ', pTypeIndex);
          groupEndIndex = thisPermission.length();
        }

        groupName = thisPermission.substring(groupIndex + 1, groupEndIndex);

        if (thisPermission.toLowerCase().charAt(pTypeIndex + 1) == 'r') {
          actionID = Constants.READ;
        } else if (thisPermission.toLowerCase().charAt(pTypeIndex + 1) == 'w') {
          actionID = Constants.WRITE;
        }

        try {
          myGroup = Group.findByName(c, groupName);
        } catch (SQLException sqle) {
          System.out.println("SQL Exception finding group name: " + groupName);
          // do nothing, will check for null group later
        }
      }

      String thisDescription = "";
      if (descriptionExists) {
        thisDescription =
            line.substring(dMarkerIndex + descriptionMarker.length(), dEndIndex).trim();
      }

      Bitstream bs = null;
      boolean notfound = true;
      if (!isTest) {
        // find bitstream
        Bitstream[] bitstreams = myItem.getNonInternalBitstreams();
        for (int j = 0; j < bitstreams.length && notfound; j++) {
          if (bitstreams[j].getName().equals(bitstreamName)) {
            bs = bitstreams[j];
            notfound = false;
          }
        }
      }

      if (notfound && !isTest) {
        // this should never happen
        System.out.println("\tdefault permissions set for " + bitstreamName);
      } else if (!isTest) {
        if (permissionsExist) {
          if (myGroup == null) {
            System.out.println("\t" + groupName + " not found, permissions set to default");
          } else if (actionID == -1) {
            System.out.println("\tinvalid permissions flag, permissions set to default");
          } else {
            System.out.println("\tSetting special permissions for " + bitstreamName);
            setPermission(c, myGroup, actionID, bs);
          }
        }

        if (descriptionExists) {
          System.out.println("\tSetting description for " + bitstreamName);
          bs.setDescription(thisDescription);
          bs.update();
        }
      }
    }
  }
Пример #4
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;
  }