KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > httpclient > methods > multipart > Part


1 /*
2  * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.10.2.2 2004/02/22 18:21:15 olegk Exp $
3  * $Revision: 1.10.2.2 $
4  * $Date: 2004/02/22 18:21:15 $
5  *
6  * ====================================================================
7  *
8  * Copyright 2002-2004 The Apache Software Foundation
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  * ====================================================================
22  *
23  * This software consists of voluntary contributions made by many
24  * individuals on behalf of the Apache Software Foundation. For more
25  * information on the Apache Software Foundation, please see
26  * <http://www.apache.org/>.
27  *
28  * [Additional notices, if required by prior licensing conditions]
29  *
30  */

31
32 package org.apache.commons.httpclient.methods.multipart;
33
34 import java.io.ByteArrayOutputStream JavaDoc;
35 import java.io.IOException JavaDoc;
36 import java.io.OutputStream JavaDoc;
37
38 import org.apache.commons.httpclient.HttpConstants;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 /**
43  * Abstract class for one Part of a multipart post object.
44  *
45  * @author <a HREF="mailto:mattalbright@yahoo.com">Matthew Albright</a>
46  * @author <a HREF="mailto:jsdever@apache.org">Jeff Dever</a>
47  * @author <a HREF="mailto:adrian@ephox.com">Adrian Sutton</a>
48  * @author <a HREF="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
49  * @author <a HREF="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
50  *
51  * @since 2.0
52  */

