View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package javax.xml.soap;
17  
18  import javax.activation.DataHandler;
19  import java.io.IOException;
20  import java.io.OutputStream;
21  import java.util.Iterator;
22  
23  /**
24   * <P>The root class for all SOAP messages. As transmitted on the
25   * "wire", a SOAP message is an XML document or a MIME message
26   * whose first body part is an XML/SOAP document.</P>
27   *
28   * <P>A <CODE>SOAPMessage</CODE> object consists of a SOAP part
29   * and optionally one or more attachment parts. The SOAP part for
30   * a <CODE>SOAPMessage</CODE> object is a <CODE>SOAPPart</CODE>
31   * object, which contains information used for message routing and
32   * identification, and which can contain application-specific
33   * content. All data in the SOAP Part of a message must be in XML
34   * format.</P>
35   *
36   * <P>A new <CODE>SOAPMessage</CODE> object contains the following
37   * by default:</P>
38   *
39   * <UL>
40   *  <LI>A <CODE>SOAPPart</CODE> object</LI>
41   *
42   *  <LI>A <CODE>SOAPEnvelope</CODE> object</LI>
43   *
44   *  <LI>A <CODE>SOAPBody</CODE> object</LI>
45   *
46   *  <LI>A <CODE>SOAPHeader</CODE> object</LI>
47   * </UL>
48   * The SOAP part of a message can be retrieved by calling the
49   * method <CODE>SOAPMessage.getSOAPPart()</CODE>. The <CODE>
50   * SOAPEnvelope</CODE> object is retrieved from the <CODE>
51   * SOAPPart</CODE> object, and the <CODE>SOAPEnvelope</CODE>
52   * object is used to retrieve the <CODE>SOAPBody</CODE> and <CODE>
53   * SOAPHeader</CODE> objects.
54   * <PRE>
55   * SOAPPart sp = message.getSOAPPart();
56   * SOAPEnvelope se = sp.getEnvelope();
57   * SOAPBody sb = se.getBody();
58   * SOAPHeader sh = se.getHeader();
59   * </PRE>
60   *
61   * <P>In addition to the mandatory <CODE>SOAPPart</CODE> object, a
62   * <CODE>SOAPMessage</CODE> object may contain zero or more <CODE>
63   * AttachmentPart</CODE> objects, each of which contains
64   * application-specific data. The <CODE>SOAPMessage</CODE>
65   * interface provides methods for creating <CODE>
66   * AttachmentPart</CODE> objects and also for adding them to a
67   * <CODE>SOAPMessage</CODE> object. A party that has received a
68   * <CODE>SOAPMessage</CODE> object can examine its contents by
69   * retrieving individual attachment parts.</P>
70   *
71   * <P>Unlike the rest of a SOAP message, an attachment is not
72   * required to be in XML format and can therefore be anything from
73   * simple text to an image file. Consequently, any message content
74   * that is not in XML format must be in an <CODE>
75   * AttachmentPart</CODE> object.</P>
76   *
77   * <P>A <CODE>MessageFactory</CODE> object creates new <CODE>
78   * SOAPMessage</CODE> objects. If the <CODE>MessageFactory</CODE>
79   * object was initialized with a messaging Profile, it produces
80   * <CODE>SOAPMessage</CODE> objects that conform to that Profile.
81   * For example, a <CODE>SOAPMessage</CODE> object created by a
82   * <CODE>MessageFactory</CODE> object initialized with the ebXML
83   * Profile will have the appropriate ebXML headers.</P>
84   * @see MessageFactory MessageFactory
85   * @see AttachmentPart AttachmentPart
86   */
87  public abstract class SOAPMessage {
88  
89      public SOAPMessage() {}
90  
91      /**
92       * Retrieves a description of this <CODE>SOAPMessage</CODE>
93       * object's content.
94       * @return  a <CODE>String</CODE> describing the content of this
95       *     message or <CODE>null</CODE> if no description has been
96       *     set
97       * @see #setContentDescription(java.lang.String) setContentDescription(java.lang.String)
98       */
99      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 }