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.cxfbc.interceptors;
018
019 import javax.xml.namespace.QName;
020 import javax.xml.stream.XMLStreamReader;
021
022 import org.apache.cxf.attachment.LazyAttachmentCollection;
023 import org.apache.cxf.binding.soap.model.SoapBindingInfo;
024 import org.apache.cxf.binding.soap.model.SoapBodyInfo;
025 import org.apache.cxf.endpoint.Endpoint;
026 import org.apache.cxf.interceptor.Fault;
027 import org.apache.cxf.interceptor.URIMappingInterceptor;
028 import org.apache.cxf.message.Message;
029 import org.apache.cxf.phase.AbstractPhaseInterceptor;
030 import org.apache.cxf.phase.Phase;
031 import org.apache.cxf.service.model.BindingMessageInfo;
032 import org.apache.cxf.service.model.BindingOperationInfo;
033 import org.apache.cxf.service.model.OperationInfo;
034 import org.apache.cxf.service.model.ServiceModelUtil;
035 import org.apache.cxf.staxutils.DepthXMLStreamReader;
036 import org.apache.cxf.staxutils.StaxUtils;
037
038
039 public class JbiOperationInterceptor extends AbstractPhaseInterceptor<Message> {
040
041
042 public JbiOperationInterceptor() {
043 super(Phase.UNMARSHAL);
044 addAfter(URIMappingInterceptor.class.getName());
045 }
046
047 public void handleMessage(Message message) {
048 loadAttachments(message);
049 if (isGET(message)) {
050 return;
051 }
052 if (message.getExchange().get(BindingOperationInfo.class) != null) {
053 return;
054 }
055
056 DepthXMLStreamReader xmlReader = getXMLStreamReader(message);
057
058 BindingOperationInfo operation = null;
059 if (!StaxUtils.toNextElement(xmlReader)) {
060 message.setContent(Exception.class, new RuntimeException(
061 "There must be a method name element."));
062 }
063 String opName = xmlReader.getLocalName();
064 if (isRequestor(message) && opName.endsWith("Response")) {
065 opName = opName.substring(0, opName.length() - 8);
066 }
067 QName opQName = new QName(xmlReader.getNamespaceURI(), opName);
068 SoapBindingInfo binding = (SoapBindingInfo) message.getExchange().get(
069 Endpoint.class).getEndpointInfo().getBinding();
070 for (BindingOperationInfo op : binding.getOperations()) {
071 String style = binding.getStyle(op.getOperationInfo());
072 if (style == null) {
073 style = binding.getStyle();
074 }
075 if ("document".equals(style)) {
076 BindingMessageInfo msg = !isRequestor(message) ? op.getInput()
077 : op.getOutput();
078 if (msg.getExtensor(SoapBodyInfo.class)
079 .getParts().get(0).getElementQName().equals(opQName)) {
080 operation = op;
081 break;
082 }
083 } else {
084 if (opQName.equals(op.getName())) {
085 operation = op;
086 break;
087 }
088 }
089 }
090 if (operation != null) {
091 message.getExchange().put(BindingOperationInfo.class, operation);
092 message.getExchange().put(OperationInfo.class,
093 operation.getOperationInfo());
094 message.getExchange().setOneWay(operation.getOperationInfo().isOneWay());
095 }
096 }
097
098 private void loadAttachments(Message message) {
099 //get chance to cache the attachments
100 if (message.getAttachments() != null) {
101 LazyAttachmentCollection attachments = (LazyAttachmentCollection) message.getAttachments();
102 attachments.size();
103 }
104 }
105
106 protected DepthXMLStreamReader getXMLStreamReader(Message message) {
107
108 XMLStreamReader xr = message.getContent(XMLStreamReader.class);
109 if (xr instanceof DepthXMLStreamReader) {
110 return (DepthXMLStreamReader) xr;
111 }
112 DepthXMLStreamReader dr = new DepthXMLStreamReader(xr);
113 message.setContent(XMLStreamReader.class, dr);
114 return dr;
115 }
116
117 protected BindingOperationInfo getOperation(Message message, QName opName) {
118 BindingOperationInfo op = ServiceModelUtil.getOperation(message
119 .getExchange(), opName);
120 if (op == null) {
121 throw new Fault(new Exception("Unrecognized operation"));
122 }
123 return op;
124 }
125
126 protected boolean isRequestor(Message message) {
127 return Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE));
128 }
129
130 }