Beispiel #1
0
  protected DSpaceObject resolveHandle(String handle) {
    DSpaceObject dso = null;
    try {
      dso = handleService.resolveToObject(this.context, handle);
    } catch (SQLException ex) {
      log.error(ex);
      System.err.println(
          "A problem with the database connection " + "occurred. Canceled pending actions.");
      System.err.println(ex.getMessage());
      ex.printStackTrace(System.err);
      System.exit(1);
    } catch (IllegalStateException ex) {
      log.error(ex);
      System.err.println("Cannot recognize identifier '" + handle + "', skipping.");
      return null;
    }
    if (dso == null) {
      System.err.println("Cannot resolve identifier '" + handle + "', skipping.");
      log.debug("Couldn't resolve identifier '" + handle + "', dso was null.");
      return null;
    }
    if (dso.getType() != Constants.SITE
        && dso.getType() != Constants.COMMUNITY
        && dso.getType() != Constants.COLLECTION
        && dso.getType() != Constants.ITEM) {
      System.err.println(
          contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
              + " are currently not "
              + "supported as independent entities. Bundles and Bitstreams "
              + "should be processed as part of their item.");
      return null;
    }

    return dso;
  }
  /**
   * Match the URIs this subclass understands and return the corresponding resource. Since the
   * "dso_" format can lead to several different resource types, handle it here.
   *
   * @param context the context
   * @param request the request
   * @param response the response
   * @param pathElt the path elt
   * @return the DAV resource
   * @throws DAVStatusException the DAV status exception
   * @throws SQLException the SQL exception
   * @throws AuthorizeException the authorize exception
   */
  protected static DAVResource matchResourceURI(
      Context context, HttpServletRequest request, HttpServletResponse response, String pathElt[])
      throws DAVStatusException, SQLException, AuthorizeException {
    // Match /dso_<handle>{...} .. look for last "dso_" element
    if (pathElt[0].startsWith("dso_")) {
      int i = 1;
      for (; i < pathElt.length && pathElt[i].startsWith("dso_"); ++i) {
        // empty
      }
      --i;
      String handle = decodeHandle(pathElt[i].substring(4));

      // Replace substituted handle separator char with '/' to
      // get back a normal handle: (inverse of getPathElt() above)
      int sepIndex = handle.indexOf(handleSeparator);
      if (sepIndex >= 0) {
        char hc[] = handle.toCharArray();
        hc[sepIndex] = '/';
        handle = String.copyValueOf(hc);
      }

      DSpaceObject dso = HandleManager.resolveToObject(context, handle);
      if (dso == null) {
        throw new DAVStatusException(
            HttpServletResponse.SC_NOT_FOUND, "Cannot resolve handle \"" + handle + "\"");
      } else if (dso.getType() == Constants.ITEM) {
        if (i + 1 < pathElt.length) {
          if (pathElt[i + 1].startsWith("bitstream_")) {
            Bitstream bs = DAVBitstream.findBitstream(context, (Item) dso, pathElt[i + 1]);
            if (bs == null) {
              throw new DAVStatusException(
                  HttpServletResponse.SC_NOT_FOUND,
                  "Bitstream \"" + pathElt[i + 1] + "\" not found in item: " + pathElt[i]);
            }
            return new DAVBitstream(context, request, response, pathElt, (Item) dso, bs);
          } else {
            throw new DAVStatusException(
                HttpServletResponse.SC_NOT_FOUND,
                "Illegal resource path, \""
                    + pathElt[i + 1]
                    + "\" is not a Bitstream identifier for item: "
                    + pathElt[i]);
          }
        } else {
          return new DAVItem(context, request, response, pathElt, (Item) dso);
        }
      } else if (dso.getType() == Constants.COLLECTION) {
        return new DAVCollection(context, request, response, pathElt, (Collection) dso);
      } else if (dso.getType() == Constants.COMMUNITY) {
        return new DAVCommunity(context, request, response, pathElt, (Community) dso);
      } else {
        throw new DAVStatusException(
            HttpServletResponse.SC_BAD_REQUEST,
            "Unrecognized DSpace object type for handle=" + handle);
      }
    }
    return null;
  }
Beispiel #3
0
  /**
   * Delete the data about the DSpaceObject from the triplestore. All data about descendent
   * Subcommunities, Collections and Items will be deleted as well.
   */
  public void delete(DSpaceObject dso, boolean reset) throws SQLException {
    if (dso.getType() != Constants.SITE
        && dso.getType() != Constants.COMMUNITY
        && dso.getType() != Constants.COLLECTION
        && dso.getType() != Constants.ITEM) {
      throw new IllegalArgumentException(
          contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
              + " is currently not supported as independent entity.");
    }

    if (dso.getType() == Constants.SITE) {
      // we don't need to iterate over all objects, use a shorctut:
      this.deleteAll();
    }
    Callback callback =
        new Callback() {
          @Override
          protected void callback(DSpaceObject dso) throws SQLException {
            String identifier = RDFUtil.generateIdentifier(context, dso);

            if (StringUtils.isEmpty(identifier)) {
              System.err.println(
                  "Cannot determine RDF URI for "
                      + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                      + " "
                      + dso.getID()
                      + "(handle "
                      + dso.getHandle()
                      + ")"
                      + ", skipping. Please "
                      + "delete it specifing the RDF URI.");
              log.error(
                  "Cannot detgermine RDF URI for "
                      + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                      + " "
                      + dso.getID()
                      + "(handle "
                      + dso.getHandle()
                      + ")"
                      + ", skipping deletion.");
              return;
            }

            report("Deleting Named Graph" + identifier);
            if (!dryrun) {
              storage.delete(identifier);
            }
          }
        };
    this.dspaceDFS(dso, callback, false, reset);
  }
