FileDocCategorySizeDatePackage
Message.javaAPI DocApache Axis 1.429345Sat Apr 22 18:57:28 BST 2006org.apache.axis

Message

public class Message extends SOAPMessage implements Serializable
A complete SOAP (and/or XML-RPC, eventually) message. Includes both the root part (as a SOAPPart), and zero or more MIME attachments (as AttachmentParts).

Eventually should be refactored to generalize SOAPPart for multiple protocols (XML-RPC?).

author
Rob Jellinghaus (robj@unrealities.com)
author
Doug Davis (dug@us.ibm.com)
author
Glen Daniels (gdaniels@allaire.com)
author
Rick Rineholt
author
Heejune Ahn (cityboy@tmax.co.kr)

Fields Summary
protected static Log
log
The Log that this class uses for logging all messages.
public static final String
REQUEST
Message is a request.
public static final String
RESPONSE
Message is a a response.
public static final String
MIME_MULTIPART_RELATED
MIME parts defined for messages.
public static final String
MIME_APPLICATION_DIME
DIME parts defined for messages.
public static final String
CONTENT_TYPE_MTOM
Content Type for MTOM/XOP
public static final String
DEFAULT_ATTACHMNET_IMPL
Default Attachments Implementation class.
private static String
mAttachmentsImplClassName
Current Attachment implementation.
public static final String
MIME_UNKNOWN
Look at the input stream to find the headers to decide the mime type.
private String
messageType
The messageType indicates whether this is request or response.
private SOAPPart
mSOAPPart
This Message's SOAPPart. Will always be here.
private org.apache.axis.attachments.Attachments
mAttachments
This Message's Attachments object, which manages the attachments contained in this Message.
private org.apache.axis.message.MimeHeaders
headers
private boolean
saveRequired
private MessageContext
msgContext
private static Class
attachImpl
private static boolean
checkForAttachmentSupport
private static boolean
attachmentSupportEnabled
private Hashtable
mProps
Constructors Summary
public Message(Object initialContents)
Construct a Message. An overload of Message(Object, boolean), defaulting bodyInStream to false.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault

        setup(initialContents, false, null, null, null);
    
public Message(Object initialContents, boolean bodyInStream)
Construct a Message, using the provided initialContents as the contents of the Message's SOAPPart.

Eventually, genericize this to return the RootPart instead, which will have some kind of EnvelopeFactory to enable support for things other than SOAP. But that all will come later, with lots of additional refactoring.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault.
param
bodyInStream is true if initialContents is an InputStream containing just the SOAP body (no SOAP-ENV).

        setup(initialContents, bodyInStream, null, null, null);
    
public Message(Object initialContents, boolean bodyInStream, MimeHeaders headers)
Construct a Message, using the provided initialContents as the contents of the Message's SOAPPart.

Eventually, genericize this to return the RootPart instead, which will have some kind of EnvelopeFactory to enable support for things other than SOAP. But that all will come later, with lots of additional refactoring.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault.
param
bodyInStream is true if initialContents is an InputStream containing just the SOAP body (no SOAP-ENV).
param
headers Mime Headers.

        setup(initialContents, bodyInStream, null, null, headers);
    
public Message(Object initialContents, org.apache.axis.message.MimeHeaders headers)
Construct a Message, using the provided initialContents as the contents of the Message's SOAPPart.

Eventually, genericize this to return the RootPart instead, which will have some kind of EnvelopeFactory to enable support for things other than SOAP. But that all will come later, with lots of additional refactoring.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault.
param
headers Mime Headers.

        setup(initialContents, true, null, null, headers);
    
public Message(Object initialContents, boolean bodyInStream, String contentType, String contentLocation)
Construct a Message, using the provided initialContents as the contents of the Message's SOAPPart.

