1 /*
   2  * Copyright (c) 2004, 2015, 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  * {@code
  59  *     SOAPPart sp = message.getSOAPPart();
  60  *     SOAPEnvelope se = sp.getEnvelope();
  61  *     SOAPBody sb = se.getBody();
  62  *     SOAPHeader sh = se.getHeader();
  63  * }
  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     /**
 108      * Specifies the character type encoding for the SOAP Message. Valid values
 109      * include "utf-8" and "utf-16". See vendor documentation for additional
 110      * supported values. The default is "utf-8".
 111      *
 112      * @see SOAPMessage#setProperty(String, Object) SOAPMessage.setProperty
 113      * @since 1.6, SAAJ 1.2
 114      */
 115     public static final String CHARACTER_SET_ENCODING =
 116         "javax.xml.soap.character-set-encoding";
 117 
 118     /**
 119      * Specifies whether the SOAP Message will contain an XML declaration when
 120      * it is sent. The only valid values are "true" and "false". The default is
 121      * "false".
 122      *
 123      * @see SOAPMessage#setProperty(String, Object) SOAPMessage.setProperty
 124      * @since 1.6, SAAJ 1.2
 125      */
 126     public static final String WRITE_XML_DECLARATION =
 127         "javax.xml.soap.write-xml-declaration";
 128 
 129     /**
 130      * Sets the description of this {@code SOAPMessage} object's
 131      * content with the given description.
 132      *
 133      * @param description a {@code String} describing the content of this
 134      *         message
 135      * @see #getContentDescription
 136      */
 137     public abstract void setContentDescription(String description);
 138 
 139     /**
 140      * Retrieves a description of this {@code SOAPMessage} object's
 141      * content.
 142      *
 143      * @return a {@code String} describing the content of this
 144      *         message or {@code null} if no description has been set
 145      * @see #setContentDescription
 146      */
 147     public abstract String getContentDescription();
 148 
 149     /**
 150      * Gets the SOAP part of this {@code SOAPMessage} object.
 151      * <p>
 152      * {@code SOAPMessage} object contains one or more attachments, the
 153      * SOAP Part must be the first MIME body part in the message.
 154      *
 155      * @return the {@code SOAPPart} object for this {@code SOAPMessage}
 156      * object
 157      */
 158     public abstract SOAPPart getSOAPPart();
 159 
 160     /**
 161      * Gets the SOAP Body contained in this {@code SOAPMessage} object.
 162      *
 163      * @return the {@code SOAPBody} object contained by this {@code SOAPMessage}
 164      * object
 165      * @throws SOAPException 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 a {@code MimeHeaders} object containing the MIME
 216      *                headers for which to search
 217      * @return an iterator over all attachments that have a header that matches
 218      * one of the given headers
 219      */
 220     public abstract Iterator getAttachments(MimeHeaders headers);
 221 
 222     /**
 223      * Removes all the {@code AttachmentPart} objects that have header
 224      * entries that match the specified headers. Note that the removed
 225      * attachment could have headers in addition to those specified.
 226      *
 227      * @param headers
 228      *           a {@code MimeHeaders} object containing the MIME
 229      *           headers for which to search
 230      * @since 1.6, SAAJ 1.3
 231      */
 232     public abstract void removeAttachments(MimeHeaders headers);
 233 
 234 
 235     /**
 236      * Returns an {@code AttachmentPart} object that is associated with an
 237      * attachment that is referenced by this {@code SOAPElement} or
 238      * {@code null} if no such attachment exists. References can be made
 239      * via an {@code href} attribute as described in
 240      * <a href="http://www.w3.org/TR/SOAP-attachments#SOAPReferenceToAttachements">SOAP Messages with Attachments</a>,
 241      * or via a single {@code Text} child node containing a URI as
 242      * described in the WS-I Attachments Profile 1.0 for elements of schema
 243      * type <a href="http://www.ws-i.org/Profiles/AttachmentsProfile-1.0-2004-08-24.html">ref:swaRef</a>.
 244      * These two mechanisms must be supported.
 245      * The support for references via {@code href} attribute also implies that
 246      * this method should also be supported on an element that is an
 247      * <i>xop:Include</i> element (
 248      * <a href="http://www.w3.org/2000/xp/Group/3/06/Attachments/XOP.html">XOP</a>).
 249      * other reference mechanisms may be supported by individual
 250      * implementations of this standard. Contact your vendor for details.
 251      *
 252      * @param  element The {@code SOAPElement} containing the reference to an Attachment
 253      * @return the referenced {@code AttachmentPart} or null if no such
 254      *          {@code AttachmentPart} exists or no reference can be
 255      *          found in this {@code SOAPElement}.
 256      * @throws SOAPException if there is an error in the attempt to access the
 257      *          attachment
 258      *
 259      * @since 1.6, SAAJ 1.3
 260      */
 261     public abstract AttachmentPart getAttachment(SOAPElement element) throws SOAPException;
 262 
 263 
 264     /**
 265      * Adds the given {@code AttachmentPart} object to this {@code SOAPMessage}
 266      * object. An {@code AttachmentPart} object must be created before
 267      * it can be added to a message.
 268      *
 269      * @param AttachmentPart
 270      *           an {@code AttachmentPart} object that is to become part
 271      *           of this {@code SOAPMessage} object
 272      * @exception IllegalArgumentException
 273      */
 274     public abstract void addAttachmentPart(AttachmentPart AttachmentPart);
 275 
 276     /**
 277      * Creates a new empty {@code AttachmentPart} object. Note that the
 278      * method {@code addAttachmentPart} must be called with this new
 279      * {@code AttachmentPart} object as the parameter in order for it to
 280      * become an attachment to this {@code SOAPMessage} object.
 281      *
 282      * @return a new {@code AttachmentPart} object that can be populated
 283      *         and added to this {@code SOAPMessage} object
 284      */
 285     public abstract AttachmentPart createAttachmentPart();
 286 
 287     /**
 288      * Creates an {@code AttachmentPart} object and populates it using
 289      * the given {@code DataHandler} object.
 290      *
 291      * @param dataHandler
 292      *           the {@code javax.activation.DataHandler} object that
 293      *           will generate the content for this {@code SOAPMessage}
 294      *           object
 295      * @return a new {@code AttachmentPart} object that contains data
 296      *         generated by the given {@code DataHandler} object
 297      * @exception IllegalArgumentException
 298      *               if there was a problem with the specified {@code DataHandler}
 299      *               object
 300      * @see javax.activation.DataHandler
 301      * @see javax.activation.DataContentHandler
 302      */
 303     public AttachmentPart createAttachmentPart(DataHandler dataHandler) {
 304         AttachmentPart attachment = createAttachmentPart();
 305         attachment.setDataHandler(dataHandler);
 306         return attachment;
 307     }
 308 
 309     /**
 310      * Returns all the transport-specific MIME headers for this {@code SOAPMessage}
 311      * object in a transport-independent fashion.
 312      *
 313      * @return a {@code MimeHeaders} object containing the {@code MimeHeader}
 314      *         objects
 315      */
 316     public abstract MimeHeaders getMimeHeaders();
 317 
 318     /**
 319      * Creates an {@code AttachmentPart} object and populates it with
 320      * the specified data of the specified content type. The type of the
 321      * {@code Object} should correspond to the value given for the
 322      * {@code Content-Type}.
 323      *
 324      * @param content
 325      *           an {@code Object} containing the content for the
 326      *           {@code AttachmentPart} object to be created
 327      * @param contentType
 328      *           a {@code String} object giving the type of content;
 329      *           examples are "text/xml", "text/plain", and "image/jpeg"
 330      * @return a new {@code AttachmentPart} object that contains the
 331      *         given data
 332      * @exception IllegalArgumentException
 333      *               may be thrown if the contentType does not match the type
 334      *               of the content object, or if there was no
 335      *               {@code DataContentHandler} object for the given
 336      *               content object
 337      * @see javax.activation.DataHandler
 338      * @see javax.activation.DataContentHandler
 339      */
 340     public AttachmentPart createAttachmentPart(
 341         Object content,
 342         String contentType) {
 343         AttachmentPart attachment = createAttachmentPart();
 344         attachment.setContent(content, contentType);
 345         return attachment;
 346     }
 347 
 348     /**
 349      * Updates this {@code SOAPMessage} object with all the changes that
 350      * have been made to it. This method is called automatically when
 351      * {@link SOAPMessage#writeTo(OutputStream)} is  called. However, if
 352      * changes are made to a message that was received or to one that has
 353      * already been sent, the method {@code saveChanges} needs to be
 354      * called explicitly in order to save the changes. The method {@code saveChanges}
 355      * also generates any changes that can be read back (for example, a
 356      * MessageId in profiles that support a message id). All MIME headers in a
 357      * message that is created for sending purposes are guaranteed to have
 358      * valid values only after {@code saveChanges} has been called.
 359      * <P>
 360      * In addition, this method marks the point at which the data from all
 361      * constituent {@code AttachmentPart} objects are pulled into the
 362      * message.
 363      *
 364      * @exception SOAPException if there was a problem saving
 365      *            changes to this message.
 366      */
 367     public abstract void saveChanges() throws SOAPException;
 368 
 369     /**
 370      * Indicates whether this {@code SOAPMessage} object needs to have
 371      * the method {@code saveChanges} called on it.
 372      *
 373      * @return {@code true} if {@code saveChanges} needs to be
 374      *         called; {@code false} otherwise.
 375      */
 376     public abstract boolean saveRequired();
 377 
 378     /**
 379      * Writes this {@code SOAPMessage} object to the given output
 380      * stream. The externalization format is as defined by the SOAP 1.1 with
 381      * Attachments specification.
 382      * <P>
 383      * If there are no attachments, just an XML stream is written out. For
 384      * those messages that have attachments, {@code writeTo} writes a
 385      * MIME-encoded byte stream.
 386      * <P>
 387      * Note that this method does not write the transport-specific MIME Headers
 388      * of the Message
 389      *
 390      * @param out
 391      *           the {@code OutputStream} object to which this {@code SOAPMessage}
 392      *           object will be written
 393      * @exception IOException
 394      *               if an I/O error occurs
 395      * @exception SOAPException
 396      *               if there was a problem in externalizing this SOAP message
 397      */
 398     public abstract void writeTo(OutputStream out)
 399         throws SOAPException, IOException;
 400 
 401     /**
 402      * Associates the specified value with the specified property. If there was
 403      * already a value associated with this property, the old value is
 404      * replaced.
 405      * <p>
 406      * The valid property names include
 407      * {@link SOAPMessage#WRITE_XML_DECLARATION}  and
 408      * {@link SOAPMessage#CHARACTER_SET_ENCODING}. All of these standard SAAJ
 409      * properties are prefixed by "javax.xml.soap". Vendors may also add
 410      * implementation specific properties. These properties must be prefixed
 411      * with package names that are unique to the vendor.
 412      * <p>
 413      * Setting the property {@code WRITE_XML_DECLARATION} to {@code "true"}
 414      * will cause an XML Declaration to be written out at the start of the SOAP
 415      * message. The default value of "false" suppresses this declaration.
 416      * <p>
 417      * The property {@code CHARACTER_SET_ENCODING} defaults to the value
 418      * {@code "utf-8"} which causes the SOAP message to be encoded using
 419      * UTF-8. Setting {@code CHARACTER_SET_ENCODING} to {@code "utf-16"}
 420      * causes the SOAP message to be encoded using UTF-16.
 421      * <p>
 422      * Some implementations may allow encodings in addition to UTF-8 and
 423      * UTF-16. Refer to your vendor's documentation for details.
 424      *
 425      * @param property
 426      *           the property with which the specified value is to be
 427      *           associated.
 428      * @param value
 429      *           the value to be associated with the specified property
 430      * @exception SOAPException
 431      *               if the property name is not recognized.
 432      * @since 1.6, SAAJ 1.2
 433      */
 434     public void setProperty(String property, Object value)
 435         throws SOAPException {
 436             throw new UnsupportedOperationException("setProperty must be overridden by all subclasses of SOAPMessage");
 437     }
 438 
 439     /**
 440      * Retrieves value of the specified property.
 441      *
 442      * @param property
 443      *           the name of the property to retrieve
 444      * @return the value associated with the named property or {@code null}
 445      *         if no such property exists.
 446      * @exception SOAPException
 447      *               if the property name is not recognized.
 448      * @since 1.6, SAAJ 1.2
 449      */
 450     public Object getProperty(String property) throws SOAPException {
 451         throw new UnsupportedOperationException("getProperty must be overridden by all subclasses of SOAPMessage");
 452     }
 453 }