Beispiel #4
0
  /**
   * Return a List of the policies for an object
   *
   * @param c current context
   * @param o object to retrieve policies for
   * @return List of <code>ResourcePolicy</code> objects
   */
  public static List<ResourcePolicy> getPolicies(Context c, DSpaceObject o) throws SQLException {
    TableRowIterator tri =
        DatabaseManager.queryTable(
            c,
            "resourcepolicy",
            "SELECT * FROM resourcepolicy WHERE resource_type_id= ? AND resource_id= ? ",
            o.getType(),
            o.getID());

    List<ResourcePolicy> policies = new ArrayList<ResourcePolicy>();

    try {
      while (tri.hasNext()) {
        TableRow row = tri.next();

        // first check the cache (FIXME: is this right?)
        ResourcePolicy cachepolicy =
            (ResourcePolicy) c.fromCache(ResourcePolicy.class, row.getIntColumn("policy_id"));

        if (cachepolicy != null) {
          policies.add(cachepolicy);
        } else {
          policies.add(new ResourcePolicy(c, row));
        }
      }
    } finally {
      if (tri != null) {
        tri.close();
      }
    }

    return policies;
  }
 /**
  * Create URI as string for a given handle and optional bitstream. URI is relative to top of DAV
  * hierarchy, but starts with '/'.
  *
  * @param dso a DSpace object (Item, Collection, etc)
  * @param bsPid bitstream persistent identifier.
  * @return "absolute" URI from top of DAV hierarchy
  * @throws IOException Signals that an I/O exception has occurred.
  * @throws SQLException the SQL exception
  */
 private String makeURI(DSpaceObject dso, String bsPid) throws IOException, SQLException {
   // make sure that bitstream actually exists:
   if (bsPid != null) {
     if (dso.getType() != Constants.ITEM) {
       log.warn("Non-Item with Bitstream Sequence ID in DAV Lookup.");
       return null;
     }
     try {
       int pid = Integer.parseInt(bsPid);
       if (DAVBitstream.getBitstreamBySequenceID((Item) dso, pid) == null) {
         log.warn("Bitstream Sequence ID Not Found in DAV Lookup: \"" + bsPid + "\"");
         return null;
       }
     } catch (NumberFormatException nfe) {
       log.warn("Invalid Bitstream Sequence ID in DAV Lookup: \"" + bsPid + "\"");
       return null;
     }
   }
   String base = "/" + DAVDSpaceObject.getPathElt(dso);
   if (bsPid != null) {
     return base + "/bitstream_" + bsPid;
   } else {
     return base;
   }
 }
  private List disseminateListInternal(DSpaceObject dso, boolean addSchema)
      throws CrosswalkException, IOException, SQLException, AuthorizeException {
    if (dso.getType() != Constants.ITEM)
      throw new CrosswalkObjectNotSupported(
          "MODSDisseminationCrosswalk can only crosswalk an Item.");
    Item item = (Item) dso;
    initMap();

    MetadataValue[] dc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
    List result = new ArrayList(dc.length);
    for (int i = 0; i < dc.length; i++) {
      // Compose qualified DC name - schema.element[.qualifier]
      // e.g. "dc.title", "dc.subject.lcc", "lom.Classification.Keyword"
      String qdc =
          dc[i].getMetadataField().getSchema()
              + "."
              + ((dc[i].getMetadataField().getQualifier() == null)
                  ? dc[i].getMetadataField().getElement()
                  : (dc[i].getMetadataField().getElement()
                      + "."
                      + dc[i].getMetadataField().getQualifier()));

      modsTriple trip = (modsTriple) modsMap.get(qdc);
      if (trip == null)
        log.warn("WARNING: " + getPluginInstanceName() + ": No MODS mapping for \"" + qdc + "\"");
      else {
        try {
          Element me = (Element) trip.xml.clone();
          if (addSchema) me.setAttribute("schemaLocation", schemaLocation, XSI_NS);
          Iterator ni = trip.xpath.selectNodes(me).iterator();
          if (!ni.hasNext())
            log.warn(
                "XPath \""
                    + trip.xpath.getXPath()
                    + "\" found no elements in \""
                    + outputUgly.outputString(me)
                    + "\", qdc="
                    + qdc);
          while (ni.hasNext()) {
            Object what = ni.next();
            if (what instanceof Element) ((Element) what).setText(dc[i].getValue());
            else if (what instanceof Attribute) ((Attribute) what).setValue(dc[i].getValue());
            else if (what instanceof Text) ((Text) what).setText(dc[i].getValue());
            else log.warn("Got unknown object from XPath, class=" + what.getClass().getName());
          }
          result.add(me);
        } catch (JDOMException je) {
          log.error(
              "Error following XPath in modsTriple: context="
                  + outputUgly.outputString(trip.xml)
                  + ", xpath="
                  + trip.xpath.getXPath()
                  + ", exception="
                  + je.toString());
        }
      }
    }
    return result;
  }
Beispiel #7
0
 /**
  * removes ALL policies for an object. FIXME doesn't check authorization
  *
  * @param c DSpace context
  * @param o object to remove policies for
  * @throws SQLException if there's a database problem
  */
 public static void removeAllPolicies(Context c, DSpaceObject o) throws SQLException {
   // FIXME: authorization check?
   DatabaseManager.updateQuery(
       c,
       "DELETE FROM resourcepolicy WHERE " + "resource_type_id= ? AND resource_id= ? ",
       o.getType(),
       o.getID());
 }
  private static String formatAction(Action action, DSpaceObject object) {
    try {
      String objText = Constants.typeText[object.getType()].toLowerCase();
      return action.text() + "_" + objText;
    } catch (Exception e) {

    }
    return "";
  }
Beispiel #9
0
 /**
  * Removes all policies from a group for a particular object that belong to a Group. FIXME doesn't
  * check authorization
  *
  * @param c current context
  * @param o the object
  * @param g the group
  * @throws SQLException if there's a database problem
  */
 public static void removeGroupPolicies(Context c, DSpaceObject o, Group g) throws SQLException {
   DatabaseManager.updateQuery(
       c,
       "DELETE FROM resourcepolicy WHERE "
           + "resource_type_id= ? AND resource_id= ? AND epersongroup_id= ? ",
       o.getType(),
       o.getID(),
       g.getID());
 }
Beispiel #10
0
  /**
   * Returns all groups authorized to perform an action on an object. Returns empty array if no
   * matches.
   *
   * @param c current context
   * @param o object
   * @param actionID ID of action frm <code>org.dspace.core.Constants</code>
   * @return array of <code>Group</code>s that can perform the specified action on the specified
   *     object
   * @throws java.sql.SQLException if there's a database problem
   */
  public static Group[] getAuthorizedGroups(Context c, DSpaceObject o, int actionID)
      throws java.sql.SQLException {
    // do query matching groups, actions, and objects
    TableRowIterator tri =
        DatabaseManager.queryTable(
            c,
            "resourcepolicy",
            "SELECT * FROM resourcepolicy WHERE resource_type_id= ? "
                + "AND resource_id= ? AND action_id= ? ",
            o.getType(),
            o.getID(),
            actionID);

    List<Group> groups = new ArrayList<Group>();
    try {

      while (tri.hasNext()) {
        TableRow row = tri.next();

        // first check the cache (FIXME: is this right?)
        ResourcePolicy cachepolicy =
            (ResourcePolicy) c.fromCache(ResourcePolicy.class, row.getIntColumn("policy_id"));

        ResourcePolicy myPolicy = null;

        if (cachepolicy != null) {
          myPolicy = cachepolicy;
        } else {
          myPolicy = new ResourcePolicy(c, row);
        }

        // now do we have a group?
        Group myGroup = myPolicy.getGroup();

        if (myGroup != null) {
          groups.add(myGroup);
        }
      }
    } finally {
      if (tri != null) {
        tri.close();
      }
    }

    Group[] groupArray = new Group[groups.size()];
    groupArray = groups.toArray(groupArray);

    return groupArray;
  }
Beispiel #11
0
 /**
  * Remove all policies from an object that match a given action. FIXME doesn't check authorization
  *
  * @param context current context
  * @param dso object to remove policies from
  * @param actionID ID of action to match from <code>org.dspace.core.Constants</code>, or -1=all
  * @throws SQLException if there's a database problem
  */
 public static void removePoliciesActionFilter(Context context, DSpaceObject dso, int actionID)
     throws SQLException {
   if (actionID == -1) {
     // remove all policies from object
     removeAllPolicies(context, dso);
   } else {
     DatabaseManager.updateQuery(
         context,
         "DELETE FROM resourcepolicy WHERE resource_type_id= ? AND "
             + "resource_id= ? AND action_id= ? ",
         dso.getType(),
         dso.getID(),
         actionID);
   }
 }
  private static String formatMessage(DSpaceObject object) {
    try {
      String objText = Constants.typeText[object.getType()].toLowerCase();
      String handle = object.getHandle();

      /* Emulate Item logger */
      if (handle != null && object instanceof Item) {
        return "handle=" + object.getHandle();
      } else {
        return objText + "_id=" + object.getID();
      }

    } catch (Exception e) {

    }
    return "";
  }
  public Element disseminateElement(DSpaceObject dso)
      throws CrosswalkException, IOException, SQLException, AuthorizeException {
    if (dso.getType() != Constants.ITEM) {
      throw new CrosswalkObjectNotSupported(
          "METSDisseminationCrosswalk can only crosswalk an Item.");
    }
    Item item = (Item) dso;

    PackageDisseminator dip =
        (PackageDisseminator)
            PluginManager.getNamedPlugin(PackageDisseminator.class, METS_PACKAGER_PLUGIN);
    if (dip == null) {
      throw new CrosswalkInternalException(
          "Cannot find a disseminate plugin for package=" + METS_PACKAGER_PLUGIN);
    }

    try {
      // Set the manifestOnly=true param so we just get METS document
      PackageParameters pparams = new PackageParameters();
      pparams.put("manifestOnly", "true");

      // Create a temporary file to disseminate into
      String tempDirectory = ConfigurationManager.getProperty("upload.temp.dir");
      File tempFile =
          File.createTempFile("METSDissemination" + item.hashCode(), null, new File(tempDirectory));
      tempFile.deleteOnExit();

      // Disseminate METS to temp file
      Context context = new Context();
      dip.disseminate(context, item, pparams, tempFile);

      try {
        SAXBuilder builder = new SAXBuilder();
        Document metsDocument = builder.build(tempFile);
        return metsDocument.getRootElement();
      } catch (JDOMException je) {
        throw new MetadataValidationException(
            "Error parsing METS (see wrapped error message for more details) ", je);
      }
    } catch (PackageException pe) {
      throw new CrosswalkInternalException(
          "Failed making METS manifest in packager (see wrapped error message for more details) ",
          pe);
    }
  }
