001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.binding.soap.interceptor;
019:
020: import java.util.Map;
021: import java.util.ResourceBundle;
022:
023: import javax.xml.parsers.DocumentBuilderFactory;
024: import javax.xml.parsers.ParserConfigurationException;
025: import javax.xml.stream.XMLStreamException;
026: import javax.xml.stream.XMLStreamWriter;
027:
028: import org.w3c.dom.Document;
029: import org.w3c.dom.Element;
030: import org.w3c.dom.NodeList;
031:
032: import org.apache.cxf.binding.soap.Soap11;
033: import org.apache.cxf.binding.soap.SoapFault;
034: import org.apache.cxf.binding.soap.SoapMessage;
035: import org.apache.cxf.common.i18n.BundleUtils;
036: import org.apache.cxf.common.i18n.Message;
037: import org.apache.cxf.interceptor.Fault;
038: import org.apache.cxf.phase.Phase;
039: import org.apache.cxf.staxutils.StaxUtils;
040:
041: public class Soap11FaultOutInterceptor extends AbstractSoapInterceptor {
042: private static final ResourceBundle BUNDLE = BundleUtils
043: .getBundle(Soap11FaultOutInterceptor.class);
044:
045: public Soap11FaultOutInterceptor() {
046: super (Phase.MARSHAL);
047: }
048:
049: public void handleMessage(SoapMessage message) throws Fault {
050: message.put(org.apache.cxf.message.Message.RESPONSE_CODE,
051: new Integer(500));
052:
053: XMLStreamWriter writer = message
054: .getContent(XMLStreamWriter.class);
055: Fault f = (Fault) message.getContent(Exception.class);
056:
057: SoapFault fault = SoapFault
058: .createFault(f, message.getVersion());
059:
060: try {
061: Map<String, String> namespaces = fault.getNamespaces();
062: for (Map.Entry<String, String> e : namespaces.entrySet()) {
063: writer.writeNamespace(e.getKey(), e.getValue());
064: }
065:
066: String ns = message.getVersion().getNamespace();
067: String defaultPrefix = writer.getPrefix(ns);
068: if (defaultPrefix == null) {
069: defaultPrefix = StaxUtils.getUniquePrefix(writer, ns,
070: false);
071: writer.writeStartElement(defaultPrefix, "Fault", ns);
072: writer.writeNamespace(defaultPrefix, ns);
073: } else {
074: writer.writeStartElement(defaultPrefix, "Fault", ns);
075: }
076:
077: writer.writeStartElement("faultcode");
078:
079: String codeString = fault.getCodeString(getFaultCodePrefix(
080: writer, fault.getFaultCode()), defaultPrefix);
081:
082: writer.writeCharacters(codeString);
083: writer.writeEndElement();
084:
085: writer.writeStartElement("faultstring");
086: if (fault.getMessage() != null) {
087: writer.writeCharacters(fault.getMessage());
088: } else {
089: writer
090: .writeCharacters("Fault occurred while processing.");
091: }
092: writer.writeEndElement();
093: String config = (String) message
094: .getContextualProperty(org.apache.cxf.message.Message.FAULT_STACKTRACE_ENABLED);
095: if (config != null
096: && Boolean.valueOf(config).booleanValue()
097: && fault.getCause() != null) {
098: StringBuffer sb = new StringBuffer();
099: for (StackTraceElement ste : fault.getCause()
100: .getStackTrace()) {
101: sb.append(ste.getClassName() + "!"
102: + ste.getMethodName() + "!"
103: + ste.getFileName() + "!"
104: + ste.getLineNumber() + "\n");
105: }
106: try {
107: Element detail = fault.getDetail();
108: if (detail == null) {
109: DocumentBuilderFactory factory = DocumentBuilderFactory
110: .newInstance();
111: factory.setNamespaceAware(true);
112: Document doc = factory.newDocumentBuilder()
113: .newDocument();
114: Element stackTrace = doc
115: .createElementNS(Soap11.SOAP_NAMESPACE,
116: Fault.STACKTRACE);
117: stackTrace.setTextContent(sb.toString());
118: detail = doc.createElementNS(
119: Soap11.SOAP_NAMESPACE, "detail");
120: fault.setDetail(detail);
121: detail.appendChild(stackTrace);
122: } else {
123: Element stackTrace = detail.getOwnerDocument()
124: .createElementNS(Soap11.SOAP_NAMESPACE,
125: Fault.STACKTRACE);
126: detail.appendChild(stackTrace);
127: }
128: } catch (ParserConfigurationException pe) {
129: // move on...
130: }
131: }
132:
133: if (fault.hasDetails()) {
134: Element detail = fault.getDetail();
135: writer.writeStartElement("detail");
136:
137: NodeList details = detail.getChildNodes();
138: for (int i = 0; i < details.getLength(); i++) {
139: StaxUtils.writeNode(details.item(i), writer, true);
140: }
141:
142: // Details
143: writer.writeEndElement();
144: }
145:
146: if (fault.getRole() != null) {
147: writer.writeStartElement("faultactor");
148: writer.writeCharacters(fault.getRole());
149: writer.writeEndElement();
150: }
151:
152: // Fault
153: writer.writeEndElement();
154: } catch (XMLStreamException xe) {
155: throw new Fault(new Message("XML_WRITE_EXC", BUNDLE), xe);
156: }
157: }
158: }
|