FileDocCategorySizeDatePackage
LazyStreamBasedMessage.javaAPI DocExample17237Tue May 29 16:56:32 BST 2007com.sun.xml.ws.message.stream

LazyStreamBasedMessage

public class LazyStreamBasedMessage extends com.sun.xml.ws.api.message.Message
author
K.Venugopal@sun.com

Fields Summary
protected static final Logger
logger
private com.sun.xml.ws.api.pipe.StreamSOAPCodec
codec
private boolean
readMessage
private XMLStreamReader
reader
private com.sun.xml.ws.api.message.Message
message
private com.sun.xml.stream.buffer.MutableXMLStreamBuffer
buffer
Constructors Summary
public LazyStreamBasedMessage(XMLStreamReader message, com.sun.xml.ws.api.pipe.StreamSOAPCodec codec)
Creates a new instance of StreamMessage

           
        
        this.reader = message;
        this.codec = codec;
    
Methods Summary
private synchronized voidcacheMessage()

        if(!readMessage){
            message = codec.decode(reader);
            readMessage = true;
        }
    
public com.sun.xml.ws.api.message.Messagecopy()
Creates a copy of a {@link Message}.

This method creates a new {@link Message} whose header/payload/attachments/properties are identical to this {@link Message}. Once created, the created {@link Message} and the original {@link Message} behaves independently --- adding header/ attachment to one {@link Message} doesn't affect another {@link Message} at all.

This method does NOT consume a message.

To enable efficient copy operations, there's a few restrictions on how copied message can be used.

  1. The original and the copy may not be used concurrently by two threads (this allows two {@link Message}s to share some internal resources, such as JAXB marshallers.) Note that it's OK for the original and the copy to be processed by two threads, as long as they are not concurrent.
  2. The copy has the same 'life scope' as the original (this allows shallower copy, such as JAXB beans wrapped in {@link JAXBMessage}.)

A 'life scope' of a message created during a message processing in a pipeline is until a pipeline processes the next message. A message cannot be kept beyond its life scope. (This experimental design is to allow message objects to be reused --- feedback appreciated.)

Design Rationale

Since a {@link Message} body is read-once, sometimes (such as when you do fail-over, or WS-RM) you need to create an idential copy of a {@link Message}.

The actual copy operation depends on the layout of the data in memory, hence it's best to be done by the {@link Message} implementation itself.

The restrictions placed on the use of copied {@link Message} can be relaxed if necessary, but it will make the copy method more expensive.

        if(!readMessage){
            cacheMessage();
        }
        return message.copy();
    
public com.sun.xml.ws.api.message.AttachmentSetgetAttachments()
Gets the attachments of this message (attachments live outside a message.)

        if(!readMessage){
            cacheMessage();
        }
        return message.getAttachments();
    
public com.sun.xml.ws.api.pipe.StreamSOAPCodecgetCodec()

        return codec;
    
public com.sun.xml.ws.api.message.HeaderListgetHeaders()
Gets all the headers of this message.

Implementation Note

