1 /*
2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.14.2.2 2004/01/27 20:56:05 olegk Exp $
3 * $Revision: 1.14.2.2 $
4 * $Date: 2004/01/27 20:56:05 $
5 *
6 * ====================================================================
7 *
8 * The Apache Software License, Version 1.1
9 *
10 * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
11 * reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
23 * distribution.
24 *
25 * 3. The end-user documentation included with the redistribution, if
26 * any, must include the following acknowlegement:
27 * "This product includes software developed by the
28 * Apache Software Foundation (http://www.apache.org/)."
29 * Alternately, this acknowlegement may appear in the software itself,
30 * if and wherever such third-party acknowlegements normally appear.
31 *
32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33 * Foundation" must not be used to endorse or promote products derived
34 * from this software without prior written permission. For written
35 * permission, please contact apache@apache.org.
36 *
37 * 5. Products derived from this software may not be called "Apache"
38 * nor may "Apache" appear in their names without prior written
39 * permission of the Apache Group.
40 *
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This software consists of voluntary contributions made by many
56 * individuals on behalf of the Apache Software Foundation. For more
57 * information on the Apache Software Foundation, please see
58 * <http://www.apache.org/>.
59 *
60 * [Additional notices, if required by prior licensing conditions]
61 *
62 */
63
64 package org.apache.commons.httpclient.methods.multipart;
65
66 import java.io.File;
67 import java.io.FileNotFoundException;
68 import java.io.IOException;
69 import java.io.InputStream;
70 import java.io.OutputStream;
71 import org.apache.commons.httpclient.HttpConstants;
72 import org.apache.commons.logging.Log;
73 import org.apache.commons.logging.LogFactory;
74
75 /***
76 * This class implements a part of a Multipart post object that
77 * consists of a file.
78 *
79 * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
80 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
81 * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
82 * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
83 * @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
84 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
85 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
86 *
87 * @since 2.0
88 *
89 */
90 public class FilePart extends PartBase {
91
92 /*** Default content encoding of file attachments. */
93 public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
94
95 /*** Default charset of file attachments. */
96 public static final String DEFAULT_CHARSET = HttpConstants.DEFAULT_CONTENT_CHARSET;
97
98 /*** Default transfer encoding of file attachments. */
99 public static final String DEFAULT_TRANSFER_ENCODING = "binary";
100
101 /*** Log object for this class. */
102 private static final Log LOG = LogFactory.getLog(FilePart.class);
103
104 /*** Attachment's file name */
105 protected static final String FILE_NAME = "; filename=";
106
107 /*** Attachment's file name as a byte array */
108 protected static final byte[] FILE_NAME_BYTES =
109 HttpConstants.getAsciiBytes(FILE_NAME);
110
111 /*** Source of the file part. */
112 private PartSource source;
113
114 /***
115 * FilePart Constructor.
116 *
117 * @param name the name for this part
118 * @param partSource the source for this part
119 * @param contentType the content type for this part, if <code>null</code> the
120 * {@link #DEFAULT_CONTENT_TYPE default} is used
121 * @param charset the charset encoding for this part, if <code>null</code> the
122 * {@link #DEFAULT_CHARSET default} is used
123 */
124 public FilePart(String name, PartSource partSource, String contentType, String charset) {
125
126 super(
127 name,
128 contentType == null ? DEFAULT_CONTENT_TYPE : contentType,
129 charset == null ? DEFAULT_CHARSET : charset,
130 DEFAULT_TRANSFER_ENCODING
131 );
132
133 if (partSource == null) {
134 throw new IllegalArgumentException("Source may not be null");
135 }
136 if (partSource.getLength() < 0) {
137 throw new IllegalArgumentException("Source length must be >= 0");
138 }
139 this.source = partSource;
140 }
141
142 /***
143 * FilePart Constructor.
144 *
145 * @param name the name for this part
146 * @param partSource the source for this part
147 */
148 public FilePart(String name, PartSource partSource) {
149 this(name, partSource, null, null);
150 }
151
152 /***
153 * FilePart Constructor.
154 *
155 * @param name the name of the file part
156 * @param file the file to post
157 *
158 * @throws FileNotFoundException if the <i>file</i> is not a normal
159 * file or if it is not readable.
160 */
161 public FilePart(String name, File file)
162 throws FileNotFoundException {
163 this(name, new FilePartSource(file), null, null);
164 }
165
166 /***
167 * FilePart Constructor.
168 *
169 * @param name the name of the file part
170 * @param file the file to post
171 * @param contentType the content type for this part, if <code>null</code> the
172 * {@link #DEFAULT_CONTENT_TYPE default} is used
173 * @param charset the charset encoding for this part, if <code>null</code> the
174 * {@link #DEFAULT_CHARSET default} is used
175 *
176 * @throws FileNotFoundException if the <i>file</i> is not a normal
177 * file or if it is not readable.
178 */
179 public FilePart(String name, File file, String contentType, String charset)
180 throws FileNotFoundException {
181 this(name, new FilePartSource(file), contentType, charset);
182 }
183
184 /***
185 * FilePart Constructor.
186 *
187 * @param name the name of the file part
188 * @param fileName the file name
189 * @param file the file to post
190 *
191 * @throws FileNotFoundException if the <i>file</i> is not a normal
192 * file or if it is not readable.
193 */
194 public FilePart(String name, String fileName, File file)
195 throws FileNotFoundException {
196 this(name, new FilePartSource(fileName, file), null, null);
197 }
198
199 /***
200 * FilePart Constructor.
201 *
202 * @param name the name of the file part
203 * @param fileName the file name
204 * @param file the file to post
205 * @param contentType the content type for this part, if <code>null</code> the
206 * {@link #DEFAULT_CONTENT_TYPE default} is used
207 * @param charset the charset encoding for this part, if <code>null</code> the
208 * {@link #DEFAULT_CHARSET default} is used
209 *
210 * @throws FileNotFoundException if the <i>file</i> is not a normal
211 * file or if it is not readable.
212 */
213 public FilePart(String name, String fileName, File file, String contentType, String charset)
214 throws FileNotFoundException {
215 this(name, new FilePartSource(fileName, file), contentType, charset);
216 }
217
218 /***
219 * Write the disposition header to the output stream
220 * @param out The output stream
221 * @throws IOException If an IO problem occurs
222 * @see Part#sendDispositionHeader(OutputStream)
223 */
224 protected void sendDispositionHeader(OutputStream out)
225 throws IOException {
226 LOG.trace("enter sendDispositionHeader(OutputStream out)");
227 super.sendDispositionHeader(out);
228 String filename = this.source.getFileName();
229 if (filename != null) {
230 out.write(FILE_NAME_BYTES);
231 out.write(QUOTE_BYTES);
232 out.write(HttpConstants.getAsciiBytes(filename));
233 out.write(QUOTE_BYTES);
234 }
235 }
236
237 /***
238 * Write the data in "source" to the specified stream.
239 * @param out The output stream.
240 * @throws IOException if an IO problem occurs.
241 * @see org.apache.commons.httpclient.methods.multipart.Part#sendData(OutputStream)
242 */
243 protected void sendData(OutputStream out) throws IOException {
244 LOG.trace("enter sendData(OutputStream out)");
245 if (lengthOfData() == 0) {
246
247 // this file contains no data, so there is nothing to send.
248 // we don't want to create a zero length buffer as this will
249 // cause an infinite loop when reading.
250 LOG.debug("No data to send.");
251 return;
252 }
253
254 byte[] tmp = new byte[4096];
255 InputStream instream = source.createInputStream();
256 try {
257 int len;
258 while ((len = instream.read(tmp)) >= 0) {
259 out.write(tmp, 0, len);
260 }
261 } finally {
262 // we're done with the stream, close it
263 instream.close();
264 }
265 }
266
267 /***
268 * Returns the source of the file part.
269 *
270 * @return The source.
271 */
272 protected PartSource getSource() {
273 LOG.trace("enter getSource()");
274 return this.source;
275 }
276
277 /***
278 * Return the length of the data.
279 * @return The length.
280 * @throws IOException if an IO problem occurs
281 * @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
282 */
283 protected long lengthOfData() throws IOException {
284 LOG.trace("enter lengthOfData()");
285 return source.getLength();
286 }
287
288 }
This page was automatically generated by Maven