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.jaxws.handler.soap;
019:
020: import java.net.URI;
021: import java.util.HashSet;
022: import java.util.Set;
023:
024: import javax.xml.namespace.QName;
025: import javax.xml.soap.SOAPBody;
026: import javax.xml.soap.SOAPException;
027: import javax.xml.soap.SOAPFault;
028: import javax.xml.soap.SOAPMessage;
029: import javax.xml.ws.Binding;
030: import javax.xml.ws.handler.Handler;
031: import javax.xml.ws.handler.MessageContext;
032: import javax.xml.ws.handler.soap.SOAPHandler;
033: import javax.xml.ws.soap.SOAPFaultException;
034:
035: import org.w3c.dom.Node;
036:
037: import org.apache.cxf.binding.soap.SoapFault;
038: import org.apache.cxf.binding.soap.SoapMessage;
039: import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
040: import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
041: import org.apache.cxf.binding.soap.interceptor.SoapInterceptor;
042: import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
043: import org.apache.cxf.helpers.CastUtils;
044: import org.apache.cxf.interceptor.Fault;
045: import org.apache.cxf.interceptor.StaxOutInterceptor;
046: import org.apache.cxf.jaxws.handler.AbstractProtocolHandlerInterceptor;
047: import org.apache.cxf.jaxws.handler.HandlerChainInvoker;
048: import org.apache.cxf.phase.Phase;
049:
050: public class SOAPHandlerFaultOutInterceptor extends
051: AbstractProtocolHandlerInterceptor<SoapMessage> implements
052: SoapInterceptor {
053: private static final SAAJOutInterceptor SAAJ_OUT = new SAAJOutInterceptor();
054: private static final String ENDING_ID = SOAPHandlerFaultOutInterceptor.class
055: .getName()
056: + ".ENDING";
057:
058: AbstractSoapInterceptor ending = new AbstractSoapInterceptor(
059: ENDING_ID, Phase.USER_PROTOCOL) {
060: public void handleMessage(SoapMessage message) throws Fault {
061: handleMessageInternal(message);
062: }
063: };
064:
065: public SOAPHandlerFaultOutInterceptor(Binding binding) {
066: super (binding, Phase.PRE_PROTOCOL);
067: addAfter(MustUnderstandInterceptor.class.getName());
068: addAfter(StaxOutInterceptor.class.getName());
069: addAfter(SAAJOutInterceptor.class.getName());
070: }
071:
072: public Set<URI> getRoles() {
073: Set<URI> roles = new HashSet<URI>();
074: // TODO
075: return roles;
076: }
077:
078: public Set<QName> getUnderstoodHeaders() {
079: Set<QName> understood = new HashSet<QName>();
080: for (Handler h : getBinding().getHandlerChain()) {
081: if (h instanceof SOAPHandler) {
082: Set<QName> headers = CastUtils.cast(((SOAPHandler) h)
083: .getHeaders());
084: if (headers != null) {
085: understood.addAll(headers);
086: }
087: }
088: }
089: return understood;
090: }
091:
092: public void handleMessage(SoapMessage message) {
093: if (getInvoker(message).getProtocolHandlers().isEmpty()) {
094: return;
095: }
096:
097: if (getInvoker(message).isOutbound()) {
098: //The SOAPMessage might be set from the outchain, in this case,
099: //we need to clean it up and create a new SOAPMessage dedicated to fault.
100: message.setContent(SOAPMessage.class, null);
101:
102: SAAJ_OUT.handleMessage(message);
103:
104: message.getInterceptorChain().add(ending);
105: }
106: }
107:
108: private void handleMessageInternal(SoapMessage message) {
109: MessageContext context = createProtocolMessageContext(message);
110: HandlerChainInvoker invoker = getInvoker(message);
111: invoker.setProtocolMessageContext(context);
112:
113: try {
114: if (!invoker.invokeProtocolHandlersHandleFault(
115: isRequestor(message), context)) {
116: // handleAbort(message, context);
117: }
118: } catch (RuntimeException exception) {
119: /*
120: * handleFault throws exception, in this case we need to replace
121: * SOAPFault with the exception thrown from HandleFault so that the
122: * exception can be dispatched.
123: */
124: try {
125: SOAPMessage originalMsg = message
126: .getContent(SOAPMessage.class);
127: SOAPBody body = originalMsg.getSOAPBody();
128: body.removeContents();
129:
130: SOAPFault soapFault = body.addFault();
131:
132: if (exception instanceof SOAPFaultException) {
133: SOAPFaultException sf = (SOAPFaultException) exception;
134: soapFault.setFaultString(sf.getFault()
135: .getFaultString());
136: soapFault.setFaultCode(sf.getFault()
137: .getFaultCodeAsQName());
138: soapFault.setFaultActor(sf.getFault()
139: .getFaultActor());
140: if (sf.getFault().hasDetail()) {
141: Node nd = originalMsg.getSOAPPart().importNode(
142: sf.getFault().getDetail()
143: .getFirstChild(), true);
144: soapFault.addDetail().appendChild(nd);
145: }
146: } else if (exception instanceof Fault) {
147: SoapFault sf = SoapFault.createFault(
148: (Fault) exception, ((SoapMessage) message)
149: .getVersion());
150: soapFault.setFaultString(sf.getReason());
151: soapFault.setFaultCode(sf.getFaultCode());
152: Node nd = originalMsg.getSOAPPart().importNode(
153: sf.getOrCreateDetail(), true);
154: soapFault.addDetail().appendChild(nd);
155: } else {
156: soapFault.setFaultString(exception.getMessage());
157: soapFault.setFaultCode(new QName(
158: "http://cxf.apache.org/faultcode",
159: "HandleFault"));
160: }
161: } catch (SOAPException e) {
162: // do nothing
163: e.printStackTrace();
164: }
165: }
166:
167: onCompletion(message);
168: }
169:
170: @Override
171: protected MessageContext createProtocolMessageContext(
172: SoapMessage message) {
173: return new SOAPMessageContextImpl(message);
174: }
175:
176: public void handleFault(SoapMessage message) {
177: }
178: }
|