53 public abstract class Part {
54
55     /** Log object for this class. */
56     private static final Log LOG = LogFactory.getLog(Part.class);
57
58     //TODO: Make this configurable
59

60     /** The boundary */
61     protected static final String JavaDoc BOUNDARY = "----------------314159265358979323846";
62     
63     /** The boundary as a byte array */
64     protected static final byte[] BOUNDARY_BYTES = HttpConstants.getAsciiBytes(BOUNDARY);
65     
66     /** Carriage return/linefeed */
67     protected static final String JavaDoc CRLF = "\r\n";
68     
69     /** Carriage return/linefeed as a byte array */
70     protected static final byte[] CRLF_BYTES = HttpConstants.getAsciiBytes(CRLF);
71     
72     /** Content dispostion characters */
73     protected static final String JavaDoc QUOTE = "\"";
74     
75     /** Content dispostion as a byte array */
76     protected static final byte[] QUOTE_BYTES =
77       HttpConstants.getAsciiBytes(QUOTE);
78
79     /** Extra characters */
80     protected static final String JavaDoc EXTRA = "--";
81     
82     /** Extra characters as a byte array */
83     protected static final byte[] EXTRA_BYTES =
84       HttpConstants.getAsciiBytes(EXTRA);
85     
86     /** Content dispostion characters */
87     protected static final String JavaDoc CONTENT_DISPOSITION = "Content-Disposition: form-data; name=";
88     
89     /** Content dispostion as a byte array */
90     protected static final byte[] CONTENT_DISPOSITION_BYTES =
91       HttpConstants.getAsciiBytes(CONTENT_DISPOSITION);
92
93     /** Content type header */
94     protected static final String JavaDoc CONTENT_TYPE = "Content-Type: ";
95
96     /** Content type header as a byte array */
97     protected static final byte[] CONTENT_TYPE_BYTES =
98       HttpConstants.getAsciiBytes(CONTENT_TYPE);
99
100     /** Content charset */
101     protected static final String JavaDoc CHARSET = "; charset=";
102
103     /** Content charset as a byte array */
104     protected static final byte[] CHARSET_BYTES =
105       HttpConstants.getAsciiBytes(CHARSET);
106
107     /** Content type header */
108     protected static final String JavaDoc CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: ";
109
110     /** Content type header as a byte array */
111     protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES =
112       HttpConstants.getAsciiBytes(CONTENT_TRANSFER_ENCODING);
113
114     /**
115      * Return the boundary string.
116      * @return the boundary string
117      */

118     public static String JavaDoc getBoundary() {
119         return BOUNDARY;
120     }
121     
122     /**
123      * Return the name of this part.
124      * @return The name.
125      */

126     public abstract String JavaDoc getName();
127     
128     /**
129      * Returns the content type of this part.
130      * @return the content type, or <code>null</code> to exclude the content type header
131      */

132     public abstract String JavaDoc getContentType();
133
134     /**
135      * Return the character encoding of this part.
136      * @return the character encoding, or <code>null</code> to exclude the character
137      * encoding header
138      */

139     public abstract String JavaDoc getCharSet();
140
141     /**
142      * Return the transfer encoding of this part.
143      * @return the transfer encoding, or <code>null</code> to exclude the transfer encoding header
144      */

145     public abstract String JavaDoc getTransferEncoding();
146
147     /**
148      * Write the start to the specified output stream
149      * @param out The output stream
150      * @throws IOException If an IO problem occurs.
151      */

152     protected void sendStart(OutputStream JavaDoc out) throws IOException JavaDoc {
153         LOG.trace("enter sendStart(OutputStream out)");
154         out.write(EXTRA_BYTES);
155         out.write(BOUNDARY_BYTES);
156         out.write(CRLF_BYTES);
157     }
158     
159     /**
160      * Write the content disposition header to the specified output stream
161      *
162      * @param out The output stream
163      * @throws IOException If an IO problem occurs.
164      */

165     protected void sendDispositionHeader(OutputStream JavaDoc out) throws IOException JavaDoc {
166         LOG.trace("enter sendDispositionHeader(OutputStream out)");
167         out.write(CONTENT_DISPOSITION_BYTES);
168         out.write(QUOTE_BYTES);
169         out.write(HttpConstants.getAsciiBytes(getName()));
170         out.write(QUOTE_BYTES);
171     }
172     
173     /**
174      * Write the content type header to the specified output stream
175      * @param out The output stream
176      * @throws IOException If an IO problem occurs.
177      */

178      protected void sendContentTypeHeader(OutputStream JavaDoc out) throws IOException JavaDoc {
179         LOG.trace("enter sendContentTypeHeader(OutputStream out)");
180         String JavaDoc contentType = getContentType();
181         if (contentType != null) {
182             out.write(CRLF_BYTES);
183             out.write(CONTENT_TYPE_BYTES);
184             out.write(HttpConstants.getAsciiBytes(contentType));
185             String JavaDoc charSet = getCharSet();
186             if (charSet != null) {
187                 out.write(CHARSET_BYTES);
188                 out.write(HttpConstants.getAsciiBytes(charSet));
189             }
190         }
191     }
192
193     /**
194      * Write the content transfer encoding header to the specified
195      * output stream
196      *
197      * @param out The output stream
198      * @throws IOException If an IO problem occurs.
199      */

200      protected void sendTransferEncodingHeader(OutputStream JavaDoc out) throws IOException JavaDoc {
201         LOG.trace("enter sendTransferEncodingHeader(OutputStream out)");
202         String JavaDoc transferEncoding = getTransferEncoding();
203         if (transferEncoding != null) {
204             out.write(CRLF_BYTES);
205             out.write(CONTENT_TRANSFER_ENCODING_BYTES);
206             out.write(HttpConstants.getAsciiBytes(transferEncoding));
207         }
208     }
209
210     /**
211      * Write the end of the header to the output stream
212      * @param out The output stream
213      * @throws IOException If an IO problem occurs.
214      */

215     protected void sendEndOfHeader(OutputStream JavaDoc out) throws IOException JavaDoc {
216         LOG.trace("enter sendEndOfHeader(OutputStream out)");
217         out.write(CRLF_BYTES);
218         out.write(CRLF_BYTES);
219     }
220     
221     /**
222      * Write the data to the specified output stream
223      * @param out The output stream
224      * @throws IOException If an IO problem occurs.
225      */

226     protected abstract void sendData(OutputStream JavaDoc out) throws IOException JavaDoc;
227     
228     /**
229      * Return the length of the main content
230      *
231      * @return long The length.
232      * @throws IOException If an IO problem occurs
233      */

234     protected abstract long lengthOfData() throws IOException JavaDoc;
235     
236     /**
237      * Write the end data to the output stream.
238      * @param out The output stream
239      * @throws IOException If an IO problem occurs.
240      */

241     protected void sendEnd(OutputStream JavaDoc out) throws IOException JavaDoc {
242         LOG.trace("enter sendEnd(OutputStream out)");
243         out.write(CRLF_BYTES);
244     }
245     
246     /**
247      * Write all the data to the output stream.
248      * If you override this method make sure to override
249      * #length() as well
250      *
251      * @param out The output stream
252      * @throws IOException If an IO problem occurs.
253      */

254     public void send(OutputStream JavaDoc out) throws IOException JavaDoc {
255         LOG.trace("enter send(OutputStream out)");
256         sendStart(out);
257         sendDispositionHeader(out);
258         sendContentTypeHeader(out);
259         sendTransferEncodingHeader(out);
260         sendEndOfHeader(out);
261         sendData(out);
262         sendEnd(out);
263     }
264
265
266     /**
267      * Return the full length of all the data.
268      * If you override this method make sure to override
269      * #send(OutputStream) as well
270      *
271      * @return long The length.
272      * @throws IOException If an IO problem occurs
273      */

274     public long length() throws IOException JavaDoc {
275         LOG.trace("enter length()");
276         ByteArrayOutputStream JavaDoc overhead = new ByteArrayOutputStream JavaDoc();
277         sendStart(overhead);
278         sendDispositionHeader(overhead);
279         sendContentTypeHeader(overhead);
280         sendTransferEncodingHeader(overhead);
281         sendEndOfHeader(overhead);
282         sendEnd(overhead);
283         return overhead.size() + lengthOfData();
284     }
285
286     /**
287      * Return a string representation of this object.
288      * @return A string representation of this object.
289      * @see java.lang.Object#toString()
290      */

291     public String JavaDoc toString() {
292         return this.getName();
293     }
294
295     /**
296      * Write all parts and the last boundary to the specified output stream
297      *
298      * @param out The output stream
299      * @param parts The array of parts to be sent
300      *
301      * @throws IOException If an IO problem occurs.
302      */

303     public static void sendParts(OutputStream JavaDoc out, final Part[] parts)
304     throws IOException JavaDoc {
305         LOG.trace("enter sendParts(OutputStream out, Parts[])");
306         if (parts == null) {
307             throw new IllegalArgumentException JavaDoc("Parts may not be null");
308         }
309         for (int i = 0; i < parts.length; i++) {
310             parts[i].send(out);
311         }
312         out.write(EXTRA_BYTES);
313         out.write(BOUNDARY_BYTES);
314         out.write(EXTRA_BYTES);
315         out.write(CRLF_BYTES);
316     }
317
318     /**
319      * Return the total sum of all parts and that of the last boundary
320      *
321      * @param parts The array of parts
322      *
323      * @return the total length
324      *
325      * @throws IOException If an IO problem occurs.
326      */

327     public static long getLengthOfParts(final Part[] parts)
328     throws IOException JavaDoc {
329         LOG.trace("getLengthOfParts(Parts[])");
330         if (parts == null) {
331             throw new IllegalArgumentException JavaDoc("Parts may not be null");
332         }
333         long total = 0;
334         for (int i = 0; i < parts.length; i++) {
335             total += parts[i].length();
336         }
337         total += EXTRA_BYTES.length;
338         total += BOUNDARY_BYTES.length;
339         total += EXTRA_BYTES.length;
340         total += CRLF_BYTES.length;
341         return total;
342     }
343 }
344
Popular Tags