001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 package javax.xml.soap; 021 022 import javax.activation.DataHandler; 023 import java.util.Iterator; 024 025 /** 026 * <P>A single attachment to a <CODE>SOAPMessage</CODE> object. A 027 * <CODE>SOAPMessage</CODE> object may contain zero, one, or many 028 * <CODE>AttachmentPart</CODE> objects. Each <CODE> 029 * AttachmentPart</CODE> object consists of two parts, 030 * application-specific content and associated MIME headers. The 031 * MIME headers consists of name/value pairs that can be used to 032 * identify and describe the content.</P> 033 * 034 * <P>An <CODE>AttachmentPart</CODE> object must conform to 035 * certain standards.</P> 036 * 037 * <OL> 038 * <LI>It must conform to <A href= 039 * "http://www.ietf.org/rfc/rfc2045.txt">MIME [RFC2045] 040 * standards</A></LI> 041 * 042 * <LI>It MUST contain content</LI> 043 * 044 * <LI> 045 * The header portion MUST include the following header: 046 * 047 * <UL> 048 * <LI> 049 * <CODE>Content-Type</CODE><BR> 050 * This header identifies the type of data in the content 051 * of an <CODE>AttachmentPart</CODE> object and MUST 052 * conform to [RFC2045]. The following is an example of a 053 * Content-Type header: 054 * <PRE> 055 * Content-Type: application/xml 056 * 057 * </PRE> 058 * The following line of code, in which <CODE>ap</CODE> is 059 * an <CODE>AttachmentPart</CODE> object, sets the header 060 * shown in the previous example. 061 * <PRE> 062 * ap.setMimeHeader("Content-Type", "application/xml"); 063 * 064 * </PRE> 065 * 066 * <P></P> 067 * </LI> 068 * </UL> 069 * </LI> 070 * </OL> 071 * 072 * <P>There are no restrictions on the content portion of an 073 * <CODE>AttachmentPart</CODE> object. The content may be anything 074 * from a simple plain text object to a complex XML document or 075 * image file.</P> 076 * 077 * <P>An <CODE>AttachmentPart</CODE> object is created with the 078 * method <CODE>SOAPMessage.createAttachmentPart</CODE>. After 079 * setting its MIME headers, the <CODE>AttachmentPart</CODE> 080 * object is added to the message that created it with the method 081 * <CODE>SOAPMessage.addAttachmentPart</CODE>.</P> 082 * 083 * <P>The following code fragment, in which <CODE>m</CODE> is a 084 * <CODE>SOAPMessage</CODE> object and <CODE>contentStringl</CODE> 085 * is a <CODE>String</CODE>, creates an instance of <CODE> 086 * AttachmentPart</CODE>, sets the <CODE>AttachmentPart</CODE> 087 * object with some content and header information, and adds the 088 * <CODE>AttachmentPart</CODE> object to the <CODE> 089 * SOAPMessage</CODE> object.</P> 090 * <PRE> 091 * AttachmentPart ap1 = m.createAttachmentPart(); 092 * ap1.setContent(contentString1, "text/plain"); 093 * m.addAttachmentPart(ap1); 094 * </PRE> 095 * 096 * <P>The following code fragment creates and adds a second <CODE> 097 * AttachmentPart</CODE> instance to the same message. <CODE> 098 * jpegData</CODE> is a binary byte buffer representing the jpeg 099 * file.</P> 100 * <PRE> 101 * AttachmentPart ap2 = m.createAttachmentPart(); 102 * byte[] jpegData = ...; 103 * ap2.setContent(new ByteArrayInputStream(jpegData), "image/jpeg"); 104 * m.addAttachmentPart(ap2); 105 * </PRE> 106 * 107 * <P>The <CODE>getContent</CODE> method retrieves the contents 108 * and header from an <CODE>AttachmentPart</CODE> object. 109 * Depending on the <CODE>DataContentHandler</CODE> objects 110 * present, the returned <CODE>Object</CODE> can either be a typed 111 * Java object corresponding to the MIME type or an <CODE> 112 * InputStream</CODE> object that contains the content as 113 * bytes.</P> 114 * <PRE> 115 * String content1 = ap1.getContent(); 116 * java.io.InputStream content2 = ap2.getContent(); 117 * </PRE> 118 * The method <CODE>clearContent</CODE> removes all the content 119 * from an <CODE>AttachmentPart</CODE> object but does not affect 120 * its header information. 121 * <PRE> 122 * ap1.clearContent(); 123 * </PRE> 124 */ 125 public abstract class AttachmentPart { 126 127 // fixme: should this constructor be protected? 128 /** Create a new AttachmentPart. */ 129 public AttachmentPart() {} 130 131 /** 132 * Returns the number of bytes in this <CODE> 133 * AttachmentPart</CODE> object. 134 * @return the size of this <CODE>AttachmentPart</CODE> object 135 * in bytes or -1 if the size cannot be determined 136 * @throws SOAPException if the content of this 137 * attachment is corrupted of if there was an exception 138 * while trying to determine the size. 139 */ 140 public abstract int getSize() throws SOAPException; 141 142 /** 143 * Clears out the content of this <CODE> 144 * AttachmentPart</CODE> object. The MIME header portion is left 145 * untouched. 146 */ 147 public abstract void clearContent(); 148 149 /** 150 * Gets the content of this <code>AttachmentPart</code> object as a Java 151 * object. The type of the returned Java object depends on (1) the 152 * <code>DataContentHandler</code> object that is used to interpret the bytes 153 * and (2) the <code>Content-Type</code> given in the header. 154 * <p> 155 * For the MIME content types "text/plain", "text/html" and "text/xml", the 156 * <code>DataContentHandler</code> object does the conversions to and 157 * from the Java types corresponding to the MIME types. 158 * For other MIME types,the <code>DataContentHandler</code> object 159 * can return an <code>InputStream</code> object that contains the content data 160 * as raw bytes. 161 * <p> 162 * A JAXM-compliant implementation must, as a minimum, return a 163 * <code>java.lang.String</code> object corresponding to any content 164 * stream with a <code>Content-Type</code> value of 165 * <code>text/plain</code>, a 166 * <code>javax.xml.transform.StreamSource</code> object corresponding to a 167 * content stream with a <code>Content-Type</code> value of 168 * <code>text/xml</code>, a <code>java.awt.Image</code> object 169 * corresponding to a content stream with a 170 * <code>Content-Type</code> value of <code>image/gif</code> or 171 * <code>image/jpeg</code>. For those content types that an 172 * installed <code>DataContentHandler</code> object does not understand, the 173 * <code>DataContentHandler</code> object is required to return a 174 * <code>java.io.InputStream</code> object with the raw bytes. 175 * 176 * @return a Java object with the content of this <CODE> 177 * AttachmentPart</CODE> object 178 * @throws SOAPException if there is no content set 179 * into this <CODE>AttachmentPart</CODE> object or if there 180 * was a data transformation error 181 */ 182 public abstract Object getContent() throws SOAPException; 183 184 /** 185 * Sets the content of this attachment part to that of the 186 * given <CODE>Object</CODE> and sets the value of the <CODE> 187 * Content-Type</CODE> header to the given type. The type of the 188 * <CODE>Object</CODE> should correspond to the value given for 189 * the <CODE>Content-Type</CODE>. This depends on the particular 190 * set of <CODE>DataContentHandler</CODE> objects in use. 191 * @param object the Java object that makes up 192 * the content for this attachment part 193 * @param contentType the MIME string that 194 * specifies the type of the content 195 * @throws java.lang.IllegalArgumentException if 196 * the contentType does not match the type of the content 197 * object, or if there was no <CODE> 198 * DataContentHandler</CODE> object for this content 199 * object 200 * @see #getContent() getContent() 201 */ 202 public abstract void setContent(Object object, String contentType); 203 204 /** 205 * Gets the <CODE>DataHandler</CODE> object for this <CODE> 206 * AttachmentPart</CODE> object. 207 * @return the <CODE>DataHandler</CODE> object associated with 208 * this <CODE>AttachmentPart</CODE> object 209 * @throws SOAPException if there is 210 * no data in this <CODE>AttachmentPart</CODE> object 211 */ 212 public abstract DataHandler getDataHandler() throws SOAPException; 213 214 /** 215 * Sets the given <CODE>DataHandler</CODE> object as the 216 * data handler for this <CODE>AttachmentPart</CODE> object. 217 * Typically, on an incoming message, the data handler is 218 * automatically set. When a message is being created and 219 * populated with content, the <CODE>setDataHandler</CODE> 220 * method can be used to get data from various data sources into 221 * the message. 222 * @param datahandler <CODE>DataHandler</CODE> object to 223 * be set 224 * @throws java.lang.IllegalArgumentException if 225 * there was a problem with the specified <CODE> 226 * DataHandler</CODE> object 227 */ 228 public abstract void setDataHandler(DataHandler datahandler); 229 230 /** 231 * Gets the value of the MIME header whose name is 232 * "Content-Id". 233 * @return a <CODE>String</CODE> giving the value of the 234 * "Content-Id" header or <CODE>null</CODE> if there is 235 * none 236 * @see #setContentId(java.lang.String) setContentId(java.lang.String) 237 */ 238 public String getContentId() { 239 240 String as[] = getMimeHeader("Content-Id"); 241 242 if (as != null && as.length > 0) { 243 return as[0]; 244 } else { 245 return null; 246 } 247 } 248 249 /** 250 * Gets the value of the MIME header 251 * "Content-Location". 252 * @return a <CODE>String</CODE> giving the value of the 253 * "Content-Location" header or <CODE>null</CODE> if there 254 * is none 255 */ 256 public String getContentLocation() { 257 258 String as[] = getMimeHeader("Content-Location"); 259 260 if (as != null && as.length > 0) { 261 return as[0]; 262 } else { 263 return null; 264 } 265 } 266 267 /** 268 * Gets the value of the MIME header "Content-Type". 269 * @return a <CODE>String</CODE> giving the value of the 270 * "Content-Type" header or <CODE>null</CODE> if there is 271 * none 272 */ 273 public String getContentType() { 274 275 String as[] = getMimeHeader("Content-Type"); 276 277 if (as != null && as.length > 0) { 278 return as[0]; 279 } else { 280 return null; 281 } 282 } 283 284 /** 285 * Sets the MIME header "Content-Id" with the given 286 * value. 287 * @param contentId a <CODE>String</CODE> giving 288 * the value of the "Content-Id" header 289 * @throws java.lang.IllegalArgumentException if 290 * there was a problem with the specified <CODE> 291 * contentId</CODE> value 292 * @see #getContentId() getContentId() 293 */ 294 public void setContentId(String contentId) { 295 setMimeHeader("Content-Id", contentId); 296 } 297 298 /** 299 * Sets the MIME header "Content-Location" with the given 300 * value. 301 * @param contentLocation a <CODE>String</CODE> 302 * giving the value of the "Content-Location" header 303 * @throws java.lang.IllegalArgumentException if 304 * there was a problem with the specified content 305 * location 306 */ 307 public void setContentLocation(String contentLocation) { 308 setMimeHeader("Content-Location", contentLocation); 309 } 310 311 /** 312 * Sets the MIME header "Content-Type" with the given 313 * value. 314 * @param contentType a <CODE>String</CODE> 315 * giving the value of the "Content-Type" header 316 * @throws java.lang.IllegalArgumentException if 317 * there was a problem with the specified content type 318 */ 319 public void setContentType(String contentType) { 320 setMimeHeader("Content-Type", contentType); 321 } 322 323 /** 324 * Removes all MIME headers that match the given name. 325 * @param header - the string name of the MIME 326 * header/s to be removed 327 */ 328 public abstract void removeMimeHeader(String header); 329 330 /** Removes all the MIME header entries. */ 331 public abstract void removeAllMimeHeaders(); 332 333 /** 334 * Gets all the values of the header identified by the given 335 * <CODE>String</CODE>. 336 * @param name the name of the header; example: 337 * "Content-Type" 338 * @return a <CODE>String</CODE> array giving the value for the 339 * specified header 340 * @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String) 341 */ 342 public abstract String[] getMimeHeader(String name); 343 344 /** 345 * Changes the first header entry that matches the given name 346 * to the given value, adding a new header if no existing 347 * header matches. This method also removes all matching 348 * headers but the first. 349 * 350 * <P>Note that RFC822 headers can only contain US-ASCII 351 * characters.</P> 352 * @param name a <CODE>String</CODE> giving the 353 * name of the header for which to search 354 * @param value a <CODE>String</CODE> giving the 355 * value to be set for the header whose name matches the 356 * given name 357 * @throws java.lang.IllegalArgumentException if 358 * there was a problem with the specified mime header name 359 * or value 360 */ 361 public abstract void setMimeHeader(String name, String value); 362 363 /** 364 * Adds a MIME header with the specified name and value to 365 * this <CODE>AttachmentPart</CODE> object. 366 * 367 * <P>Note that RFC822 headers can contain only US-ASCII 368 * characters.</P> 369 * @param name a <CODE>String</CODE> giving the 370 * name of the header to be added 371 * @param value a <CODE>String</CODE> giving the 372 * value of the header to be added 373 * @throws java.lang.IllegalArgumentException if 374 * there was a problem with the specified mime header name 375 * or value 376 */ 377 public abstract void addMimeHeader(String name, String value); 378 379 /** 380 * Retrieves all the headers for this <CODE> 381 * AttachmentPart</CODE> object as an iterator over the <CODE> 382 * MimeHeader</CODE> objects. 383 * @return an <CODE>Iterator</CODE> object with all of the Mime 384 * headers for this <CODE>AttachmentPart</CODE> object 385 */ 386 public abstract Iterator getAllMimeHeaders(); 387 388 /** 389 * Retrieves all <CODE>MimeHeader</CODE> objects that match 390 * a name in the given array. 391 * @param names a <CODE>String</CODE> array with 392 * the name(s) of the MIME headers to be returned 393 * @return all of the MIME headers that match one of the names 394 * in the given array as an <CODE>Iterator</CODE> 395 * object 396 */ 397 public abstract Iterator getMatchingMimeHeaders(String names[]); 398 399 /** 400 * Retrieves all <CODE>MimeHeader</CODE> objects whose name 401 * does not match a name in the given array. 402 * @param names a <CODE>String</CODE> array with 403 * the name(s) of the MIME headers not to be returned 404 * @return all of the MIME headers in this <CODE> 405 * AttachmentPart</CODE> object except those that match one 406 * of the names in the given array. The nonmatching MIME 407 * headers are returned as an <CODE>Iterator</CODE> 408 * object. 409 */ 410 public abstract Iterator getNonMatchingMimeHeaders(String names[]); 411 }