View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/methods/multipart/Part.java,v 1.10.2.1 2003/10/10 04:16:02 mbecke Exp $ 3 * $Revision: 1.10.2.1 $ 4 * $Date: 2003/10/10 04:16:02 $ 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.ByteArrayOutputStream; 67 import java.io.IOException; 68 import java.io.OutputStream; 69 70 import org.apache.commons.httpclient.HttpConstants; 71 import org.apache.commons.logging.Log; 72 import org.apache.commons.logging.LogFactory; 73 74 /*** 75 * Abstract class for one Part of a multipart post object. 76 * 77 * @author <a href="mailto:mattalbright@yahoo.com">Matthew Albright</a> 78 * @author <a href="mailto:jsdever@apache.org">Jeff Dever</a> 79 * @author <a href="mailto:adrian@ephox.com">Adrian Sutton</a> 80 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 81 * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> 82 * 83 * @since 2.0 84 */ 85 public abstract class Part { 86 87 /*** Log object for this class. */ 88 private static final Log LOG = LogFactory.getLog(Part.class); 89 90 //TODO: Make this configurable 91 92 /*** The boundary */ 93 protected static final String BOUNDARY = "----------------314159265358979323846"; 94 95 /*** The boundary as a byte array */ 96 protected static final byte[] BOUNDARY_BYTES = HttpConstants.getAsciiBytes(BOUNDARY); 97 98 /*** Carriage return/linefeed */ 99 protected static final String CRLF = "\r\n"; 100 101 /*** Carriage return/linefeed as a byte array */ 102 protected static final byte[] CRLF_BYTES = HttpConstants.getAsciiBytes(CRLF); 103 104 /*** Content dispostion characters */ 105 protected static final String QUOTE = "\""; 106 107 /*** Content dispostion as a byte array */ 108 protected static final byte[] QUOTE_BYTES = 109 HttpConstants.getAsciiBytes(QUOTE); 110 111 /*** Extra characters */ 112 protected static final String EXTRA = "--"; 113 114 /*** Extra characters as a byte array */ 115 protected static final byte[] EXTRA_BYTES = 116 HttpConstants.getAsciiBytes(EXTRA); 117 118 /*** Content dispostion characters */ 119 protected static final String CONTENT_DISPOSITION = "Content-Disposition: form-data; name="; 120 121 /*** Content dispostion as a byte array */ 122 protected static final byte[] CONTENT_DISPOSITION_BYTES = 123 HttpConstants.getAsciiBytes(CONTENT_DISPOSITION); 124 125 /*** Content type header */ 126 protected static final String CONTENT_TYPE = "Content-Type: "; 127 128 /*** Content type header as a byte array */ 129 protected static final byte[] CONTENT_TYPE_BYTES = 130 HttpConstants.getAsciiBytes(CONTENT_TYPE); 131 132 /*** Content charset */ 133 protected static final String CHARSET = "; charset="; 134 135 /*** Content charset as a byte array */ 136 protected static final byte[] CHARSET_BYTES = 137 HttpConstants.getAsciiBytes(CHARSET); 138 139 /*** Content type header */ 140 protected static final String CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding: "; 141 142 /*** Content type header as a byte array */ 143 protected static final byte[] CONTENT_TRANSFER_ENCODING_BYTES = 144 HttpConstants.getAsciiBytes(CONTENT_TRANSFER_ENCODING); 145 146 /*** 147 * Return the boundary string. 148 * @return the boundary string 149 */ 150 public static String getBoundary() { 151 return BOUNDARY; 152 } 153 154 /*** 155 * Return the name of this part. 156 * @return The name. 157 */ 158 public abstract String getName(); 159 160 /*** 161 * Returns the content type of this part. 162 * @return the content type, or <code>null</code> to exclude the content type header 163 */ 164 public abstract String getContentType(); 165 166 /*** 167 * Return the character encoding of this part. 168 * @return the character encoding, or <code>null</code> to exclude the character 169 * encoding header 170 */ 171 public abstract String getCharSet(); 172 173 /*** 174 * Return the transfer encoding of this part. 175 * @return the transfer encoding, or <code>null</code> to exclude the transfer encoding header 176 */ 177 public abstract String getTransferEncoding(); 178 179 /*** 180 * Write the start to the specified output stream 181 * @param out The output stream 182 * @throws IOException If an IO problem occurs. 183 */ 184 protected void sendStart(OutputStream out) throws IOException { 185 LOG.trace("enter sendStart(OutputStream out)"); 186 out.write(EXTRA_BYTES); 187 out.write(BOUNDARY_BYTES); 188 out.write(CRLF_BYTES); 189 } 190 191 /*** 192 * Write the content disposition header to the specified output stream 193 * 194 * @param out The output stream 195 * @throws IOException If an IO problem occurs. 196 */ 197 protected void sendDispositionHeader(OutputStream out) throws IOException { 198 LOG.trace("enter sendDispositionHeader(OutputStream out)"); 199 out.write(CONTENT_DISPOSITION_BYTES); 200 out.write(QUOTE_BYTES); 201 out.write(HttpConstants.getAsciiBytes(getName())); 202 out.write(QUOTE_BYTES); 203 } 204 205 /*** 206 * Write the content type header to the specified output stream 207 * @param out The output stream 208 * @throws IOException If an IO problem occurs. 209 */ 210 protected void sendContentTypeHeader(OutputStream out) throws IOException { 211 LOG.trace("enter sendContentTypeHeader(OutputStream out)"); 212 String contentType = getContentType(); 213 if (contentType != null) { 214 out.write(CRLF_BYTES); 215 out.write(CONTENT_TYPE_BYTES); 216 out.write(HttpConstants.getAsciiBytes(contentType)); 217 String charSet = getCharSet(); 218 if (charSet != null) { 219 out.write(CHARSET_BYTES); 220 out.write(HttpConstants.getAsciiBytes(charSet)); 221 } 222 } 223 } 224 225 /*** 226 * Write the content transfer encoding header to the specified 227 * output stream 228 * 229 * @param out The output stream 230 * @throws IOException If an IO problem occurs. 231 */ 232 protected void sendTransferEncodingHeader(OutputStream out) throws IOException { 233 LOG.trace("enter sendTransferEncodingHeader(OutputStream out)"); 234 String transferEncoding = getTransferEncoding(); 235 if (transferEncoding != null) { 236 out.write(CRLF_BYTES); 237 out.write(CONTENT_TRANSFER_ENCODING_BYTES); 238 out.write(HttpConstants.getAsciiBytes(transferEncoding)); 239 } 240 } 241 242 /*** 243 * Write the end of the header to the output stream 244 * @param out The output stream 245 * @throws IOException If an IO problem occurs. 246 */ 247 protected void sendEndOfHeader(OutputStream out) throws IOException { 248 LOG.trace("enter sendEndOfHeader(OutputStream out)"); 249 out.write(CRLF_BYTES); 250 out.write(CRLF_BYTES); 251 } 252 253 /*** 254 * Write the data to the specified output stream 255 * @param out The output stream 256 * @throws IOException If an IO problem occurs. 257 */ 258 protected abstract void sendData(OutputStream out) throws IOException; 259 260 /*** 261 * Return the length of the main content 262 * 263 * @return long The length. 264 * @throws IOException If an IO problem occurs 265 */ 266 protected abstract long lengthOfData() throws IOException; 267 268 /*** 269 * Write the end data to the output stream. 270 * @param out The output stream 271 * @throws IOException If an IO problem occurs. 272 */ 273 protected void sendEnd(OutputStream out) throws IOException { 274 LOG.trace("enter sendEnd(OutputStream out)"); 275 out.write(CRLF_BYTES); 276 } 277 278 /*** 279 * Write all the data to the output stream. 280 * If you override this method make sure to override 281 * #length() as well 282 * 283 * @param out The output stream 284 * @throws IOException If an IO problem occurs. 285 */ 286 public void send(OutputStream out) throws IOException { 287 LOG.trace("enter send(OutputStream out)"); 288 sendStart(out); 289 sendDispositionHeader(out); 290 sendContentTypeHeader(out); 291 sendTransferEncodingHeader(out); 292 sendEndOfHeader(out); 293 sendData(out); 294 sendEnd(out); 295 } 296 297 298 /*** 299 * Return the full length of all the data. 300 * If you override this method make sure to override 301 * #send(OutputStream) as well 302 * 303 * @return long The length. 304 * @throws IOException If an IO problem occurs 305 */ 306 public long length() throws IOException { 307 LOG.trace("enter length()"); 308 ByteArrayOutputStream overhead = new ByteArrayOutputStream(); 309 sendStart(overhead); 310 sendDispositionHeader(overhead); 311 sendContentTypeHeader(overhead); 312 sendTransferEncodingHeader(overhead); 313 sendEndOfHeader(overhead); 314 sendEnd(overhead); 315 return overhead.size() + lengthOfData(); 316 } 317 318 /*** 319 * Return a string representation of this object. 320 * @return A string representation of this object. 321 * @see java.lang.Object#toString() 322 */ 323 public String toString() { 324 return this.getName(); 325 } 326 327 /*** 328 * Write all parts and the last boundary to the specified output stream 329 * 330 * @param out The output stream 331 * @param parts The array of parts to be sent 332 * 333 * @throws IOException If an IO problem occurs. 334 */ 335 public static void sendParts(OutputStream out, final Part[] parts) 336 throws IOException { 337 LOG.trace("enter sendParts(OutputStream out, Parts[])"); 338 if (parts == null) { 339 throw new IllegalArgumentException("Parts may not be null"); 340 } 341 for (int i = 0; i < parts.length; i++) { 342 parts[i].send(out); 343 } 344 out.write(EXTRA_BYTES); 345 out.write(BOUNDARY_BYTES); 346 out.write(EXTRA_BYTES); 347 out.write(CRLF_BYTES); 348 } 349 350 /*** 351 * Return the total sum of all parts and that of the last boundary 352 * 353 * @param parts The array of parts 354 * 355 * @return the total length 356 * 357 * @throws IOException If an IO problem occurs. 358 */ 359 public static long getLengthOfParts(final Part[] parts) 360 throws IOException { 361 LOG.trace("getLengthOfParts(Parts[])"); 362 if (parts == null) { 363 throw new IllegalArgumentException("Parts may not be null"); 364 } 365 long total = 0; 366 for (int i = 0; i < parts.length; i++) { 367 total += parts[i].length(); 368 } 369 total += EXTRA_BYTES.length; 370 total += BOUNDARY_BYTES.length; 371 total += EXTRA_BYTES.length; 372 total += CRLF_BYTES.length; 373 return total; 374 } 375 }

This page was automatically generated by Maven