KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > struts > actions > DownloadAction


1 /*
2  * $Id: DownloadAction.java 164530 2005-04-25 03:11:07Z niallp $
3  *
4  * Copyright 2004-2005 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19
20 package org.apache.struts.actions;
21
22 import java.io.BufferedInputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.OutputStream JavaDoc;
28
29 import javax.servlet.ServletContext JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32
33 import org.apache.struts.action.Action;
34 import org.apache.struts.action.ActionForm;
35 import org.apache.struts.action.ActionForward;
36 import org.apache.struts.action.ActionMapping;
37
38
39 /**
40  * This is an abstract base class that minimizes the amount of special coding
41  * that needs to be written to download a file. All that is required to use
42  * this class is to extend it and implement the <code>getStreamInfo()</code>
43  * method so that it returns the relevant information for the file (or other
44  * stream) to be downloaded. Optionally, the <code>getBufferSize()</code>
45  * method may be overridden to customize the size of the buffer used to
46  * transfer the file.
47  *
48  * @since Struts 1.2.6
49  */

50 public abstract class DownloadAction extends Action {
51
52     /**
53      * If the <code>getBufferSize()</code> method is not overridden, this is
54      * the buffer size that will be used to transfer the data to the servlet
55      * output stream.
56      */

57     protected static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
58
59     /**
60      * Returns the information on the file, or other stream, to be downloaded
61      * by this action. This method must be implemented by an extending class.
62      *
63      * @param mapping The ActionMapping used to select this instance.
64      * @param form The optional ActionForm bean for this request (if any).
65      * @param request The HTTP request we are processing.
66      * @param response The HTTP response we are creating.
67      *
68      * @return The information for the file to be downloaded.
69      *
70      * @throws Exception if an exception occurs.
71      */

72     protected abstract StreamInfo getStreamInfo(ActionMapping mapping,
73             ActionForm form, HttpServletRequest JavaDoc request,
74             HttpServletResponse JavaDoc response)
75             throws Exception JavaDoc;
76
77     /**
78      * Returns the size of the buffer to be used in transferring the data to
79      * the servlet output stream. This method may be overridden by an extending
80      * class in order to customize the buffer size.
81      *
82      * @return The size of the transfer buffer, in bytes.
83      */

84     protected int getBufferSize() {
85         return DEFAULT_BUFFER_SIZE;
86     }
87
88     /**
89      * Process the specified HTTP request, and create the corresponding HTTP
90      * response (or forward to another web component that will create it).
91      * Return an <code>ActionForward</code> instance describing where and how
92      * control should be forwarded, or <code>null</code> if the response has
93      * already been completed.
94      *
95      * @param mapping The ActionMapping used to select this instance.
96      * @param form The optional ActionForm bean for this request (if any).
97      * @param request The HTTP request we are processing.
98      * @param response The HTTP response we are creating.
99      *
100      * @throws Exception if an exception occurs.
101      */

102     public ActionForward execute(ActionMapping mapping, ActionForm form,
103             HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
104             throws Exception JavaDoc {
105
106         StreamInfo info = getStreamInfo(mapping, form, request, response);
107         String JavaDoc contentType = info.getContentType();
108         InputStream JavaDoc stream = info.getInputStream();
109
110         try {
111             response.setContentType(contentType);
112             copy(stream, response.getOutputStream());
113         } finally {
114             if (stream != null) {
115                 stream.close();
116             }
117         }
118
119         // Tell Struts that we are done with the response.
120
return null;
121     }
122
123     /**
124      * Copy bytes from an <code>InputStream</code> to an
125      * <code>OutputStream</code>.
126      *
127      * @param input The <code>InputStream</code> to read from.
128      * @param output The <code>OutputStream</code> to write to.
129      *
130      * @return the number of bytes copied
131      *
132      * @throws IOException In case of an I/O problem
133      */

134     public int copy(InputStream JavaDoc input, OutputStream JavaDoc output)
135             throws IOException JavaDoc {
136         byte[] buffer = new byte[getBufferSize()];
137         int count = 0;
138         int n = 0;
139         while (-1 != (n = input.read(buffer))) {
140             output.write(buffer, 0, n);
141             count += n;
142         }
143         return count;
144     }
145
146     /**
147      * The information on a file, or other stream, to be downloaded by the
148      * <code>DownloadAction</code>.
149      */

150     public static interface StreamInfo {
151
152         /**
153          * Returns the content type of the stream to be downloaded.
154          *
155          * @return The content type of the stream.
156          */

157         public abstract String JavaDoc getContentType();
158
159         /**
160          * Returns an input stream on the content to be downloaded. This stream
161          * will be closed by the <code>DownloadAction</code>.
162          *
163          * @return The input stream for the content to be downloaded.
164          */

165         public abstract InputStream JavaDoc getInputStream() throws IOException JavaDoc;
166     }
167
168     /**
169      * A concrete implementation of the <code>StreamInfo</code> interface which
170      * simplifies the downloading of a file from the disk.
171      */

172     public static class FileStreamInfo implements StreamInfo {
173
174         /**
175          * The content type for this stream.
176          */

177         private String JavaDoc contentType;
178
179         /**
180          * The file to be downloaded.
181          */

182         private File JavaDoc file;
183
184         /**
185          * Constructs an instance of this class, based on the supplied
186          * parameters.
187          *
188          * @param contentType The content type of the file.
189          * @param file The file to be downloaded.
190          */

191         public FileStreamInfo(String JavaDoc contentType, File JavaDoc file) {
192             this.contentType = contentType;
193             this.file = file;
194         }
195
196         /**
197          * Returns the content type of the stream to be downloaded.
198          *
199          * @return The content type of the stream.
200          */

201         public String JavaDoc getContentType() {
202             return this.contentType;
203         }
204
205         /**
206          * Returns an input stream on the file to be downloaded. This stream
207          * will be closed by the <code>DownloadAction</code>.
208          *
209          * @return The input stream for the file to be downloaded.
210          */

211         public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
212             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(file);
213             BufferedInputStream JavaDoc bis = new BufferedInputStream JavaDoc(fis);
214             return bis;
215         }
216     }
217
218     /**
219      * A concrete implementation of the <code>StreamInfo</code> interface which
220      * simplifies the downloading of a web application resource.
221      */

222     public static class ResourceStreamInfo implements StreamInfo {
223
224         /**
225          * The content type for this stream.
226          */

227         private String JavaDoc contentType;
228
229         /**
230          * The servlet context for the resource to be downloaded.
231          */

232         private ServletContext JavaDoc context;
233
234         /**
235          * The path to the resource to be downloaded.
236          */

237         private String JavaDoc path;
238
239         /**
240          * Constructs an instance of this class, based on the supplied
241          * parameters.
242          *
243          * @param contentType The content type of the file.
244          * @param context The servlet context for the resource.
245          * @param path The path to the resource to be downloaded.
246          */

247         public ResourceStreamInfo(String JavaDoc contentType, ServletContext JavaDoc context,
248                 String JavaDoc path) {
249             this.contentType = contentType;
250             this.context = context;
251             this.path = path;
252         }
253
254         /**
255          * Returns the content type of the stream to be downloaded.
256          *
257          * @return The content type of the stream.
258          */

259         public String JavaDoc getContentType() {
260             return this.contentType;
261         }
262
263         /**
264          * Returns an input stream on the resource to be downloaded. This stream
265          * will be closed by the <code>DownloadAction</code>.
266          *
267          * @return The input stream for the resource to be downloaded.
268          */

269         public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
270             return context.getResourceAsStream(path);
271         }
272     }
273 }
274
Popular Tags