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