alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Apache CXF example source code file (SoapOutInterceptor.java)

This example Apache CXF source code file (SoapOutInterceptor.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Apache CXF tags/keywords

bundle, bundle, dom, io, list, soapfault, soapheader, soapheader, soapoutendinginterceptor, soapversion, string, string, util, xml_write_exc, xmlstreamexception, xmlstreamexception, xmlstreamwriter

The Apache CXF SoapOutInterceptor.java source code

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.cxf.binding.soap.interceptor;


import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.w3c.dom.Element;

import org.apache.cxf.Bus;
import org.apache.cxf.binding.soap.SoapFault;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.SoapVersion;
import org.apache.cxf.binding.soap.model.SoapHeaderInfo;
import org.apache.cxf.common.i18n.BundleUtils;
import org.apache.cxf.common.util.StringUtils;
import org.apache.cxf.databinding.DataBinding;
import org.apache.cxf.databinding.DataWriter;
import org.apache.cxf.headers.Header;
import org.apache.cxf.headers.HeaderManager;
import org.apache.cxf.headers.HeaderProcessor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.WriteOnCloseOutputStream;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.service.Service;
import org.apache.cxf.service.model.BindingMessageInfo;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.apache.cxf.service.model.MessagePartInfo;
import org.apache.cxf.service.model.ServiceModelUtil;
import org.apache.cxf.staxutils.DelegatingXMLStreamWriter;
import org.apache.cxf.staxutils.StaxUtils;

public class SoapOutInterceptor extends AbstractSoapInterceptor {
    public static final String WROTE_ENVELOPE_START = "wrote.envelope.start";
    
    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(SoapOutInterceptor.class);
    
    private Bus bus;
    
    public SoapOutInterceptor(Bus b) {
        super(Phase.WRITE);
        bus = b;
    }
    public SoapOutInterceptor(Bus b, String phase) {
        super(phase);
        bus = b;
    }
    
    public void handleMessage(SoapMessage message) {
        // Yes this is ugly, but it avoids us from having to implement any kind of caching strategy
        boolean wroteStart = MessageUtils.isTrue(message.get(WROTE_ENVELOPE_START));
        if (!wroteStart) {
            writeSoapEnvelopeStart(message);
            
            OutputStream os = message.getContent(OutputStream.class);
            // Unless we're caching the whole message in memory skip the envelope writing
            // if there's a fault later.
            if (!(os instanceof WriteOnCloseOutputStream) && !MessageUtils.isDOMPresent(message)) {
                message.put(WROTE_ENVELOPE_START, Boolean.TRUE);
            }
        }

        // Add a final interceptor to write end elements
        message.getInterceptorChain().add(new SoapOutEndingInterceptor());
    }
    
    private void writeSoapEnvelopeStart(final SoapMessage message) {
        final SoapVersion soapVersion = message.getVersion();
        try {            
            XMLStreamWriter xtw = message.getContent(XMLStreamWriter.class);
            String soapPrefix = xtw.getPrefix(soapVersion.getNamespace());
            if (StringUtils.isEmpty(soapPrefix)) {
                soapPrefix = "soap";
            }
            if (message.hasAdditionalEnvNs()) {
                Map<String, String> nsMap = message.getEnvelopeNs();
                for (Map.Entry<String, String> entry : nsMap.entrySet()) {
                    if (soapVersion.getNamespace().equals(entry.getValue())) {
                        soapPrefix = entry.getKey();
                    }
                }
                xtw.setPrefix(soapPrefix, soapVersion.getNamespace());
                xtw.writeStartElement(soapPrefix, 
                                      soapVersion.getEnvelope().getLocalPart(),
                                      soapVersion.getNamespace());
                xtw.writeNamespace(soapPrefix, soapVersion.getNamespace());
                for (Map.Entry<String, String> entry : nsMap.entrySet()) {
                    if (!soapVersion.getNamespace().equals(entry.getValue())) {
                        xtw.writeNamespace(entry.getKey(), entry.getValue());
                    }
                }                
            } else {
                xtw.setPrefix(soapPrefix, soapVersion.getNamespace());
                xtw.writeStartElement(soapPrefix, 
                                      soapVersion.getEnvelope().getLocalPart(),
                                      soapVersion.getNamespace());
                String s2 = xtw.getPrefix(soapVersion.getNamespace());
                if (StringUtils.isEmpty(s2) || soapPrefix.equals(s2)) {
                    xtw.writeNamespace(soapPrefix, soapVersion.getNamespace());
                } else {
                    soapPrefix = s2;
                }
            }
            boolean preexistingHeaders = message.hasHeaders();

            if (preexistingHeaders) {
                xtw.writeStartElement(soapPrefix, 
                                      soapVersion.getHeader().getLocalPart(),
                                      soapVersion.getNamespace());   
                List<Header> hdrList = message.getHeaders();
                for (Header header : hdrList) {
                    XMLStreamWriter writer = xtw;
                    if (header instanceof SoapHeader) {
                        SoapHeader soapHeader = (SoapHeader)header;
                        writer = new SOAPHeaderWriter(xtw, soapHeader, soapVersion, soapPrefix);
                    }
                    DataBinding b = header.getDataBinding();
                    if (b == null) {
                        HeaderProcessor hp = bus.getExtension(HeaderManager.class)
                                .getHeaderProcessor(header.getName().getNamespaceURI());
                        if (hp != null) {
                            b = hp.getDataBinding();
                        }
                    }
                    if (b != null) {
                        MessagePartInfo part = new MessagePartInfo(header.getName(), null);
                        part.setConcreteName(header.getName());
                        b.createWriter(XMLStreamWriter.class)
                            .write(header.getObject(), part, writer);
                    } else {
                        Element node = (Element)header.getObject();
                        StaxUtils.copy(node, writer);
                    }
                }
            }
            boolean endedHeader = handleHeaderPart(preexistingHeaders, message, soapPrefix);
            if (preexistingHeaders && !endedHeader) {
                xtw.writeEndElement();
            }

            xtw.writeStartElement(soapPrefix, 
                                  soapVersion.getBody().getLocalPart(),
                                  soapVersion.getNamespace());
            
            // Interceptors followed such as Wrapped/RPC/Doc Interceptor will write SOAP body
        } catch (XMLStreamException e) {
            throw new SoapFault(
                new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), e, soapVersion.getSender());
        }
    }
    
    private boolean handleHeaderPart(boolean preexistingHeaders, SoapMessage message, String soapPrefix) {
        //add MessagePart to soapHeader if necessary
        boolean endedHeader = false;
        Exchange exchange = message.getExchange();
        BindingOperationInfo bop = (BindingOperationInfo)exchange.get(BindingOperationInfo.class
                                                                            .getName());
        if (bop == null) {
            return endedHeader;
        }
        
        XMLStreamWriter xtw = message.getContent(XMLStreamWriter.class);        
        boolean startedHeader = false;
        BindingOperationInfo unwrappedOp = bop;
        if (bop.isUnwrapped()) {
            unwrappedOp = bop.getWrappedOperation();
        }
        boolean client = isRequestor(message);
        BindingMessageInfo bmi = client ? unwrappedOp.getInput() : unwrappedOp.getOutput();
        BindingMessageInfo wrappedBmi = client ? bop.getInput() : bop.getOutput();
        
        if (bmi == null) {
            return endedHeader;
        }
        
        List<MessagePartInfo> parts = wrappedBmi.getMessageInfo().getMessageParts();
        if (parts.size() > 0) {
            MessageContentsList objs = MessageContentsList.getContentsList(message);
            if (objs == null) {
                return endedHeader;
            }
            SoapVersion soapVersion = message.getVersion();
            List<SoapHeaderInfo> headers = bmi.getExtensors(SoapHeaderInfo.class);
            if (headers == null) {
                return endedHeader;
            }            

            for (SoapHeaderInfo header : headers) {
                MessagePartInfo part = header.getPart();
                if (wrappedBmi != bmi) {
                    part = wrappedBmi.getMessageInfo().addMessagePart(part.getName());
                }
                if (part.getIndex() >= objs.size()) {
                    // The optional out of band header is not a part of parameters of the method
                    continue;
                }
                Object arg = objs.get(part);
                if (arg == null) {
                    continue;
                }
                objs.remove(part);
                if (!(startedHeader || preexistingHeaders)) {
                    try {
                        xtw.writeStartElement(soapPrefix, 
                                              soapVersion.getHeader().getLocalPart(),
                                              soapVersion.getNamespace());
                    } catch (XMLStreamException e) {
                        throw new SoapFault(new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), 
                            e, soapVersion.getSender());
                    }
                    startedHeader = true;
                }
                DataWriter<XMLStreamWriter> dataWriter = getDataWriter(message);
                dataWriter.write(arg, header.getPart(), xtw);
            }
            
            if (startedHeader || preexistingHeaders) {
                try {
                    xtw.writeEndElement();
                    endedHeader = true;
                } catch (XMLStreamException e) {
                    throw new SoapFault(new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), 
                        e, soapVersion.getSender());
                }
            }
        }
        return endedHeader;
    }       
    
    protected DataWriter<XMLStreamWriter> getDataWriter(Message message) {
        Service service = ServiceModelUtil.getService(message.getExchange());
        DataWriter<XMLStreamWriter> dataWriter = service.getDataBinding().createWriter(XMLStreamWriter.class);
        if (dataWriter == null) {
            throw new Fault(new org.apache.cxf.common.i18n.Message("NO_DATAWRITER", BUNDLE, service
                .getName()));
        }
        dataWriter.setAttachments(message.getAttachments());

        return dataWriter;
    }
        
    public class SoapOutEndingInterceptor extends AbstractSoapInterceptor {
        public SoapOutEndingInterceptor() {
            super(SoapOutEndingInterceptor.class.getName(), Phase.WRITE_ENDING);
        }

        public void handleMessage(SoapMessage message) throws Fault {
            try {
                XMLStreamWriter xtw = message.getContent(XMLStreamWriter.class);
                if (xtw != null) {
                    xtw.writeEndElement();            
                    // Write Envelope end element
                    xtw.writeEndElement();
                    xtw.writeEndDocument();
                    
                    xtw.flush();
                }
            } catch (XMLStreamException e) {
                SoapVersion soapVersion = message.getVersion();
                throw new SoapFault(new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), e,
                                    soapVersion.getSender());
            }
        }
    }
    
    public static class SOAPHeaderWriter extends DelegatingXMLStreamWriter {
        final SoapHeader soapHeader;
        final SoapVersion soapVersion;
        final String soapPrefix;
        boolean firstDone;
        
        
        public SOAPHeaderWriter(XMLStreamWriter writer,
                                SoapHeader header,
                                SoapVersion version,
                                String pfx) {
            super(writer);
            soapHeader = header;
            soapVersion = version;
            soapPrefix = pfx;
        }
        
        public void writeAttribute(String prefix, String uri, String local, String value)
            throws XMLStreamException {
            if (soapVersion.getNamespace().equals(uri)
                && (local.equals(soapVersion.getAttrNameMustUnderstand())
                    || local.equals(soapVersion.getAttrNameRole()))) {
                return;
            }
            super.writeAttribute(prefix, uri, local, value);
        }
        public void writeAttribute(String uri, String local, String value) throws XMLStreamException {
            if (soapVersion.getNamespace().equals(uri)
                && (local.equals(soapVersion.getAttrNameMustUnderstand())
                    || local.equals(soapVersion.getAttrNameRole()))) {
                return;
            }
            super.writeAttribute(uri, local, value);
        }
        
        private void writeSoapAttributes() throws XMLStreamException {
            if (!firstDone) {
                firstDone = true;
                if (!StringUtils.isEmpty(soapHeader.getActor())) {
                    super.writeAttribute(soapPrefix,
                                   soapVersion.getNamespace(),
                                   soapVersion.getAttrNameRole(),
                                   soapHeader.getActor());
                }
                boolean mu = soapHeader.isMustUnderstand();
                if (mu) {
                    String mul = soapVersion.getAttrValueMustUnderstand(mu); 
                    super.writeAttribute(soapPrefix,
                                   soapVersion.getNamespace(),
                                   soapVersion.getAttrNameMustUnderstand(),
                                   mul);                                        
                }
            }
        }
        public void writeStartElement(String arg0, String arg1, String arg2)
            throws XMLStreamException {
            super.writeStartElement(arg0, arg1, arg2);
            writeSoapAttributes();
        }
        public void writeStartElement(String arg0, String arg1)
            throws XMLStreamException {
            super.writeStartElement(arg0, arg1);
            writeSoapAttributes();
        }
        public void writeStartElement(String arg0) throws XMLStreamException {
            super.writeStartElement(arg0);
            writeSoapAttributes();
        }
        
        
    };
}

Other Apache CXF examples (source code examples)

Here is a short list of links related to this Apache CXF SoapOutInterceptor.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.