Beispiel #14
0
  /**
   * Process sets of objects to add, update, and delete in index. Correct for interactions between
   * the sets -- e.g. objects which were deleted do not need to be added or updated, new objects
   * don't also need an update, etc.
   */
  public void end(Context ctx) throws Exception {

    if (objectsToUpdate != null && handlesToDelete != null) {

      // update the changed Items not deleted because they were on create list
      for (DSpaceObject iu : objectsToUpdate) {
        /* we let all types through here and
         * allow the search DSIndexer to make
         * decisions on indexing and/or removal
         */
        String hdl = iu.getHandle();
        if (hdl != null && !handlesToDelete.contains(hdl)) {
          try {
            DSIndexer.indexContent(ctx, iu, true);
            log.debug(
                "Indexed "
                    + Constants.typeText[iu.getType()]
                    + ", id="
                    + String.valueOf(iu.getID())
                    + ", handle="
                    + hdl);
          } catch (Exception e) {
            log.error("Failed while indexing object: ", e);
          }
        }
      }

      for (String hdl : handlesToDelete) {
        try {
          DSIndexer.unIndexContent(ctx, hdl);
          if (log.isDebugEnabled()) {
            log.debug("UN-Indexed Item, handle=" + hdl);
          }
        } catch (Exception e) {
          log.error("Failed while UN-indexing object: " + hdl, e);
        }
      }
    }

    // "free" the resources
    objectsToUpdate = null;
    handlesToDelete = null;
  }
  /**
   * Ingest a whole document. Build Document object around root element, and feed that to the
   * transformation, since it may get handled differently than a List of metadata elements.
   */
  public void ingest(Context context, DSpaceObject dso, Element root)
      throws CrosswalkException, IOException, SQLException, AuthorizeException {
    if (dso.getType() != Constants.ITEM)
      throw new CrosswalkObjectNotSupported(
          "XsltSubmissionionCrosswalk can only crosswalk to an Item.");
    Item item = (Item) dso;

    XSLTransformer xform = getTransformer(DIRECTION);
    if (xform == null)
      throw new CrosswalkInternalException(
          "Failed to initialize transformer, probably error loading stylesheet.");
    try {
      Document dimDoc = xform.transform(new Document((Element) root.clone()));
      applyDim(dimDoc.getRootElement().getChildren(), item);
    } catch (XSLTransformException e) {
      log.error("Got error: " + e.toString());
      throw new CrosswalkInternalException("XSL Transformation failed: " + e.toString());
    }
  }
  public List disseminateList(DSpaceObject dso)
      throws CrosswalkException, IOException, SQLException, AuthorizeException {
    init();

    if (dso.getType() != Constants.ITEM)
      throw new CrosswalkObjectNotSupported(
          "XSLTDisseminationCrosswalk can only crosswalk an Item.");
    Item item = (Item) dso;
    XSLTransformer xform = getTransformer(DIRECTION);
    if (xform == null)
      throw new CrosswalkInternalException(
          "Failed to initialize transformer, probably error loading stylesheet.");

    try {
      return xform.transform(getDim(item).getChildren());
    } catch (XSLTransformException e) {
      log.error("Got error: " + e.toString());
      throw new CrosswalkInternalException("XSL translation failed: " + e.toString());
    }
  }
