diff --git a/dspace/etc/database_schema.sql b/dspace/etc/database_schema.sql index d1a9c6d266..c3b4bf2158 100644 --- a/dspace/etc/database_schema.sql +++ b/dspace/etc/database_schema.sql @@ -149,7 +149,8 @@ CREATE TABLE Bitstream source VARCHAR(256), internal_id VARCHAR(256), deleted BOOL, - store_number INTEGER + store_number INTEGER, + sequence_id INTEGER ); ------------------------------------------------------- diff --git a/dspace/etc/dspace-web.xml b/dspace/etc/dspace-web.xml index 2ce2a1a1c8..743cd003fb 100644 --- a/dspace/etc/dspace-web.xml +++ b/dspace/etc/dspace-web.xml @@ -130,6 +130,11 @@ org.dspace.app.webui.servlet.AdvancedSearchServlet + + bitstream + org.dspace.app.webui.servlet.BitstreamServlet + + browse-author org.dspace.app.webui.servlet.BrowseServlet @@ -216,6 +221,11 @@ org.dspace.app.webui.servlet.HandleServlet + + html + org.dspace.app.webui.servlet.HTMLServlet + + internal-error org.dspace.app.webui.servlet.InternalErrorServlet @@ -260,11 +270,6 @@ - - html - org.dspace.app.webui.servlet.HTMLServlet - - retrieve org.dspace.app.webui.servlet.RetrieveServlet @@ -303,6 +308,11 @@ /advanced-search + + bitstream + /bitstream/* + + browse-author /browse-author @@ -373,6 +383,11 @@ /handle/* + + html + /html/* + + internal-error /internal-error @@ -413,11 +428,6 @@ /register - - html - /html/* - - retrieve /retrieve/* diff --git a/dspace/src/org/dspace/app/webui/jsptag/ItemTag.java b/dspace/src/org/dspace/app/webui/jsptag/ItemTag.java index 4dc0366782..2b80e4b46d 100644 --- a/dspace/src/org/dspace/app/webui/jsptag/ItemTag.java +++ b/dspace/src/org/dspace/app/webui/jsptag/ItemTag.java @@ -513,8 +513,17 @@ public class ItemTag extends TagSupport out.print(bitstreams[k].getFormatDescription()); out.print(" 0) + { + out.print("/bitstream/"); + out.print(item.getHandle() + "/"); + out.print(bitstreams[k].getSequenceID() + "/"); + } + else + { + out.print("/retrieve/"); + out.print(bitstreams[k].getID() + "/"); + } out.print(URLEncoder.encode(bitstreams[k].getName())); out.print("\">"); diff --git a/dspace/src/org/dspace/app/webui/servlet/BitstreamServlet.java b/dspace/src/org/dspace/app/webui/servlet/BitstreamServlet.java new file mode 100644 index 0000000000..deab0738c5 --- /dev/null +++ b/dspace/src/org/dspace/app/webui/servlet/BitstreamServlet.java @@ -0,0 +1,188 @@ +/* + * BitstreamServlet.java + * + * Version: $Revision$ + * + * Date: $Date$ + * + * Copyright (c) 2002, Hewlett-Packard Company and Massachusetts + * Institute of Technology. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the Hewlett-Packard Company nor the name of the + * Massachusetts Institute of Technology nor the names of their + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +package org.dspace.app.webui.servlet; + +import java.io.InputStream; +import java.io.IOException; +import java.sql.SQLException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Logger; + +import org.dspace.app.webui.util.JSPManager; +import org.dspace.authorize.AuthorizeException; +import org.dspace.authorize.AuthorizeManager; +import org.dspace.content.Bitstream; +import org.dspace.content.Bundle; +import org.dspace.content.Item; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.dspace.core.LogManager; +import org.dspace.core.Utils; +import org.dspace.handle.HandleManager; + + +/** + * Servlet for retrieving bitstreams. The bits are simply piped to the user. + *

+ * /bitstream/handle/sequence_id/filename + * + * @author Robert Tansley + * @version $Revision$ + */ +public class BitstreamServlet extends DSpaceServlet +{ + /** log4j category */ + private static Logger log = Logger.getLogger(RetrieveServlet.class); + + + protected void doDSGet(Context context, + HttpServletRequest request, + HttpServletResponse response) + throws ServletException, IOException, SQLException, AuthorizeException + { + Bitstream bitstream = null; + + // Get the ID from the URL + String idString = request.getPathInfo(); + String handle = ""; + String sequence = ""; + + if (idString != null) + { + // Remove leading slash + if (idString.startsWith("/")) + { + idString = idString.substring(1); + } + + // Remove last slash and filename after it + int slashIndex = idString.lastIndexOf('/'); + if (slashIndex != -1) + { + idString = idString.substring(0, slashIndex); + } + + // Get bitstream sequence ID + slashIndex = idString.lastIndexOf('/'); + if (slashIndex != -1) + { + sequence = idString.substring(slashIndex + 1); + handle = idString.substring(0, slashIndex); + } + + + // Find the corresponding bitstream + try + { + + Item item = (Item) HandleManager.resolveToObject(context, handle); + + if (item == null) + { + log.info(LogManager.getHeader(context, + "invalid_id", + "path=" + handle)); + JSPManager.showInvalidIDError(request, response, handle, -1); + return; + } + + int sid = Integer.parseInt(sequence); + 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 (sid == bitstreams[k].getSequenceID()) + { + bitstream = bitstreams[k]; + found = true; + } + } + } + } + catch (NumberFormatException nfe) + { + // Invalid ID - this will be dealt with below + } + } + + // Did we get a bitstream? + if (bitstream != null) + { + log.info(LogManager.getHeader(context, + "view_bitstream", + "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_bitstream", + "invalid_bitstream_id=" + idString)); + + JSPManager.showInvalidIDError(request, + response, + idString, + Constants.BITSTREAM); + } + } +} diff --git a/dspace/src/org/dspace/app/webui/servlet/HTMLServlet.java b/dspace/src/org/dspace/app/webui/servlet/HTMLServlet.java index 9072f20052..e958f65e72 100644 --- a/dspace/src/org/dspace/app/webui/servlet/HTMLServlet.java +++ b/dspace/src/org/dspace/app/webui/servlet/HTMLServlet.java @@ -1,5 +1,5 @@ /* - * RetrieveServlet.java + * HTMLServlet.java * * Version: $Revision$ * @@ -146,7 +146,6 @@ public class HTMLServlet extends DSpaceServlet } } - //bitstream = Bitstream.find(context, id); } catch (NumberFormatException nfe) { diff --git a/dspace/src/org/dspace/content/Bitstream.java b/dspace/src/org/dspace/content/Bitstream.java index 44ca527ff1..9e21030d57 100644 --- a/dspace/src/org/dspace/content/Bitstream.java +++ b/dspace/src/org/dspace/content/Bitstream.java @@ -214,6 +214,28 @@ public class Bitstream extends DSpaceObject } + /** + * Get the sequence ID of this bitstream + * + * @return the sequence ID + */ + public int getSequenceID() + { + return bRow.getIntColumn("sequence_id"); + } + + + /** + * Set the sequence ID of this bitstream + * + * @param sid the ID + */ + public void setSequenceID(int sid) + { + bRow.setColumn("sequence_id", sid); + } + + /** * Get the name of this bitstream - typically the filename, without * any path information diff --git a/dspace/src/org/dspace/content/Item.java b/dspace/src/org/dspace/content/Item.java index a6f8613a87..e3ff0b6d51 100644 --- a/dspace/src/org/dspace/content/Item.java +++ b/dspace/src/org/dspace/content/Item.java @@ -1107,6 +1107,39 @@ public class Item extends DSpaceObject // Set the last modified date itemRow.setColumn("last_modified", new Date()); + // Set sequence IDs for bitstreams in item + int sequence = 0; + Bundle[] bunds = getBundles(); + + // find the highest current sequence number + for (int i = 0; i < bunds.length; i++) + { + Bitstream[] streams = bunds[i].getBitstreams(); + for (int k = 0; k < streams.length; k++) + { + if (streams[k].getSequenceID() > sequence) + { + sequence = streams[k].getSequenceID(); + } + } + } + + // start sequencing bitstreams without sequence IDs + sequence++; + for (int i = 0; i < bunds.length; i++) + { + Bitstream[] streams = bunds[i].getBitstreams(); + for (int k = 0; k < streams.length; k++) + { + if (streams[k].getSequenceID() < 0) + { + streams[k].setSequenceID(sequence); + sequence++; + streams[k].update(); + } + } + } + // Make sure that withdrawn and in_archive are non-null if (itemRow.isColumnNull("in_archive")) {