Eventually, genericize this to return the RootPart instead, which will have some kind of EnvelopeFactory to enable support for things other than SOAP. But that all will come later, with lots of additional refactoring.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault
param
bodyInStream is true if initialContents is an InputStream containing just the SOAP body (no SOAP-ENV)
param
contentType this if the contentType has been already determined (as in the case of servlets)
param
contentLocation the location of the content

        setup(initialContents, bodyInStream, contentType, contentLocation, null);
    
Methods Summary
public voidaddAttachmentPart(javax.xml.soap.AttachmentPart attachmentpart)
Adds the given AttachmentPart object to this SOAPMessage object. An AttachmentPart object must be created before it can be added to a message.

param
attachmentpart an AttachmentPart object that is to become part of this SOAPMessage object
throws
java.lang.IllegalArgumentException

        try {
            mAttachments.addAttachmentPart((org.apache.axis.Part)attachmentpart);
        } catch (AxisFault af){
            log.error(Messages.getMessage("exception00"), af);
        }
    
public intcountAttachments()
Gets a count of the number of attachments in this message. This count does not include the SOAP part.

return
the number of AttachmentPart objects that are part of this SOAPMessage object

        return mAttachments == null ? 0 : mAttachments.getAttachmentCount();
    
public javax.xml.soap.AttachmentPartcreateAttachmentPart()
Creates a new empty AttachmentPart object. Note that the method addAttachmentPart must be called with this new AttachmentPart object as the parameter in order for it to become an attachment to this SOAPMessage object.

return
a new AttachmentPart object that can be populated and added to this SOAPMessage object

        if (!isAttachmentSupportEnabled(getMessageContext())) {
            throw new RuntimeException(Messages.getMessage("noAttachments"));
        }
        
        try {
            return (AttachmentPart) mAttachments.createAttachmentPart();
        } catch (AxisFault af){
            log.error(Messages.getMessage("exception00"), af);
        }
        return null;
    
public voiddispose()
Dispose of attachments.

        if(mAttachments!=null) {
            mAttachments.dispose();
        }
    
public static java.lang.StringgetAttachmentImplClassName()
Returns the name of the class prividing Attachment Implementation.

return
class name


                     
       
        return mAttachmentsImplClassName;
    
public java.util.IteratorgetAttachments()
Retrieves all the AttachmentPart objects that are part of this SOAPMessage object.

return
an iterator over all the attachments in this message

        try {
            if (mAttachments != null && 0 != mAttachments.getAttachmentCount()) {
                return mAttachments.getAttachments().iterator();
            }
        } catch (AxisFault af){
            log.error(Messages.getMessage("exception00"), af);
        }
        return Collections.EMPTY_LIST.iterator();
    
public java.util.IteratorgetAttachments(javax.xml.soap.MimeHeaders headers)
Retrieves all the AttachmentPart objects that have header entries that match the specified headers. Note that a returned attachment could have headers in addition to those specified.

param
headers a MimeHeaders object containing the MIME headers for which to search
return
an iterator over all attachments that have a header that matches one of the given headers

        return mAttachments.getAttachments(headers);
    
public org.apache.axis.attachments.AttachmentsgetAttachmentsImpl()
Get the Attachments of this Message.

If this returns null, then NO ATTACHMENT SUPPORT EXISTS in this configuration of Axis, and no attachment operations may be performed.

return
the Attachments if attachments are supported, null otherwise

        return mAttachments;
    
public java.lang.StringgetContentDescription()
Retrieves a description of this SOAPMessage object's content.

return
a String describing the content of this message or null if no description has been set
see
#setContentDescription(java.lang.String) setContentDescription(java.lang.String)

        String values[] = headers.getHeader(HTTPConstants.HEADER_CONTENT_DESCRIPTION);
        if(values != null && values.length > 0)
            return values[0];
        return null;
    
public longgetContentLength()
Get the content length, including both soap and any attachments.

return
the total length of this message in bytes
throws
org.apache.axis.AxisFault if there was a problem that prevented the length being calculated

        long ret = mSOAPPart.getContentLength();
        if (mAttachments != null && 0 < mAttachments.getAttachmentCount()) {
            ret = mAttachments.getContentLength();
        }
        return ret;
    
