001: /*
002: * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/methods/multipart/FilePart.java,v 1.19 2004/04/18 23:51:37 jsdever Exp $
003: * $Revision: 480424 $
004: * $Date: 2006-11-29 06:56:49 +0100 (Wed, 29 Nov 2006) $
005: *
006: * ====================================================================
007: *
008: * Licensed to the Apache Software Foundation (ASF) under one or more
009: * contributor license agreements. See the NOTICE file distributed with
010: * this work for additional information regarding copyright ownership.
011: * The ASF licenses this file to You under the Apache License, Version 2.0
012: * (the "License"); you may not use this file except in compliance with
013: * the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing, software
018: * distributed under the License is distributed on an "AS IS" BASIS,
019: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
020: * See the License for the specific language governing permissions and
021: * limitations under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.commons.httpclient.methods.multipart;
032:
033: import java.io.File;
034: import java.io.FileNotFoundException;
035: import java.io.IOException;
036: import java.io.InputStream;
037: import java.io.OutputStream;
038: import org.apache.commons.httpclient.util.EncodingUtil;
039: import org.apache.commons.logging.Log;
040: import org.apache.commons.logging.LogFactory;
041:
042: /**
043: * This class implements a part of a Multipart post object that
044: * consists of a file.
045: *
046: * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a>
047: * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a>
048: * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a>
049: * @author <a href="mailto:becke@u.washington.edu">Michael Becke</a>
050: * @author <a href="mailto:mdiggory@latte.harvard.edu">Mark Diggory</a>
051: * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
052: * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
053: *
054: * @since 2.0
055: *
056: */
057: public class FilePart extends PartBase {
058:
059: /** Default content encoding of file attachments. */
060: public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
061:
062: /** Default charset of file attachments. */
063: public static final String DEFAULT_CHARSET = "ISO-8859-1";
064:
065: /** Default transfer encoding of file attachments. */
066: public static final String DEFAULT_TRANSFER_ENCODING = "binary";
067:
068: /** Log object for this class. */
069: private static final Log LOG = LogFactory.getLog(FilePart.class);
070:
071: /** Attachment's file name */
072: protected static final String FILE_NAME = "; filename=";
073:
074: /** Attachment's file name as a byte array */
075: private static final byte[] FILE_NAME_BYTES = EncodingUtil
076: .getAsciiBytes(FILE_NAME);
077:
078: /** Source of the file part. */
079: private PartSource source;
080:
081: /**
082: * FilePart Constructor.
083: *
084: * @param name the name for this part
085: * @param partSource the source for this part
086: * @param contentType the content type for this part, if <code>null</code> the
087: * {@link #DEFAULT_CONTENT_TYPE default} is used
088: * @param charset the charset encoding for this part, if <code>null</code> the
089: * {@link #DEFAULT_CHARSET default} is used
090: */
091: public FilePart(String name, PartSource partSource,
092: String contentType, String charset) {
093:
094: super (name, contentType == null ? DEFAULT_CONTENT_TYPE
095: : contentType,
096: charset == null ? "ISO-8859-1" : charset,
097: DEFAULT_TRANSFER_ENCODING);
098:
099: if (partSource == null) {
100: throw new IllegalArgumentException("Source may not be null");
101: }
102: this .source = partSource;
103: }
104:
105: /**
106: * FilePart Constructor.
107: *
108: * @param name the name for this part
109: * @param partSource the source for this part
110: */
111: public FilePart(String name, PartSource partSource) {
112: this (name, partSource, null, null);
113: }
114:
115: /**
116: * FilePart Constructor.
117: *
118: * @param name the name of the file part
119: * @param file the file to post
120: *
121: * @throws FileNotFoundException if the <i>file</i> is not a normal
122: * file or if it is not readable.
123: */
124: public FilePart(String name, File file)
125: throws FileNotFoundException {
126: this (name, new FilePartSource(file), null, null);
127: }
128:
129: /**
130: * FilePart Constructor.
131: *
132: * @param name the name of the file part
133: * @param file the file to post
134: * @param contentType the content type for this part, if <code>null</code> the
135: * {@link #DEFAULT_CONTENT_TYPE default} is used
136: * @param charset the charset encoding for this part, if <code>null</code> the
137: * {@link #DEFAULT_CHARSET default} is used
138: *
139: * @throws FileNotFoundException if the <i>file</i> is not a normal
140: * file or if it is not readable.
141: */
142: public FilePart(String name, File file, String contentType,
143: String charset) throws FileNotFoundException {
144: this (name, new FilePartSource(file), contentType, charset);
145: }
146:
147: /**
148: * FilePart Constructor.
149: *
150: * @param name the name of the file part
151: * @param fileName the file name
152: * @param file the file to post
153: *
154: * @throws FileNotFoundException if the <i>file</i> is not a normal
155: * file or if it is not readable.
156: */
157: public FilePart(String name, String fileName, File file)
158: throws FileNotFoundException {
159: this (name, new FilePartSource(fileName, file), null, null);
160: }
161:
162: /**
163: * FilePart Constructor.
164: *
165: * @param name the name of the file part
166: * @param fileName the file name
167: * @param file the file to post
168: * @param contentType the content type for this part, if <code>null</code> the
169: * {@link #DEFAULT_CONTENT_TYPE default} is used
170: * @param charset the charset encoding for this part, if <code>null</code> the
171: * {@link #DEFAULT_CHARSET default} is used
172: *
173: * @throws FileNotFoundException if the <i>file</i> is not a normal
174: * file or if it is not readable.
175: */
176: public FilePart(String name, String fileName, File file,
177: String contentType, String charset)
178: throws FileNotFoundException {
179: this (name, new FilePartSource(fileName, file), contentType,
180: charset);
181: }
182:
183: /**
184: * Write the disposition header to the output stream
185: * @param out The output stream
186: * @throws IOException If an IO problem occurs
187: * @see Part#sendDispositionHeader(OutputStream)
188: */
189: protected void sendDispositionHeader(OutputStream out)
190: throws IOException {
191: LOG.trace("enter sendDispositionHeader(OutputStream out)");
192: super .sendDispositionHeader(out);
193: String filename = this .source.getFileName();
194: if (filename != null) {
195: out.write(FILE_NAME_BYTES);
196: out.write(QUOTE_BYTES);
197: out.write(EncodingUtil.getAsciiBytes(filename));
198: out.write(QUOTE_BYTES);
199: }
200: }
201:
202: /**
203: * Write the data in "source" to the specified stream.
204: * @param out The output stream.
205: * @throws IOException if an IO problem occurs.
206: * @see org.apache.commons.httpclient.methods.multipart.Part#sendData(OutputStream)
207: */
208: protected void sendData(OutputStream out) throws IOException {
209: LOG.trace("enter sendData(OutputStream out)");
210: if (lengthOfData() == 0) {
211:
212: // this file contains no data, so there is nothing to send.
213: // we don't want to create a zero length buffer as this will
214: // cause an infinite loop when reading.
215: LOG.debug("No data to send.");
216: return;
217: }
218:
219: byte[] tmp = new byte[4096];
220: InputStream instream = source.createInputStream();
221: try {
222: int len;
223: while ((len = instream.read(tmp)) >= 0) {
224: out.write(tmp, 0, len);
225: }
226: } finally {
227: // we're done with the stream, close it
228: instream.close();
229: }
230: }
231:
232: /**
233: * Returns the source of the file part.
234: *
235: * @return The source.
236: */
237: protected PartSource getSource() {
238: LOG.trace("enter getSource()");
239: return this .source;
240: }
241:
242: /**
243: * Return the length of the data.
244: * @return The length.
245: * @throws IOException if an IO problem occurs
246: * @see org.apache.commons.httpclient.methods.multipart.Part#lengthOfData()
247: */
248: protected long lengthOfData() throws IOException {
249: LOG.trace("enter lengthOfData()");
250: return source.getLength();
251: }
252:
253: }
|