FileDocCategorySizeDatePackage
Message.javaAPI DocExample11265Tue May 29 16:56:40 BST 2007com.sun.xml.ws.rm

Message.java

/*
 * $Id: Message.java,v 1.4.6.1 2007/05/29 23:56:40 ofung Exp $
 */

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.xml.ws.rm;
import com.sun.xml.ws.rm.protocol.AckRequestedElement;
import com.sun.xml.ws.rm.protocol.SequenceAcknowledgementElement;
import com.sun.xml.ws.rm.protocol.SequenceElement;

/**
 * Message is an abstraction of messages that can be added to WS-RM Sequences. 
 * Each instance wraps a JAX-WS message.
 */
public class Message {
    
    /**
     * The JAX-WS Message wrapped by this instance.
     */
    protected com.sun.xml.ws.api.message.Message message;
    
    /**
     * The Sequence to which the message belongs.
     */
    protected Sequence sequence = null;
    
    /**
     * The messageNumber of the Message in its Sequence.
     */
    protected int messageNumber = 0;
    
    
    /**
     * Flag which is true if and only if the message is waiting for
     * a notification.
     */ 
    protected boolean isWaiting = false;
    
    /**
     * Flag indicating whether message is delivered/acked.
     * The meaning differs according to the type of sequence
     * to which the message belongs.  The value must only be
     * changed using the complete() method, which should only
     * be invoked by the Sequence containing the message.
     */
    protected boolean isComplete = false;
    
    
    /**
     * For messages belonging to 2-way MEPS, the corresponding message.
     */
    protected com.sun.xml.ws.rm.Message relatedMessage = null;
    
    /**
     * Sequence stored when the corresponding com.sun.xml.ws.api.message.Header
     * is added to the message.
     */
    protected SequenceElement sequenceElement = null; 
    
    
    /**
     * SequenceElement stored when the corresponding com.sun.xml.ws.api.message.Header
     * is added to the message.
     */
    protected SequenceAcknowledgementElement sequenceAcknowledgementElement = null; 
    
    /**
     * SequenceElement stored when the corresponding com.sun.xml.ws.api.message.Header
     * is added to the message.
     */
    protected AckRequestedElement ackRequestedElement = null; 
    
    /**
     * When true, indicates that the message is a request message for
     * a two-way operation.  ClientOutboundSequence with anonymous
     * AcksTo has to handle Acknowledgements differently in this case.
     */
    public boolean isTwoWayRequest = false;
    
    /**
     * Set in empty message used to piggyback response 
     * headers on a one-way response.
     */
    public boolean isOneWayResponse = false;
    
    
    /**
     * Namespace URI corresponding to RM version.
     */
    public static final String namespaceURI = 
            RMBuilder.getConstants().getNamespaceURI();
    
    
    /**
     * Public ctor takes wrapped JAX-WS message as its argument.
     */
    public Message(com.sun.xml.ws.api.message.Message message) {
        this.message = message;
    }
    
    /**
     * Sets  the value of the sequence field.  Used by Sequence methods when
     * adding message to the sequence.
     * @param sequence The sequence.
     */
    public void setSequence(Sequence sequence) {
        this.sequence = sequence;
    }
    
    /**
     * Gets the Sequence to which the Message belongs.
     * @return The sequence.
     */
    public Sequence getSequence() {
        return sequence;
    }
    
     /**
     * Sets  the value of the messageNumber field.  Used by Sequence methods when
     * adding message to the sequence.
     * @param messageNumber The message number.
     */
    public void setMessageNumber(int messageNumber) {
        this.messageNumber = messageNumber;
    }
    
    /**
     * Returns the value of the messageNumber field
     * @return The message number.
     */
    public int getMessageNumber() {
        return messageNumber;
    }
    
    /**
     * Accessor for the relatedMessage field.
     *
     * @return The response corresponding to a request and vice-versa.
     */
    public com.sun.xml.ws.rm.Message getRelatedMessage() {
        return relatedMessage;
    }
    
    /**
     * Mutator for the relatedMessage field.
     *
     * @param mess
     */
    public void setRelatedMessage(com.sun.xml.ws.rm.Message mess) {
        //store the message with a copy of the "inner" com.sun.xml.ws.api.message.Message
        //since the original one will be consumed
        mess.copyContents();
        relatedMessage = mess;
    }
    
