/*
 * JBoss, the OpenSource EJB server
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package javax.xml.soap;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.HashMap;
import javax.activation.DataHandler;

/** The root class for all SOAP messages. As transmitted on the "wire", a SOAP message is an XML document or a
 * MIME message whose first body part is an XML/SOAP document.
 *
 * A SOAPMessage object consists of a SOAP part and optionally one or more attachment parts.
 * The SOAP part for a SOAPMessage object is a SOAPPart object, which contains information used for message routing and
 * identification, and which can contain application-specific content. All data in the SOAP Part of a message must be in XML format.
 *
 * A new SOAPMessage object contains the following by default:
 *
 * A SOAPPart object
 * A SOAPEnvelope object
 * A SOAPBody object
 * A SOAPHeader object
 *
 * The SOAP part of a message can be retrieved by calling the method SOAPMessage.getSOAPPart().
 * The SOAPEnvelope object is retrieved from the SOAPPart object, and the SOAPEnvelope object is used to retrieve the
 * SOAPBody and SOAPHeader objects.
 *
 * SOAPPart sp = message.getSOAPPart();
 * SOAPEnvelope se = sp.getEnvelope();
 * SOAPBody sb = se.getBody();
 * SOAPHeader sh = se.getHeader();
 *
 * In addition to the mandatory SOAPPart object, a SOAPMessage object may contain zero or more AttachmentPart objects,
 * each of which contains application-specific data. The SOAPMessage interface provides methods for creating AttachmentPart
 * objects and also for adding them to a SOAPMessage object. A party that has received a SOAPMessage object can examine
 * its contents by retrieving individual attachment parts.
 *
 * Unlike the rest of a SOAP message, an attachment is not required to be in XML format and can therefore be anything from
 * simple text to an image file. Consequently, any message content that is not in XML format must be in an AttachmentPart object.
 *
 * A MessageFactory object may create SOAPMessage objects with behavior that is specialized to a particular
 * implementation or application of SAAJ. For instance, a MessageFactory object may produce SOAPMessage objects that
 * conform to a particular Profile such as ebXML. In this case a MessageFactory object might produce SOAPMessage
 * objects that are initialized with ebXML headers.
 *
 * In order to ensure backward source compatibility, methods that are added to this class after version 1.1 of the SAAJ
 * specification are all concrete instead of abstract and they all have default implementations.
 * Unless otherwise noted in the JavaDocs for those methods the default implementations simply throw an
 * UnsupportedOperationException and the SAAJ implementation code must override them with methods that provide
 * the specified behavior. Legacy client code does not have this restriction, however, so long as there is no claim
 * made that it conforms to some later version of the specification than it was originally written for.
 * A legacy class that extends the SOAPMessage class can be compiled and/or run against succeeding versions of
 * the SAAJ API without modification. If such a class was correctly implemented then it will continue to behave
 * correctly relative the the version of the specification against which it was written.
 *
 * @author Scott.Stark@jboss.org
 * @version $Revision: 1.3.4.1 $
 */
public abstract class SOAPMessage
{
   private HashMap properties = new HashMap();
	public static final String CHARACTER_SET_ENCODING =
      "javax.xml.soap.character-set-encoding";
	public static final String WRITE_XML_DECLARATION =
      "javax.xml.soap.write-xml-declaration";

   public abstract void addAttachmentPart(AttachmentPart attachmentpart);

   public abstract AttachmentPart createAttachmentPart();

   public AttachmentPart createAttachmentPart(DataHandler datahandler)
   {
       AttachmentPart part = createAttachmentPart();
       part.setDataHandler(datahandler);
       return part;
   }

   public AttachmentPart createAttachmentPart(Object content, String contentType)
   {
       AttachmentPart part = createAttachmentPart();
       part.setContent(content, contentType);
       return part;
   }

   public Object getProperty(String property)
                   throws SOAPException
   {
      return properties.get(property);
   }
   public void setProperty(String property, Object value)
      throws SOAPException
   {
      properties.put(property, value);
   }

   public SOAPBody getSOAPBody() throws SOAPException
   {
      throw new SOAPException("SOAPMessage does not implement getSOAPBody");
   }
   public SOAPHeader getSOAPHeader() throws SOAPException
   {
      throw new SOAPException("SOAPMessage does not implement getSOAPHeader");      
   }

   public abstract String getContentDescription();

   public abstract void setContentDescription(String description);

   public abstract MimeHeaders getMimeHeaders();

   public abstract SOAPPart getSOAPPart();

   public abstract void removeAllAttachments();

   public abstract int countAttachments();

   public abstract Iterator getAttachments();

   public abstract Iterator getAttachments(MimeHeaders mimeheaders);

   /**
    * Updates this SOAPMessage object with all the changes that have been made to it.
    * This method is called automatically when writeTo(OutputStream) is called.
    * However, if changes are made to a message that was received or to one that has already been sent, the method
    * saveChanges needs to be called explicitly in order to save the changes.
    * The method saveChanges also generates any changes that can be read back (for example,
    * a MessageId in profiles that support a message id). All MIME headers in a message that is created for sending
    * purposes are guaranteed to have valid values only after saveChanges has been called.
    *
    * In addition, this method marks the point at which the data from all constituent AttachmentPart objects are pulled into the message.
    *
    * @throws SOAPException if there was a problem saving changes to this message.
    */
   public abstract void saveChanges() throws SOAPException;

   public abstract boolean saveRequired();

   public abstract void writeTo(OutputStream outputstream)
       throws SOAPException, IOException;

}
