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} object consists of a SOAP part and optionally
  40  * one or more attachment parts. The SOAP part for a {@code SOAPMessage}
  41  * object is a {@code SOAPPart} 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} object contains the following by default:
  47  * <UL>
  48  *   <LI>A {@code SOAPPart} object
  49  *   <LI>A {@code SOAPEnvelope} object
  50  *   <LI>A {@code SOAPBody} object
  51  *   <LI>A {@code SOAPHeader} object
  52  * </UL>
  53  * The SOAP part of a message can be retrieved by calling the method {@code SOAPMessage.getSOAPPart()}.
  54  * The {@code SOAPEnvelope} object is retrieved from the {@code SOAPPart}
  55  * object, and the {@code SOAPEnvelope} object is used to retrieve the
  56  * {@code SOAPBody} and {@code SOAPHeader} 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} object, a {@code SOAPMessage}
  67  * object may contain zero or more {@code AttachmentPart} objects, each
  68  * of which contains application-specific data. The {@code SOAPMessage}
  69  * interface provides methods for creating {@code AttachmentPart}
  70  * objects and also for adding them to a {@code SOAPMessage} object. A
  71  * party that has received a {@code SOAPMessage} 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} object.
  78  * <P>
  79  * A {@code MessageFactory} object may create {@code SOAPMessage}
  80  * objects with behavior that is specialized to a particular implementation or
  81  * application of SAAJ. For instance, a {@code MessageFactory} object
  82  * may produce {@code SOAPMessage} objects that conform to a particular
  83  * Profile such as ebXML. In this case a {@code MessageFactory} object
  84  * might produce {@code SOAPMessage} 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}
  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} object's
 130      * content with the given description.
 131      *
 132      * @param description a {@code String} 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} object's
 140      * content.
 141      *
 142      * @return a {@code String} describing the content of this
 143      *         message or {@code null} 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} object.
 150          * <P>
 151          * {@code SOAPMessage} 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} object for this {@code SOAPMessage}
 155          *         object
 156          */
 157     public abstract SOAPPart getSOAPPart();
 158 
 159     /**
 160          * Gets the SOAP Body contained in this {@code SOAPMessage} object.
 161          *
 162          * @return the {@code SOAPBody} object contained by this {@code SOAPMessage}
 163          *         object
 164          * @exception SOAPException
 165          *               if the SOAP Body does not exist or cannot be retrieved
 166          * @since 1.6, SAAJ 1.2
 167          */
 168     public SOAPBody getSOAPBody() throws SOAPException {
 169         throw new UnsupportedOperationException("getSOAPBody must be overridden by all subclasses of SOAPMessage");
 170     }
 171 
 172     /**
 173      * Gets the SOAP Header contained in this {@code SOAPMessage} object.
 174      *
 175      * @return the {@code SOAPHeader} object contained
 176      *         by this {@code SOAPMessage} object
 177      * @exception SOAPException
 178      *               if the SOAP Header does not exist or cannot be retrieved
 179      * @since 1.6, SAAJ 1.2
 180      */
 181     public SOAPHeader getSOAPHeader() throws SOAPException {
 182         throw new UnsupportedOperationException("getSOAPHeader must be overridden by all subclasses of SOAPMessage");
 183     }
 184 
 185     /**
 186          * Removes all {@code AttachmentPart} objects that have been added
 187          * to this {@code SOAPMessage} object.
 188          * <P>
 189          * This method does not touch the SOAP part.
 190          */
 191     public abstract void removeAllAttachments();
 192 
 193     /**
 194          * Gets a count of the number of attachments in this message. This count
 195          * does not include the SOAP part.
 196          *
 197          * @return the number of {@code AttachmentPart} objects that are
 198          *         part of this {@code SOAPMessage} object
 199          */
 200     public abstract int countAttachments();
 201 
 202     /**
 203          * Retrieves all the {@code AttachmentPart} objects that are part of
 204          * this {@code SOAPMessage} object.
 205          *
 206          * @return an iterator over all the attachments in this message
 207          */
 208     public abstract Iterator getAttachments();
 209 
 210     /**
 211          * Retrieves all the {@code AttachmentPart} objects that have header
 212          * entries that match the specified headers. Note that a returned
 213          * attachment could have headers in addition to those specified.
 214          *
 215          * @param headers
 216          *           a {@code MimeHeaders} object containing the MIME
 217          *           headers for which to search
 218          * @return an iterator over all attachments that have a header that matches
 219          *         one of the given headers
 220          */
 221     public abstract Iterator getAttachments(MimeHeaders headers);
 222 
 223     /**
 224      * Removes all the {@code AttachmentPart} objects that have header
 225      * entries that match the specified headers. Note that the removed
 226      * attachment could have headers in addition to those specified.
 227      *
 228      * @param headers
 229      *           a {@code MimeHeaders} object containing the MIME
 230      *           headers for which to search
 231      * @since 1.6, SAAJ 1.3
 232      */
 233     public abstract void removeAttachments(MimeHeaders headers);
 234 
 235 
 236     /**
 237      * Returns an {@code AttachmentPart} object that is associated with an
 238      * attachment that is referenced by this {@code SOAPElement} or
 239      * {@code null} if no such attachment exists. References can be made
 240      * via an {@code href} attribute as described in
 241      * <a href="http://www.w3.org/TR/SOAP-attachments#SOAPReferenceToAttachements">SOAP Messages with Attachments</a>,
 242      * or via a single {@code Text} child node containing a URI as
 243      * described in the WS-I Attachments Profile 1.0 for elements of schema
 244      * type <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.html">ref:swaRef</a>.
 245      * These two mechanisms must be supported.
 246      * The support for references via {@code href} attribute also implies that
 247      * this method should also be supported on an element that is an
 248      * <i>xop:Include</i> element (
 249      * <a href="http://www.w3.org/2000/xp/Group/3/06/Attachments/XOP.html">XOP</a>).
 250      * other reference mechanisms may be supported by individual
 251      * implementations of this standard. Contact your vendor for details.
 252      *
 253      * @param  element The {@code SOAPElement} containing the reference to an Attachment
 254      * @return the referenced {@code AttachmentPart} or null if no such
 255      *          {@code AttachmentPart} exists or no reference can be
 256      *          found in this {@code SOAPElement}.
 257      * @throws SOAPException if there is an error in the attempt to access the
 258      *          attachment
 259      *
 260      * @since 1.6, SAAJ 1.3
 261      */
 262     public abstract AttachmentPart getAttachment(SOAPElement element) throws SOAPException;
 263 
 264 
 265     /**
 266      * Adds the given {@code AttachmentPart} object to this {@code SOAPMessage}
 267      * object. An {@code AttachmentPart} object must be created before
 268      * it can be added to a message.
 269      *
 270      * @param AttachmentPart
 271      *           an {@code AttachmentPart} object that is to become part
 272      *           of this {@code SOAPMessage} object
 273      * @exception IllegalArgumentException
 274      */
 275     public abstract void addAttachmentPart(AttachmentPart AttachmentPart);
 276 
 277     /**
 278      * Creates a new empty {@code AttachmentPart} object. Note that the
 279      * method {@code addAttachmentPart} must be called with this new
 280      * {@code AttachmentPart} object as the parameter in order for it to
 281      * become an attachment to this {@code SOAPMessage} object.
 282      *
 283      * @return a new {@code AttachmentPart} object that can be populated
 284      *         and added to this {@code SOAPMessage} object
 285      */
 286     public abstract AttachmentPart createAttachmentPart();
 287 
 288     /**
 289      * Creates an {@code AttachmentPart} object and populates it using
 290      * the given {@code DataHandler} object.
 291      *
 292      * @param dataHandler
 293      *           the {@code javax.activation.DataHandler} object that
 294      *           will generate the content for this {@code SOAPMessage}
 295      *           object
 296      * @return a new {@code AttachmentPart} object that contains data
 297      *         generated by the given {@code DataHandler} object
 298      * @exception IllegalArgumentException
 299      *               if there was a problem with the specified {@code DataHandler}
 300      *               object
 301      * @see javax.activation.DataHandler
 302      * @see javax.activation.DataContentHandler
 303      */
 304     public AttachmentPart createAttachmentPart(DataHandler dataHandler) {
 305         AttachmentPart attachment = createAttachmentPart();
 306         attachment.setDataHandler(dataHandler);
 307         return attachment;
 308     }
 309 
 310     /**
 311      * Returns all the transport-specific MIME headers for this {@code SOAPMessage}
 312      * object in a transport-independent fashion.
 313      *
 314      * @return a {@code MimeHeaders} object containing the {@code MimeHeader}
 315      *         objects
 316      */
 317     public abstract MimeHeaders getMimeHeaders();
 318 
 319     /**
 320      * Creates an {@code AttachmentPart} object and populates it with
 321      * the specified data of the specified content type. The type of the
 322      * {@code Object} should correspond to the value given for the
 323      * {@code Content-Type}.
 324      *
 325      * @param content
 326      *           an {@code Object} containing the content for the
 327      *           {@code AttachmentPart} object to be created
 328      * @param contentType
 329      *           a {@code String} object giving the type of content;
 330      *           examples are "text/xml", "text/plain", and "image/jpeg"
 331      * @return a new {@code AttachmentPart} object that contains the
 332      *         given data
 333      * @exception IllegalArgumentException
 334      *               may be thrown if the contentType does not match the type
 335      *               of the content object, or if there was no
 336      *               {@code DataContentHandler} object for the given
 337      *               content object
 338      * @see javax.activation.DataHandler
 339      * @see javax.activation.DataContentHandler
 340      */
 341     public AttachmentPart createAttachmentPart(
 342         Object content,
 343         String contentType) {
 344         AttachmentPart attachment = createAttachmentPart();
 345         attachment.setContent(content, contentType);
 346         return attachment;
 347     }
 348 
 349     /**
 350      * Updates this {@code SOAPMessage} object with all the changes that
 351      * have been made to it. This method is called automatically when
 352      * {@link SOAPMessage#writeTo(OutputStream)} is  called. However, if
 353      * changes are made to a message that was received or to one that has
 354      * already been sent, the method {@code saveChanges} needs to be
 355      * called explicitly in order to save the changes. The method {@code saveChanges}
 356      * also generates any changes that can be read back (for example, a
 357      * MessageId in profiles that support a message id). All MIME headers in a
 358      * message that is created for sending purposes are guaranteed to have
 359      * valid values only after {@code saveChanges} has been called.
 360      * <P>
 361      * In addition, this method marks the point at which the data from all
 362      * constituent {@code AttachmentPart} objects are pulled into the
 363      * message.
 364      *
 365      * @exception SOAPException if there was a problem saving
 366      *            changes to this message.
 367      */
 368     public abstract void saveChanges() throws SOAPException;
 369 
 370     /**
 371      * Indicates whether this {@code SOAPMessage} object needs to have
 372      * the method {@code saveChanges} called on it.
 373      *
 374      * @return {@code true} if {@code saveChanges} needs to be
 375      *         called; {@code false} otherwise.
 376      */
 377     public abstract boolean saveRequired();
 378 
 379     /**
 380      * Writes this {@code SOAPMessage} object to the given output
 381      * stream. The externalization format is as defined by the SOAP 1.1 with
 382      * Attachments specification.
 383      * <P>
 384      * If there are no attachments, just an XML stream is written out. For
 385      * those messages that have attachments, {@code writeTo} writes a
 386      * MIME-encoded byte stream.
 387      * <P>
 388      * Note that this method does not write the transport-specific MIME Headers
 389      * of the Message
 390      *
 391      * @param out
 392      *           the {@code OutputStream} object to which this {@code SOAPMessage}
 393      *           object will be written
 394      * @exception IOException
 395      *               if an I/O error occurs
 396      * @exception SOAPException
 397      *               if there was a problem in externalizing this SOAP message
 398      */
 399     public abstract void writeTo(OutputStream out)
 400         throws SOAPException, IOException;
 401 
 402     /**
 403      * Associates the specified value with the specified property. If there was
 404      * already a value associated with this property, the old value is
 405      * replaced.
 406      * <p>
 407      * The valid property names include
 408      * {@link SOAPMessage#WRITE_XML_DECLARATION}  and
 409      * {@link SOAPMessage#CHARACTER_SET_ENCODING}. All of these standard SAAJ
 410      * properties are prefixed by "javax.xml.soap". Vendors may also add
 411      * implementation specific properties. These properties must be prefixed
 412      * with package names that are unique to the vendor.
 413      * <p>
 414      * Setting the property {@code WRITE_XML_DECLARATION} to {@code "true"}
 415      * will cause an XML Declaration to be written out at the start of the SOAP
 416      * message. The default value of "false" suppresses this declaration.
 417      * <p>
 418      * The property {@code CHARACTER_SET_ENCODING} defaults to the value
 419      * {@code "utf-8"} which causes the SOAP message to be encoded using
 420      * UTF-8. Setting {@code CHARACTER_SET_ENCODING} to {@code "utf-16"}
 421      * causes the SOAP message to be encoded using UTF-16.
 422      * <p>
 423      * Some implementations may allow encodings in addition to UTF-8 and
 424      * UTF-16. Refer to your vendor's documentation for details.
 425      *
 426      * @param property
 427      *           the property with which the specified value is to be
 428      *           associated.
 429      * @param value
 430      *           the value to be associated with the specified property
 431      * @exception SOAPException
 432      *               if the property name is not recognized.
 433      * @since 1.6, SAAJ 1.2
 434      */
 435     public void setProperty(String property, Object value)
 436         throws SOAPException {
 437             throw new UnsupportedOperationException("setProperty must be overridden by all subclasses of SOAPMessage");
 438     }
 439 
 440     /**
 441      * Retrieves value of the specified property.
 442      *
 443      * @param property
 444      *           the name of the property to retrieve
 445      * @return the value associated with the named property or {@code null}
 446      *         if no such property exists.
 447      * @exception SOAPException
 448      *               if the property name is not recognized.
 449      * @since 1.6, SAAJ 1.2
 450      */
 451     public Object getProperty(String property) throws SOAPException {
 452         throw new UnsupportedOperationException("getProperty must be overridden by all subclasses of SOAPMessage");
 453     }
 454 }