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