protected void handle()

in rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMCaptureOutInterceptor.java [82:223]


    protected void handle(Message msg) throws SequenceFault, RMException {
        AddressingProperties maps = ContextUtils.retrieveMAPs(msg, false, true,  false);
        if (null == maps) {
            LogUtils.log(LOG, Level.WARNING, "MAPS_RETRIEVAL_FAILURE_MSG");
            return;
        }
        if (Boolean.TRUE.equals(msg.get(RMMessageConstants.RM_RETRANSMISSION))) {
            return;
        }
        if (isRuntimeFault(msg)) {
            LogUtils.log(LOG, Level.WARNING, "RUNTIME_FAULT_MSG");
            // in case of a SequenceFault or other WS-RM related fault, set action appropriately.
            // the received inbound maps is available to extract some values in case if needed.
            Throwable cause = msg.getContent(Exception.class).getCause();
            if (cause instanceof SequenceFault || cause instanceof RMException) {
                maps.getAction().setValue(getAddressingNamespace(maps) + "/fault");
            }
            return;
        }

        Source source = getManager().getSource(msg);

        RMConfiguration config = getManager().getEffectiveConfiguration(msg);
        String wsaNamespace = config.getAddressingNamespace();
        String rmNamespace = config.getRMNamespace();
        ProtocolVariation protocol = ProtocolVariation.findVariant(rmNamespace, wsaNamespace);
        RMContextUtils.setProtocolVariation(msg, protocol);
        maps.exposeAs(wsaNamespace);

        String action = null;
        if (null != maps.getAction()) {
            action = maps.getAction().getValue();
        }
        //make sure we use the appropriate namespace
        maps.exposeAs(wsaNamespace);

        if (LOG.isLoggable(Level.FINE)) {
            LOG.fine("Action: " + action);
        }

        boolean isApplicationMessage = !RMContextUtils.isRMProtocolMessage(action);
        boolean isPartialResponse = MessageUtils.isPartialResponse(msg);
        RMConstants constants = protocol.getConstants();
        boolean isLastMessage = RM10Constants.CLOSE_SEQUENCE_ACTION.equals(action);

        RMProperties rmpsOut = RMContextUtils.retrieveRMProperties(msg, true);
        if (null == rmpsOut) {
            rmpsOut = new RMProperties();
            rmpsOut.exposeAs(protocol.getWSRMNamespace());
            RMContextUtils.storeRMProperties(msg, rmpsOut, true);
        }

        // Activate process response for oneWay
        if (msg.getExchange().isOneWay()) {
            msg.getExchange().put(Message.PROCESS_ONEWAY_RESPONSE, true);
        }

        RMProperties rmpsIn = null;
        Identifier inSeqId = null;
        long inMessageNumber = 0;

        if (isApplicationMessage) {
            rmpsIn = RMContextUtils.retrieveRMProperties(msg, false);
            if (null != rmpsIn && null != rmpsIn.getSequence()) {
                inSeqId = rmpsIn.getSequence().getIdentifier();
                inMessageNumber = rmpsIn.getSequence().getMessageNumber();
            }
            ContextUtils.storeDeferUncorrelatedMessageAbort(msg);
        }

        Map<?, ?> invocationContext = (Map<?, ?>)msg.get(Message.INVOCATION_CONTEXT);
        if ((isApplicationMessage || (isLastMessage && invocationContext != null)) && !isPartialResponse) {
            if (LOG.isLoggable(Level.FINE)) {
                LOG.fine("inbound sequence: " + (null == inSeqId ? "null" : inSeqId.getValue()));
            }

            // get the current sequence, requesting the creation of a new one if necessary
            synchronized (source) {
                final SourceSequence seq;
                if (isLastMessage) {
                    seq = (SourceSequence)invocationContext.get(SourceSequence.class.getName());
                } else {
                    seq = getManager().getSequence(inSeqId, msg, maps);
                }
                assert null != seq;
                
                // increase message number and store a sequence type object in
                // context
                seq.nextMessageNumber(inSeqId, inMessageNumber, isLastMessage);

                if (Boolean.TRUE.equals(msg.getContextualProperty(RMManager.WSRM_LAST_MESSAGE_PROPERTY))) {
                    // mark the message as the last one
                    seq.setLastMessage(true);
                }

                rmpsOut.setSequence(seq);

                // if this was the last message in the sequence, reset the
                // current sequence so that a new one will be created next
                // time the handler is invoked

                if (seq.isLastMessage()) {
                    source.setCurrent(null);
                }
            }
        } else if (!MessageUtils.isRequestor(msg) && constants.getCreateSequenceAction().equals(action)) {
            maps.getAction().setValue(constants.getCreateSequenceResponseAction());
        } else if (isPartialResponse && action == null
            && isResponseToAction(msg, constants.getSequenceAckAction())) {
            Collection<SequenceAcknowledgement> acks =
                rmpsIn != null ? rmpsIn.getAcks() : null;
            if (acks != null && acks.size() == 1) {
                SourceSequence ss = source.getSequence(acks.iterator().next().getIdentifier());
                if (ss != null && ss.allAcknowledged()) {
                    setAction(maps, constants.getTerminateSequenceAction());
                    setTerminateSequence(msg, ss.getIdentifier(), protocol);
                    msg.remove(Message.EMPTY_PARTIAL_RESPONSE_MESSAGE);
                    // removing this sequence now. See the comment in SourceSequence.setAcknowledged()
                    source.removeSequence(ss);
                }
            }
        }

        // capture message if retransmission possible
        if (isApplicationMessage && !isPartialResponse) {
            OutputStream os = msg.getContent(OutputStream.class);
            // We need to ensure that we have an output stream which won't start writing the
            // message until connection is setup
            if (!(os instanceof WriteOnCloseOutputStream)) {
                msg.setContent(OutputStream.class, new WriteOnCloseOutputStream(os));
            }
            getManager().initializeInterceptorChain(msg);
            //doneCaptureMessage(msg);
            captureMessage(msg);
        } else if (isLastMessage) {
            // got either the rm11 CS or the rm10 empty LM
            RMStore store = getManager().getStore();
            if (null != store) {
                store.persistOutgoing(rmpsOut.getSourceSequence(), null);
            }
        }
    }