Beispiel #17
0
  /**
   * VERY crude dissemination: just look for the first bitstream with the PDF package type, and toss
   * it out. Works on packages importer with this packager, and maybe some others.
   */
  public void disseminate(
      Context context, DSpaceObject dso, PackageParameters params, OutputStream out)
      throws PackageValidationException, CrosswalkException, AuthorizeException, SQLException,
          IOException {
    if (dso.getType() != Constants.ITEM)
      throw new PackageValidationException(
          "This disseminator can only handle objects of type ITEM.");

    Item item = (Item) dso;
    try {
      BitstreamFormat pdff = BitstreamFormat.findByShortDescription(context, BITSTREAM_FORMAT_NAME);
      if (pdff == null)
        throw new PackageValidationException(
            "Cannot find BitstreamFormat \"" + BITSTREAM_FORMAT_NAME + "\"");
      Bitstream pkgBs =
          PackageUtils.getBitstreamByFormat(item, pdff, Constants.DEFAULT_BUNDLE_NAME);
      if (pkgBs == null)
        throw new PackageValidationException(
            "Cannot find Bitstream with format \"" + BITSTREAM_FORMAT_NAME + "\"");
      Utils.copy(pkgBs.retrieve(), out);
    } finally {
    }
  }
 /**
  * Perform the curation task upon passed DSO
  *
  * @param dso the DSpace object
  * @throws IOException
  */
 @Override
 public int perform(DSpaceObject dso) throws IOException {
   if (dso.getType() == Constants.ITEM) {
     Item item = (Item) dso;
     int count = 0;
     try {
       StringBuilder sb = new StringBuilder();
       String handle = item.getHandle();
       if (handle == null) {
         // we are still in workflow - no handle assigned
         handle = "in workflow";
       }
       sb.append("Item: ").append(handle);
       for (String req : getReqList(item.getOwningCollection().getHandle())) {
         DCValue[] vals = item.getMetadata(req);
         if (vals.length == 0) {
           sb.append(" missing required field: ").append(req);
           count++;
         }
       }
       if (count == 0) {
         sb.append(" has all required fields");
       }
       report(sb.toString());
       setResult(sb.toString());
     } catch (DCInputsReaderException dcrE) {
       throw new IOException(dcrE.getMessage(), dcrE);
     } catch (SQLException sqlE) {
       throw new IOException(sqlE.getMessage(), sqlE);
     }
     return (count == 0) ? Curator.CURATE_SUCCESS : Curator.CURATE_FAIL;
   } else {
     setResult("Object skipped");
     return Curator.CURATE_SKIP;
   }
 }
 public boolean canDisseminate(DSpaceObject dso) {
   return dso.getType() == Constants.ITEM;
 }
  /**
   * Export the object (Item, Collection, or Community) to a package file on the indicated
   * OutputStream. Gets an exception of the object cannot be packaged or there is a failure creating
   * the package.
   *
   * @param context - DSpace context.
   * @param dso - DSpace object (item, collection, etc)
   * @param pkg - output stream on which to write package
   * @throws PackageException if package cannot be created or there is a fatal error in creating it.
   */
  public void disseminate(
      Context context, DSpaceObject dso, PackageParameters params, OutputStream pkg)
      throws PackageValidationException, CrosswalkException, AuthorizeException, SQLException,
          IOException {
    if (dso.getType() == Constants.ITEM) {
      Item item = (Item) dso;
      long lmTime = item.getLastModified().getTime();

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

      if (params != null && params.getProperty("manifestOnly") != null) {
        extraFiles = null;
        writeManifest(context, item, params, pkg);
      } else {
        extraFiles = new HashMap();
        ZipOutputStream zip = new ZipOutputStream(pkg);
        zip.setComment("METS archive created by DSpace METSDisseminationCrosswalk");

        // write manifest first.
        ZipEntry me = new ZipEntry(MANIFEST_FILE);
        me.setTime(lmTime);
        zip.putNextEntry(me);
        writeManifest(context, item, params, zip);
        zip.closeEntry();

        // copy extra (meta?) bitstreams into zip
        Iterator fi = extraFiles.keySet().iterator();
        while (fi.hasNext()) {
          String fname = (String) fi.next();
          ZipEntry ze = new ZipEntry(fname);
          ze.setTime(lmTime);
          zip.putNextEntry(ze);
          Utils.copy((InputStream) extraFiles.get(fname), zip);
          zip.closeEntry();
        }

        // copy all non-meta bitstreams into zip
        Bundle bundles[] = item.getBundles();
        for (int i = 0; i < bundles.length; i++) {
          if (!PackageUtils.isMetaInfoBundle(bundles[i])) {
            // unauthorized bundle?
            if (!AuthorizeManager.authorizeActionBoolean(context, bundles[i], Constants.READ)) {
              if (unauth != null && (unauth.equalsIgnoreCase("skip"))) {
                log.warn(
                    "Skipping Bundle[\""
                        + bundles[i].getName()
                        + "\"] because you are not authorized to read it.");
                continue;
              } else
                throw new AuthorizeException(
                    "Not authorized to read Bundle named \"" + bundles[i].getName() + "\"");
            }
            Bitstream[] bitstreams = bundles[i].getBitstreams();
            for (int k = 0; k < bitstreams.length; k++) {
              boolean auth =
                  AuthorizeManager.authorizeActionBoolean(context, bitstreams[k], Constants.READ);
              if (auth || (unauth != null && unauth.equalsIgnoreCase("zero"))) {
                ZipEntry ze = new ZipEntry(makeBitstreamName(bitstreams[k]));
                ze.setTime(lmTime);
                ze.setSize(auth ? bitstreams[k].getSize() : 0);
                zip.putNextEntry(ze);
                if (auth) Utils.copy(bitstreams[k].retrieve(), zip);
                else
                  log.warn(
                      "Adding zero-length file for Bitstream, SID="
                          + String.valueOf(bitstreams[k].getSequenceID())
                          + ", not authorized for READ.");
                zip.closeEntry();
              } else if (unauth != null && unauth.equalsIgnoreCase("skip")) {
                log.warn(
                    "Skipping Bitstream, SID="
                        + String.valueOf(bitstreams[k].getSequenceID())
                        + ", not authorized for READ.");
              } else {
                throw new AuthorizeException(
                    "Not authorized to read Bitstream, SID="
                        + String.valueOf(bitstreams[k].getSequenceID()));
              }
            }
          }
        }
        zip.close();
        extraFiles = null;
      }

    } else throw new PackageValidationException("Can only disseminate an Item now.");
  }
  @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();
  }
  @Override
  public List<Item> getItems(
      DSpaceObject scope,
      String startDate,
      String endDate,
      int offset,
      int limit,
      boolean items,
      boolean collections,
      boolean withdrawn)
      throws ParseException {
    try {
      // Put together our query. Note there is no need for an
      // "in_archive=true" condition, we are using the existence of a
      // persistent identifier as our 'existence criterion'.
      String query =
          "SELECT p.value, p.type_id, p.resource_id as item_id, "
              + "i.withdrawn, i.last_modified "
              + "FROM externalidentifier p, item i";

      // We are building a complex query that may contain a variable
      // about of input data points. To accomidate this while still
      // providing type safty we build a list of parameters to be
      // plugged into the query at the database level.
      List parameters = new ArrayList();

      if (scope != null) {
        if (scope.getType() == Constants.COLLECTION) {
          query += ", collection2item cl2i";
        } else if (scope.getType() == Constants.COMMUNITY) {
          query += ", communities2item cm2i";
        }
      }

      query += " WHERE p.resource_type_id=" + Constants.ITEM + " AND p.resource_id = i.item_id ";

      if (scope != null) {
        if (scope.getType() == Constants.COLLECTION) {
          query += " AND cl2i.collection_id= ? " + " AND cl2i.item_id = p.resource_id ";
          parameters.add(scope.getID());
        } else if (scope.getType() == Constants.COMMUNITY) {
          query += " AND cm2i.community_id= ? " + " AND cm2i.item_id = p.resource_id";
          parameters.add(scope.getID());
        }
      }

      if (startDate != null) {
        query = query + " AND i.last_modified >= ? ";
        parameters.add(toTimestamp(startDate, false));
      }

      if (endDate != null) {
        /*
         * If the end date has seconds precision, e.g.:
         *
         * 2004-04-29T13:45:43Z
         *
         * we need to add 999 milliseconds to this. This is because SQL
         * TIMESTAMPs have millisecond precision, and so might have a value:
         *
         * 2004-04-29T13:45:43.952Z
         *
         * and so <= '2004-04-29T13:45:43Z' would not pick this up. Reading
         * things out of the database, TIMESTAMPs are rounded down, so the
         * above value would be read as '2004-04-29T13:45:43Z', and
         * therefore a caller would expect <= '2004-04-29T13:45:43Z' to
         * include that value.
         *
         * Got that? ;-)
         */
        boolean selfGenerated = false;
        if (endDate.length() == 20) {
          endDate = endDate.substring(0, 19) + ".999Z";
          selfGenerated = true;
        }

        query += " AND i.last_modified <= ? ";
        parameters.add(toTimestamp(endDate, selfGenerated));
      }

      if (!withdrawn) {
        // Exclude withdrawn items
        if ("oracle".equals(ConfigurationManager.getProperty("db.name"))) {
          query += " AND withdrawn=0 ";
        } else {
          // postgres uses booleans
          query += " AND withdrawn=false ";
        }
      }

      // Order by item ID, so that for a given harvest the order will be
      // consistent. This is so that big harvests can be broken up into
      // several smaller operations (e.g. for OAI resumption tokens.)
      query += " ORDER BY p.resource_id";

      // Execute
      Object[] parametersArray = parameters.toArray();
      TableRowIterator tri = DatabaseManager.query(context, query, parametersArray);

      return returnAsList(tri);
    } catch (SQLException sqle) {
      throw new RuntimeException(sqle);
    }
  }
Beispiel #23
0
  protected void convert(DSpaceObject dso, boolean reset) throws SQLException {
    if (dso.getType() != Constants.SITE
        && dso.getType() != Constants.COMMUNITY
        && dso.getType() != Constants.COLLECTION
        && dso.getType() != Constants.ITEM) {
      throw new IllegalArgumentException(
          contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
              + " is currently not supported as independent entity.");
    }

    Callback callback =
        new Callback() {
          @Override
          protected void callback(DSpaceObject dso) throws SQLException {
            Model converted = null;
            try {
              if (dryrun) {
                converted = RDFUtil.convert(context, dso);
              } else {
                converted = RDFUtil.convertAndStore(context, dso);
              }
            } catch (ItemNotArchivedException ex) {
              if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
              report(
                  "Skipping conversion of Item "
                      + dso.getID()
                      + " (handle "
                      + dso.getHandle()
                      + "): Item is not "
                      + "archived.");
              return;
            } catch (ItemWithdrawnException ex) {
              if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
              report(
                  "Skipping conversion of Item "
                      + dso.getID()
                      + " (handle "
                      + dso.getHandle()
                      + "): Item is "
                      + "withdrawn.");
              return;
            } catch (ItemNotDiscoverableException ex) {
              if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
              report(
                  "Skipping conversion of Item "
                      + dso.getID()
                      + " (handle "
                      + dso.getHandle()
                      + "): Item is not "
                      + "discoverable.");
              return;
            } catch (AuthorizeException ex) {
              report(
                  "Skipping conversion of "
                      + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                      + " "
                      + dso.getID()
                      + " (handle "
                      + dso.getHandle()
                      + ")"
                      + ", not authorized: "
                      + ex.getMessage());
              return;
            } catch (RDFMissingIdentifierException ex) {
              String errormessage =
                  "Skipping conversion of "
                      + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                      + " "
                      + dso.getID()
                      + " (handle "
                      + dso.getHandle()
                      + ").";
              log.error(errormessage, ex);
              System.err.println(errormessage + " Error while converting: " + ex.getMessage());

              return;
            }

            if (stdout) {
              if (converted == null) {
                System.err.println(
                    "Conversion of "
                        + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                        + " "
                        + dso.getID()
                        + " resulted in no data.");
              } else {
                converted.write(System.out, lang);
              }
            }
            if (converted != null) converted.close();
          }
        };

    this.dspaceDFS(dso, callback, true, reset);
  }
