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 { 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); } }
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); } }
protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { // We will resolve the HTTP request parameters into a scope BrowseScope scope = new BrowseScope(context); // Will need to know whether to highlight the "focus" point boolean highlight = false; // Build up log information String logInfo = ""; // For browse by date, we'll need to work out the URL query string to // use when the user swaps the ordering, so that they stay at the same // point in the index String flipOrderingQuery = ""; // Grab HTTP request parameters String focus = request.getParameter("focus"); String startsWith = request.getParameter("starts_with"); String top = request.getParameter("top"); String bottom = request.getParameter("bottom"); // The following three are specific to browsing items by date String month = request.getParameter("month"); String year = request.getParameter("year"); String order = request.getParameter("order"); // For browse by date: oldest item first? boolean oldestFirst = false; if ((order != null) && order.equalsIgnoreCase("oldestfirst")) { oldestFirst = true; } if (browseDates && (year != null) && !year.equals("") && ((startsWith == null) || startsWith.equals(""))) { // We're browsing items by date, the user hasn't typed anything // into the "year" text box, and they've selected a year from // the drop-down list. From this we work out where to start // the browse. startsWith = year; if ((month != null) & !month.equals("-1")) { // They've selected a month as well if (month.length() == 1) { // Ensure double-digit month number month = "0" + month; } startsWith = year + "-" + month; } } // Set the scope according to the parameters passed in if (focus != null) { // ---------------------------------------------- // Browse should start at a specified focus point // ---------------------------------------------- if (browseAuthors || browseSubjects) { // For browsing authors, focus is just a text value scope.setFocus(focus); } else { // For browsing items by title or date, focus is a Handle Item item = (Item) HandleManager.resolveToObject(context, focus); if (item == null) { // Handle is invalid one. Show an error. JSPManager.showInvalidIDError(request, response, focus, Constants.ITEM); return; } scope.setFocus(item); } // Will need to highlight the focus highlight = true; logInfo = "focus=" + focus + ","; if (browseDates) { // if the date order is flipped, we'll keep the same focus flipOrderingQuery = "focus=" + URLEncoder.encode(focus, Constants.DEFAULT_ENCODING) + "&"; } } else if (startsWith != null) { // ---------------------------------------------- // Start the browse using user-specified text // ---------------------------------------------- if (browseDates) { // if the date order is flipped, we'll keep the same focus flipOrderingQuery = "starts_with=" + URLEncoder.encode(startsWith, Constants.DEFAULT_ENCODING) + "&"; /* * When the user is browsing with the most recent items first, * the browse code algorithm doesn't quite do what some people * might expect. For example, if in the index there are entries: * * Mar-2000 15-Feb-2000 6-Feb-2000 15-Jan-2000 * * and the user has selected "Feb 2000" as the start point for * the browse, the browse algorithm will start at the first * point in that index *after* "Feb 2000". "Feb 2000" would * appear in the index above between 6-Feb-2000 and 15-Jan-2000. * So, the browse code in this case will start the browse at * "15-Jan-2000". This isn't really what users are likely to * want: They're more likely to want the browse to start at the * first Feb 2000 date, i.e. 15-Feb-2000. A similar scenario * occurs when the user enters just a year. Our quick hack to * produce this behaviour is to add "-32" to the startsWith * variable, when sorting with most recent items first. This * means the browse code starts at the topmost item in the index * that matches the user's input, rather than the point in the * index where the user's input would appear. */ if (!oldestFirst) { startsWith = startsWith + "-32"; } } scope.setFocus(startsWith); highlight = true; logInfo = "starts_with=" + startsWith + ","; } else if ((top != null) || (bottom != null)) { // ---------------------------------------------- // Paginating: put specified entry at top or bottom // ---------------------------------------------- // Use a single value and a boolean to simplify the code below String val = bottom; boolean isTop = false; if (top != null) { val = top; isTop = true; } if (browseAuthors || browseSubjects) { // Value will be a text value for author browse scope.setFocus(val); } else { // Value is Handle if we're browsing items by title or date Item item = (Item) HandleManager.resolveToObject(context, val); if (item == null) { // Handle is invalid one. Show an error. JSPManager.showInvalidIDError(request, response, focus, Constants.ITEM); return; } scope.setFocus(item); } // This entry appears at the top or bottom, and so needs to have // 0 or 20 entries shown before it scope.setNumberBefore(isTop ? 0 : 20); logInfo = (isTop ? "top" : "bottom") + "=" + val + ","; if (browseDates) { // If the date order is flipped, we'll flip the table upside // down - i.e. the top will become the bottom and the bottom // the top. if (top != null) { flipOrderingQuery = "bottom=" + URLEncoder.encode(top, Constants.DEFAULT_ENCODING) + "&"; } else { flipOrderingQuery = "top=" + URLEncoder.encode(bottom, Constants.DEFAULT_ENCODING) + "&"; } } } // ---------------------------------------------- // If none of the above apply, no positioning parameters // set - use start of index // ---------------------------------------------- // Are we in a community or collection? Community community = UIUtil.getCommunityLocation(request); Collection collection = UIUtil.getCollectionLocation(request); if (collection != null) { logInfo = logInfo + ",collection_id=" + collection.getID() + ","; scope.setScope(collection); } else if (community != null) { logInfo = logInfo + ",community_id=" + community.getID() + ","; scope.setScope(community); } BrowseInfo browseInfo; try { // Query the browse index if (browseAuthors) { browseInfo = Browse.getAuthors(scope); } else if (browseDates) { browseInfo = Browse.getItemsByDate(scope, oldestFirst); } else if (browseSubjects) { browseInfo = Browse.getSubjects(scope); } else { browseInfo = Browse.getItemsByTitle(scope); } } catch (SQLException sqle) { // An invalid scope was given JSPManager.showIntegrityError(request, response); return; } // Write log entry String what = "title"; if (browseAuthors) { what = "author"; } else if (browseSubjects) { what = "subject"; } else if (browseDates) { what = "date"; } log.info( LogManager.getHeader( context, "browse_" + what, logInfo + "results=" + browseInfo.getResultCount())); if (browseInfo.getResultCount() == 0) { // No results! request.setAttribute("community", community); request.setAttribute("collection", collection); JSPManager.showJSP(request, response, "/browse/no-results.jsp"); } else { // Work out what the query strings will be for the previous // and next pages if (!browseInfo.isFirst()) { // Not the first page, so we'll need a "previous page" button // The top entry of the current page becomes the bottom // entry of the "previous page" String s; if (browseAuthors || browseSubjects) // aneesh { s = (browseInfo.getStringResults())[0]; } else { Item firstItem = (browseInfo.getItemResults())[0]; s = firstItem.getHandle(); } if (browseDates && oldestFirst) { // For browsing by date, oldest first, we need // to add the ordering parameter request.setAttribute( "previous.query", "order=oldestfirst&bottom=" + URLEncoder.encode(s, Constants.DEFAULT_ENCODING)); } else { request.setAttribute( "previous.query", "bottom=" + URLEncoder.encode(s, Constants.DEFAULT_ENCODING)); } } if (!browseInfo.isLast()) { // Not the last page, so we'll need a "next page" button // The bottom entry of the current page will be the top // entry in the next page String s; if (browseAuthors) { String[] authors = browseInfo.getStringResults(); s = authors[authors.length - 1]; } else if (browseSubjects) { String[] subjects = browseInfo.getStringResults(); s = subjects[subjects.length - 1]; } else { Item[] items = browseInfo.getItemResults(); Item lastItem = items[items.length - 1]; s = lastItem.getHandle(); } if (browseDates && oldestFirst) { // For browsing by date, oldest first, we need // to add the ordering parameter request.setAttribute( "next.query", "order=oldestfirst&top=" + URLEncoder.encode(s, Constants.DEFAULT_ENCODING)); } else { request.setAttribute( "next.query", "top=" + URLEncoder.encode(s, Constants.DEFAULT_ENCODING)); } } // Set appropriate attributes and forward to results page request.setAttribute("community", community); request.setAttribute("collection", collection); request.setAttribute("browse.info", browseInfo); request.setAttribute("highlight", new Boolean(highlight)); if (browseAuthors) { JSPManager.showJSP(request, response, "/browse/authors.jsp"); } else if (browseSubjects) { JSPManager.showJSP(request, response, "/browse/subjects.jsp"); } else if (browseDates) { request.setAttribute("oldest.first", new Boolean(oldestFirst)); request.setAttribute("flip.ordering.query", flipOrderingQuery); JSPManager.showJSP(request, response, "/browse/items-by-date.jsp"); } else { JSPManager.showJSP(request, response, "/browse/items-by-title.jsp"); } } }
protected void doDSGet(Context context, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, SQLException, AuthorizeException { ExternalIdentifierDAO identifierDAO = ExternalIdentifierDAOFactory.getInstance(context); // Obtain information from request String uri = request.getParameter("uri"); ExternalIdentifier identifier = identifierDAO.retrieve(uri); ObjectIdentifier oi = identifier.getObjectIdentifier(); // Lookup Item title & collection Item item = null; String link = ""; String title = null; String collName = null; if (identifier != null) { item = (Item) oi.getObject(context); link = item.getIdentifier().getURL().toString(); request.setAttribute("link", link); if (item != null) { DCValue[] titleDC = item.getDC("title", null, Item.ANY); if (titleDC != null || titleDC.length > 0) { title = titleDC[0].value; } Collection[] colls = item.getCollections(); collName = colls[0].getMetadata("name"); } } else { String path = request.getPathInfo(); log.info(LogManager.getHeader(context, "invalid_id", "path=" + path)); JSPManager.showInvalidIDError(request, response, path, -1); return; } if (title == null) { title = ""; } if (collName == null) { collName = ""; } request.setAttribute("suggest.title", title); // User email from context EPerson currentUser = context.getCurrentUser(); String authEmail = null; String userName = null; if (currentUser != null) { authEmail = currentUser.getEmail(); userName = currentUser.getFullName(); } if (request.getParameter("submit") != null) { String recipAddr = request.getParameter("recip_email"); // the only required field is recipient email address if (recipAddr == null || recipAddr.equals("")) { log.info(LogManager.getHeader(context, "show_suggest_form", "problem=true")); request.setAttribute("suggest.problem", new Boolean(true)); JSPManager.showJSP(request, response, "/suggest/suggest.jsp"); return; } String recipName = request.getParameter("recip_name"); if (recipName == null || "".equals(recipName)) { try { recipName = I18nUtil.getMessage("org.dspace.app.webui.servlet.SuggestServlet.recipient", context); } catch (MissingResourceException e) { log.warn( LogManager.getHeader( context, "show_suggest_form", "Missing Resource: org.dspace.app.webui.servlet.SuggestServlet.sender")); recipName = "colleague"; } } String senderName = request.getParameter("sender_name"); if (senderName == null || "".equals(senderName)) { // use userName if available if (userName != null) { senderName = userName; } else { try { senderName = I18nUtil.getMessage("org.dspace.app.webui.servlet.SuggestServlet.sender", context); } catch (MissingResourceException e) { log.warn( LogManager.getHeader( context, "show_suggest_form", "Missing Resource: org.dspace.app.webui.servlet.SuggestServlet.sender")); senderName = "A DSpace User"; } } } String senderAddr = request.getParameter("sender_email"); if (senderAddr == null || "".equals(senderAddr)) { // use authEmail if available if (authEmail != null) { senderAddr = authEmail; } } String itemUri = identifier.getURI().toString(); String message = request.getParameter("message"); String siteName = ConfigurationManager.getProperty("dspace.name"); // All data is there, send the email try { Email email = ConfigurationManager.getEmail( I18nUtil.getEmailFilename(context.getCurrentLocale(), "suggest")); email.addRecipient(recipAddr); // recipient address email.addArgument(recipName); // 1st arg - recipient name email.addArgument(senderName); // 2nd arg - sender name email.addArgument(siteName); // 3rd arg - repository name email.addArgument(title); // 4th arg - item title email.addArgument(itemUri); // 5th arg - item identifier URI email.addArgument(link); // 6th arg - item local URL email.addArgument(collName); // 7th arg - collection name email.addArgument(message); // 8th arg - user comments // Set sender's address as 'reply-to' address if supplied if (senderAddr != null && !"".equals(senderAddr)) { email.setReplyTo(senderAddr); } // Only actually send the email if feature is enabled if (ConfigurationManager.getBooleanProperty("webui.suggest.enable", false)) { email.send(); } else { throw new MessagingException( "Suggest item email not sent - webui.suggest.enable = false"); } log.info(LogManager.getHeader(context, "sent_suggest", "from=" + senderAddr)); JSPManager.showJSP(request, response, "/suggest/suggest_ok.jsp"); } catch (MessagingException me) { log.warn(LogManager.getHeader(context, "error_mailing_suggest", ""), me); JSPManager.showInternalError(request, response); } } else { // Display suggest form log.info(LogManager.getHeader(context, "show_suggest_form", "problem=false")); request.setAttribute("authenticated.email", authEmail); request.setAttribute("eperson.name", userName); JSPManager.showJSP(request, response, "/suggest/suggest.jsp"); // asd } }
@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(); }