KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > oreilly > servlet > multipart > FilePart


1 // Copyright (C) 1999-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.
2
// All rights reserved. Use of this class is limited.
3
// Please see the LICENSE for more information.
4

5 package com.oreilly.servlet.multipart;
6
7 import java.io.File JavaDoc;
8 import java.io.InputStream JavaDoc;
9 import java.io.OutputStream JavaDoc;
10 import java.io.BufferedOutputStream JavaDoc;
11 import java.io.FileOutputStream JavaDoc;
12 import java.io.IOException JavaDoc;
13 import javax.servlet.ServletInputStream JavaDoc;
14
15 /**
16  * A <code>FilePart</code> is an upload part which represents a
17  * <code>INPUT TYPE="file"</code> form parameter. Note that because file
18  * upload data arrives via a single InputStream, each FilePart's contents
19  * must be read before moving onto the next part. Don't try to store a
20  * FilePart object for later processing because by then their content will
21  * have been passed by.
22  *
23  * @author Geoff Soutter
24  * @version 1.2, 2001/01/22, getFilePath() addition thanks to Stefan Eissing
25  * @version 1.1, 2000/11/26, writeTo() bug fix thanks to Mike Shivas
26  * @version 1.0, 2000/10/27, initial revision
27  */

28 public class FilePart extends Part {
29   
30   /** "file system" name of the file */
31   private String JavaDoc fileName;
32   
33   /** path of the file as sent in the request, if given */
34   private String JavaDoc filePath;
35
36   /** content type of the file */
37   private String JavaDoc contentType;
38   
39   /** input stream containing file data */
40   private PartInputStream partInput;
41     
42   /** file rename policy */
43   private FileRenamePolicy policy;
44
45   /**
46    * Construct a file part; this is called by the parser.
47    *
48    * @param name the name of the parameter.
49    * @param in the servlet input stream to read the file from.
50    * @param boundary the MIME boundary that delimits the end of file.
51    * @param contentType the content type of the file provided in the
52    * MIME header.
53    * @param fileName the file system name of the file provided in the
54    * MIME header.
55    * @param filePath the file system path of the file provided in the
56    * MIME header (as specified in disposition info).
57    *
58    * @exception IOException if an input or output exception has occurred.
59    */

60   FilePart(String JavaDoc name, ServletInputStream JavaDoc in, String JavaDoc boundary,
61            String JavaDoc contentType, String JavaDoc fileName, String JavaDoc filePath)
62                                                    throws IOException JavaDoc {
63     super(name);
64     this.fileName = fileName;
65     this.filePath = filePath;
66     this.contentType = contentType;
67     partInput = new PartInputStream(in, boundary);
68   }
69
70   /**
71    * Puts in place the specified policy for handling file name collisions.
72    */

73   public void setRenamePolicy(FileRenamePolicy policy) {
74     this.policy = policy;
75   }
76   
77   /**
78    * Returns the name that the file was stored with on the remote system,
79    * or <code>null</code> if the user didn't enter a file to be uploaded.
80    * Note: this is not the same as the name of the form parameter used to
81    * transmit the file; that is available from the <code>getName</code>
82    * method. Further note: if file rename logic is in effect, the file
83    * name can change during the writeTo() method when there's a collision
84    * with another file of the same name in the same directory. If this
85    * matters to you, be sure to pay attention to when you call the method.
86    *
87    * @return name of file uploaded or <code>null</code>.
88    *
89    * @see Part#getName()
90    */

91   public String JavaDoc getFileName() {
92     return fileName;
93   }
94
95   /**
96    * Returns the full path and name of the file on the remote system,
97    * or <code>null</code> if the user didn't enter a file to be uploaded.
98    * If path information was not supplied by the remote system, this method
99    * will return the same as <code>getFileName()</code>.
100    *
101    * @return path of file uploaded or <code>null</code>.
102    *
103    * @see Part#getName()
104    */

105   public String JavaDoc getFilePath() {
106     return filePath;
107   }
108
109   /**
110    * Returns the content type of the file data contained within.
111    *
112    * @return content type of the file data.
113    */

114   public String JavaDoc getContentType() {
115     return contentType;
116   }
117   
118   /**
119    * Returns an input stream which contains the contents of the
120    * file supplied. If the user didn't enter a file to upload
121    * there will be <code>0</code> bytes in the input stream.
122    * It's important to read the contents of the InputStream
123    * immediately and in full before proceeding to process the
124    * next part. The contents will otherwise be lost on moving
125    * to the next part.
126    *
127    * @return an input stream containing contents of file.
128    */

129   public InputStream JavaDoc getInputStream() {
130     return partInput;
131   }
132
133   /**
134    * Write this file part to a file or directory. If the user
135    * supplied a file, we write it to that file, and if they supplied
136    * a directory, we write it to that directory with the filename
137    * that accompanied it. If this part doesn't contain a file this
138    * method does nothing.
139    *
140    * @return number of bytes written
141    * @exception IOException if an input or output exception has occurred.
142    */

143   public long writeTo(File JavaDoc fileOrDirectory) throws IOException JavaDoc {
144     long written = 0;
145     
146     OutputStream JavaDoc fileOut = null;
147     try {
148       // Only do something if this part contains a file
149
if (fileName != null) {
150         // Check if user supplied directory
151
File JavaDoc file;
152         if (fileOrDirectory.isDirectory()) {
153           // Write it to that dir the user supplied,
154
// with the filename it arrived with
155
file = new File JavaDoc(fileOrDirectory, fileName);
156         }
157         else {
158           // Write it to the file the user supplied,
159
// ignoring the filename it arrived with
160
file = fileOrDirectory;
161         }
162         if (policy != null) {
163           file = policy.rename(file);
164           fileName = file.getName();
165         }
166         fileOut = new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(file));
167         written = write(fileOut);
168       }
169     }
170     finally {
171       if (fileOut != null) fileOut.close();
172     }
173     return written;
174   }
175
176   /**
177    * Write this file part to the given output stream. If this part doesn't
178    * contain a file this method does nothing.
179    *
180    * @return number of bytes written.
181    * @exception IOException if an input or output exception has occurred.
182    */

183   public long writeTo(OutputStream JavaDoc out) throws IOException JavaDoc {
184     long size=0;
185     // Only do something if this part contains a file
186
if (fileName != null) {
187       // Write it out
188
size = write( out );
189     }
190     return size;
191   }
192
193   /**
194    * Internal method to write this file part; doesn't check to see
195    * if it has contents first.
196    *
197    * @return number of bytes written.
198    * @exception IOException if an input or output exception has occurred.
199    */

200   long write(OutputStream JavaDoc out) throws IOException JavaDoc {
201     // decode macbinary if this was sent
202
if (contentType.equals("application/x-macbinary")) {
203       out = new MacBinaryDecoderOutputStream(out);
204     }
205     long size=0;
206     int read;
207     byte[] buf = new byte[8 * 1024];
208     while((read = partInput.read(buf)) != -1) {
209       out.write(buf, 0, read);
210       size += read;
211     }
212     return size;
213   }
214   
215   /**
216    * Returns <code>true</code> to indicate this part is a file.
217    *
218    * @return true.
219    */

220   public boolean isFile() {
221     return true;
222   }
223 }
224
Popular Tags