Beispiel #24
0
  public static void main(String[] argv) throws Exception {
    Options options = new Options();
    options.addOption("c", "collection", true, "destination collection(s) Handle (repeatable)");
    options.addOption("e", "eperson", true, "email address of eperson doing importing");
    options.addOption(
        "w",
        "install",
        false,
        "disable workflow; install immediately without going through collection's workflow");
    options.addOption("t", "type", true, "package type or MIMEtype");
    options.addOption(
        "o", "option", true, "Packager option to pass to plugin, \"name=value\" (repeatable)");
    options.addOption(
        "d", "disseminate", false, "Disseminate package (output); default is to submit.");
    options.addOption("i", "item", true, "Handle of item to disseminate.");
    options.addOption("h", "help", false, "help");

    CommandLineParser parser = new PosixParser();
    CommandLine line = parser.parse(options, argv);

    String sourceFile = null;
    String eperson = null;
    String[] collections = null;
    boolean useWorkflow = true;
    String packageType = null;
    boolean submit = true;
    String itemHandle = null;
    PackageParameters pkgParams = new PackageParameters();

    if (line.hasOption('h')) {
      HelpFormatter myhelp = new HelpFormatter();
      myhelp.printHelp("Packager  [options]  package-file|-\n", options);
      System.out.println("\nAvailable Submission Package (SIP) types:");
      String pn[] = PluginManager.getAllPluginNames(PackageIngester.class);
      for (int i = 0; i < pn.length; ++i) System.out.println("  " + pn[i]);
      System.out.println("\nAvailable Dissemination Package (DIP) types:");
      pn = PluginManager.getAllPluginNames(PackageDisseminator.class);
      for (int i = 0; i < pn.length; ++i) System.out.println("  " + pn[i]);
      System.exit(0);
    }
    if (line.hasOption('w')) useWorkflow = false;
    if (line.hasOption('e')) eperson = line.getOptionValue('e');
    if (line.hasOption('c')) collections = line.getOptionValues('c');
    if (line.hasOption('t')) packageType = line.getOptionValue('t');
    if (line.hasOption('i')) itemHandle = line.getOptionValue('i');
    String files[] = line.getArgs();
    if (files.length > 0) sourceFile = files[0];
    if (line.hasOption('d')) submit = false;
    if (line.hasOption('o')) {
      String popt[] = line.getOptionValues('o');
      for (int i = 0; i < popt.length; ++i) {
        String pair[] = popt[i].split("\\=", 2);
        if (pair.length == 2) pkgParams.addProperty(pair[0].trim(), pair[1].trim());
        else if (pair.length == 1) pkgParams.addProperty(pair[0].trim(), "");
        else System.err.println("Warning: Illegal package option format: \"" + popt[i] + "\"");
      }
    }

    // Sanity checks on arg list: required args
    if (sourceFile == null
        || eperson == null
        || packageType == null
        || (submit && collections == null)) {
      System.err.println("Error - missing a REQUIRED argument or option.\n");
      HelpFormatter myhelp = new HelpFormatter();
      myhelp.printHelp("PackageManager  [options]  package-file|-\n", options);
      System.exit(0);
    }

    // find the EPerson, assign to context
    Context context = new Context();
    EPerson myEPerson = null;
    myEPerson = EPerson.findByEmail(context, eperson);
    if (myEPerson == null) usageError("Error, eperson cannot be found: " + eperson);
    context.setCurrentUser(myEPerson);

    if (submit) {
      // make sure we have an input file

      // GWaller 11/1/10 Disable piping of input in - we need to archive the package so it is
      // simpler to assume a file stream
      //                 rather than save the System.in bytes and re-read.

      if (sourceFile.equals("-")) {
        usageError(
            "Error, input piping not allowed. Specify a file name of a physical file to read");
      }

      InputStream source = new FileInputStream(sourceFile);

      PackageIngester sip =
          (PackageIngester) PluginManager.getNamedPlugin(PackageIngester.class, packageType);
      if (sip == null) usageError("Error, Unknown package type: " + packageType);

      // find collections
      Collection[] mycollections = null;

      System.out.println("Destination collections:");

      // validate each collection arg to see if it's a real collection
      mycollections = new Collection[collections.length];
      for (int i = 0; i < collections.length; i++) {
        // sanity check: did handle resolve, and to a collection?
        DSpaceObject dso = HandleManager.resolveToObject(context, collections[i]);
        if (dso == null)
          throw new IllegalArgumentException(
              "Bad collection list -- "
                  + "Cannot resolve collection handle \""
                  + collections[i]
                  + "\"");
        else if (dso.getType() != Constants.COLLECTION)
          throw new IllegalArgumentException(
              "Bad collection list -- "
                  + "Object at handle \""
                  + collections[i]
                  + "\" is not a collection!");
        mycollections[i] = (Collection) dso;
        System.out.println(
            (i == 0 ? "  Owning " : "  ") + " Collection: " + mycollections[i].getMetadata("name"));
      }

      try {
        // GWaller 26/08/09 Support array of collections
        WorkspaceItem wi = sip.ingest(context, mycollections, source, pkgParams, null);

        // GWaller 11/1/10 IssueID #157 Archive the package
        InputStream sourceCopy = new FileInputStream(sourceFile);
        Bundle archivedBundle =
            BundleUtils.getBundleByName(wi.getItem(), Constants.ARCHIVED_CONTENT_PACKAGE_BUNDLE);
        Bitstream bs = archivedBundle.createBitstream(sourceCopy);
        bs.setName(new File(sourceFile).getName());
        bs.update();
        archivedBundle.update();

        if (useWorkflow) {
          String handle = null;

          // Check if workflow completes immediately, and
          // return Handle if so.
          WorkflowItem wfi = WorkflowManager.startWithoutNotify(context, wi);

          if (wfi.getState() == WorkflowManager.WFSTATE_ARCHIVE) {
            Item ni = wfi.getItem();
            handle = HandleManager.findHandle(context, ni);
          }
          if (handle == null)
            System.out.println("Created Workflow item, ID=" + String.valueOf(wfi.getID()));
          else System.out.println("Created and installed item, handle=" + handle);
        } else {
          InstallItem.installItem(context, wi);
          System.out.println(
              "Created and installed item, handle="
                  + HandleManager.findHandle(context, wi.getItem()));
        }
        context.complete();
        System.exit(0);
      } catch (Exception e) {
        // abort all operations
        context.abort();
        e.printStackTrace();
        System.out.println(e);
        System.exit(1);
      }
    } else {
      OutputStream dest =
          (sourceFile.equals("-"))
              ? (OutputStream) System.out
              : (OutputStream) (new FileOutputStream(sourceFile));

      PackageDisseminator dip =
          (PackageDisseminator)
              PluginManager.getNamedPlugin(PackageDisseminator.class, packageType);
      if (dip == null) usageError("Error, Unknown package type: " + packageType);

      DSpaceObject dso = HandleManager.resolveToObject(context, itemHandle);
      if (dso == null)
        throw new IllegalArgumentException(
            "Bad Item handle -- " + "Cannot resolve handle \"" + itemHandle);
      dip.disseminate(context, dso, pkgParams, dest);
    }
  }