public java.lang.StringgetContentType(org.apache.axis.soap.SOAPConstants sc)
Get the content type of the attachments.

param
sc provides the default content type
return
a String giving the content type of the attachment
throws
AxisFault if there was an error deducing the content type from this message

        boolean soap12 = false;
        
        if(sc != null) {
            if(sc == SOAPConstants.SOAP12_CONSTANTS) {
                soap12 = true;
            }
        } else {
            // Support of SOAP 1.2 HTTP binding
            SOAPEnvelope envelope = getSOAPEnvelope();
            if (envelope != null) {
                if (envelope.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS) {
                    soap12 = true;
                }
            }
        }

        String encoding = XMLUtils.getEncoding(this, msgContext);;
        String ret = sc.getContentType() + "; charset=" + encoding.toLowerCase();
        
        // Support of SOAP 1.2 HTTP binding
        if (soap12) {
            ret = HTTPConstants.HEADER_ACCEPT_APPL_SOAP +"; charset=" + encoding;
        }

        if (getSendType() != Attachments.SEND_TYPE_NONE && mAttachments != null &&
                0 != mAttachments.getAttachmentCount()) {
            ret = mAttachments.getContentType();
        }
        return ret;
    
public MessageContextgetMessageContext()
Get the context associated with this message.

return
the message context for this message

        return msgContext;
    
public java.lang.StringgetMessageType()
Get the message type.

return
the message type String

        return messageType;
    
public javax.xml.soap.MimeHeadersgetMimeHeaders()
Returns all the transport-specific MIME headers for this SOAPMessage object in a transport-independent fashion.

return
a MimeHeaders object containing the MimeHeader objects

        return headers;
    
public java.lang.ObjectgetProperty(java.lang.String property)

        return mProps.get(property);
    
public javax.xml.soap.SOAPBodygetSOAPBody()

    
         
        return mSOAPPart.getEnvelope().getBody();
    
public org.apache.axis.message.SOAPEnvelopegetSOAPEnvelope()
Get this message's SOAPPart as a SOAPEnvelope.

return
a SOAPEnvelope containing this message's SOAPPart
throws
AxisFault if this failed

        return mSOAPPart.getAsSOAPEnvelope();
    
public javax.xml.soap.SOAPHeadergetSOAPHeader()

        return mSOAPPart.getEnvelope().getHeader();
    
public javax.xml.soap.SOAPPartgetSOAPPart()
Get this message's SOAPPart.

Eventually, this should be generalized beyond just SOAP, but it's hard to know how to do that without necessitating a lot of casts in client code. Refactoring keeps getting easier anyhow.

return
the soap part of this message

        return mSOAPPart;
    
public byte[]getSOAPPartAsBytes()
Get a byte array representation of this message's SOAPPart.

return
the soap part of this message as a byte[]
throws
org.apache.axis.AxisFault if creating the byte[] failed

        return mSOAPPart.getAsBytes();
    
public java.lang.StringgetSOAPPartAsString()
Get a string representation of this message's SOAPPart.

return
the soap part of this message as a String
throws
org.apache.axis.AxisFault if the stringification failed

        return mSOAPPart.getAsString();
    
private intgetSendType()

        int sendType = Attachments.SEND_TYPE_NOTSET;
        if ((msgContext != null) && (msgContext.getService() != null)) {
            sendType = msgContext.getService().getSendType();
        }
        return sendType;
    
