1 /*
   2  * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.xml.soap;
  27 import java.io.OutputStream;
  28 import java.io.IOException;
  29 
  30 import java.util.Iterator;
  31 
  32 import javax.activation.DataHandler;
  33 
  34 /**
  35  * The root class for all SOAP messages. As transmitted on the "wire", a SOAP
  36  * message is an XML document or a MIME message whose first body part is an
  37  * XML/SOAP document.
  38  * <P>
  39  * A <code>SOAPMessage</code> object consists of a SOAP part and optionally
  40  * one or more attachment parts. The SOAP part for a <code>SOAPMessage</code>
  41  * object is a <code>SOAPPart</code> object, which contains information used
  42  * for message routing and identification, and which can contain
  43  * application-specific content. All data in the SOAP Part of a message must be
  44  * in XML format.
  45  * <P>
  46  * A new <code>SOAPMessage</code> object contains the following by default:
  47  * <UL>
  48  *   <LI>A <code>SOAPPart</code> object
  49  *   <LI>A <code>SOAPEnvelope</code> object
  50  *   <LI>A <code>SOAPBody</code> object
  51  *   <LI>A <code>SOAPHeader</code> object
  52  * </UL>
  53  * The SOAP part of a message can be retrieved by calling the method <code>SOAPMessage.getSOAPPart()</code>.
  54  * The <code>SOAPEnvelope</code> object is retrieved from the <code>SOAPPart</code>
  55  * object, and the <code>SOAPEnvelope</code> object is used to retrieve the
  56  * <code>SOAPBody</code> and <code>SOAPHeader</code> objects.
  57  *
  58  * <PRE>
  59  *     SOAPPart sp = message.getSOAPPart();
  60  *     SOAPEnvelope se = sp.getEnvelope();
  61  *     SOAPBody sb = se.getBody();
  62  *     SOAPHeader sh = se.getHeader();
  63  * </PRE>
  64  *
  65  * <P>
  66  * In addition to the mandatory <code>SOAPPart</code> object, a <code>SOAPMessage</code>
  67  * object may contain zero or more <code>AttachmentPart</code> objects, each
  68  * of which contains application-specific data. The <code>SOAPMessage</code>
  69  * interface provides methods for creating <code>AttachmentPart</code>
  70  * objects and also for adding them to a <code>SOAPMessage</code> object. A
  71  * party that has received a <code>SOAPMessage</code> object can examine its
  72  * contents by retrieving individual attachment parts.
  73  * <P>
  74  * Unlike the rest of a SOAP message, an attachment is not required to be in
  75  * XML format and can therefore be anything from simple text to an image file.
  76  * Consequently, any message content that is not in XML format must be in an
  77  * <code>AttachmentPart</code> object.
  78  * <P>
  79  * A <code>MessageFactory</code> object may create <code>SOAPMessage</code>
  80  * objects with behavior that is specialized to a particular implementation or
  81  * application of SAAJ. For instance, a <code>MessageFactory</code> object
  82  * may produce <code>SOAPMessage</code> objects that conform to a particular
  83  * Profile such as ebXML. In this case a <code>MessageFactory</code> object
  84  * might produce <code>SOAPMessage</code> objects that are initialized with
  85  * ebXML headers.
  86  * <P>
  87  * In order to ensure backward source compatibility, methods that are added to
  88  * this class after version 1.1 of the SAAJ specification are all concrete
  89  * instead of abstract and they all have default implementations. Unless
  90  * otherwise noted in the JavaDocs for those methods the default
  91  * implementations simply throw an <code>UnsupportedOperationException</code>
  92  * and the SAAJ implementation code must override them with methods that
  93  * provide the specified behavior. Legacy client code does not have this
  94  * restriction, however, so long as there is no claim made that it conforms to
  95  * some later version of the specification than it was originally written for.
  96  * A legacy class that extends the SOAPMessage class can be compiled and/or run
  97  * against succeeding versions of the SAAJ API without modification. If such a
  98  * class was correctly implemented then it will continue to behave correctly
  99  * relative to the version of the specification against which it was written.
 100  *
 101  * @see MessageFactory
 102  * @see AttachmentPart
 103  * @since 1.6
 104  */
 105 public abstract class SOAPMessage {
 106     /**
 107          * Specifies the character type encoding for the SOAP Message. Valid values
 108          * include "utf-8" and "utf-16". See vendor documentation for additional
 109          * supported values. The default is "utf-8".
 110          *
 111          * @see SOAPMessage#setProperty(String, Object) SOAPMessage.setProperty
 112          * @since 1.6, SAAJ 1.2
 113          */
 114     public static final String CHARACTER_SET_ENCODING =
 115         "javax.xml.soap.character-set-encoding";
 116 
 117     /**
 118      * Specifies whether the SOAP Message will contain an XML declaration when
 119      * it is sent. The only valid values are "true" and "false". The default is
 120      * "false".
 121      *
 122      * @see SOAPMessage#setProperty(String, Object) SOAPMessage.setProperty
 123      * @since 1.6, SAAJ 1.2
 124      */
 125     public static final String WRITE_XML_DECLARATION =
 126         "javax.xml.soap.write-xml-declaration";
 127 
 128     /**
 129      * Sets the description of this <code>SOAPMessage</code> object's
 130      * content with the given description.
 131      *
 132      * @param description a <code>String</code> describing the content of this
 133      *         message
 134      * @see #getContentDescription
 135      */
 136     public abstract void setContentDescription(String description);
 137 
 138     /**
 139      * Retrieves a description of this <code>SOAPMessage</code> object's
 140      * content.
 141      *
 142      * @return a <code>String</code> describing the content of this
 143      *         message or <code>null</code> if no description has been set
 144      * @see #setContentDescription
 145      */
 146     public abstract String getContentDescription();
 147 
 148     /**
 149          * Gets the SOAP part of this <code>SOAPMessage</code> object.
 150          * <P>
 151          * <code>SOAPMessage</code> object contains one or more attachments, the
 152          * SOAP Part must be the first MIME body part in the message.
 153          *
 154          * @return the <code>SOAPPart</code> object for this <code>SOAPMessage</code>
 155          *         object
 156          */
 157     public abstract SOAPPart getSOAPPart();
 158 
 159     /**
 160          * Gets the SOAP Body contained in this <code>SOAPMessage</code> object.
 161          * <p>
 162          *
 163          * @return the <code>SOAPBody</code> object contained by this <code>SOAPMessage</code>
 164          *         object
 165          * @exception SOAPException
 166          *               if the SOAP Body does not exist or cannot be retrieved
 167          * @since 1.6, SAAJ 1.2
 168          */
 169     public SOAPBody getSOAPBody() throws SOAPException {
 170         throw new UnsupportedOperationException("getSOAPBody must be overridden by all subclasses of SOAPMessage");
 171     }
 172 
 173     /**
 174          * Gets the SOAP Header contained in this <code>SOAPMessage</code>
 175          * object.
 176          * <p>
 177          *
 178          * @return the <code>SOAPHeader</code> object contained by this <code>SOAPMessage</code>
 179          *         object
 180          * @exception SOAPException
 181          *               if the SOAP Header does not exist or cannot be retrieved
 182          * @since 1.6, SAAJ 1.2
 183          */
 184     public SOAPHeader getSOAPHeader() throws SOAPException {
 185         throw new UnsupportedOperationException("getSOAPHeader must be overridden by all subclasses of SOAPMessage");
 186     }
 187 
 188     /**
 189          * Removes all <code>AttachmentPart</code> objects that have been added
 190          * to this <code>SOAPMessage</code> object.
 191          * <P>
 192          * This method does not touch the SOAP part.
 193          */
 194     public abstract void removeAllAttachments();
 195 
 196     /**
 197          * Gets a count of the number of attachments in this message. This count
 198          * does not include the SOAP part.
 199          *
 200          * @return the number of <code>AttachmentPart</code> objects that are
 201          *         part of this <code>SOAPMessage</code> object
 202          */
 203     public abstract int countAttachments();
 204 
 205     /**
 206          * Retrieves all the <code>AttachmentPart</code> objects that are part of
 207          * this <code>SOAPMessage</code> object.
 208          *
 209          * @return an iterator over all the attachments in this message
 210          */
 211     public abstract Iterator getAttachments();
 212 
 213     /**
 214          * Retrieves all the <code>AttachmentPart</code> objects that have header
 215          * entries that match the specified headers. Note that a returned
 216          * attachment could have headers in addition to those specified.
 217          *
 218          * @param headers
 219          *           a <code>MimeHeaders</code> object containing the MIME
 220          *           headers for which to search
 221          * @return an iterator over all attachments that have a header that matches
 222          *         one of the given headers
 223          */
 224     public abstract Iterator getAttachments(MimeHeaders headers);
 225 
 226     /**
 227      * Removes all the <code>AttachmentPart</code> objects that have header
 228      * entries that match the specified headers. Note that the removed
 229      * attachment could have headers in addition to those specified.
 230      *
 231      * @param headers
 232      *           a <code>MimeHeaders</code> object containing the MIME
 233      *           headers for which to search
 234      * @since 1.6, SAAJ 1.3
 235      */
 236     public abstract void removeAttachments(MimeHeaders headers);
 237 
 238 
 239     /**
 240      * Returns an <code>AttachmentPart</code> object that is associated with an
 241      * attachment that is referenced by this <code>SOAPElement</code> or
 242      * <code>null</code> if no such attachment exists. References can be made
 243      * via an <code>href</code> attribute as described in
 244      * {@link <a href="http://www.w3.org/TR/SOAP-attachments#SOAPReferenceToAttachements">SOAP Messages with Attachments</a>},
 245      * or via a single <code>Text</code> child node containing a URI as
 246      * described in the WS-I Attachments Profile 1.0 for elements of schema
 247      * type {@link <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.html">ref:swaRef</a>}.  These two mechanisms must be supported.
 248      * The support for references via <code>href</code> attribute also implies that
 249      * this method should also be supported on an element that is an
 250      * <i>xop:Include</i> element (
 251      * {@link <a  href="http://www.w3.org/2000/xp/Group/3/06/Attachments/XOP.html">XOP</a>}).
 252      * other reference mechanisms may be supported by individual
 253      * implementations of this standard. Contact your vendor for details.
 254      *
 255      * @param  element The <code>SOAPElement</code> containing the reference to an Attachment
 256      * @return the referenced <code>AttachmentPart</code> or null if no such
 257      *          <code>AttachmentPart</code> exists or no reference can be
 258      *          found in this <code>SOAPElement</code>.
 259      * @throws SOAPException if there is an error in the attempt to access the
 260      *          attachment
 261      *
 262      * @since 1.6, SAAJ 1.3
 263      */
 264     public abstract AttachmentPart getAttachment(SOAPElement element) throws SOAPException;
 265 
 266 
 267     /**
 268      * Adds the given <code>AttachmentPart</code> object to this <code>SOAPMessage</code>
 269      * object. An <code>AttachmentPart</code> object must be created before
 270      * it can be added to a message.
 271      *
 272      * @param AttachmentPart
 273      *           an <code>AttachmentPart</code> object that is to become part
 274      *           of this <code>SOAPMessage</code> object
 275      * @exception IllegalArgumentException
 276      */
 277     public abstract void addAttachmentPart(AttachmentPart AttachmentPart);
 278 
 279     /**
 280      * Creates a new empty <code>AttachmentPart</code> object. Note that the
 281      * method <code>addAttachmentPart</code> must be called with this new
 282      * <code>AttachmentPart</code> object as the parameter in order for it to
 283      * become an attachment to this <code>SOAPMessage</code> object.
 284      *
 285      * @return a new <code>AttachmentPart</code> object that can be populated
 286      *         and added to this <code>SOAPMessage</code> object
 287      */
 288     public abstract AttachmentPart createAttachmentPart();
 289 
 290     /**
 291      * Creates an <code>AttachmentPart</code> object and populates it using
 292      * the given <code>DataHandler</code> object.
 293      *
 294      * @param dataHandler
 295      *           the <code>javax.activation.DataHandler</code> object that
 296      *           will generate the content for this <code>SOAPMessage</code>
 297      *           object
 298      * @return a new <code>AttachmentPart</code> object that contains data
 299      *         generated by the given <code>DataHandler</code> object
 300      * @exception IllegalArgumentException
 301      *               if there was a problem with the specified <code>DataHandler</code>
 302      *               object
 303      * @see javax.activation.DataHandler
 304      * @see javax.activation.DataContentHandler
 305      */
 306     public AttachmentPart createAttachmentPart(DataHandler dataHandler) {
 307         AttachmentPart attachment = createAttachmentPart();
 308         attachment.setDataHandler(dataHandler);
 309         return attachment;
 310     }
 311 
 312     /**
 313      * Returns all the transport-specific MIME headers for this <code>SOAPMessage</code>
 314      * object in a transport-independent fashion.
 315      *
 316      * @return a <code>MimeHeaders</code> object containing the <code>MimeHeader</code>
 317      *         objects
 318      */
 319     public abstract MimeHeaders getMimeHeaders();
 320 
 321     /**
 322      * Creates an <code>AttachmentPart</code> object and populates it with
 323      * the specified data of the specified content type. The type of the
 324      * <code>Object</code> should correspond to the value given for the
 325      * <code>Content-Type</code>.
 326      *
 327      * @param content
 328      *           an <code>Object</code> containing the content for the
 329      *           <code>AttachmentPart</code> object to be created
 330      * @param contentType
 331      *           a <code>String</code> object giving the type of content;
 332      *           examples are "text/xml", "text/plain", and "image/jpeg"
 333      * @return a new <code>AttachmentPart</code> object that contains the
 334      *         given data
 335      * @exception IllegalArgumentException
 336      *               may be thrown if the contentType does not match the type
 337      *               of the content object, or if there was no
 338      *               <code>DataContentHandler</code> object for the given
 339      *               content object
 340      * @see javax.activation.DataHandler
 341      * @see javax.activation.DataContentHandler
 342      */
 343     public AttachmentPart createAttachmentPart(
 344         Object content,
 345         String contentType) {
 346         AttachmentPart attachment = createAttachmentPart();
 347         attachment.setContent(content, contentType);
 348         return attachment;
 349     }
 350 
 351     /**
 352      * Updates this <code>SOAPMessage</code> object with all the changes that
 353      * have been made to it. This method is called automatically when
 354      * {@link SOAPMessage#writeTo(OutputStream)} is  called. However, if
 355      * changes are made to a message that was received or to one that has
 356      * already been sent, the method <code>saveChanges</code> needs to be
 357      * called explicitly in order to save the changes. The method <code>saveChanges</code>
 358      * also generates any changes that can be read back (for example, a
 359      * MessageId in profiles that support a message id). All MIME headers in a
 360      * message that is created for sending purposes are guaranteed to have
 361      * valid values only after <code>saveChanges</code> has been called.
 362      * <P>
 363      * In addition, this method marks the point at which the data from all
 364      * constituent <code>AttachmentPart</code> objects are pulled into the
 365      * message.
 366      * <P>
 367      *
 368      * @exception <code>SOAPException</code> if there was a problem saving
 369      *               changes to this message.
 370      */
 371     public abstract void saveChanges() throws SOAPException;
 372 
 373     /**
 374      * Indicates whether this <code>SOAPMessage</code> object needs to have
 375      * the method <code>saveChanges</code> called on it.
 376      *
 377      * @return <code>true</code> if <code>saveChanges</code> needs to be
 378      *         called; <code>false</code> otherwise.
 379      */
 380     public abstract boolean saveRequired();
 381 
 382     /**
 383      * Writes this <code>SOAPMessage</code> object to the given output
 384      * stream. The externalization format is as defined by the SOAP 1.1 with
 385      * Attachments specification.
 386      * <P>
 387      * If there are no attachments, just an XML stream is written out. For
 388      * those messages that have attachments, <code>writeTo</code> writes a
 389      * MIME-encoded byte stream.
 390      * <P>
 391      * Note that this method does not write the transport-specific MIME Headers
 392      * of the Message
 393      *
 394      * @param out
 395      *           the <code>OutputStream</code> object to which this <code>SOAPMessage</code>
 396      *           object will be written
 397      * @exception IOException
 398      *               if an I/O error occurs
 399      * @exception SOAPException
 400      *               if there was a problem in externalizing this SOAP message
 401      */
 402     public abstract void writeTo(OutputStream out)
 403         throws SOAPException, IOException;
 404 
 405     /**
 406      * Associates the specified value with the specified property. If there was
 407      * already a value associated with this property, the old value is
 408      * replaced.
 409      * <p>
 410      * The valid property names include
 411      * {@link SOAPMessage#WRITE_XML_DECLARATION}  and
 412      * {@link SOAPMessage#CHARACTER_SET_ENCODING}. All of these standard SAAJ
 413      * properties are prefixed by "javax.xml.soap". Vendors may also add
 414      * implementation specific properties. These properties must be prefixed
 415      * with package names that are unique to the vendor.
 416      * <p>
 417      * Setting the property <code>WRITE_XML_DECLARATION</code> to <code>"true"</code>
 418      * will cause an XML Declaration to be written out at the start of the SOAP
 419      * message. The default value of "false" suppresses this declaration.
 420      * <p>
 421      * The property <code>CHARACTER_SET_ENCODING</code> defaults to the value
 422      * <code>"utf-8"</code> which causes the SOAP message to be encoded using
 423      * UTF-8. Setting <code>CHARACTER_SET_ENCODING</code> to <code>"utf-16"</code>
 424      * causes the SOAP message to be encoded using UTF-16.
 425      * <p>
 426      * Some implementations may allow encodings in addition to UTF-8 and
 427      * UTF-16. Refer to your vendor's documentation for details.
 428      *
 429      * @param property
 430      *           the property with which the specified value is to be
 431      *           associated.
 432      * @param value
 433      *           the value to be associated with the specified property
 434      * @exception SOAPException
 435      *               if the property name is not recognized.
 436      * @since 1.6, SAAJ 1.2
 437      */
 438     public void setProperty(String property, Object value)
 439         throws SOAPException {
 440             throw new UnsupportedOperationException("setProperty must be overridden by all subclasses of SOAPMessage");
 441     }
 442 
 443     /**
 444      * Retrieves value of the specified property.
 445      *
 446      * @param property
 447      *           the name of the property to retrieve
 448      * @return the value associated with the named property or <code>null</code>
 449      *         if no such property exists.
 450      * @exception SOAPException
 451      *               if the property name is not recognized.
 452      * @since 1.6, SAAJ 1.2
 453      */
 454     public Object getProperty(String property) throws SOAPException {
 455         throw new UnsupportedOperationException("getProperty must be overridden by all subclasses of SOAPMessage");
 456     }
 457 }