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    }