%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.turbine.util.upload.FileItem |
|
|
1 | package org.apache.turbine.util.upload; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-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 | import java.io.BufferedInputStream; |
|
20 | import java.io.BufferedOutputStream; |
|
21 | import java.io.ByteArrayInputStream; |
|
22 | import java.io.ByteArrayOutputStream; |
|
23 | import java.io.File; |
|
24 | import java.io.FileInputStream; |
|
25 | import java.io.FileOutputStream; |
|
26 | import java.io.IOException; |
|
27 | import java.io.InputStream; |
|
28 | import java.io.OutputStream; |
|
29 | import java.io.UnsupportedEncodingException; |
|
30 | import javax.activation.DataSource; |
|
31 | ||
32 | import org.apache.turbine.services.uniqueid.TurbineUniqueId; |
|
33 | import org.apache.turbine.services.upload.TurbineUpload; |
|
34 | ||
35 | /** |
|
36 | * <p> This class represents a file that was received by Turbine using |
|
37 | * <code>multipart/form-data</code> POST request. |
|
38 | * |
|
39 | * <p> After retrieving an instance of this class from the {@link |
|
40 | * org.apache.turbine.util.ParameterParser ParameterParser} (see |
|
41 | * {@link org.apache.turbine.util.ParameterParser#getFileItem(String) |
|
42 | * ParameterParser.getFileItem(String)} and {@link |
|
43 | * org.apache.turbine.util.ParameterParser#getFileItems(String) |
|
44 | * ParameterParser.getFileItems(String)}) you can use it to acces the |
|
45 | * data that was sent by the browser. You may either request all |
|
46 | * contents of file at once using {@link #get()} or request an {@link |
|
47 | * java.io.InputStream InputStream} with {@link #getStream()} and |
|
48 | * process the file without attempting to load it into memory, which |
|
49 | * may come handy with large files. |
|
50 | * |
|
51 | * Implements the javax.activation.DataSource interface (which allows |
|
52 | * for example the adding of a FileItem as an attachment to a multipart |
|
53 | * email). |
|
54 | * |
|
55 | * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a> |
|
56 | * @author <a href="mailto:sean@informage.net">Sean Legassick</a> |
|
57 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> |
|
58 | * @version $Id: FileItem.java 264148 2005-08-29 14:21:04Z henning $ |
|
59 | * @deprecated use commons-fileupload instead |
|
60 | */ |
|
61 | public class FileItem implements DataSource |
|
62 | { |
|
63 | /** |
|
64 | * The maximal size of request that will have it's elements stored |
|
65 | * in memory. |
|
66 | */ |
|
67 | public static final int DEFAULT_UPLOAD_SIZE_THRESHOLD = 10240; |
|
68 | ||
69 | /** The original filename in the user's filesystem. */ |
|
70 | protected String fileName; |
|
71 | ||
72 | /** |
|
73 | * The content type passed by the browser or <code>null</code> if |
|
74 | * not defined. |
|
75 | */ |
|
76 | protected String contentType; |
|
77 | ||
78 | /** Cached contents of the file. */ |
|
79 | protected byte[] content; |
|
80 | ||
81 | /** Temporary storage location. */ |
|
82 | protected File storeLocation; |
|
83 | ||
84 | /** Temporary storage for in-memory files. */ |
|
85 | protected ByteArrayOutputStream byteStream; |
|
86 | ||
87 | /** |
|
88 | * Constructs a new <code>FileItem</code>. |
|
89 | * |
|
90 | * <p>Use {@link #newInstance(String,String,String,int)} to |
|
91 | * instantiate <code>FileItems</code>. |
|
92 | * |
|
93 | * @param fileName The original filename in the user's filesystem. |
|
94 | * @param contentType The content type passed by the browser or |
|
95 | * <code>null</code> if not defined. |
|
96 | */ |
|
97 | protected FileItem(String fileName, String contentType) |
|
98 | 0 | { |
99 | 0 | this.fileName = fileName; |
100 | 0 | this.contentType = contentType; |
101 | 0 | } |
102 | ||
103 | /** |
|
104 | * Returns the original filename in the user's filesystem. |
|
105 | * (implements DataSource method) |
|
106 | * |
|
107 | * @return The original filename in the user's filesystem. |
|
108 | */ |
|
109 | public String getName() |
|
110 | { |
|
111 | 0 | return getFileName(); |
112 | } |
|
113 | ||
114 | /** |
|
115 | * Returns the original filename in the user's filesystem. |
|
116 | * |
|
117 | * @return The original filename in the user's filesystem. |
|
118 | */ |
|
119 | public String getFileName() |
|
120 | { |
|
121 | 0 | return fileName; |
122 | } |
|
123 | ||
124 | /** |
|
125 | * Returns the content type passed by the browser or |
|
126 | * <code>null</code> if not defined. (implements |
|
127 | * DataSource method). |
|
128 | * |
|
129 | * @return The content type passed by the browser or |
|
130 | * <code>null</code> if not defined. |
|
131 | */ |
|
132 | public String getContentType() |
|
133 | { |
|
134 | 0 | return contentType; |
135 | } |
|
136 | ||
137 | /** |
|
138 | * Provides a hint if the file contents will be read from memory. |
|
139 | * |
|
140 | * @return <code>True</code> if the file contents will be read |
|
141 | * from memory. |
|
142 | */ |
|
143 | public boolean inMemory() |
|
144 | { |
|
145 | 0 | return (content != null || byteStream != class="keyword">null); |
146 | } |
|
147 | ||
148 | /** |
|
149 | * Returns the size of the file. |
|
150 | * |
|
151 | * @return The size of the file. |
|
152 | */ |
|
153 | public long getSize() |
|
154 | { |
|
155 | 0 | if (storeLocation != null) |
156 | { |
|
157 | 0 | return storeLocation.length(); |
158 | } |
|
159 | 0 | else if (byteStream != null) |
160 | { |
|
161 | 0 | return byteStream.size(); |
162 | } |
|
163 | else |
|
164 | { |
|
165 | 0 | return content.length; |
166 | } |
|
167 | } |
|
168 | ||
169 | /** |
|
170 | * Returns the contents of the file as an array of bytes. If the |
|
171 | * contents of the file were not yet cached int the memory, they |
|
172 | * will be loaded from the disk storage and chached. |
|
173 | * |
|
174 | * @return The contents of the file as an array of bytes. |
|
175 | */ |
|
176 | public byte[] get() |
|
177 | { |
|
178 | 0 | if (content == null) |
179 | { |
|
180 | 0 | if (storeLocation != null) |
181 | { |
|
182 | 0 | content = new byte[(int) getSize()]; |
183 | try |
|
184 | { |
|
185 | 0 | FileInputStream fis = new FileInputStream(storeLocation); |
186 | 0 | fis.read(content); |
187 | } |
|
188 | 0 | catch (Exception e) |
189 | { |
|
190 | 0 | content = null; |
191 | 0 | } |
192 | } |
|
193 | else |
|
194 | { |
|
195 | 0 | content = byteStream.toByteArray(); |
196 | 0 | byteStream = null; |
197 | } |
|
198 | } |
|
199 | 0 | return content; |
200 | } |
|
201 | ||
202 | /** |
|
203 | * Returns the contents of the file as a String, using default |
|
204 | * encoding. This method uses {@link #get()} to retrieve the |
|
205 | * contents of the file. |
|
206 | * |
|
207 | * @return The contents of the file. |
|
208 | */ |
|
209 | public String getString() |
|
210 | { |
|
211 | 0 | return new String(get()); |
212 | } |
|
213 | ||
214 | /** |
|
215 | * Returns the contents of the file as a String, using specified |
|
216 | * encoding. This method uses {@link #get()} to retireve the |
|
217 | * contents of the file.<br> |
|
218 | * |
|
219 | * @param encoding The encoding to use. |
|
220 | * @return The contents of the file. |
|
221 | * @exception UnsupportedEncodingException. |
|
222 | */ |
|
223 | public String getString(String encoding) |
|
224 | throws UnsupportedEncodingException |
|
225 | { |
|
226 | 0 | return new String(get(), encoding); |
227 | } |
|
228 | ||
229 | /** |
|
230 | * Returns an {@link java.io.InputStream InputStream} that can be |
|
231 | * used to retrieve the contents of the file. (implements DataSource |
|
232 | * method) |
|
233 | * |
|
234 | * @return An {@link java.io.InputStream InputStream} that can be |
|
235 | * used to retrieve the contents of the file. |
|
236 | * @exception Exception, a generic exception. |
|
237 | */ |
|
238 | public InputStream getInputStream() |
|
239 | throws IOException |
|
240 | { |
|
241 | 0 | return getStream(); |
242 | } |
|
243 | ||
244 | /** |
|
245 | * Returns an {@link java.io.InputStream InputStream} that can be |
|
246 | * used to retrieve the contents of the file. |
|
247 | * |
|
248 | * @return An {@link java.io.InputStream InputStream} that can be |
|
249 | * used to retrieve the contents of the file. |
|
250 | * @exception Exception, a generic exception. |
|
251 | */ |
|
252 | public InputStream getStream() |
|
253 | throws IOException |
|
254 | { |
|
255 | 0 | if (content == null) |
256 | { |
|
257 | 0 | if (storeLocation != null) |
258 | { |
|
259 | 0 | return new FileInputStream(storeLocation); |
260 | } |
|
261 | else |
|
262 | { |
|
263 | 0 | content = byteStream.toByteArray(); |
264 | 0 | byteStream = null; |
265 | } |
|
266 | } |
|
267 | 0 | return new ByteArrayInputStream(content); |
268 | } |
|
269 | ||
270 | /** |
|
271 | * Returns the {@link java.io.File} objects for the FileItems's |
|
272 | * data temporary location on the disk. Note that for |
|
273 | * <code>FileItems</code> that have their data stored in memory |
|
274 | * this method will return <code>null</code>. When handling large |
|
275 | * files, you can use {@link java.io.File#renameTo(File)} to |
|
276 | * move the file to new location without copying the data, if the |
|
277 | * source and destination locations reside within the same logical |
|
278 | * volume. |
|
279 | * |
|
280 | * @return A File. |
|
281 | */ |
|
282 | public File getStoreLocation() |
|
283 | { |
|
284 | 0 | return storeLocation; |
285 | } |
|
286 | ||
287 | /** |
|
288 | * Removes the file contents from the temporary storage. |
|
289 | */ |
|
290 | protected void finalize() |
|
291 | { |
|
292 | 0 | if (storeLocation != null && storeLocation.exists()) |
293 | { |
|
294 | 0 | storeLocation.delete(); |
295 | } |
|
296 | 0 | } |
297 | ||
298 | /** |
|
299 | * Returns an {@link java.io.OutputStream OutputStream} that can |
|
300 | * be used for storing the contents of the file. |
|
301 | * (implements DataSource method) |
|
302 | * |
|
303 | * @return an {@link java.io.OutputStream OutputStream} that can be |
|
304 | * used for storing the contensts of the file. |
|
305 | * @exception IOException. |
|
306 | */ |
|
307 | public OutputStream getOutputStream() |
|
308 | throws IOException |
|
309 | { |
|
310 | 0 | if (storeLocation == null) |
311 | { |
|
312 | 0 | return byteStream; |
313 | } |
|
314 | else |
|
315 | { |
|
316 | 0 | return new FileOutputStream(storeLocation); |
317 | } |
|
318 | } |
|
319 | ||
320 | /** |
|
321 | * Instantiates a FileItem. It uses <code>requestSize</code> to |
|
322 | * decide what temporary storage approach the new item should |
|
323 | * take. The largest request that will have its items cached in |
|
324 | * memory can be configured in |
|
325 | * <code>TurbineResources.properties</code> in the entry named |
|
326 | * <code>file.upload.size.threshold</code> |
|
327 | * |
|
328 | * @param path A String. |
|
329 | * @param name The original filename in the user's filesystem. |
|
330 | * @param contentType The content type passed by the browser or |
|
331 | * <code>null</code> if not defined. |
|
332 | * @param requestSize The total size of the POST request this item |
|
333 | * belongs to. |
|
334 | * @return A FileItem. |
|
335 | */ |
|
336 | public static FileItem newInstance(String path, |
|
337 | String name, |
|
338 | String contentType, |
|
339 | int requestSize) |
|
340 | { |
|
341 | 0 | FileItem item = new FileItem(name, contentType); |
342 | 0 | if (requestSize > TurbineUpload.getSizeThreshold()) |
343 | { |
|
344 | 0 | String instanceName = TurbineUniqueId.getInstanceId(); |
345 | 0 | String fileName = TurbineUniqueId.getUniqueId(); |
346 | 0 | fileName = instanceName + "_upload_" + fileName + ".tmp"; |
347 | 0 | fileName = path + "/" + fileName; |
348 | 0 | item.storeLocation = new File(fileName); |
349 | 0 | item.storeLocation.deleteOnExit(); |
350 | } |
|
351 | else |
|
352 | { |
|
353 | 0 | item.byteStream = new ByteArrayOutputStream(); |
354 | } |
|
355 | 0 | return item; |
356 | } |
|
357 | ||
358 | /** |
|
359 | * A convenience method to write an uploaded |
|
360 | * file to disk. The client code is not concerned |
|
361 | * whether or not the file is stored in memory, |
|
362 | * or on disk in a temporary location. They just |
|
363 | * want to write the uploaded file to disk. |
|
364 | * |
|
365 | * @param String full path to location where uploaded |
|
366 | * should be stored. |
|
367 | */ |
|
368 | public void write(String file) throws Exception |
|
369 | { |
|
370 | 0 | if (inMemory()) |
371 | { |
|
372 | 0 | FileOutputStream fout = null; |
373 | try |
|
374 | { |
|
375 | 0 | fout = new FileOutputStream(file); |
376 | 0 | fout.write(get()); |
377 | } |
|
378 | finally |
|
379 | { |
|
380 | 0 | if (fout != null) |
381 | { |
|
382 | 0 | fout.close(); |
383 | } |
|
384 | } |
|
385 | } |
|
386 | 0 | else if (storeLocation != null) |
387 | { |
|
388 | /* |
|
389 | * The uploaded file is being stored on disk |
|
390 | * in a temporary location so move it to the |
|
391 | * desired file. |
|
392 | */ |
|
393 | 0 | if (storeLocation.renameTo(new File(file)) == false) |
394 | { |
|
395 | 0 | BufferedInputStream in = null; |
396 | 0 | BufferedOutputStream out = null; |
397 | try |
|
398 | { |
|
399 | 0 | in = new BufferedInputStream( |
400 | new FileInputStream(storeLocation)); |
|
401 | 0 | out = new BufferedOutputStream(class="keyword">new FileOutputStream(file)); |
402 | 0 | byte[] bytes = new byte[2048]; |
403 | 0 | int s = 0; |
404 | 0 | while ((s = in.read(bytes)) != -1) |
405 | { |
|
406 | 0 | out.write(bytes, 0, s); |
407 | } |
|
408 | } |
|
409 | finally |
|
410 | { |
|
411 | 0 | try |
412 | { |
|
413 | 0 | in.close(); |
414 | } |
|
415 | 0 | catch (Exception e) |
416 | { |
|
417 | // ignore |
|
418 | 0 | } |
419 | try |
|
420 | { |
|
421 | 0 | out.close(); |
422 | } |
|
423 | 0 | catch (Exception e) |
424 | { |
|
425 | // ignore |
|
426 | 0 | } |
427 | 0 | } |
428 | } |
|
429 | } |
|
430 | else |
|
431 | { |
|
432 | /* |
|
433 | * For whatever reason we cannot write the |
|
434 | * file to disk. |
|
435 | */ |
|
436 | 0 | throw new Exception("Cannot write uploaded file to disk!"); |
437 | } |
|
438 | 0 | } |
439 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |