001 /* 002 * Copyright 2001-2004 The Apache Software Foundation. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package javax.xml.soap; 017 018 import javax.activation.DataHandler; 019 import java.io.IOException; 020 import java.io.OutputStream; 021 import java.util.Iterator; 022 023 /** 024 * <P>The root class for all SOAP messages. As transmitted on the 025 * "wire", a SOAP message is an XML document or a MIME message 026 * whose first body part is an XML/SOAP document.</P> 027 * 028 * <P>A <CODE>SOAPMessage</CODE> object consists of a SOAP part 029 * and optionally one or more attachment parts. The SOAP part for 030 * a <CODE>SOAPMessage</CODE> object is a <CODE>SOAPPart</CODE> 031 * object, which contains information used for message routing and 032 * identification, and which can contain application-specific 033 * content. All data in the SOAP Part of a message must be in XML 034 * format.</P> 035 * 036 * <P>A new <CODE>SOAPMessage</CODE> object contains the following 037 * by default:</P> 038 * 039 * <UL> 040 * <LI>A <CODE>SOAPPart</CODE> object</LI> 041 * 042 * <LI>A <CODE>SOAPEnvelope</CODE> object</LI> 043 * 044 * <LI>A <CODE>SOAPBody</CODE> object</LI> 045 * 046 * <LI>A <CODE>SOAPHeader</CODE> object</LI> 047 * </UL> 048 * The SOAP part of a message can be retrieved by calling the 049 * method <CODE>SOAPMessage.getSOAPPart()</CODE>. The <CODE> 050 * SOAPEnvelope</CODE> object is retrieved from the <CODE> 051 * SOAPPart</CODE> object, and the <CODE>SOAPEnvelope</CODE> 052 * object is used to retrieve the <CODE>SOAPBody</CODE> and <CODE> 053 * SOAPHeader</CODE> objects. 054 * <PRE> 055 * SOAPPart sp = message.getSOAPPart(); 056 * SOAPEnvelope se = sp.getEnvelope(); 057 * SOAPBody sb = se.getBody(); 058 * SOAPHeader sh = se.getHeader(); 059 * </PRE> 060 * 061 * <P>In addition to the mandatory <CODE>SOAPPart</CODE> object, a 062 * <CODE>SOAPMessage</CODE> object may contain zero or more <CODE> 063 * AttachmentPart</CODE> objects, each of which contains 064 * application-specific data. The <CODE>SOAPMessage</CODE> 065 * interface provides methods for creating <CODE> 066 * AttachmentPart</CODE> objects and also for adding them to a 067 * <CODE>SOAPMessage</CODE> object. A party that has received a 068 * <CODE>SOAPMessage</CODE> object can examine its contents by 069 * retrieving individual attachment parts.</P> 070 * 071 * <P>Unlike the rest of a SOAP message, an attachment is not 072 * required to be in XML format and can therefore be anything from 073 * simple text to an image file. Consequently, any message content 074 * that is not in XML format must be in an <CODE> 075 * AttachmentPart</CODE> object.</P> 076 * 077 * <P>A <CODE>MessageFactory</CODE> object creates new <CODE> 078 * SOAPMessage</CODE> objects. If the <CODE>MessageFactory</CODE> 079 * object was initialized with a messaging Profile, it produces 080 * <CODE>SOAPMessage</CODE> objects that conform to that Profile. 081 * For example, a <CODE>SOAPMessage</CODE> object created by a 082 * <CODE>MessageFactory</CODE> object initialized with the ebXML 083 * Profile will have the appropriate ebXML headers.</P> 084 * @see MessageFactory MessageFactory 085 * @see AttachmentPart AttachmentPart 086 */ 087 public abstract class SOAPMessage { 088 089 public SOAPMessage() {} 090 091 /** 092 * Retrieves a description of this <CODE>SOAPMessage</CODE> 093 * object's content. 094 * @return a <CODE>String</CODE> describing the content of this 095 * message or <CODE>null</CODE> if no description has been 096 * set 097 * @see #setContentDescription(java.lang.String) setContentDescription(java.lang.String) 098 */ 099 public abstract String getContentDescription(); 100 101 /** 102 * Sets the description of this <CODE>SOAPMessage</CODE> 103 * object's content with the given description. 104 * @param description a <CODE>String</CODE> 105 * describing the content of this message 106 * @see #getContentDescription() getContentDescription() 107 */ 108 public abstract void setContentDescription(String description); 109 110 /** 111 * Gets the SOAP part of this <CODE>SOAPMessage</CODE> object. 112 * 113 * 114 * <P>If a <CODE>SOAPMessage</CODE> object contains one or 115 * more attachments, the SOAP Part must be the first MIME body 116 * part in the message.</P> 117 * @return the <CODE>SOAPPart</CODE> object for this <CODE> 118 * SOAPMessage</CODE> object 119 */ 120 public abstract SOAPPart getSOAPPart(); 121 122 /** 123 * Removes all <CODE>AttachmentPart</CODE> objects that have 124 * been added to this <CODE>SOAPMessage</CODE> object. 125 * 126 * <P>This method does not touch the SOAP part.</P> 127 */ 128 public abstract void removeAllAttachments(); 129 130 /** 131 * Gets a count of the number of attachments in this 132 * message. This count does not include the SOAP part. 133 * @return the number of <CODE>AttachmentPart</CODE> objects 134 * that are part of this <CODE>SOAPMessage</CODE> 135 * object 136 */ 137 public abstract int countAttachments(); 138 139 /** 140 * Retrieves all the <CODE>AttachmentPart</CODE> objects 141 * that are part of this <CODE>SOAPMessage</CODE> object. 142 * @return an iterator over all the attachments in this 143 * message 144 */ 145 public abstract Iterator getAttachments(); 146 147 /** 148 * Retrieves all the <CODE>AttachmentPart</CODE> objects 149 * that have header entries that match the specified headers. 150 * Note that a returned attachment could have headers in 151 * addition to those specified. 152 * @param headers a <CODE>MimeHeaders</CODE> 153 * object containing the MIME headers for which to 154 * search 155 * @return an iterator over all attachments that have a header 156 * that matches one of the given headers 157 */ 158 public abstract Iterator getAttachments(MimeHeaders headers); 159 160 /** 161 * Adds the given <CODE>AttachmentPart</CODE> object to this 162 * <CODE>SOAPMessage</CODE> object. An <CODE> 163 * AttachmentPart</CODE> object must be created before it can be 164 * added to a message. 165 * @param attachmentpart an <CODE> 166 * AttachmentPart</CODE> object that is to become part of 167 * this <CODE>SOAPMessage</CODE> object 168 * @throws java.lang.IllegalArgumentException 169 */ 170 public abstract void addAttachmentPart(AttachmentPart attachmentpart); 171 172 /** 173 * Creates a new empty <CODE>AttachmentPart</CODE> object. 174 * Note that the method <CODE>addAttachmentPart</CODE> must be 175 * called with this new <CODE>AttachmentPart</CODE> object as 176 * the parameter in order for it to become an attachment to this 177 * <CODE>SOAPMessage</CODE> object. 178 * @return a new <CODE>AttachmentPart</CODE> object that can be 179 * populated and added to this <CODE>SOAPMessage</CODE> 180 * object 181 */ 182 public abstract AttachmentPart createAttachmentPart(); 183 184 /** 185 * Creates an <CODE>AttachmentPart</CODE> object and 186 * populates it using the given <CODE>DataHandler</CODE> 187 * object. 188 * @param datahandler the <CODE> 189 * javax.activation.DataHandler</CODE> object that will 190 * generate the content for this <CODE>SOAPMessage</CODE> 191 * object 192 * @return a new <CODE>AttachmentPart</CODE> object that 193 * contains data generated by the given <CODE> 194 * DataHandler</CODE> object 195 * @throws java.lang.IllegalArgumentException if 196 * there was a problem with the specified <CODE> 197 * DataHandler</CODE> object 198 * @see DataHandler DataHandler 199 * @see javax.activation.DataContentHandler DataContentHandler 200 */ 201 public AttachmentPart createAttachmentPart(DataHandler datahandler) { 202 203 AttachmentPart attachmentpart = createAttachmentPart(); 204 205 attachmentpart.setDataHandler(datahandler); 206 207 return attachmentpart; 208 } 209 210 /** 211 * Returns all the transport-specific MIME headers for this 212 * <CODE>SOAPMessage</CODE> object in a transport-independent 213 * fashion. 214 * @return a <CODE>MimeHeaders</CODE> object containing the 215 * <CODE>MimeHeader</CODE> objects 216 */ 217 public abstract MimeHeaders getMimeHeaders(); 218 219 /** 220 * Creates an <CODE>AttachmentPart</CODE> object and 221 * populates it with the specified data of the specified content 222 * type. 223 * @param content an <CODE>Object</CODE> 224 * containing the content for this <CODE>SOAPMessage</CODE> 225 * object 226 * @param contentType a <CODE>String</CODE> 227 * object giving the type of content; examples are 228 * "text/xml", "text/plain", and "image/jpeg" 229 * @return a new <CODE>AttachmentPart</CODE> object that 230 * contains the given data 231 * @throws java.lang.IllegalArgumentException if the contentType does not match the type of the content 232 * object, or if there was no <CODE> 233 * DataContentHandler</CODE> object for the given content 234 * object 235 * @see DataHandler DataHandler 236 * @see javax.activation.DataContentHandler DataContentHandler 237 */ 238 public AttachmentPart createAttachmentPart(Object content, 239 String contentType) { 240 241 AttachmentPart attachmentpart = createAttachmentPart(); 242 243 attachmentpart.setContent(content, contentType); 244 245 return attachmentpart; 246 } 247 248 /** 249 * Updates this <CODE>SOAPMessage</CODE> object with all the 250 * changes that have been made to it. This method is called 251 * automatically when a message is sent or written to by the 252 * methods <CODE>ProviderConnection.send</CODE>, <CODE> 253 * SOAPConnection.call</CODE>, or <CODE> 254 * SOAPMessage.writeTo</CODE>. However, if changes are made to 255 * a message that was received or to one that has already been 256 * sent, the method <CODE>saveChanges</CODE> needs to be 257 * called explicitly in order to save the changes. The method 258 * <CODE>saveChanges</CODE> also generates any changes that 259 * can be read back (for example, a MessageId in profiles that 260 * support a message id). All MIME headers in a message that 261 * is created for sending purposes are guaranteed to have 262 * valid values only after <CODE>saveChanges</CODE> has been 263 * called. 264 * 265 * <P>In addition, this method marks the point at which the 266 * data from all constituent <CODE>AttachmentPart</CODE> 267 * objects are pulled into the message.</P> 268 * @throws SOAPException if there 269 * was a problem saving changes to this message. 270 */ 271 public abstract void saveChanges() throws SOAPException; 272 273 /** 274 * Indicates whether this <CODE>SOAPMessage</CODE> object 275 * has had the method <CODE>saveChanges</CODE> called on 276 * it. 277 * @return <CODE>true</CODE> if <CODE>saveChanges</CODE> has 278 * been called on this message at least once; <CODE> 279 * false</CODE> otherwise. 280 */ 281 public abstract boolean saveRequired(); 282 283 /** 284 * Writes this <CODE>SOAPMessage</CODE> object to the given 285 * output stream. The externalization format is as defined by 286 * the SOAP 1.1 with Attachments specification. 287 * 288 * <P>If there are no attachments, just an XML stream is 289 * written out. For those messages that have attachments, 290 * <CODE>writeTo</CODE> writes a MIME-encoded byte stream.</P> 291 * @param out the <CODE>OutputStream</CODE> 292 * object to which this <CODE>SOAPMessage</CODE> object will 293 * be written 294 * @throws SOAPException if there was a problem in 295 * externalizing this SOAP message 296 * @throws IOException if an I/O error 297 * occurs 298 */ 299 public abstract void writeTo(OutputStream out) 300 throws SOAPException, IOException; 301 302 /** 303 * Gets the SOAP Body contained in this <code>SOAPMessage</code> object. 304 * 305 * @return the <code>SOAPBody</code> object contained by this 306 * <code>SOAPMessage</code> object 307 * @throws SOAPException if the SOAP Body does not exist or cannot be 308 * retrieved 309 */ 310 public SOAPBody getSOAPBody() throws SOAPException { 311 throw new UnsupportedOperationException("getSOAPBody must be overridden in subclasses of SOAPMessage"); 312 } 313 314 /** 315 * Gets the SOAP Header contained in this <code>SOAPMessage</code> object. 316 * 317 * @return the <code>SOAPHeader</code> object contained by this 318 * <code>SOAPMessage</code> object 319 * @throws SOAPException if the SOAP Header does not exist or cannot be 320 * retrieved 321 */ 322 public SOAPHeader getSOAPHeader() throws SOAPException { 323 throw new UnsupportedOperationException("getSOAPHeader must be overridden in subclasses of SOAPMessage"); 324 } 325 326 /** 327 * Associates the specified value with the specified property. If there was 328 * already a value associated with this property, the old value is replaced. 329 * <p> 330 * The valid property names include <code>WRITE_XML_DECLARATION</code> and 331 * <code>CHARACTER_SET_ENCODING</code>. All of these standard SAAJ 332 * properties are prefixed by "javax.xml.soap". Vendors may also add 333 * implementation specific properties. These properties must be prefixed 334 * with package names that are unique to the vendor. 335 * <p> 336 * Setting the property <code>WRITE_XML_DECLARATION</code> to 337 * <code>"true"</code> will cause an XML Declaration to be written out at 338 * the start of the SOAP message. The default value of "false" suppresses 339 * this declaration. 340 * <p> 341 * The property <code>CHARACTER_SET_ENCODING</code> defaults to the value 342 * <code>"utf-8"</code> which causes the SOAP message to be encoded using 343 * UTF-8. Setting <code>CHARACTER_SET_ENCODING</code> to 344 * <code>"utf-16"</code> causes the SOAP message to be encoded using UTF-16. 345 * <p> 346 * Some implementations may allow encodings in addition to UTF-8 and UTF-16. 347 * Refer to your vendor's documentation for details. 348 * 349 * @param property the property with which the specified value is to be 350 * associated 351 * @param value the value to be associated with the specified property 352 * @throws SOAPException if the property name is not recognized 353 */ 354 public void setProperty(String property, Object value) 355 throws SOAPException { 356 throw new UnsupportedOperationException("setProperty must be overridden in subclasses of SOAPMessage"); 357 } 358 359 /** 360 * Retrieves value of the specified property. 361 * 362 * @param property the name of the property to retrieve 363 * @return the value of the property or <code>null</code> if no such 364 * property exists 365 * @throws SOAPException if the property name is not recognized 366 */ 367 public Object getProperty(String property) throws SOAPException { 368 throw new UnsupportedOperationException("getProperty must be overridden in subclasses of SOAPMessage"); 369 } 370 371 /** Specifies the character type encoding for the SOAP Message. */ 372 public static final String CHARACTER_SET_ENCODING 373 = "javax.xml.soap.character-set-encoding"; 374 375 /** Specifies whether the SOAP Message should contain an XML declaration. */ 376 public static final String WRITE_XML_DECLARATION 377 = "javax.xml.soap.write-xml-declaration"; 378 }