FileDocCategorySizeDatePackage
ProtocolMessageSender.javaAPI DocExample15780Tue May 29 16:56:42 BST 2007com.sun.xml.ws.rm.jaxws.runtime.client

ProtocolMessageSender

public class ProtocolMessageSender extends Object
Helper class used to send protocol message addressed to the endpoint. The messages belong to the following types:
  • CreateSequence. A message with a CreateSequence element in its body is sent. The response message contains a CreateSequenceResponse element in its body
  • Last. A message with empty body, and a Sequence header with Last child is sent. The headers on the body are processed.
  • AckRequensted. A message with empty body, and a Sequence header with Last child is sent. The headers on the body are processed.
  • TerminateSequence A message with a TerminateSequence element in its body is sent.

Fields Summary
private com.sun.xml.ws.rm.jaxws.runtime.InboundMessageProcessor
processor
Helper to process InboundMessages.
private com.sun.xml.ws.api.pipe.Pipe
nextPipe
The next client pipe in the pipeline. Used to propogate the messages.
private Marshaller
marshaller
The marshaller to write the messages
private Unmarshaller
unmarshaller
The unmarshaller to read the messages
private RMConstants
constants
private Packet
packet
Properties like the BindingProvider to associate with the request and response context contentNegotiation etc can be obtained from the packet
private com.sun.xml.ws.api.model.wsdl.WSDLPort
port
private com.sun.xml.ws.api.WSBinding
binding
Constructors Summary
public ProtocolMessageSender(com.sun.xml.ws.rm.jaxws.runtime.InboundMessageProcessor processor, Marshaller marshaller, Unmarshaller unmarshaller, com.sun.xml.ws.api.model.wsdl.WSDLPort port, com.sun.xml.ws.api.WSBinding binding, com.sun.xml.ws.api.pipe.Pipe nextPipe, Packet packet)
Public ctor. Initialize the fields


        this.processor = processor;
        this.nextPipe = nextPipe;
        this.port = port;
        this.binding = binding;
        this.marshaller = marshaller;
        this.unmarshaller = unmarshaller;
        this.constants =  RMConstants.getRMConstants(binding.getAddressingVersion());
        this.packet = packet;

    
Methods Summary
private PacketaddAddressingHeaders(Packet requestPacket, java.lang.String action, java.net.URI destination, java.net.URI acksTo, boolean oneWay)
Initialize an AddressingProperties object using the arguments. Put the AddressingProperties object in the RequestContext obtained from getMessageProperties.

       
        /*ADDRESSING FIX_ME

        Current API does not allow assignment of non-anon reply to, if we
           need to support non-anon acksTo.
         */
        Message message = requestPacket.getMessage();
        HeaderList list = message.getHeaders();
        if (oneWay) {
            message.assertOneWay(true);
        } else {
            message.assertOneWay(false);
        }
        //list.fillRequestAddressingHeaders(port, binding, requestPacket, action);
        requestPacket.setEndPointAddressString(destination.toString());
        list.fillRequestAddressingHeaders(requestPacket,constants.getAddressingVersion(),binding.getSOAPVersion(),oneWay,action);

        return requestPacket;
       
   
private AckRequestedElementcreateAckRequestedElement(com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence seq)
Return a AckReqesutedElement whose Sequence ID matches the specified OutboundSequence and whose MessageNumber is the highest sent within a Sequence sequence.

        AckRequestedElement ackRequestedElement = new AckRequestedElement();
        ackRequestedElement.setId(seq.getId());
        ackRequestedElement.setMaxMessageNumber(seq.getNextIndex()-1);
        return ackRequestedElement;
    
private com.sun.xml.ws.api.message.MessagecreateEmptyMessage(com.sun.xml.ws.api.SOAPVersion version)
Create an empty message using correct SOAPVersion

        return Messages.createEmpty(version);
    
private com.sun.xml.ws.api.message.HeadercreateHeader(java.lang.Object obj)

        return com.sun.xml.ws.api.message.Headers.create(constants.getJAXBRIContextHeaders(), obj);
    
private SequenceElementcreateLastHeader(com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence seq)
Return a SequenceElement.LastMessage

        SequenceElement sequenceElement = new SequenceElement();
        sequenceElement.setId(seq.getId());
        sequenceElement.setNumber(seq.getNextIndex());
        sequenceElement.setLastMessage(new SequenceElement.LastMessage());
        return sequenceElement;
    
public RMConstantsgetConstants()

        return constants;
    
public voidsendAckRequested(com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence seq, com.sun.xml.ws.api.SOAPVersion version)
Send Message with empty body and a AckRequestedElement (with Last child) down the pipe. Process the response, which may contain a SequenceAcknowledgementElement.

param
seq Outbound sequence to which SequenceHeaderElement will belong.


        try {
            Message request = createEmptyMessage(version);
            AckRequestedElement el = createAckRequestedElement(seq);
            //request.getHeaders().add(Headers.create(version,marshaller,el));
            request.getHeaders().add(createHeader(el));


            Packet requestPacket = new Packet(request);
            requestPacket.proxy = packet.proxy;
            requestPacket.contentNegotiation = packet.contentNegotiation;

            addAddressingHeaders (requestPacket, Constants.ACK_REQUESTED_ACTION,
                    seq.getDestination(),seq.getAcksTo(), /*true*/ false);

            requestPacket.setEndPointAddressString(seq.getDestination().toString());

            Packet responsePacket = nextPipe.process(requestPacket);
            Message response = responsePacket.getMessage();
            if (response != null && response.isFault()){
                    //reset alarm
                    ((ClientOutboundSequence)seq).resetLastActivityTime();
                    throw new RMException(response);
            }

            com.sun.xml.ws.rm.Message msg = new com.sun.xml.ws.rm.Message(response);
            processor.processMessage(msg, marshaller, unmarshaller);
        } finally {
            //Make sure that alarm is reset.
            ((ClientOutboundSequence)seq).resetLastActivityTime();
        }

    