Beispiel #25
0
  protected void dspaceDFS(DSpaceObject dso, Callback callback, boolean check, boolean reset)
      throws SQLException {
    if (dso.getType() != Constants.SITE
        && dso.getType() != Constants.COMMUNITY
        && dso.getType() != Constants.COLLECTION
        && dso.getType() != Constants.ITEM) {
      throw new IllegalArgumentException(
          contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
              + " is currently not supported as independent entity.");
    }

    if (reset) {
      this.processed.clear();
    }

    if (isProcessed(dso)) {
      log.debug(
          "Skipping processing of "
              + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
              + " "
              + dso.getID()
              + " (handle "
              + dso.getHandle()
              + "), already processed.");
      return;
    }
    markProcessed(dso);
    // this is useful to debug depth first search, but it is really noisy.
    // log.debug("Procesing " + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso) +
    // " " + dso.getID() + ":" + dso.getHandle() + ".");

    // if this method is used for conversion we should check if we have the
    // permissions to read a DSO before converting all of it decendents
    // (e.g. check read permission on a community before converting all of
    // its subcommunties and collections).
    // just skip items with missing permissions and report them.
    if (check) {
      try {
        RDFUtil.isPublic(context, dso);
      } catch (ItemNotArchivedException ex) {
        if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
        report(
            "Skipping processing of Item "
                + dso.getID()
                + " (handle "
                + dso.getHandle()
                + "): Item is not "
                + "archived.");
        return;
      } catch (ItemWithdrawnException ex) {
        if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
        report(
            "Skipping processing of Item "
                + dso.getID()
                + " (handle "
                + dso.getHandle()
                + "): Item is "
                + "withdrawn.");
        return;
      } catch (ItemNotDiscoverableException ex) {
        if (!(dso instanceof Item)) throw new IllegalStateException(ex.getMessage(), ex);
        report(
            "Skipping processing of Item "
                + dso.getID()
                + " (handle "
                + dso.getHandle()
                + "): Item is not "
                + "discoverable.");
        return;
      } catch (AuthorizeException ex) {
        report(
            "Skipping processing of "
                + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
                + " "
                + dso.getID()
                + " (handle "
                + dso.getHandle()
                + ")"
                + ", not authorized: "
                + ex.getMessage());
        return;
      }
    }

    if (dso instanceof Site) {
      List<Community> communities = communityService.findAllTop(context);
      for (Community community : communities) {
        this.dspaceDFS(community, callback, check, false);
      }
    }

    if (dso instanceof Community) {
      List<Community> subcommunities = ((Community) dso).getSubcommunities();
      for (Community sub : subcommunities) {
        this.dspaceDFS(sub, callback, check, false);
      }
      List<Collection> collections = ((Community) dso).getCollections();
      for (Collection collection : collections) {
        this.dspaceDFS(collection, callback, check, false);
      }
    }

    if (dso instanceof Collection) {
      Iterator<Item> items = itemService.findAllByCollection(context, (Collection) dso);
      while (items.hasNext()) {
        Item item = items.next();
        this.dspaceDFS(item, callback, check, false);
      }
    }

    //        Currently Bundles and Bitsreams aren't supported as independent entities.
    //        They should be converted as part of an item. So we do not need to make
    //        the recursive call for them. An item itself will be converted as part
    //        of the callback call below.
    //        The following code is left here for the day, we decide to also convert
    //        bundles and/or bitstreams.
    //
    //        if (dso instanceof Item)
    //        {
    //            Bundle[] bundles = ((Item) dso).getBundles();
    //            for (Bundle bundle : bundles)
    //            {
    //                this.dspaceDFS(bundle, callback, check, false);
    //            }
    //        }
    //
    //        if (dso instanceof Bundle)
    //        {
    //            Bitstream[] bistreams = ((Bundle) dso).getBitstreams();
    //            for (Bitstream bitstream : bistreams)
    //            {
    //                this.dspaceDFS(bitstream, callback, check, false);
    //            }
    //        }

    callback.callback(dso);
    report(
        "Processed "
            + contentServiceFactory.getDSpaceObjectService(dso).getTypeText(dso)
            + " "
            + dso.getID()
            + " (handle "
            + dso.getHandle()
            + ").");
  }
Beispiel #26
0
  protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException, SQLException, AuthorizeException {
    includeAll = ConfigurationManager.getBooleanProperty("harvest.includerestricted.rss", true);
    String path = request.getPathInfo();
    String feedType = null;
    String handle = null;

    // build label map from localized Messages resource bundle
    Locale locale = request.getLocale();
    ResourceBundle msgs = ResourceBundle.getBundle("Messages", locale);
    Map<String, String> labelMap = new HashMap<String, String>();
    labelMap.put(SyndicationFeed.MSG_UNTITLED, msgs.getString(clazz + ".notitle"));
    labelMap.put(SyndicationFeed.MSG_LOGO_TITLE, msgs.getString(clazz + ".logo.title"));
    labelMap.put(
        SyndicationFeed.MSG_FEED_DESCRIPTION, msgs.getString(clazz + ".general-feed.description"));
    labelMap.put(SyndicationFeed.MSG_UITYPE, SyndicationFeed.UITYPE_JSPUI);
    for (String selector : SyndicationFeed.getDescriptionSelectors()) {
      labelMap.put("metadata." + selector, msgs.getString(SyndicationFeed.MSG_METADATA + selector));
    }

    if (path != null) {
      // substring(1) is to remove initial '/'
      path = path.substring(1);
      int split = path.indexOf('/');
      if (split != -1) {
        feedType = path.substring(0, split);
        handle = path.substring(split + 1);
      }
    }

    DSpaceObject dso = null;

    // as long as this is not a site wide feed,
    // attempt to retrieve the Collection or Community object
    if (handle != null && !handle.equals(SITE_FEED_KEY)) {
      // Determine if handle is a valid reference
      dso = HandleManager.resolveToObject(context, handle);
      if (dso == null) {
        log.info(LogManager.getHeader(context, "invalid_handle", "path=" + path));
        JSPManager.showInvalidIDError(request, response, handle, -1);
        return;
      }
    }

    if (!enabled
        || (dso != null
            && (dso.getType() != Constants.COLLECTION && dso.getType() != Constants.COMMUNITY))) {
      log.info(LogManager.getHeader(context, "invalid_id", "path=" + path));
      JSPManager.showInvalidIDError(request, response, path, -1);
      return;
    }

    // Determine if requested format is supported
    if (feedType == null || !formats.contains(feedType)) {
      log.info(LogManager.getHeader(context, "invalid_syndformat", "path=" + path));
      JSPManager.showInvalidIDError(request, response, path, -1);
      return;
    }

    if (dso != null && dso.getType() == Constants.COLLECTION) {
      labelMap.put(
          SyndicationFeed.MSG_FEED_TITLE,
          MessageFormat.format(
              msgs.getString(clazz + ".feed.title"),
              msgs.getString(clazz + ".feed-type.collection"),
              dso.getMetadata("short_description")));
    } else if (dso != null && dso.getType() == Constants.COMMUNITY) {
      labelMap.put(
          SyndicationFeed.MSG_FEED_TITLE,
          MessageFormat.format(
              msgs.getString(clazz + ".feed.title"),
              msgs.getString(clazz + ".feed-type.community"),
              dso.getMetadata("short_description")));
    }

    // Lookup or generate the feed
    // Cache key is handle + locale
    String cacheKey = (handle == null ? "site" : handle) + "." + locale.toString();
    SyndicationFeed feed = null;
    if (feedCache != null) {
      CacheFeed cFeed = feedCache.get(cacheKey);
      if (cFeed != null) // cache hit, but...
      {
        // Is the feed current?
        boolean cacheFeedCurrent = false;
        if (cFeed.timeStamp + (cacheAge * HOUR_MSECS) < System.currentTimeMillis()) {
          cacheFeedCurrent = true;
        }
        // Not current, but have any items changed since feed was created/last checked?
        else if (!itemsChanged(context, dso, cFeed.timeStamp)) {
          // no items have changed, re-stamp feed and use it
          cFeed.timeStamp = System.currentTimeMillis();
          cacheFeedCurrent = true;
        }
        if (cacheFeedCurrent) {
          feed = cFeed.access();
        }
      }
    }

    // either not caching, not found in cache, or feed in cache not current
    if (feed == null) {
      feed = new SyndicationFeed(SyndicationFeed.UITYPE_JSPUI);
      feed.populate(request, dso, getItems(context, dso), labelMap);
      if (feedCache != null) {
        cache(cacheKey, new CacheFeed(feed));
      }
    }

    // set the feed to the requested type & return it
    try {
      feed.setType(feedType);
      response.setContentType("text/xml; charset=UTF-8");
      feed.output(response.getWriter());
    } catch (FeedException fex) {
      throw new IOException(fex.getMessage(), fex);
    }
  }
  public static void main(String[] argv) throws Exception {
    // set headless for non-gui workstations
    System.setProperty("java.awt.headless", "true");

    // create an options object and populate it
    CommandLineParser parser = new PosixParser();

    Options options = new Options();

    options.addOption(
        "v", "verbose", false, "print all extracted text and other details to STDOUT");
    options.addOption("f", "force", false, "force all bitstreams to be processed");
    options.addOption(
        "n", "noindex", false, "do NOT update the search index after filtering bitstreams");
    options.addOption("i", "identifier", true, "ONLY process bitstreams belonging to identifier");
    options.addOption("m", "maximum", true, "process no more than maximum items");
    options.addOption("h", "help", false, "help");

    CommandLine line = parser.parse(options, argv);

    if (line.hasOption('h')) {
      HelpFormatter myhelp = new HelpFormatter();
      myhelp.printHelp("MediaFilter\n", options);

      System.exit(0);
    }

    if (line.hasOption('v')) {
      isVerbose = true;
    }

    if (line.hasOption('n')) {
      updateIndex = false;
    }

    if (line.hasOption('f')) {
      isForce = true;
    }

    if (line.hasOption('i')) {
      identifier = line.getOptionValue('i');
    }

    if (line.hasOption('m')) {
      max2Process = Integer.parseInt(line.getOptionValue('m'));
      if (max2Process <= 1) {
        System.out.println("Invalid maximum value '" + line.getOptionValue('m') + "' - ignoring");
        max2Process = Integer.MAX_VALUE;
      }
    }

    // set up filters
    filterClasses = (MediaFilter[]) PluginManager.getPluginSequence(MediaFilter.class);
    for (int i = 0; i < filterClasses.length; i++) {
      String filterName = filterClasses[i].getClass().getName();
      String formats = ConfigurationManager.getProperty("filter." + filterName + ".inputFormats");
      if (formats != null) {
        filterFormats.put(filterName, Arrays.asList(formats.split(",[\\s]*")));
      }
    }

    Context c = null;

    try {
      c = new Context();

      // have to be super-user to do the filtering
      c.setIgnoreAuthorization(true);

      // now apply the filters
      if (identifier == null) {
        applyFiltersAllItems(c);
      } else // restrict application scope to identifier
      {
        DSpaceObject dso = HandleManager.resolveToObject(c, identifier);
        if (dso == null) {
          throw new IllegalArgumentException(
              "Cannot resolve " + identifier + " to a DSpace object");
        }

        switch (dso.getType()) {
          case Constants.COMMUNITY:
            applyFiltersCommunity(c, (Community) dso);
            break;
          case Constants.COLLECTION:
            applyFiltersCollection(c, (Collection) dso);
            break;
          case Constants.ITEM:
            applyFiltersItem(c, (Item) dso);
            break;
        }
      }

      // update search index?
      if (updateIndex) {
        System.out.println("Updating search index:");
        DSIndexer.updateIndex(c);
      }

      c.complete();
      c = null;
    } finally {
      if (c != null) {
        c.abort();
      }
    }
  }