{@link Message} implementation is allowed to defer the construction of {@link HeaderList} object. So if you only want to check for the existence of any header element, use {@link #hasHeaders()}.

return
always return the same non-null object.

        if(!readMessage){
            cacheMessage();
        }
        return message.getHeaders();
    
public java.lang.StringgetPayloadLocalPart()
Gets the local name of the payload element.

return
null if a {@link Message} doesn't have any payload.

        if(!readMessage){
            cacheMessage();
        }
        return message.getPayloadLocalPart();
    
public java.lang.StringgetPayloadNamespaceURI()
Gets the namespace URI of the payload element.

return
null if a {@link Message} doesn't have any payload.

        if(!readMessage){
            cacheMessage();
        }
        return message.getPayloadNamespaceURI();
    
public booleanhasHeaders()
Returns true if headers are present in the message.

return
true if headers are present.

        if(!readMessage){
            cacheMessage();
        }
        return message.hasHeaders();
    
public booleanhasPayload()
Returns true if a {@link Message} has a payload.

A message without a payload is a SOAP message that looks like:


<S:Envelope>
<S:Header>
...
</S:Header>
<S:Body />
</S:Envelope>

        if(!readMessage){
            cacheMessage();
        }
        return message.hasPayload();
    
public booleanisFault()
Returns true if this message is a fault.

Just a convenience method built on {@link #getPayloadNamespaceURI()} and {@link #getPayloadLocalPart()}.

        return false;
        //        if(!readMessage){
        //            cacheMessage();
        //        }
        //        return message.isFault();
    
public booleanisOneWay(com.sun.xml.ws.api.model.wsdl.WSDLPort port)
Returns true if this message is a request message for a one way operation according to the given WSDL. False otherwise.

This method is functionally equivalent as doing {@code getOperation(port).getOperation().isOneWay()} (with proper null check and all.) But this method can sometimes work faster than that (for example, on the client side when used with SEI.)

param
port {@link Message}s are always created under the context of one {@link WSDLPort} and they never go outside that context. Pass in that "governing" {@link WSDLPort} object here. We chose to receive this as a parameter instead of keeping {@link WSDLPort} in a message, just to save the storage.

The implementation of this method involves caching the return value, so the behavior is undefined if multiple callers provide different {@link WSDLPort} objects, which is a bug of the caller.

        if(!readMessage){
            cacheMessage();
        }
        return message.isOneWay(port);
    
public voidprint()

        if(readMessage){
            try         {
                message.readAsSOAPMessage().writeTo(java.lang.System.out);
                return;
            } catch (SOAPException ex) {
                logger.log(java.util.logging.Level.SEVERE,
                       LogStringsMessages.WSSMSG_0003_ERROR_PRINT(),ex);
            } catch (IOException ex) {
                logger.log(java.util.logging.Level.SEVERE,
                       LogStringsMessages.WSSMSG_0003_ERROR_PRINT(),ex);
            }
        }
        if(buffer == null){
            buffer = new MutableXMLStreamBuffer();
            buffer.createFromXMLStreamReader(reader);
            reader =  buffer.readAsXMLStreamReader();
        }
        XMLOutputFactory xof = XMLOutputFactory.newInstance();
        buffer.writeToXMLStreamWriter(xof.createXMLStreamWriter(System.out));
    
public javax.xml.soap.SOAPMessagereadAsSOAPMessage()
Creates the equivalent {@link SOAPMessage} from this message. This consumes the message.

throws
SOAPException if there's any error while creating a {@link SOAPMessage}.

        if(!readMessage){
            cacheMessage();
        }
        return message.readAsSOAPMessage();
    
public javax.xml.transform.SourcereadEnvelopeAsSource()
Consumes this message including the envelope. returns it as a {@link Source} object.

        if(!readMessage){
            cacheMessage();
        }
        return message.readEnvelopeAsSource();
    
public javax.xml.stream.XMLStreamReaderreadMessage()

        
        if (!readMessage) {
            return reader;
        }
        
        if (buffer == null) {
            try {
                buffer = new com.sun.xml.stream.buffer.MutableXMLStreamBuffer();
                javax.xml.stream.XMLStreamWriter writer = buffer.createFromXMLStreamWriter();
                
                message.writeTo(writer);
            } catch (javax.xml.stream.XMLStreamException ex) {
                logger.log(java.util.logging.Level.SEVERE,LogStringsMessages.WSSMSG_0001_PROBLEM_CACHING(),ex);
            }
        }
        try     {
            reader = buffer.readAsXMLStreamReader();
            return reader;
        } catch (XMLStreamException ex) {
            logger.log(java.util.logging.Level.SEVERE,LogStringsMessages.WSSMSG_0002_ERROR_READING_BUFFER(),ex);                   
        }
        return null;
    
public javax.xml.stream.XMLStreamReaderreadPayload()
Reads the payload as a {@link XMLStreamReader} This consumes the message.

return
If there's no payload, this method returns null. Otherwise always non-null valid {@link XMLStreamReader} that points to the payload tag name.

        if(!readMessage){
            cacheMessage();
        }
        return message.readPayload();
    
public TreadPayloadAsJAXB(javax.xml.bind.Unmarshaller unmarshaller)
Reads the payload as a JAXB object by using the given unmarshaller. This consumes the message.

throws
JAXBException If JAXB reports an error during the processing.

        if(!readMessage){
            cacheMessage();
        }
        throw new UnsupportedOperationException();
    
public TreadPayloadAsJAXB(com.sun.xml.bind.api.Bridge bridge)
Reads the payload as a JAXB object according to the given {@link Bridge}. This consumes the message.

throws
JAXBException If JAXB reports an error during the processing.

        if(!readMessage){
            cacheMessage();
        }
        return message.readPayloadAsJAXB(bridge);
    
public javax.xml.transform.SourcereadPayloadAsSource()
Returns the payload as a {@link Source} object. This consumes the message.

return
if there's no payload, this method returns null.

        if(!readMessage){
            cacheMessage();
        }
        return message.readPayloadAsSource();
    
public voidwritePayloadTo(javax.xml.stream.XMLStreamWriter sw)
Writes the payload to StAX. This method writes just the payload of the message to the writer. This consumes the message. The implementation will not write {@link XMLStreamWriter#writeStartDocument()} nor {@link XMLStreamWriter#writeEndDocument()}

If there's no payload, this method is no-op.

throws
XMLStreamException If the {@link XMLStreamWriter} reports an error, or some other errors happen during the processing.

        if(!readMessage){
            cacheMessage();
        }
        message.writePayloadTo(sw);
    
public voidwriteTo(javax.xml.stream.XMLStreamWriter sw)
Writes the whole SOAP message (but not attachments) to the given writer. This consumes the message.

throws
XMLStreamException If the {@link XMLStreamWriter} reports an error, or some other errors happen during the processing.

        if(!readMessage){
            cacheMessage();
        }
        message.writeTo(sw);
    
public voidwriteTo(org.xml.sax.ContentHandler contentHandler, org.xml.sax.ErrorHandler errorHandler)
Writes the whole SOAP envelope as SAX events.

This consumes the message.

param
contentHandler must not be nulll.
param
errorHandler must not be null. any error encountered during the SAX event production must be first reported to this error handler. Fatal errors can be then thrown as {@link SAXParseException}. {@link SAXException}s thrown from {@link ErrorHandler} should propagate directly through this method.

        if(!readMessage){
            cacheMessage();
        }
        message.writeTo(contentHandler,errorHandler);