@RequestMapping(method = RequestMethod.GET) protected String processGet( @RequestAttribute Context context, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { Group group = null; group = checkGroup(context, request); if (group != null) { // unknown action, show edit page model.addAttribute("group", group); model.addAttribute("members", group.getMembers()); model.addAttribute("membergroups", group.getMemberGroups()); String utilsGrpName = Utils.addEntities(group.getName()); model.addAttribute("utilsGrpName", utilsGrpName); return "pages/admin/group-edit"; } else { return showMainPage(context, model, request, response); } } // end processGet
/** * Factory method for ResultsPruners (used to load ConfigurationManager properties. * * @param props * @throws FileNotFoundException */ public static ResultsPruner getPruner(Context context, Properties props) throws FileNotFoundException { ResultsPruner rp = new ResultsPruner(context); Pattern retentionPattern = Pattern.compile("checker\\.retention\\.(.*)"); for (Enumeration<String> en = (Enumeration<String>) props.propertyNames(); en.hasMoreElements(); ) { String name = en.nextElement(); Matcher matcher = retentionPattern.matcher(name); if (!matcher.matches()) { continue; } String resultCode = matcher.group(1); long duration; try { duration = Utils.parseDuration(props.getProperty(name)); } catch (ParseException e) { throw new IllegalStateException("Problem parsing duration: " + e.getMessage(), e); } ChecksumResultCode code = ChecksumResultCode.valueOf(resultCode); if (code == null) { throw new IllegalStateException("Checksum result code not found: " + resultCode); } if ("default".equals(resultCode)) { rp.setDefaultDuration(duration); } else { rp.addInterested(code, duration); } } return rp; }
/** * Get the license for this Item as String. License is the first bitstream named "license.txt" in * a LICENSE bundle, apparently? * * <p>FIXME: is this correct? there's no counterexample.. * * @return license string, or null if none found. * @throws SQLException the SQL exception * @throws AuthorizeException the authorize exception * @throws IOException Signals that an I/O exception has occurred. */ private String getLicenseAsString() throws SQLException, AuthorizeException, IOException { Bundle lb[] = this.item.getBundles(Constants.LICENSE_BUNDLE_NAME); for (Bundle element : lb) { Bitstream lbs = element.getBitstreamByName("license.txt"); if (lbs != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream((int) lbs.getSize()); Utils.copy(lbs.retrieve(), baos); return baos.toString(); } } return null; }
/** * Add the current date to the item metadata. This looks up the field in which to store this * metadata in the configuration sword.updated.field * * @param item * @throws DSpaceSwordException */ protected void setUpdatedDate(Item item, VerboseDescription verboseDescription) throws DSpaceSwordException { String field = ConfigurationManager.getProperty("swordv2-server", "updated.field"); if (field == null || "".equals(field)) { throw new DSpaceSwordException( "No configuration, or configuration is invalid for: sword.updated.field"); } MDValue dc = this.configToDC(field, null); item.clearMetadata(dc.getSchema(), dc.getElement(), dc.getQualifier(), MDValue.ANY); item.addMetadata( dc.getSchema(), dc.getElement(), dc.getQualifier(), null, Utils.asISO8601(new Date())); verboseDescription.append("Updated date added to response from item metadata where available"); }
/** * 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 { } }
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; } }
protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { ExternalIdentifierDAO identifierDAO = ExternalIdentifierDAOFactory.getInstance(context); Item item = null; Bitstream bitstream = null; String idString = request.getPathInfo(); String filenameNoPath = null; String fullpath = null; String uri = null; // Parse URL if (idString != null) { // Remove leading slash if (idString.startsWith("/")) { idString = idString.substring(1); } // Get uri and full file path int slashIndex = idString.indexOf('/'); if (slashIndex != -1) { slashIndex = idString.indexOf('/', slashIndex + 1); if (slashIndex != -1) { uri = idString.substring(0, slashIndex); fullpath = URLDecoder.decode(idString.substring(slashIndex + 1), Constants.DEFAULT_ENCODING); // Get filename with no path slashIndex = fullpath.indexOf('/'); if (slashIndex != -1) { String[] pathComponents = fullpath.split("/"); if (pathComponents.length <= maxDepthGuess + 1) { filenameNoPath = pathComponents[pathComponents.length - 1]; } } } } } if (uri != null && fullpath != null) { // Find the item try { /* * If the original item doesn't have a persistent identifier * yet (because it's in the workflow) what we actually have is * a URL of the form: db-id/1234 where 1234 is the database ID * of the item. * * FIXME: This first part could be totally omitted now that we * have the dsi:x/y format of identification. */ if (uri.startsWith("db-id")) { String dbIDString = uri.substring(uri.indexOf('/') + 1); int dbID = Integer.parseInt(dbIDString); item = ItemDAOFactory.getInstance(context).retrieve(dbID); } else { ExternalIdentifier identifier = identifierDAO.retrieve(uri); ObjectIdentifier oi = identifier.getObjectIdentifier(); item = (Item) oi.getObject(context); } } catch (NumberFormatException nfe) { // Invalid ID - this will be dealt with below } } if (item != null) { // Try to find bitstream with exactly matching name + path bitstream = getItemBitstreamByName(item, fullpath); if (bitstream == null && filenameNoPath != null) { // No match with the full path, but we can try again with // only the filename bitstream = getItemBitstreamByName(item, filenameNoPath); } } // Did we get a bitstream? if (bitstream != null) { log.info( LogManager.getHeader( context, "view_html", "uri=" + uri + ",bitstream_id=" + bitstream.getID())); // Set the response MIME type response.setContentType(bitstream.getFormat().getMIMEType()); // Response length response.setHeader("Content-Length", String.valueOf(bitstream.getSize())); // Pipe the bits InputStream is = bitstream.retrieve(); Utils.bufferedCopy(is, response.getOutputStream()); is.close(); response.getOutputStream().flush(); } else { // No bitstream - we got an invalid ID log.info(LogManager.getHeader(context, "view_html", "invalid_bitstream_id=" + idString)); JSPManager.showInvalidIDError(request, response, idString, Constants.BITSTREAM); } }
@RequestMapping(method = RequestMethod.POST) protected String processPost( @RequestAttribute Context context, ModelMap model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { Group group = null; group = checkGroup(context, request); if (group != null) { // is this user authorized to edit this group? AuthorizeManager.authorizeAction(context, group, Constants.ADD); boolean submit_edit = (request.getParameter("submit_edit") != null); boolean submit_group_update = (request.getParameter("submit_group_update") != null); boolean submit_group_delete = (request.getParameter("submit_group_delete") != null); boolean submit_confirm_delete = (request.getParameter("submit_confirm_delete") != null); boolean submit_cancel_delete = (request.getParameter("submit_cancel_delete") != null); // just chosen a group to edit - get group and pass it to // group-edit.jsp if (submit_edit && !submit_group_update && !submit_group_delete) { model.addAttribute("group", group); model.addAttribute("members", group.getMembers()); model.addAttribute("membergroups", group.getMemberGroups()); String utilsGrpName = Utils.addEntities(group.getName()); model.addAttribute("utilsGrpName", utilsGrpName); return "pages/admin/group-edit"; } // update the members of the group else if (submit_group_update) { // first off, did we change the group name? String newName = request.getParameter("group_name"); if (!newName.equals(group.getName())) { group.setName(newName); group.update(); } int[] eperson_ids = Util.getIntParameters(request, "eperson_id"); int[] group_ids = Util.getIntParameters(request, "group_ids"); // now get members, and add new ones and remove missing ones EPerson[] members = group.getMembers(); Group[] membergroups = group.getMemberGroups(); if (eperson_ids != null) { // some epeople were listed, now make group's epeople match // given epeople Set memberSet = new HashSet(); Set epersonIDSet = new HashSet(); // add all members to a set for (int x = 0; x < members.length; x++) { Integer epersonID = Integer.valueOf(members[x].getID()); memberSet.add(epersonID); } // now all eperson_ids are put in a set for (int x = 0; x < eperson_ids.length; x++) { epersonIDSet.add(Integer.valueOf(eperson_ids[x])); } // process eperson_ids, adding those to group not already // members Iterator i = epersonIDSet.iterator(); while (i.hasNext()) { Integer currentID = (Integer) i.next(); if (!memberSet.contains(currentID)) { group.addMember(EPerson.find(context, currentID.intValue())); } } // process members, removing any that aren't in eperson_ids for (int x = 0; x < members.length; x++) { EPerson e = members[x]; if (!epersonIDSet.contains(Integer.valueOf(e.getID()))) { group.removeMember(e); } } } else { // no members found (ids == null), remove them all! for (int y = 0; y < members.length; y++) { group.removeMember(members[y]); } } if (group_ids != null) { // some groups were listed, now make group's member groups // match given group IDs Set memberSet = new HashSet(); Set groupIDSet = new HashSet(); // add all members to a set for (int x = 0; x < membergroups.length; x++) { Integer myID = Integer.valueOf(membergroups[x].getID()); memberSet.add(myID); } // now all eperson_ids are put in a set for (int x = 0; x < group_ids.length; x++) { groupIDSet.add(Integer.valueOf(group_ids[x])); } // process group_ids, adding those to group not already // members Iterator i = groupIDSet.iterator(); while (i.hasNext()) { Integer currentID = (Integer) i.next(); if (!memberSet.contains(currentID)) { group.addMember(Group.find(context, currentID.intValue())); } } // process members, removing any that aren't in eperson_ids for (int x = 0; x < membergroups.length; x++) { Group g = membergroups[x]; if (!groupIDSet.contains(Integer.valueOf(g.getID()))) { group.removeMember(g); } } } else { // no members found (ids == null), remove them all! for (int y = 0; y < membergroups.length; y++) { group.removeMember(membergroups[y]); } } group.update(); model.addAttribute("group", group); model.addAttribute("members", group.getMembers()); model.addAttribute("membergroups", group.getMemberGroups()); String utilsGrpName = Utils.addEntities(group.getName()); model.addAttribute("utilsGrpName", utilsGrpName); context.commit(); return "pages/admin/group-edit"; } else if (submit_group_delete) { // direct to a confirmation step model.addAttribute("group", group); return "pages/admin/group-confirm-delete"; } else if (submit_confirm_delete) { // phony authorize, only admins can do this AuthorizeManager.authorizeAction(context, group, Constants.WRITE); // delete group, return to group-list.jsp group.delete(); return showMainPage(context, model, request, response); } else if (submit_cancel_delete) { // show group list return showMainPage(context, model, request, response); } else { // unknown action, show edit page model.addAttribute("group", group); model.addAttribute("members", group.getMembers()); model.addAttribute("membergroups", group.getMemberGroups()); String utilsGrpName = Utils.addEntities(group.getName()); model.addAttribute("utilsGrpName", utilsGrpName); return "pages/admin/group-edit"; } } else { // want to add a group - create a blank one, and pass to // group_edit.jsp String button = UIUtil.getSubmitButton(request, "submit"); if (button.equals("submit_add")) { group = Group.create(context); group.setName("new group" + group.getID()); group.update(); model.addAttribute("group", group); model.addAttribute("members", group.getMembers()); model.addAttribute("membergroups", group.getMemberGroups()); String utilsGrpName = Utils.addEntities(group.getName()); model.addAttribute("utilsGrpName", utilsGrpName); context.commit(); return "pages/admin/group-edit"; } else { // show the main page (select groups) return showMainPage(context, model, request, response); } } // end } // end processGet
/** * 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."); }
public boolean checkPassword(String attempt) { String encoded = Utils.getMD5(attempt); return (encoded.equals(metadata.get(EPersonMetadataField.PASSWORD))); }
public void setPassword(String password) { metadata.put(EPersonMetadataField.PASSWORD, Utils.getMD5(password)); modified = true; }
/** * Add a result and the length of time before it is removed from the checksum history table. * * @param result code in the database. * @param duration before bitstreams with the specified result type in the checksum history is * removed. * @throws ParseException if the duration cannot be parsed into a long value. */ public void addInterested(ChecksumResultCode result, String duration) throws ParseException { addInterested(result, Utils.parseDuration(duration)); }
@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(); }