Code Search for Developers
 
 
  

BitstreamServlet.java from DSpace at Krugle


Show BitstreamServlet.java syntax highlighted

/*
 * BitstreamServlet.java
 *
 * Version: $Revision: 2073 $
 *
 * Date: $Date: 2007-07-19 09:45:10 -0700 (Thu, 19 Jul 2007) $
 *
 * Copyright (c) 2002-2005, 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.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.internet.MimeUtility;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
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.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.DSpaceObject;
import org.dspace.content.Item;
import org.dspace.core.ConfigurationManager;
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. If
 * there is an <code>If-Modified-Since</code> header, only a 304 status code
 * is returned if the containing item has not been modified since that date.
 * <P>
 * <code>/bitstream/handle/sequence_id/filename</code>
 * 
 * @author Robert Tansley
 * @version $Revision: 2073 $
 */
public class BitstreamServlet extends DSpaceServlet
{
    /** log4j category */
    private static Logger log = Logger.getLogger(BitstreamServlet.class);

    /**
     * Threshold on Bitstream size before content-disposition will be set.
     */
    private int threshold;
    
	/**
	 * Pattern used to get file.ext from filename (which can be a path)
	 */
	private static Pattern p = Pattern.compile("[^/]*$");

    @Override
	public void init(ServletConfig arg0) throws ServletException {

		super.init(arg0);
		threshold = ConfigurationManager
				.getIntProperty("webui.content_disposition_threshold");
	}

    @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
        // 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();
    }
	
	/**
	 * Evaluate filename and client and encode appropriate disposition
	 * 
	 * @param uri
	 * @param request
	 * @param response
	 * @throws UnsupportedEncodingException
	 */
	private void setBitstreamDisposition(String filename, HttpServletRequest request,
			HttpServletResponse response)
	{
		
		String name = filename;
		
		Matcher m = p.matcher(name);
		
		if (m.find() && !m.group().equals(""))
		{
			name = m.group();
		}

		try 
		{
			String agent = request.getHeader("USER-AGENT");

			if (null != agent && -1 != agent.indexOf("MSIE")) 
			{
				name = URLEncoder.encode(name, "UTF8");
			} 
			else if (null != agent && -1 != agent.indexOf("Mozilla")) 
			{
				name = MimeUtility.encodeText(name, "UTF8", "B");
			} 

		} 
		catch (UnsupportedEncodingException e) 
		{
			log.error(e.getMessage(),e);
		}
		finally
		{
			response.setHeader("Content-Disposition", "attachment;filename=" + name);
		}
		
		
	}
}




See more files for this project here

DSpace

Open Source Digital Asset Management system that enables services for access, provision, stewardship and re-use of digital assets with a focus on educational and research materials

Project homepage: http://sourceforge.net/projects/dspace
Programming language(s): Java,JSP,XML
License: other

  admin/
    AuthorizeAdminServlet.java
    BitstreamFormatRegistry.java
    CollectionWizardServlet.java
    EPersonAdminServlet.java
    EPersonListServlet.java
    EditCommunitiesServlet.java
    EditItemServlet.java
    GroupEditServlet.java
    GroupListServlet.java
    ItemMapServlet.java
    LicenseEditServlet.java
    MetadataFieldRegistryServlet.java
    MetadataSchemaRegistryServlet.java
    NewsEditServlet.java
    SuperviseServlet.java
    WithdrawnBrowserServlet.java
    WorkflowAbortServlet.java
  AbstractBrowserServlet.java
  AdvancedSearchServlet.java
  BitstreamServlet.java
  BrowserServlet.java
  CommunityListServlet.java
  ControlledVocabularySearchServlet.java
  ControlledVocabularyServlet.java
  DSpaceServlet.java
  EditProfileServlet.java
  FeedServlet.java
  FeedbackServlet.java
  HTMLServlet.java
  HandleServlet.java
  InternalErrorServlet.java
  LDAPServlet.java
  LoadDSpaceConfig.java
  LogoutServlet.java
  MyDSpaceServlet.java
  OpenURLServlet.java
  PasswordServlet.java
  RegisterServlet.java
  RetrieveServlet.java
  SimpleSearchServlet.java
  SitemapServlet.java
  StatisticsServlet.java
  SubmissionController.java
  SubscribeServlet.java
  SuggestServlet.java
  ViewWorkspaceItemServlet.java
  WorkspaceServlet.java