/** * Attempt to filter a bitstream * * <p>An exception will be thrown if the media filter class cannot be instantiated, exceptions * from filtering will be logged to STDOUT and swallowed. * * @return true if bitstream processed, false if no applicable filter or already processed */ public static boolean filterBitstream(Context c, Item myItem, Bitstream myBitstream) throws Exception { boolean filtered = false; // iterate through filter classes. A single format may be actioned // by more than one filter for (int i = 0; i < filterClasses.length; i++) { List fmts = (List) filterFormats.get(filterClasses[i].getClass().getName()); if (fmts.contains(myBitstream.getFormat().getShortDescription())) { try { // only update item if bitstream not skipped if (filterClasses[i].processBitstream(c, myItem, myBitstream)) { myItem.update(); // Make sure new bitstream has a sequence // number filtered = true; } } catch (Exception e) { System.out.println( "ERROR filtering, skipping bitstream #" + myBitstream.getID() + " " + e); e.printStackTrace(); } } } return filtered; }
public void setup(org.dspace.content.Bitstream bitstream, String expand) throws SQLException { List<String> expandFields = new ArrayList<String>(); if (expand != null) { expandFields = Arrays.asList(expand.split(",")); } // A logo bitstream might not have a bundle... if (bitstream.getBundles() != null & bitstream.getBundles().length >= 0) { if (bitstream.getParentObject().getType() == Constants.ITEM) { bundleName = bitstream.getBundles()[0].getName(); } } description = bitstream.getDescription(); format = bitstream.getFormatDescription(); sizeBytes = bitstream.getSize(); retrieveLink = "/bitstreams/" + bitstream.getID() + "/retrieve"; mimeType = bitstream.getFormat().getMIMEType(); sequenceId = bitstream.getSequenceID(); CheckSum checkSum = new CheckSum(); checkSum.setCheckSumAlgorith(bitstream.getChecksumAlgorithm()); checkSum.setValue(bitstream.getChecksum()); this.setCheckSum(checkSum); if (expandFields.contains("parent") || expandFields.contains("all")) { parentObject = new DSpaceObject(bitstream.getParentObject()); } else { this.addExpand("parent"); } if (!expandFields.contains("all")) { this.addExpand("all"); } }
private void populateEntry(Context context, Entry entry, Bitstream bitstream) throws DSpaceSwordException { BitstreamFormat format = bitstream.getFormat(); String contentType = null; if (format != null) { contentType = format.getMIMEType(); } SwordUrlManager urlManager = new SwordUrlManager(new SwordConfigurationDSpace(), context); String bsUrl = urlManager.getBitstreamUrl(bitstream); entry.setId(bsUrl); entry.setTitle(bitstream.getName()); String desc = bitstream.getDescription(); if ("".equals(desc) || desc == null) { desc = bitstream.getName(); } entry.setSummary(desc); entry.setUpdated(new Date()); // required, though content is spurious // add an edit-media link for the bitstream ... Abdera abdera = new Abdera(); Link link = abdera.getFactory().newLink(); link.setHref(urlManager.getActionableBitstreamUrl(bitstream)); link.setMimeType(contentType); link.setRel("edit-media"); entry.addLink(link); // set the content of the bitstream entry.setContent(new IRI(bsUrl), contentType); }
/** * Return this resource's children. Item's children are its bitstreams. * * @return the DAV resource[] * @throws SQLException the SQL exception */ @Override protected DAVResource[] children() throws SQLException { // Check for overall read permission on Item if (!AuthorizeManager.authorizeActionBoolean(this.context, this.item, Constants.READ)) { return new DAVResource[0]; } Vector result = new Vector(); Bundle[] bundles = this.item.getBundles(); for (Bundle element : bundles) { // check read permission on this Bundle if (!AuthorizeManager.authorizeActionBoolean(this.context, element, Constants.READ)) { continue; } Bitstream[] bitstreams = element.getBitstreams(); for (Bitstream element0 : bitstreams) { String ext[] = element0.getFormat().getExtensions(); result.add( new DAVBitstream( this.context, this.request, this.response, makeChildPath( DAVBitstream.getPathElt( element0.getSequenceID(), ext.length < 1 ? null : ext[0])), this.item, element0)); } } return (DAVResource[]) result.toArray(new DAVResource[result.size()]); }
@GET @Path("/{bitstream_id}/retrieve") public javax.ws.rs.core.Response getFile( @PathParam("bitstream_id") final Integer bitstream_id, @QueryParam("userIP") String user_ip, @QueryParam("userAgent") String user_agent, @QueryParam("xforwarderfor") String xforwarderfor, @Context HttpHeaders headers, @Context HttpServletRequest request) { org.dspace.core.Context context = null; try { context = new org.dspace.core.Context(); org.dspace.content.Bitstream bitstream = org.dspace.content.Bitstream.find(context, bitstream_id); if (AuthorizeManager.authorizeActionBoolean( context, bitstream, org.dspace.core.Constants.READ)) { if (writeStatistics) { writeStats(context, bitstream_id, user_ip, user_agent, xforwarderfor, headers, request); } return Response.ok(bitstream.retrieve()).type(bitstream.getFormat().getMIMEType()).build(); } else { throw new WebApplicationException(Response.Status.UNAUTHORIZED); } } catch (IOException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (SQLException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (AuthorizeException e) { log.error(e.getMessage()); throw new WebApplicationException(Response.Status.UNAUTHORIZED); } finally { if (context != null) { try { context.complete(); } catch (SQLException e) { log.error(e.getMessage() + " occurred while trying to close"); } } } }
/** * Process Item, correcting CC-License if encountered. * * @param item * @throws SQLException * @throws AuthorizeException * @throws IOException */ protected static void handleItem(Item item) throws SQLException, AuthorizeException, IOException { Bundle[] bundles = item.getBundles("CC-LICENSE"); if (bundles == null || bundles.length == 0) return; Bundle bundle = bundles[0]; Bitstream bitstream = bundle.getBitstreamByName("license_rdf"); String license_rdf = new String(copy(bitstream)); /* quickly fix xml by ripping out offensive parts */ license_rdf = license_rdf.replaceFirst("<license", ""); license_rdf = license_rdf.replaceFirst("</license>", ""); StringWriter result = new StringWriter(); try { templates .newTransformer() .transform( new StreamSource(new ByteArrayInputStream(license_rdf.getBytes())), new StreamResult(result)); } catch (TransformerException e) { throw new RuntimeException(e.getMessage(), e); } StringBuffer buffer = result.getBuffer(); Bitstream newBitstream = bundle.createBitstream(new ByteArrayInputStream(buffer.toString().getBytes())); newBitstream.setName(bitstream.getName()); newBitstream.setDescription(bitstream.getDescription()); newBitstream.setFormat(bitstream.getFormat()); newBitstream.setSource(bitstream.getSource()); newBitstream.setUserFormatDescription(bitstream.getUserFormatDescription()); newBitstream.update(); bundle.removeBitstream(bitstream); bundle.update(); }
/** * Each submission step must define its own information to be reviewed during the final * Review/Verify Step in the submission process. * * <p>The information to review should be tacked onto the passed in List object. * * <p>NOTE: To remain consistent across all Steps, you should first add a sub-List object (with * this step's name as the heading), by using a call to reviewList.addList(). This sublist is the * list you return from this method! * * @param reviewList The List to which all reviewable information should be added * @return The new sub-List object created by this step, which contains all the reviewable * information. If this step has nothing to review, then return null! */ public List addReviewSection(List reviewList) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException { // Create a new list section for this step (and set its heading) List uploadSection = reviewList.addList("submit-review-" + this.stepAndPage, List.TYPE_FORM); uploadSection.setHead(T_head); // Review all uploaded files Item item = submission.getItem(); Bundle[] bundles = item.getBundles("ORIGINAL"); Bitstream[] bitstreams = new Bitstream[0]; if (bundles.length > 0) { bitstreams = bundles[0].getBitstreams(); } for (Bitstream bitstream : bitstreams) { BitstreamFormat bitstreamFormat = bitstream.getFormat(); String name = bitstream.getName(); String url = makeBitstreamLink(item, bitstream); String format = bitstreamFormat.getShortDescription(); Message support = ReviewStep.T_unknown; if (bitstreamFormat.getSupportLevel() == BitstreamFormat.KNOWN) { support = T_known; } else if (bitstreamFormat.getSupportLevel() == BitstreamFormat.SUPPORTED) { support = T_supported; } org.dspace.app.xmlui.wing.element.Item file = uploadSection.addItem(); file.addXref(url, name); file.addContent(" - " + format + " "); file.addContent(support); } // return this new "upload" section return uploadSection; }
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); } }
/** * Create name that bitstream will have in archive. Name must be unique and relative to archive * top level, e.g. "bitstream_<id>.ext" */ private String makeBitstreamName(Bitstream bitstream) { String base = "bitstream_" + String.valueOf(bitstream.getID()); String ext[] = bitstream.getFormat().getExtensions(); return (ext.length > 0) ? base + "." + ext[0] : base; }
/** * Generate a METS file element for a given bitstream. * * @param context * @param item If the bitstream is associated with an item, provide the item, otherwise leave * null. * @param bitstream The bitstream to build a file element for. * @param fileID The unique file id for this file. * @param groupID The group id for this file, if it is derived from another file then they should * share the same groupID. * @param admID The IDs of the administrative metadata sections which pertain to this file * @throws org.xml.sax.SAXException passed through. * @throws java.sql.SQLException passed through. */ protected final void renderFile( Context context, Item item, Bitstream bitstream, String fileID, String groupID, String admID) throws SAXException, SQLException { AttributeMap attributes; // ////////////////////////////// // Determine the file attributes BitstreamFormat format = bitstream.getFormat(context); String mimeType = null; if (format != null) { mimeType = format.getMIMEType(); } String checksumType = bitstream.getChecksumAlgorithm(); String checksum = bitstream.getChecksum(); long size = bitstream.getSize(); // //////////////////////////////// // Start the actual file attributes = new AttributeMap(); attributes.put("ID", fileID); attributes.put("GROUPID", groupID); if (admID != null && admID.length() > 0) { attributes.put("ADMID", admID); } if (mimeType != null && mimeType.length() > 0) { attributes.put("MIMETYPE", mimeType); } if (checksumType != null && checksum != null) { attributes.put("CHECKSUM", checksum); attributes.put("CHECKSUMTYPE", checksumType); } attributes.put("SIZE", String.valueOf(size)); startElement(METS, "file", attributes); // //////////////////////////////////// // Determine the file location attributes String name = bitstream.getName(); String description = bitstream.getDescription(); // If possible, reference this bitstream via a handle, however this may // be null if a handle has not yet been assigned. In this case reference the // item its internal id. In the last case where the bitstream is not associated // with an item (such as a community logo) then reference the bitstreamID directly. String identifier = null; if (item != null && item.getHandle() != null) { identifier = "handle/" + item.getHandle(); } else if (item != null) { identifier = "item/" + item.getID(); } else { identifier = "id/" + bitstream.getID(); } String url = contextPath + "/bitstream/" + identifier + "/"; // If we can, append the pretty name of the bitstream to the URL try { if (bitstream.getName() != null) { url += Util.encodeBitstreamName(bitstream.getName(), "UTF-8"); } } catch (UnsupportedEncodingException uee) { // just ignore it, we don't have to have a pretty // name at the end of the URL because the sequence id will // locate it. However it means that links in this file might // not work.... } url += "?sequence=" + bitstream.getSequenceID(); // ////////////////////// // Start the file location attributes = new AttributeMap(); AttributeMap attributesXLINK = new AttributeMap(); attributesXLINK.setNamespace(XLINK); attributes.put("LOCTYPE", "URL"); attributesXLINK.put("type", "locator"); attributesXLINK.put("title", name); if (description != null) { attributesXLINK.put("label", description); } attributesXLINK.put("href", url); startElement(METS, "FLocat", attributes, attributesXLINK); // /////////////////////// // End file location endElement(METS, "FLocate"); // //////////////////////////////// // End the file endElement(METS, "file"); }
public void addBody(Body body) throws SQLException, WingException { // Get our parameters and state int itemID = parameters.getParameterAsInteger("itemID", -1); Item item = Item.find(context, itemID); String baseURL = contextPath + "/admin/item?administrative-continue=" + knot.getId(); // DIVISION: main div Division main = body.addInteractiveDivision( "edit-item-status", contextPath + "/admin/item", Division.METHOD_POST, "primary administrative item"); main.setHead(T_option_head); // LIST: options List options = main.addList("options", List.TYPE_SIMPLE, "horizontal"); options.addItem().addXref(baseURL + "&submit_status", T_option_status); options .addItem() .addHighlight("bold") .addXref(baseURL + "&submit_bitstreams", T_option_bitstreams); options.addItem().addXref(baseURL + "&submit_metadata", T_option_metadata); options.addItem().addXref(baseURL + "&view_item", T_option_view); // TABLE: Bitstream summary Table files = main.addTable("editItemBitstreams", 1, 1); files.setHead(T_head1); Row header = files.addRow(Row.ROLE_HEADER); header.addCellContent(T_column1); header.addCellContent(T_column2); header.addCellContent(T_column3); header.addCellContent(T_column4); header.addCellContent(T_column5); Bundle[] bundles = item.getBundles(); for (Bundle bundle : bundles) { Cell bundleCell = files.addRow().addCell(1, 5); bundleCell.addContent(T_bundle_label.parameterize(bundle.getName())); Bitstream[] bitstreams = bundle.getBitstreams(); for (Bitstream bitstream : bitstreams) { boolean primary = (bundle.getPrimaryBitstreamID() == bitstream.getID()); String name = bitstream.getName(); if (name != null && name.length() > 50) { // If the fiel name is too long the shorten it so that it will display nicely. String shortName = name.substring(0, 15); shortName += " ... "; shortName += name.substring(name.length() - 25, name.length()); name = shortName; } String description = bitstream.getDescription(); String format = null; BitstreamFormat bitstreamFormat = bitstream.getFormat(); if (bitstreamFormat != null) format = bitstreamFormat.getShortDescription(); String editURL = contextPath + "/admin/item?administrative-continue=" + knot.getId() + "&bitstreamID=" + bitstream.getID() + "&submit_edit"; String viewURL = contextPath + "/bitstream/id/" + bitstream.getID() + "/" + bitstream.getName(); Row row = files.addRow(); CheckBox remove = row.addCell().addCheckBox("remove"); remove.setLabel("remove"); remove.addOption(bundle.getID() + "/" + bitstream.getID()); if (!AuthorizeManager.authorizeActionBoolean(context, item, Constants.REMOVE)) { remove.setDisabled(); } if (AuthorizeManager.authorizeActionBoolean(context, bitstream, Constants.WRITE)) { // The user can edit the bitstream give them a link. Cell cell = row.addCell(); cell.addXref(editURL, name); if (primary) cell.addXref(editURL, T_primary_label); row.addCell().addXref(editURL, description); row.addCell().addXref(editURL, format); } else { // The user can't edit the bitstream just show them it. Cell cell = row.addCell(); cell.addContent(name); if (primary) cell.addContent(T_primary_label); row.addCell().addContent(description); row.addCell().addContent(format); } Highlight highlight = row.addCell().addHighlight("fade"); highlight.addContent("["); highlight.addXref(viewURL, T_view_link); highlight.addContent("]"); } } if (AuthorizeManager.authorizeActionBoolean(context, item, Constants.ADD)) { Cell cell = files.addRow().addCell(1, 5); cell.addXref( contextPath + "/admin/item?administrative-continue=" + knot.getId() + "&submit_add", T_submit_add); } else { Cell cell = files.addRow().addCell(1, 5); cell.addHighlight("fade").addContent(T_no_upload); } // PARA: actions Para actions = main.addPara("editItemActionsP", "editItemActionsP"); if (AuthorizeManager.authorizeActionBoolean(context, item, Constants.REMOVE)) actions.addButton("submit_delete").setValue(T_submit_delete); else { Button button = actions.addButton("submit_delete"); button.setValue(T_submit_delete); button.setDisabled(); main.addPara().addHighlight("fade").addContent(T_no_remove); } actions.addButton("submit_return").setValue(T_submit_return); main.addHidden("administrative-continue").setValue(knot.getId()); }
public void addBody(Body body) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException { // If we are actually editing information of an uploaded file, // then display that body instead! if (this.editFile != null) { editFile.addBody(body); return; } // Get a list of all files in the original bundle Item item = submission.getItem(); Collection collection = submission.getCollection(); String actionURL = contextPath + "/handle/" + collection.getHandle() + "/submit/" + knot.getId() + ".continue"; boolean disableFileEditing = (submissionInfo.isInWorkflow()) && !ConfigurationManager.getBooleanProperty("workflow", "reviewer.file-edit"); Bundle[] bundles = item.getBundles("ORIGINAL"); Bitstream[] bitstreams = new Bitstream[0]; if (bundles.length > 0) { bitstreams = bundles[0].getBitstreams(); } // Part A: // First ask the user if they would like to upload a new file (may be the first one) Division div = body.addInteractiveDivision( "submit-upload", actionURL, Division.METHOD_MULTIPART, "primary submission"); div.setHead(T_submission_head); addSubmissionProgressList(div); List upload = null; if (!disableFileEditing) { // Only add the upload capabilities for new item submissions upload = div.addList("submit-upload-new", List.TYPE_FORM); upload.setHead(T_head); addRioxxVersionSection(upload, item); File file = upload.addItem().addFile("file"); file.setLabel(T_file); file.setHelp(T_file_help); file.setRequired(); // if no files found error was thrown by processing class, display it! if (this.errorFlag == org.dspace.submit.step.UploadStep.STATUS_NO_FILES_ERROR) { file.addError(T_file_error); } // if an upload error was thrown by processing class, display it! if (this.errorFlag == org.dspace.submit.step.UploadStep.STATUS_UPLOAD_ERROR) { file.addError(T_upload_error); } // if virus checking was attempted and failed in error then let the user know if (this.errorFlag == org.dspace.submit.step.UploadStep.STATUS_VIRUS_CHECKER_UNAVAILABLE) { file.addError(T_virus_checker_error); } // if virus checking was attempted and a virus found then let the user know if (this.errorFlag == org.dspace.submit.step.UploadStep.STATUS_CONTAINS_VIRUS) { file.addError(T_virus_error); } Text description = upload.addItem().addText("description"); description.setLabel(T_description); description.setHelp(T_description_help); Button uploadSubmit = upload.addItem().addButton("submit_upload"); uploadSubmit.setValue(T_submit_upload); } make_sherpaRomeo_submission(item, div); // Part B: // If the user has already uploaded files provide a list for the user. if (bitstreams.length > 0 || disableFileEditing) { Table summary = div.addTable("submit-upload-summary", (bitstreams.length * 2) + 2, 7); summary.setHead(T_head2); Row header = summary.addRow(Row.ROLE_HEADER); header.addCellContent(T_column0); // primary bitstream header.addCellContent(T_column1); // select checkbox header.addCellContent(T_column2); // file name header.addCellContent(T_column3); // size header.addCellContent(T_column4); // description header.addCellContent(T_column5); // format header.addCellContent(T_column6); // edit button for (Bitstream bitstream : bitstreams) { int id = bitstream.getID(); String name = bitstream.getName(); String url = makeBitstreamLink(item, bitstream); long bytes = bitstream.getSize(); String desc = bitstream.getDescription(); String algorithm = bitstream.getChecksumAlgorithm(); String checksum = bitstream.getChecksum(); Row row = summary.addRow(); // Add radio-button to select this as the primary bitstream Radio primary = row.addCell().addRadio("primary_bitstream_id"); primary.addOption(String.valueOf(id)); // If this bitstream is already marked as the primary bitstream // mark it as such. if (bundles[0].getPrimaryBitstreamID() == id) { primary.setOptionSelected(String.valueOf(id)); } if (!disableFileEditing) { // Workflow users can not remove files. CheckBox remove = row.addCell().addCheckBox("remove"); remove.setLabel("remove"); remove.addOption(id); } else { row.addCell(); } row.addCell().addXref(url, name); row.addCellContent(bytes + " bytes"); if (desc == null || desc.length() == 0) { row.addCellContent(T_unknown_name); } else { row.addCellContent(desc); } BitstreamFormat format = bitstream.getFormat(); if (format == null) { row.addCellContent(T_unknown_format); } else { int support = format.getSupportLevel(); Cell cell = row.addCell(); cell.addContent(format.getMIMEType()); cell.addContent(" "); switch (support) { case 1: cell.addContent(T_supported); break; case 2: cell.addContent(T_known); break; case 3: cell.addContent(T_unsupported); break; } } Button edit = row.addCell().addButton("submit_edit_" + id); edit.setValue(T_submit_edit); Row checksumRow = summary.addRow(); checksumRow.addCell(); Cell checksumCell = checksumRow.addCell(null, null, 0, 6, null); checksumCell.addHighlight("bold").addContent(T_checksum); checksumCell.addContent(" "); checksumCell.addContent(algorithm + ":" + checksum); } if (!disableFileEditing) { // Workflow users can not remove files. Row actionRow = summary.addRow(); actionRow.addCell(); Button removeSeleceted = actionRow.addCell(null, null, 0, 6, null).addButton("submit_remove_selected"); removeSeleceted.setValue(T_submit_remove); } upload = div.addList("submit-upload-new-part2", List.TYPE_FORM); } // Part C: // add standard control/paging buttons addControlButtons(upload); }
/** * 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); } }
@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(); }