1 /*
   2  * Copyright (c) 2004, 2017, 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>{@code
  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     /**
 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<AttachmentPart> 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<AttachmentPart> 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      *               if there was a problem with the specified {@code attachmentPart}
 274      *               object
 275      */
 276     public abstract void addAttachmentPart(AttachmentPart attachmentPart);
 277 
 278     /**
 279      * Creates a new empty {@code AttachmentPart} object. Note that the
 280      * method {@code addAttachmentPart} must be called with this new
 281      * {@code AttachmentPart} object as the parameter in order for it to
 282      * become an attachment to this {@code SOAPMessage} object.
 283      *
 284      * @return a new {@code AttachmentPart} object that can be populated
 285      *         and added to this {@code SOAPMessage} object
 286      */
 287     public abstract AttachmentPart createAttachmentPart();
 288 
 289     /**
 290      * Creates an {@code AttachmentPart} object and populates it using
 291      * the given {@code DataHandler} object.
 292      *
 293      * @param dataHandler
 294      *           the {@code javax.activation.DataHandler} object that
 295      *           will generate the content for this {@code SOAPMessage}
 296      *           object
 297      * @return a new {@code AttachmentPart} object that contains data
 298      *         generated by the given {@code DataHandler} object
 299      * @exception IllegalArgumentException
 300      *               if there was a problem with the specified {@code DataHandler}
 301      *               object
 302      * @see javax.activation.DataHandler
 303      * @see javax.activation.DataContentHandler
 304      */
 305     public AttachmentPart createAttachmentPart(DataHandler dataHandler) {
 306         AttachmentPart attachment = createAttachmentPart();
 307         attachment.setDataHandler(dataHandler);
 308         return attachment;
 309     }
 310 
 311     /**
 312      * Returns all the transport-specific MIME headers for this {@code SOAPMessage}
 313      * object in a transport-independent fashion.
 314      *
 315      * @return a {@code MimeHeaders} object containing the {@code MimeHeader}
 316      *         objects
 317      */
 318     public abstract MimeHeaders getMimeHeaders();
 319 
 320     /**
 321      * Creates an {@code AttachmentPart} object and populates it with
 322      * the specified data of the specified content type. The type of the
 323      * {@code Object} should correspond to the value given for the
 324      * {@code Content-Type}.
 325      *
 326      * @param content
 327      *           an {@code Object} containing the content for the
 328      *           {@code AttachmentPart} object to be created
 329      * @param contentType
 330      *           a {@code String} object giving the type of content;
 331      *           examples are "text/xml", "text/plain", and "image/jpeg"
 332      * @return a new {@code AttachmentPart} object that contains the
 333      *         given data
 334      * @exception IllegalArgumentException
 335      *               may be thrown if the contentType does not match the type
 336      *               of the content object, or if there was no
 337      *               {@code DataContentHandler} object for the given
 338      *               content object
 339      * @see javax.activation.DataHandler
 340      * @see javax.activation.DataContentHandler
 341      */
 342     public AttachmentPart createAttachmentPart(
 343         Object content,
 344         String contentType) {
 345         AttachmentPart attachment = createAttachmentPart();
 346         attachment.setContent(content, contentType);
 347         return attachment;
 348     }
 349 
 350     /**
 351      * Updates this {@code SOAPMessage} object with all the changes that
 352      * have been made to it. This method is called automatically when
 353      * {@link SOAPMessage#writeTo(OutputStream)} is  called. However, if
 354      * changes are made to a message that was received or to one that has
 355      * already been sent, the method {@code saveChanges} needs to be
 356      * called explicitly in order to save the changes. The method {@code saveChanges}
 357      * also generates any changes that can be read back (for example, a
 358      * MessageId in profiles that support a message id). All MIME headers in a
 359      * message that is created for sending purposes are guaranteed to have
 360      * valid values only after {@code saveChanges} has been called.
 361      * <P>
 362      * In addition, this method marks the point at which the data from all
 363      * constituent {@code AttachmentPart} objects are pulled into the
 364      * message.
 365      *
 366      * @exception SOAPException if there was a problem saving
 367      *            changes to this message.
 368      */
 369     public abstract void saveChanges() throws SOAPException;
 370 
 371     /**
 372      * Indicates whether this {@code SOAPMessage} object needs to have
 373      * the method {@code saveChanges} called on it.
 374      *
 375      * @return {@code true} if {@code saveChanges} needs to be
 376      *         called; {@code false} otherwise.
 377      */
 378     public abstract boolean saveRequired();
 379 
 380     /**
 381      * Writes this {@code SOAPMessage} object to the given output
 382      * stream. The externalization format is as defined by the SOAP 1.1 with
 383      * Attachments specification.
 384      * <P>
 385      * If there are no attachments, just an XML stream is written out. For
 386      * those messages that have attachments, {@code writeTo} writes a
 387      * MIME-encoded byte stream.
 388      * <P>
 389      * Note that this method does not write the transport-specific MIME Headers
 390      * of the Message
 391      *
 392      * @param out
 393      *           the {@code OutputStream} object to which this {@code SOAPMessage}
 394      *           object will be written
 395      * @exception IOException
 396      *               if an I/O error occurs
 397      * @exception SOAPException
 398      *               if there was a problem in externalizing this SOAP message
 399      */
 400     public abstract void writeTo(OutputStream out)
 401         throws SOAPException, IOException;
 402 
 403     /**
 404      * Associates the specified value with the specified property. If there was
 405      * already a value associated with this property, the old value is
 406      * replaced.
 407      * <p>
 408      * The valid property names include
 409      * {@link SOAPMessage#WRITE_XML_DECLARATION}  and
 410      * {@link SOAPMessage#CHARACTER_SET_ENCODING}. All of these standard SAAJ
 411      * properties are prefixed by "javax.xml.soap". Vendors may also add
 412      * implementation specific properties. These properties must be prefixed
 413      * with package names that are unique to the vendor.
 414      * <p>
 415      * Setting the property {@code WRITE_XML_DECLARATION} to {@code "true"}
 416      * will cause an XML Declaration to be written out at the start of the SOAP
 417      * message. The default value of "false" suppresses this declaration.
 418      * <p>
 419      * The property {@code CHARACTER_SET_ENCODING} defaults to the value
 420      * {@code "utf-8"} which causes the SOAP message to be encoded using
 421      * UTF-8. Setting {@code CHARACTER_SET_ENCODING} to {@code "utf-16"}
 422      * causes the SOAP message to be encoded using UTF-16.
 423      * <p>
 424      * Some implementations may allow encodings in addition to UTF-8 and
 425      * UTF-16. Refer to your vendor's documentation for details.
 426      *
 427      * @param property
 428      *           the property with which the specified value is to be
 429      *           associated.
 430      * @param value
 431      *           the value to be associated with the specified property
 432      * @exception SOAPException
 433      *               if the property name is not recognized.
 434      * @since 1.6, SAAJ 1.2
 435      */
 436     public void setProperty(String property, Object value)
 437         throws SOAPException {
 438             throw new UnsupportedOperationException("setProperty must be overridden by all subclasses of SOAPMessage");
 439     }
 440 
 441     /**
 442      * Retrieves value of the specified property.
 443      *
 444      * @param property
 445      *           the name of the property to retrieve
 446      * @return the value associated with the named property or {@code null}
 447      *         if no such property exists.
 448      * @exception SOAPException
 449      *               if the property name is not recognized.
 450      * @since 1.6, SAAJ 1.2
 451      */
 452     public Object getProperty(String property) throws SOAPException {
 453         throw new UnsupportedOperationException("getProperty must be overridden by all subclasses of SOAPMessage");
 454     }
 455 }