    /**
     * Get the RM Header Element with the specified name from the underlying
     * JAX-WS message's HeaderList
     * @param name The name of the Header to find.
     */
    public com.sun.xml.ws.api.message.Header getHeader(String name) {
        if (message == null || !message.hasHeaders()) {
            return null;
        }
        
        return message.getHeaders().get(namespaceURI, name, true);     
    }
    
    /**
     * Add the specified RM Header element to the underlying JAX-WS message's
     * <code>HeaderList</code>.
     *
     * @param header The <code>Header</code> to add to the <code>HeaderList</code>.
     */
    public void addHeader(com.sun.xml.ws.api.message.Header header) {
        message.getHeaders().add(header);
    }
    
    /**
     * Determines whether this message is delivered/acked
     *
     * @return The value of the isComplete flag
     */
    public boolean isComplete() {
        //synchronized block is redundant.
        synchronized(sequence) {
            return isComplete;
        }
    }
    
    /**
     * Sets the isComplete field to true, indicating that the message has been acked. Also
     * discards the stored com.sun.xml.api.message.Message.
     */
    public void complete() {
        //release reference to JAX-WS message.
        synchronized(sequence) {
            message = null;
            isComplete = true;
        }
    }
    
    /**
     * Block the current thread using the monitor of this <code>Message</code>.
     */
     public synchronized void block() {
     
        isWaiting = true;
        try {
            while (!isComplete && isWaiting) {
                wait();
            }
        } catch (InterruptedException e) {}
    }
    
    /**
     * Wake up the current thread which is waiting on this Message's monitor.
     */
    public synchronized  void resume() {
            isWaiting = false;
            notify();
    }
    
    public synchronized boolean isWaiting() {
        return isWaiting;
    }
    
    /**
     * Returns a copy of the wrapped com.sun.xml.ws.api.message.Message.
     */
    public com.sun.xml.ws.api.message.Message getCopy() {
        return message == null ? null : message.copy();
    }
    
    /**
     * Returns a com.sun.ws.rm.Message whose inner com.sun.xml.ws.api.message.Message is replaced by
     * a copy of the original one.  This message is stored in the relatedMessage field of ClientInboundSequence
     * messages.  A copy needs to be retained rather than the original since the original will already
     * have been consumed at such time the relatedMessage needs to be resent.
     *
     */
    public void copyContents() {
        if (message != null) {
            com.sun.xml.ws.api.message.Message newmessage = message.copy();
            message = newmessage;
        }
    }
    
    public String toString() {
        
         
        String ret = Messages.MESSAGE_NUMBER_STRING.format(messageNumber);
        ret += Messages.SEQUENCE_STRING.format(getSequence() != null ?
                                                getSequence().getId() :
                                                "null");
        
        SequenceElement sel;
        SequenceAcknowledgementElement sael;
        AckRequestedElement ael;
        if ( null != (sel = getSequenceElement())) {
            ret += sel.toString();
        }
        
        if ( null != (sael = getSequenceAcknowledgementElement())) {
            ret += sael.toString();
        }
        
        if ( null != (ael = getAckRequestedElement())) {
            ret += ael.toString();
        }
        
        return ret;
        
        
    }
    
    /*      Diagnostic methods store com.sun.xml.ws.protocol.* elements when
     *      corresponding com.sun.xml.ws.api.message.Headers are added to the 
     *      message
     */
    
    public SequenceAcknowledgementElement getSequenceAcknowledgementElement() {
        return sequenceAcknowledgementElement;
    }
    
    public void setSequenceAcknowledgementElement(SequenceAcknowledgementElement el) {
        sequenceAcknowledgementElement = el;
    }
    
    public SequenceElement getSequenceElement() {
        return sequenceElement;
    }
    
    public void setSequenceElement(SequenceElement el) {
        sequenceElement = el;
    }
    
    public AckRequestedElement getAckRequestedElement() {
        return ackRequestedElement;
    }
    
    public void setAckRequestedElement(AckRequestedElement el) {
        ackRequestedElement = el;
    }
              
}