001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.servicemix.soap.bindings.soap.interceptors;
018    
019    import java.net.URI;
020    
021    import javax.xml.XMLConstants;
022    import javax.xml.namespace.QName;
023    import javax.xml.stream.XMLStreamException;
024    import javax.xml.stream.XMLStreamReader;
025    import javax.xml.stream.XMLStreamWriter;
026    import javax.xml.transform.Source;
027    
028    import org.apache.servicemix.soap.api.Fault;
029    import org.apache.servicemix.soap.api.Message;
030    import org.apache.servicemix.soap.bindings.soap.Soap11;
031    import org.apache.servicemix.soap.bindings.soap.SoapConstants;
032    import org.apache.servicemix.soap.bindings.soap.SoapFault;
033    import org.apache.servicemix.soap.bindings.soap.SoapVersion;
034    import org.apache.servicemix.soap.core.AbstractInterceptor;
035    import org.apache.servicemix.soap.util.stax.StaxUtil;
036    
037    /**
038     * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
039     */
040    public class SoapFaultOutInterceptor extends AbstractInterceptor {
041    
042        public void handleMessage(Message message) {
043            Exception exception = message.getContent(Exception.class);
044            XMLStreamWriter writer = message.getContent(XMLStreamWriter.class);
045            SoapVersion soapVersion = message.get(SoapVersion.class);
046            try {
047                if (exception instanceof SoapFault) {
048                    SoapFault fault = (SoapFault) exception;
049                    if (soapVersion == null) {
050                        soapVersion = Soap11.getInstance();
051                    }
052                    if (soapVersion.getVersion() == 1.1) {
053                        writeSoap11Fault(writer, fault, soapVersion);
054                    } else if (soapVersion.getVersion() == 1.2) {
055                        writeSoap12Fault(writer, fault, soapVersion);
056                    } else {
057                        throw new IllegalStateException("Unrecognized soap version: " + soapVersion.getVersion());
058                    }
059                }
060            } catch (XMLStreamException e) {
061                throw new Fault(e);
062            }
063        }
064    
065        private void writeSoap11Fault(XMLStreamWriter writer, SoapFault fault, SoapVersion soapVersion) throws XMLStreamException {
066            fault.translateCodeTo11();
067    
068            StaxUtil.writeStartElement(writer, soapVersion.getFault());
069            QName code = fault.getCode();
070            if (code != null) {
071                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_11_FAULTCODE);
072                StaxUtil.writeTextQName(writer, code);
073                writer.writeEndElement();
074            }
075            String reason = fault.getReason();
076            if (reason == null && fault.getCause() != null) {
077                reason = fault.getCause().toString();
078            }
079            StaxUtil.writeStartElement(writer, SoapConstants.SOAP_11_FAULTSTRING);
080            if (reason != null) {
081                writer.writeCharacters(reason);
082            }
083            writer.writeEndElement();
084            URI node = fault.getNode();
085            if (node != null) {
086                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_11_FAULTACTOR);
087                writer.writeCharacters(node.toString());
088                writer.writeEndElement();
089            }
090            Source details = fault.getDetails();
091            if (details != null) {
092                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_11_FAULTDETAIL);
093                XMLStreamReader reader = StaxUtil.createReader(details);
094                StaxUtil.copy(reader, writer);
095                writer.writeEndElement();
096            }
097    
098            writer.writeEndElement();
099        }
100    
101        private void writeSoap12Fault(XMLStreamWriter writer, SoapFault fault, SoapVersion soapVersion) throws XMLStreamException {
102            fault.translateCodeTo12();
103            
104            StaxUtil.writeStartElement(writer, soapVersion.getFault());
105            QName code = fault.getCode();
106            if (code != null) {
107                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTCODE);
108                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTVALUE);
109                StaxUtil.writeTextQName(writer, code);
110                writer.writeEndElement();
111                QName subcode = fault.getSubcode();
112                if (subcode != null) {
113                    StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTSUBCODE);
114                    StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTVALUE);
115                    StaxUtil.writeTextQName(writer, subcode);
116                    writer.writeEndElement();
117                    writer.writeEndElement();
118                }
119                writer.writeEndElement();
120            }
121            String reason = fault.getReason();
122            if (reason == null && fault.getCause() != null) {
123                reason = fault.getCause().toString();
124            }
125            StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTREASON);
126            StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTTEXT);
127            writer.writeAttribute(XMLConstants.XML_NS_PREFIX, XMLConstants.XML_NS_URI, "lang", "en");
128            if (reason != null) {
129                writer.writeCharacters(reason);
130            }
131            writer.writeEndElement();
132            writer.writeEndElement();
133            URI node = fault.getNode();
134            if (node != null) {
135                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTNODE);
136                writer.writeCharacters(node.toString());
137                writer.writeEndElement();
138            }
139    
140            URI role = fault.getRole();
141            if (role != null) {
142                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTROLE);
143                writer.writeCharacters(role.toString());
144                writer.writeEndElement();
145            }
146    
147            Source details = fault.getDetails();
148            if (details != null) {
149                StaxUtil.writeStartElement(writer, SoapConstants.SOAP_12_FAULTDETAIL);
150                XMLStreamReader reader = StaxUtil.createReader(details);
151                StaxUtil.copy(reader, writer);
152                writer.writeEndElement();
153            }
154    
155            writer.writeEndElement();
156        }
157        
158    }