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.SOAPException;
026: import javax.xml.soap.SOAPMessage;
027: import javax.xml.stream.XMLStreamException;
028: import javax.xml.stream.XMLStreamReader;
029: import javax.xml.transform.dom.DOMSource;
030: import javax.xml.ws.Binding;
031: import javax.xml.ws.handler.Handler;
032: import javax.xml.ws.handler.MessageContext;
033: import javax.xml.ws.handler.soap.SOAPHandler;
034: import javax.xml.ws.handler.soap.SOAPMessageContext;
035:
036: import org.apache.cxf.binding.soap.SoapMessage;
037: import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
038: import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
039: import org.apache.cxf.binding.soap.interceptor.SoapActionOutInterceptor;
040: import org.apache.cxf.binding.soap.interceptor.SoapInterceptor;
041: import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
042: import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
043: import org.apache.cxf.endpoint.Endpoint;
044: import org.apache.cxf.helpers.CastUtils;
045: import org.apache.cxf.interceptor.Fault;
046: import org.apache.cxf.interceptor.InterceptorChain;
047: import org.apache.cxf.interceptor.OutgoingChainInterceptor;
048: import org.apache.cxf.jaxws.handler.AbstractProtocolHandlerInterceptor;
049: import org.apache.cxf.jaxws.handler.HandlerChainInvoker;
050: import org.apache.cxf.jaxws.support.ContextPropertiesMapping;
051: import org.apache.cxf.message.Message;
052: import org.apache.cxf.phase.Phase;
053: import org.apache.cxf.phase.PhaseInterceptorChain;
054: import org.apache.cxf.staxutils.StaxUtils;
055: import org.apache.cxf.transport.MessageObserver;
056:
057: public class SOAPHandlerInterceptor extends
058: AbstractProtocolHandlerInterceptor<SoapMessage> implements
059: SoapInterceptor {
060: private static final SAAJOutInterceptor SAAJ_OUT = new SAAJOutInterceptor();
061:
062: AbstractSoapInterceptor ending = new AbstractSoapInterceptor(
063: SOAPHandlerInterceptor.class.getName() + ".ENDING",
064: Phase.USER_PROTOCOL) {
065:
066: public void handleMessage(SoapMessage message) throws Fault {
067: handleMessageInternal(message);
068: }
069: };
070:
071: public SOAPHandlerInterceptor(Binding binding) {
072: super (binding, Phase.PRE_PROTOCOL);
073: addAfter(MustUnderstandInterceptor.class.getName());
074: addAfter(SAAJOutInterceptor.class.getName());
075: }
076:
077: public Set<URI> getRoles() {
078: Set<URI> roles = new HashSet<URI>();
079: //TODO
080: return roles;
081: }
082:
083: public Set<QName> getUnderstoodHeaders() {
084: Set<QName> understood = new HashSet<QName>();
085: for (Handler h : getBinding().getHandlerChain()) {
086: if (h instanceof SOAPHandler) {
087: Set<QName> headers = CastUtils.cast(((SOAPHandler) h)
088: .getHeaders());
089: if (headers != null) {
090: understood.addAll(headers);
091: }
092: }
093: }
094: return understood;
095: }
096:
097: public void handleMessage(SoapMessage message) {
098: if (getInvoker(message).getProtocolHandlers().isEmpty()) {
099: return;
100: }
101:
102: if (getInvoker(message).isOutbound()) {
103:
104: SAAJ_OUT.handleMessage(message);
105:
106: message.getInterceptorChain().add(ending);
107: } else {
108: handleMessageInternal(message);
109: SOAPMessage msg = message.getContent(SOAPMessage.class);
110: if (msg != null) {
111: XMLStreamReader xmlReader = createXMLStreamReaderFromSOAPMessage(msg);
112: message.setContent(XMLStreamReader.class, xmlReader);
113: // replace headers
114: try {
115: SAAJInInterceptor.replaceHeaders(msg, message);
116: } catch (SOAPException e) {
117: e.printStackTrace();
118: }
119: }
120: }
121: }
122:
123: private void handleMessageInternal(SoapMessage message) {
124: MessageContext context = createProtocolMessageContext(message);
125: HandlerChainInvoker invoker = getInvoker(message);
126: invoker.setProtocolMessageContext(context);
127:
128: if (!invoker.invokeProtocolHandlers(isRequestor(message),
129: context)) {
130: handleAbort(message, context);
131: }
132:
133: // If this is the outbound and end of MEP, call MEP completion
134: if (isRequestor(message)
135: && invoker.getLogicalHandlers().isEmpty()
136: && !isOutbound(message) && isMEPComlete(message)) {
137: onCompletion(message);
138: } else if (isOutbound(message) && isMEPComlete(message)) {
139: onCompletion(message);
140: }
141: }
142:
143: private void handleAbort(SoapMessage message, MessageContext context) {
144: if (isRequestor(message)) {
145: // client side outbound
146: if (getInvoker(message).isOutbound()) {
147: message.getInterceptorChain().abort();
148: Endpoint e = message.getExchange().get(Endpoint.class);
149: Message responseMsg = e.getBinding().createMessage();
150:
151: MessageObserver observer = (MessageObserver) message
152: .getExchange().get(MessageObserver.class);
153: if (observer != null) {
154: // the request message becomes the response message
155: message.getExchange().setInMessage(responseMsg);
156: SOAPMessage soapMessage = ((SOAPMessageContext) context)
157: .getMessage();
158:
159: if (soapMessage != null) {
160: responseMsg.setContent(SOAPMessage.class,
161: soapMessage);
162: XMLStreamReader xmlReader = createXMLStreamReaderFromSOAPMessage(soapMessage);
163: responseMsg.setContent(XMLStreamReader.class,
164: xmlReader);
165: }
166: responseMsg
167: .put(
168: PhaseInterceptorChain.STARTING_AT_INTERCEPTOR_ID,
169: SOAPHandlerInterceptor.class
170: .getName());
171: observer.onMessage(responseMsg);
172: }
173:
174: //We dont call onCompletion here, as onCompletion will be called by inbound
175: //LogicalHandlerInterceptor
176: } else {
177: // client side inbound - Normal handler message processing
178: // stops, but the inbound interceptor chain still continues, dispatch the message
179: //By onCompletion here, we can skip following Logical handlers
180: onCompletion(message);
181: }
182: } else {
183: if (!getInvoker(message).isOutbound()) {
184: // server side inbound
185: message.getInterceptorChain().abort();
186: Endpoint e = message.getExchange().get(Endpoint.class);
187: Message responseMsg = e.getBinding().createMessage();
188: if (!message.getExchange().isOneWay()) {
189: message.getExchange().setOutMessage(responseMsg);
190: SOAPMessage soapMessage = ((SOAPMessageContext) context)
191: .getMessage();
192:
193: responseMsg.setContent(SOAPMessage.class,
194: soapMessage);
195:
196: InterceptorChain chain = OutgoingChainInterceptor
197: .getOutInterceptorChain(message
198: .getExchange());
199: responseMsg.setInterceptorChain(chain);
200: // so the idea of starting interceptor chain from any
201: // specified point does not work
202: // well for outbound case, as many outbound interceptors
203: // have their ending interceptors.
204: // For example, we can not skip MessageSenderInterceptor.
205: chain.doInterceptStartingAfter(responseMsg,
206: SoapActionOutInterceptor.class.getName());
207: }
208:
209: } else {
210: // server side outbound - Normal handler message processing
211: // stops, but still continue the outbound interceptor chain, dispatch the message
212: }
213: }
214: }
215:
216: @Override
217: protected MessageContext createProtocolMessageContext(
218: SoapMessage message) {
219: SOAPMessageContextImpl sm = new SOAPMessageContextImpl(message);
220: boolean requestor = isRequestor(message);
221: ContextPropertiesMapping.mapCxf2Jaxws(message.getExchange(),
222: sm, requestor);
223: return sm;
224: }
225:
226: private XMLStreamReader createXMLStreamReaderFromSOAPMessage(
227: SOAPMessage soapMessage) {
228: // responseMsg.setContent(SOAPMessage.class, soapMessage);
229: XMLStreamReader xmlReader = null;
230: try {
231: DOMSource bodySource = new DOMSource(soapMessage
232: .getSOAPPart().getEnvelope().getBody());
233: xmlReader = StaxUtils.createXMLStreamReader(bodySource);
234: xmlReader.nextTag();
235: xmlReader.nextTag(); // move past body tag
236: } catch (SOAPException e) {
237: e.printStackTrace();
238: } catch (XMLStreamException e) {
239: e.printStackTrace();
240: }
241: return xmlReader;
242: }
243:
244: public void handleFault(SoapMessage message) {
245: }
246: }
|