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 }