View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.control;
16  
17  import javax.servlet.ServletException;
18  import javax.servlet.UnavailableException;
19  import javax.servlet.http.HttpServlet;
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.OutputStream;
26  import java.io.FileInputStream;
27  import java.io.BufferedInputStream;
28  import java.util.zip.GZIPOutputStream;
29  /**
30   * Servlet that allows to download a file which full UNC path is put
31   * into to the query parameters ("path" denotes the directory and "file"
32   * short name of file itself).
33   * @author  <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
34   * @version $Revision: 1.2 $
35   */
36  public class DownloadServlet extends HttpServlet{
37     
38     // Attributes ---------------------------------------------------------------
39     
40     /** URL to redirect to in case the specified file does not exists. */
41     protected String notExistsURL;
42     /** URL to redirect to in case the specified file is not readable. */
43     protected String notReadableURL;
44     
45     
46     // Override of HttpServlet --------------------------------------------------
47     
48     /**
49      * Override of default init() method. Call super.init() and then retrieve
50      * and store servlet parameters.
51      * @throws ServletException if one init parameter is missing
52      */
53     public void init() throws ServletException{
54        // Make sure to always call the super's init() first.
55        super.init();
56        
57        // Retrieve servlet init parameters and check them.
58        notExistsURL = getInitParameter("file.doesnot.exists.url");
59        notReadableURL = getInitParameter("file.is.not.readable.url");
60        
61        if (notExistsURL == null || notExistsURL.length() == 0)
62           throw new UnavailableException("The file.doesnot.exists.url parameter is mandatory");
63        if (notReadableURL == null || notReadableURL.length() == 0)
64           throw new UnavailableException("The file.is.not.readable.url parameter is mandatory");
65     }
66     
67     /**
68      * Override of default <code>doGet()</code> method: just call the protected
69      * <code>downloadFile()</code> method, passing around request and response.
70      * @param request The http request (containing query string specifying file)
71      * @param response Thee http response (for writing ouput)
72      * @throws IOException if requested file cannot be opened or written to response
73      * @throws ServletException in any other exception case
74      */
75     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
76        // Just call downloadFile() ...
77        downloadFile(request, response);
78     }
79     
80     
81     // Protected ----------------------------------------------------------------
82     
83     /**
84      * Retrieve the file to download path from query string. Make some
85      * check (non null, existence, readability) before dumping the file
86      * into ouputstream. If gzip encoding is supported, wrap the dump into
87      * a GZIPOutputStream to save bandwidth ...
88      * @param request The http request (containing parameters specifying file)
89      * @param response Thee http response (for writing ouput)
90      * @throws IOException if outputstream cannot be opened or written
91      */
92     protected void downloadFile(HttpServletRequest request, HttpServletResponse response) throws IOException{
93        // Retrieve file path.
94        String pathStr = request.getParameter("path");
95        String fileStr = request.getParameter("file");
96        
97        if (pathStr != null && pathStr.length() > 0
98                && fileStr != null && fileStr.length() > 0){
99           // Build the file object corresponding.
100          File file = new File(pathStr, fileStr);
101          
102          if (file.exists()){
103             if (file.canRead()){
104                // Get file name and encoding.
105                String name = file.getName();
106                String encoding = request.getHeader("Accept-Encoding");
107                
108                if (encoding != null && encoding.indexOf("gzip") != -1){
109                   response.setHeader("Content-Encoding", "gzip");
110                   response.setHeader("Content-Disposition", "attachment;filename=\"" + name + "\"");
111                   GZIPOutputStream os = new GZIPOutputStream(response.getOutputStream());
112                   dumpFile(file, os);
113                }
114                else{
115                   response.setContentType("application/octet-stream");
116                   response.setHeader("Content-Disposition", "attachment;filename=\"" + name + "\"");
117                   dumpFile(file, response.getOutputStream());
118                }
119             }
120             else response.sendRedirect(request.getContextPath() + notReadableURL);
121          }
122          else response.sendRedirect(request.getContextPath() + notExistsURL);
123       }
124    }
125    
126    /**
127     * Dump a file content into the given ouput stream.
128     * Best efforts are made to cleanly flush & close input and ouput streams.
129     * @param file The file to dump
130     * @param os The ouput stream to dump in
131     */
132    protected void dumpFile(File file, OutputStream os){
133       // Prepare materials.
134       int i;
135       byte[] bytes = new byte[4096];
136       BufferedInputStream is = null;
137       
138       try{
139          is = new BufferedInputStream(new FileInputStream(file));
140          while((i = is.read(bytes, 0, 4096)) != -1)
141             os.write(bytes, 0, i);
142       }
143       catch (Exception e){
144          // Nothing to do here...
145       }
146       finally{
147          // Try closing input & output streams.
148          try {is.close();}
149          catch (Exception ee) {/* Do nothing here... */}
150          try {os.flush(); os.close();}
151          catch (Exception ee) {/* Do nothing here... */}
152       }
153    }
154 }