public CreateSequenceResponseElementsendCreateSequence(CreateSequenceElement cs, java.net.URI destination, java.net.URI acksTo, com.sun.xml.ws.api.SOAPVersion version)


        //Used from com.sun.xml.ws.jaxws.runtime.client.ClientOutboundSequence.connect, where
        //CreateSequence object is constructed and resulting CreateSequenceResponse object is
        //processed.
        CreateSequenceResponseElement csrElem = null;

        //1. Initialize  message adding CreateSequence to body
        if (cs != null) {
            Message request = Messages.create(constants.getJAXBContext(),cs,version);


            //Addressing Headers are added by configuring the following property
            //on the packet

            Packet requestPacket = new Packet(request);
            requestPacket.proxy = packet.proxy;
            requestPacket.contentNegotiation = packet.contentNegotiation;
            requestPacket.setEndPointAddressString(destination.toString());

            addAddressingHeaders (requestPacket, Constants.CREATE_SEQUENCE_ACTION,
                    destination , acksTo, false);

            String messageId = null ;/*= ADDRESSING_FIXME - initialize with mesageID
                                   assigned by addAddressingHeaders for use in
                                   correlating non-anonymous acksTo response*/



            Packet responsePacket = nextPipe.process(requestPacket);

            if (acksTo.equals(constants.getAnonymousURI())) {

                Message response = responsePacket.getMessage();
               if (response.isFault()){
                    throw new CreateSequenceException("CreateSequence was refused by the RMDestination \n ",response);
                }

                //unmarshall CreateSequenceResponse object from body of response.
                //need the null check because this might be a non-anonymous ackto and
                //CSR will be processed on another connection.
                if (response != null) {
                    csrElem = unmarshallCreateSequenceResponse(response);
                }
            } else {

                csrElem = ProtocolMessageReceiver.getCreateSequenceResponse(messageId);
            }
        }

        return csrElem;
    
public voidsendLast(com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence seq, com.sun.xml.ws.api.SOAPVersion version)
Send Message with empty body and a single SequenceElement (with Last child) down the pipe. Process the response, which may contain a SequenceAcknowledgementElement.

param
seq Outbound sequence to which SequenceHeaderElement will belong.


        Message request = createEmptyMessage(version);
        SequenceElement el = createLastHeader(seq);
        //request.getHeaders().add(Headers.create(version,marshaller,el));
        request.getHeaders().add(createHeader(el));

        seq.setLast();

        Packet requestPacket = new Packet(request);
        requestPacket.proxy = packet.proxy;
        //requestPacket.proxy = new ProxyWrapper(packet.proxy);
        requestPacket.setEndPointAddressString(seq.getDestination().toString());
        requestPacket.contentNegotiation = packet.contentNegotiation;
        addAddressingHeaders(requestPacket, constants.getLastAction(),seq.getDestination(),
                seq.getAcksTo(), /*true*/ false);

       

        Packet responsePacket = nextPipe.process(requestPacket);
        Message response = responsePacket.getMessage();

        com.sun.xml.ws.rm.Message msg = new com.sun.xml.ws.rm.Message(response);
        if (response != null && response.isFault()){
                throw new RMException(response);
        }

        processor.processMessage(msg, marshaller, unmarshaller);

    
public voidsendTerminateSequence(TerminateSequenceElement ts, com.sun.xml.ws.rm.jaxws.runtime.OutboundSequence seq, com.sun.xml.ws.api.SOAPVersion version)


        //Used from com.sun.xml.ws.jaxws.runtime.client.ClientOutboundSequence.disconnect, where the
        //TerminateSequence message is initialzied.

        Message request = Messages.create(constants.getJAXBContext(),ts,version);

        //piggyback an acknowledgement if one is pending
        seq.processAcknowledgement(new com.sun.xml.ws.rm.Message(request), marshaller);

        Packet requestPacket = new Packet(request);
        requestPacket.proxy = packet.proxy;
        requestPacket.contentNegotiation = packet.contentNegotiation;
        addAddressingHeaders (requestPacket,Constants.TERMINATE_SEQUENCE_ACTION,seq.getDestination(),seq.getAcksTo(),/*true*/ false);
        requestPacket.setEndPointAddressString(seq.getDestination().toString());
        Packet responsePacket = nextPipe.process(requestPacket);
        Message response = responsePacket.getMessage();
        if (response != null && response.isFault()){
                throw new TerminateSequenceException("There was an error trying to terminate the sequence " ,response);
        }


        //What to do with response?
        //TODO
        //It may have a TerminateSequence for reverse sequence on it as well as
        //ack headers
        //Process these.

    
private CreateSequenceResponseElementunmarshallCreateSequenceResponse(com.sun.xml.ws.api.message.Message response)

        CreateSequenceResponseElement csrElement = null;
        try {
            csrElement = response.readPayloadAsJAXB(unmarshaller);
        } catch (JAXBException e) {
            throw new RMException (e);
        }
        return csrElement;