private static synchronized booleanisAttachmentSupportEnabled(MessageContext mc)


          
        if (checkForAttachmentSupport) {
            //aviod testing and possibly failing everytime.
            checkForAttachmentSupport = false;
            try {
                // Get the default setting from AxisProperties
                String attachImpName = AxisProperties.getProperty(AxisEngine.PROP_ATTACHMENT_IMPLEMENTATION,
                        AxisEngine.DEFAULT_ATTACHMENT_IMPL);
                // override the default with any changes specified in the engine configuration
                if (null != mc) {
                    AxisEngine ae = mc.getAxisEngine();
                    if (null != ae) {
                        attachImpName = (String) ae.getOption(
                                AxisEngine.PROP_ATTACHMENT_IMPLEMENTATION);
                    }
                }

                /**
                 * Attempt to resolve class name, verify that these are present...
                 */
                ClassUtils.forName("javax.activation.DataHandler");
                ClassUtils.forName("javax.mail.internet.MimeMultipart");

                attachImpl = ClassUtils.forName(attachImpName);

                attachmentSupportEnabled = true;
            } catch (ClassNotFoundException ex) {
                // no support for it, leave mAttachments null.
            } catch (java.lang.NoClassDefFoundError ex) {
                // no support for it, leave mAttachments null.
            } catch (java.lang.SecurityException ex) {
                // no support for it, leave mAttachments null.
            }
            log.debug(Messages.getMessage("attachEnabled") + "  " +
                    attachmentSupportEnabled);
        }
        return attachmentSupportEnabled;
    
public voidremoveAllAttachments()
Removes all AttachmentPart objects that have been added to this SOAPMessage object.

This method does not touch the SOAP part.

        mAttachments.removeAllAttachments();
    
public voidsaveChanges()
Updates this SOAPMessage object with all the changes that have been made to it. This method is called automatically when a message is sent or written to by the methods ProviderConnection.send, SOAPConnection.call, or SOAPMessage.writeTo. 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.

        headers.removeHeader("Content-Length");
        if (mAttachments != null && 0 < mAttachments.getAttachmentCount()) {
            try {
                headers.setHeader("Content-Type",mAttachments.getContentType());
            } catch (AxisFault af){
                log.error(Messages.getMessage("exception00"), af);
            }
        }
        saveRequired = false;
        try {
            /* Fix for Bug 16418 - Start from scratch */ 
            mSOAPPart.saveChanges();
        } catch (AxisFault axisFault) {
            log.error(Messages.getMessage("exception00"), axisFault);
        }
    
public booleansaveRequired()
Indicates whether this SOAPMessage object has had the method saveChanges called on it.

return
true if saveChanges has been called on this message at least once; false otherwise.

        return saveRequired;
    
public voidsetContentDescription(java.lang.String description)
Sets the description of this SOAPMessage object's content with the given description.

param
description a String describing the content of this message
see
#getContentDescription() getContentDescription()

        headers.setHeader(HTTPConstants.HEADER_CONTENT_DESCRIPTION, description);
    
public voidsetMessageContext(MessageContext msgContext)
Set the context associated with this message.

param
msgContext the message context for this message

        this.msgContext = msgContext;
    
public voidsetMessageType(java.lang.String messageType)
Set the message type.

param
messageType the message type String

        this.messageType = messageType;
    
public voidsetProperty(java.lang.String property, java.lang.Object value)

        mProps.put(property, value);
    
private voidsetup(java.lang.Object initialContents, boolean bodyInStream, java.lang.String contentType, java.lang.String contentLocation, javax.xml.soap.MimeHeaders mimeHeaders)
Do the work of construction.