Beispiel #28
0
  /**
   * Fills in the feed and entry-level metadata from DSpace objects.
   *
   * @param request request
   * @param context context
   * @param dso DSpaceObject
   * @param items array of objects
   * @param labels label map
   */
  public void populate(
      HttpServletRequest request,
      Context context,
      DSpaceObject dso,
      List<? extends DSpaceObject> items,
      Map<String, String> labels) {
    String logoURL = null;
    String objectURL = null;
    String defaultTitle = null;
    boolean podcastFeed = false;
    this.request = request;

    // dso is null for the whole site, or a search without scope
    if (dso == null) {
      defaultTitle = ConfigurationManager.getProperty("dspace.name");
      feed.setDescription(localize(labels, MSG_FEED_DESCRIPTION));
      objectURL = resolveURL(request, null);
      logoURL = ConfigurationManager.getProperty("webui.feed.logo.url");
    } else {
      Bitstream logo = null;
      if (dso.getType() == Constants.COLLECTION) {
        Collection col = (Collection) dso;
        defaultTitle = col.getName();
        feed.setDescription(collectionService.getMetadata(col, "short_description"));
        logo = col.getLogo();
        String cols = ConfigurationManager.getProperty("webui.feed.podcast.collections");
        if (cols != null && cols.length() > 1 && cols.contains(col.getHandle())) {
          podcastFeed = true;
        }
      } else if (dso.getType() == Constants.COMMUNITY) {
        Community comm = (Community) dso;
        defaultTitle = comm.getName();
        feed.setDescription(communityService.getMetadata(comm, "short_description"));
        logo = comm.getLogo();
        String comms = ConfigurationManager.getProperty("webui.feed.podcast.communities");
        if (comms != null && comms.length() > 1 && comms.contains(comm.getHandle())) {
          podcastFeed = true;
        }
      }
      objectURL = resolveURL(request, dso);
      if (logo != null) {
        logoURL = urlOfBitstream(request, logo);
      }
    }
    feed.setTitle(
        labels.containsKey(MSG_FEED_TITLE) ? localize(labels, MSG_FEED_TITLE) : defaultTitle);
    feed.setLink(objectURL);
    feed.setPublishedDate(new Date());
    feed.setUri(objectURL);

    // add logo if we found one:
    if (logoURL != null) {
      // we use the path to the logo for this, the logo itself cannot
      // be contained in the rdf. Not all RSS-viewers show this logo.
      SyndImage image = new SyndImageImpl();
      image.setLink(objectURL);
      if (StringUtils.isNotBlank(feed.getTitle())) {
        image.setTitle(feed.getTitle());
      } else {
        image.setTitle(localize(labels, MSG_LOGO_TITLE));
      }
      image.setUrl(logoURL);
      feed.setImage(image);
    }

    // add entries for items
    if (items != null) {
      List<SyndEntry> entries = new ArrayList<SyndEntry>();
      for (DSpaceObject itemDSO : items) {
        if (itemDSO.getType() != Constants.ITEM) {
          continue;
        }
        Item item = (Item) itemDSO;
        boolean hasDate = false;
        SyndEntry entry = new SyndEntryImpl();
        entries.add(entry);

        String entryURL = resolveURL(request, item);
        entry.setLink(entryURL);
        entry.setUri(entryURL);

        String title = getOneDC(item, titleField);
        entry.setTitle(title == null ? localize(labels, MSG_UNTITLED) : title);

        // "published" date -- should be dc.date.issued
        String pubDate = getOneDC(item, dateField);
        if (pubDate != null) {
          entry.setPublishedDate((new DCDate(pubDate)).toDate());
          hasDate = true;
        }
        // date of last change to Item
        entry.setUpdatedDate(item.getLastModified());

        StringBuffer db = new StringBuffer();
        for (String df : descriptionFields) {
          // Special Case: "(date)" in field name means render as date
          boolean isDate = df.indexOf("(date)") > 0;
          if (isDate) {
            df = df.replaceAll("\\(date\\)", "");
          }

          List<MetadataValue> dcv = itemService.getMetadataByMetadataString(item, df);
          if (dcv.size() > 0) {
            String fieldLabel = labels.get(MSG_METADATA + df);
            if (fieldLabel != null && fieldLabel.length() > 0) {
              db.append(fieldLabel).append(": ");
            }
            boolean first = true;
            for (MetadataValue v : dcv) {
              if (first) {
                first = false;
              } else {
                db.append("; ");
              }
              db.append(isDate ? new DCDate(v.getValue()).toString() : v.getValue());
            }
            db.append("\n");
          }
        }
        if (db.length() > 0) {
          SyndContent desc = new SyndContentImpl();
          desc.setType("text/plain");
          desc.setValue(db.toString());
          entry.setDescription(desc);
        }

        // This gets the authors into an ATOM feed
        List<MetadataValue> authors = itemService.getMetadataByMetadataString(item, authorField);
        if (authors.size() > 0) {
          List<SyndPerson> creators = new ArrayList<SyndPerson>();
          for (MetadataValue author : authors) {
            SyndPerson sp = new SyndPersonImpl();
            sp.setName(author.getValue());
            creators.add(sp);
          }
          entry.setAuthors(creators);
        }

        // only add DC module if any DC fields are configured
        if (dcCreatorField != null || dcDateField != null || dcDescriptionField != null) {
          DCModule dc = new DCModuleImpl();
          if (dcCreatorField != null) {
            List<MetadataValue> dcAuthors =
                itemService.getMetadataByMetadataString(item, dcCreatorField);
            if (dcAuthors.size() > 0) {
              List<String> creators = new ArrayList<String>();
              for (MetadataValue author : dcAuthors) {
                creators.add(author.getValue());
              }
              dc.setCreators(creators);
            }
          }
          if (dcDateField != null && !hasDate) {
            List<MetadataValue> v = itemService.getMetadataByMetadataString(item, dcDateField);
            if (v.size() > 0) {
              dc.setDate((new DCDate(v.get(0).getValue())).toDate());
            }
          }
          if (dcDescriptionField != null) {
            List<MetadataValue> v =
                itemService.getMetadataByMetadataString(item, dcDescriptionField);
            if (v.size() > 0) {
              StringBuffer descs = new StringBuffer();
              for (MetadataValue d : v) {
                if (descs.length() > 0) {
                  descs.append("\n\n");
                }
                descs.append(d.getValue());
              }
              dc.setDescription(descs.toString());
            }
          }
          entry.getModules().add(dc);
        }

        // iTunes Podcast Support - START
        if (podcastFeed) {
          // Add enclosure(s)
          List<SyndEnclosure> enclosures = new ArrayList();
          try {
            List<Bundle> bunds = itemService.getBundles(item, "ORIGINAL");
            if (bunds.get(0) != null) {
              List<Bitstream> bits = bunds.get(0).getBitstreams();
              for (Bitstream bit : bits) {
                String mime = bit.getFormat(context).getMIMEType();
                if (ArrayUtils.contains(podcastableMIMETypes, mime)) {
                  SyndEnclosure enc = new SyndEnclosureImpl();
                  enc.setType(bit.getFormat(context).getMIMEType());
                  enc.setLength(bit.getSize());
                  enc.setUrl(urlOfBitstream(request, bit));
                  enclosures.add(enc);
                } else {
                  continue;
                }
              }
            }
            // Also try to add an external value from dc.identifier.other
            // We are assuming that if this is set, then it is a media file
            List<MetadataValue> externalMedia =
                itemService.getMetadataByMetadataString(item, externalSourceField);
            if (externalMedia.size() > 0) {
              for (MetadataValue anExternalMedia : externalMedia) {
                SyndEnclosure enc = new SyndEnclosureImpl();
                enc.setType(
                    "audio/x-mpeg"); // We can't determine MIME of external file, so just picking
                                     // one.
                enc.setLength(1);
                enc.setUrl(anExternalMedia.getValue());
                enclosures.add(enc);
              }
            }

          } catch (Exception e) {
            System.out.println(e.getMessage());
          }
          entry.setEnclosures(enclosures);

          // Get iTunes specific fields: author, subtitle, summary, duration, keywords
          EntryInformation itunes = new EntryInformationImpl();

          String author = getOneDC(item, authorField);
          if (author != null && author.length() > 0) {
            itunes.setAuthor(author); // <itunes:author>
          }

          itunes.setSubtitle(
              title == null ? localize(labels, MSG_UNTITLED) : title); // <itunes:subtitle>

          if (db.length() > 0) {
            itunes.setSummary(db.toString()); // <itunes:summary>
          }

          String extent =
              getOneDC(
                  item,
                  "dc.format.extent"); // assumed that user will enter this field with length of
                                       // song in seconds
          if (extent != null && extent.length() > 0) {
            extent = extent.split(" ")[0];
            Integer duration = Integer.parseInt(extent);
            itunes.setDuration(new Duration(duration)); // <itunes:duration>
          }

          String subject = getOneDC(item, "dc.subject");
          if (subject != null && subject.length() > 0) {
            String[] subjects = new String[1];
            subjects[0] = subject;
            itunes.setKeywords(subjects); // <itunes:keywords>
          }

          entry.getModules().add(itunes);
        }
      }
      feed.setEntries(entries);
    }
  }
  public void processDSpaceObject(
      Context context,
      HttpServletRequest request,
      HttpServletResponse response,
      DSpaceObject dso,
      String extraPathInfo)
      throws ServletException, IOException, SQLException, AuthorizeException {
    // OK, we have a valid URI. What is it?
    if (dso.getType() == Constants.BITSTREAM) {
      // FIXME: Check for if-modified-since header
      Bitstream bitstream = (Bitstream) dso;

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

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

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

      response.setHeader("Content-Length", String.valueOf(bitstream.getSize()));
      response.setHeader("Content-disposition", "attachment; filename=" + bitstream.getName());

      Utils.bufferedCopy(is, response.getOutputStream());
      is.close();
      response.getOutputStream().flush();
    } else if (dso.getType() == Constants.ITEM) {
      Item item = (Item) dso;

      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);
      } else {
        // Display the item page
        displayItem(context, request, response, item);
      }
    } else if (dso.getType() == Constants.COLLECTION) {
      Collection c = (Collection) dso;

      // Store collection location in request
      request.setAttribute("dspace.collection", c);

      /*
       * Find the "parent" community the collection, mainly for
       * "breadcrumbs" FIXME: At the moment, just grab the first community
       * the collection is in. This should probably be more context
       * sensitive when we have multiple inclusion.
       */
      Community[] parents = (Community[]) c.getCommunities().toArray();
      request.setAttribute("dspace.community", parents[0]);

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

      // home page, or forward to another page?
      if ((extraPathInfo == null) || (extraPathInfo.equals("/"))) {
        collectionHome(context, request, response, parents[0], c);
      } else {
        // Forward to another servlet
        request.getRequestDispatcher(extraPathInfo).forward(request, response);
      }
    } else if (dso.getType() == Constants.COMMUNITY) {
      Community c = (Community) dso;

      // Store collection location in request
      request.setAttribute("dspace.community", c);

      /*
       * Find all the "parent" communities for the community
       */
      request.setAttribute("dspace.communities", getParents(c, false));

      // home page, or forward to another page?
      if ((extraPathInfo == null) || (extraPathInfo.equals("/"))) {
        communityHome(context, request, response, c);
      } else {
        // Forward to another servlet
        request.getRequestDispatcher(extraPathInfo).forward(request, response);
      }
    } else {
      // Shouldn't happen. Log and treat as invalid ID
      log.info(
          LogManager.getHeader(
              context,
              "URI not an item, collection or community",
              "identifier=" + dso.getIdentifier().toString()));
      JSPManager.showInvalidIDError(request, response, request.getPathInfo(), -1);

      return;
    }
  }
  @Override
  public void authorizeAction(
      Context c, EPerson e, DSpaceObject o, int action, boolean useInheritance)
      throws AuthorizeException, SQLException {
    if (o == null) {
      // action can be -1 due to a null entry
      String actionText;

      if (action == -1) {
        actionText = "null";
      } else {
        actionText = Constants.actionText[action];
      }

      UUID userid;

      if (e == null) {
        userid = null;
      } else {
        userid = e.getID();
      }

      throw new AuthorizeException(
          "Authorization attempted on null DSpace object " + actionText + " by user " + userid);
    }

    if (!authorize(c, o, action, e, useInheritance)) {
      // denied, assemble and throw exception
      int otype = o.getType();
      UUID oid = o.getID();
      UUID userid;

      if (e == null) {
        userid = null;
      } else {
        userid = e.getID();
      }

      //            AuthorizeException j = new AuthorizeException("Denied");
      //            j.printStackTrace();
      // action can be -1 due to a null entry
      String actionText;

      if (action == -1) {
        actionText = "null";
      } else {
        actionText = Constants.actionText[action];
      }

      throw new AuthorizeException(
          "Authorization denied for action "
              + actionText
              + " on "
              + Constants.typeText[otype]
              + ":"
              + oid
              + " by user "
              + userid,
          o,
          action);
    }
  }