param
initialContents may be String, byte[], InputStream, SOAPEnvelope, or AxisFault
param
bodyInStream is true if initialContents is an InputStream containing just the SOAP body (no SOAP-ENV)
param
contentType this if the contentType has been already determined (as in the case of servlets)
param
contentLocation the location of the content
param
mimeHeaders mime headers for attachments


        if(contentType == null && mimeHeaders != null) {
            String contentTypes[] = mimeHeaders.getHeader("Content-Type");
            contentType = (contentTypes != null)? contentTypes[0] : null;
        }
        if(contentLocation == null && mimeHeaders != null) {
            String contentLocations[] = mimeHeaders.getHeader("Content-Location");
            contentLocation = (contentLocations != null)? contentLocations[0] : null;
        }
        if (contentType != null) {
            int delimiterIndex = contentType.lastIndexOf("charset");
            if (delimiterIndex > 0) {
                String charsetPart = contentType.substring(delimiterIndex);
                int delimiterIndex2 = charsetPart.indexOf(';");
                if(delimiterIndex2 != -1){
                    charsetPart = charsetPart.substring(0, delimiterIndex2);
                }
                int charsetIndex = charsetPart.indexOf('=");
                String charset = charsetPart.substring(charsetIndex + 1).trim();
                if ((charset.startsWith("\"") || charset.startsWith("\'"))) {
                    charset = charset.substring(1, charset.length());
                }
                if ((charset.endsWith("\"") || charset.endsWith("\'"))) {
                    charset = charset.substring(0, charset.length()-1);
                }
                try {
                    setProperty(SOAPMessage.CHARACTER_SET_ENCODING, charset);
                } catch (SOAPException e) {
                }
            }
        }
        // Try to construct an AttachmentsImpl object for attachment
        // functionality.
        // If there is no org.apache.axis.attachments.AttachmentsImpl class,
        // it must mean activation.jar is not present and attachments are not
        // supported.
        if (isAttachmentSupportEnabled(getMessageContext())) {
            // Construct one, and cast to Attachments.
            // There must be exactly one constructor of AttachmentsImpl, which
            // must take an org.apache.axis.Message!
            Constructor attachImplConstr = attachImpl.getConstructors()[0];
            try {
                mAttachments = (Attachments) attachImplConstr.newInstance(
                        new Object[] { initialContents,
                                       contentType, contentLocation});

                //If it can't support it, it wont have a root part.
                mSOAPPart = (SOAPPart) mAttachments.getRootPart();
            } catch (InvocationTargetException ex) {
                log.fatal(Messages.getMessage("invocationTargetException00"),
                          ex);
                throw new RuntimeException(ex.getMessage());
            } catch (InstantiationException ex) {
                log.fatal(Messages.getMessage("instantiationException00"),
                          ex);
                throw new RuntimeException(ex.getMessage());
            } catch (IllegalAccessException ex) {
                log.fatal(Messages.getMessage("illegalAccessException00"),
                          ex);
                throw new RuntimeException(ex.getMessage());
            }
        } else if (contentType != null && contentType.startsWith("multipart")){
            throw new RuntimeException(Messages.getMessage("noAttachments"));
        }

        // text/xml
        if (null == mSOAPPart) {
            mSOAPPart = new SOAPPart(this, initialContents, bodyInStream);
        }
        else
          mSOAPPart.setMessage(this);

        // The stream was not determined by a more complex type so default to
        if(mAttachments!=null) mAttachments.setRootPart(mSOAPPart);

        headers = (mimeHeaders == null) ? new MimeHeaders() : new MimeHeaders(mimeHeaders);
    
public voidwriteTo(java.io.OutputStream os)
Writes this SOAPMessage object to the given output stream. The externalization format is as defined by the SOAP 1.1 with Attachments specification.

If there are no attachments, just an XML stream is written out. For those messages that have attachments, writeTo writes a MIME-encoded byte stream.

param
os the OutputStream object to which this SOAPMessage object will be written
throws
SOAPException if there was a problem in externalizing this SOAP message
throws
IOException if an I/O error occurs

         //Do it the old fashion way.
        if (getSendType() == Attachments.SEND_TYPE_NONE || mAttachments == null || 0 == mAttachments.getAttachmentCount()) {
            try {
                String charEncoding = XMLUtils.getEncoding(this, msgContext);;
                mSOAPPart.setEncoding(charEncoding);
                mSOAPPart.writeTo(os);
            } catch (java.io.IOException e) {
                log.error(Messages.getMessage("javaIOException00"), e);
            }
        } else {
            try {
                mAttachments.writeContentToStream(os);
            } catch (java.lang.Exception e) {
                log.error(Messages.getMessage("exception00"), e);
            }
        }