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 java.net.URI;
020: import java.util.HashMap;
021: import java.util.Map;
022:
023: import javax.jbi.JBIException;
024: import javax.jbi.component.ComponentContext;
025: import javax.jbi.messaging.DeliveryChannel;
026: import javax.jbi.messaging.MessageExchange;
027: import javax.jbi.messaging.MessageExchangeFactory;
028: import javax.jbi.messaging.MessagingException;
029: import javax.jbi.messaging.NormalizedMessage;
030: import javax.security.auth.Subject;
031: import javax.xml.transform.Source;
032:
033: import org.apache.cxf.binding.soap.SoapMessage;
034: import org.apache.cxf.headers.Header;
035: import org.apache.cxf.interceptor.Fault;
036: import org.apache.cxf.message.Attachment;
037: import org.apache.cxf.message.Message;
038: import org.apache.cxf.phase.AbstractPhaseInterceptor;
039: import org.apache.cxf.phase.Phase;
040: import org.apache.cxf.service.model.BindingOperationInfo;
041: import org.apache.cxf.ws.addressing.AddressingProperties;
042: import org.apache.servicemix.cxfbc.WSAUtils;
043: import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
044: import org.apache.servicemix.soap.util.QNameUtil;
045:
046: /**
047: * @author <a href="mailto:gnodet [at] gmail.com">Guillaume Nodet</a>
048: */
049: public class JbiInInterceptor extends AbstractPhaseInterceptor<Message> {
050:
051: public static final String OPERATION_MEP = "MEP";
052:
053: public JbiInInterceptor() {
054: super (Phase.PRE_INVOKE);
055: }
056:
057: public void handleMessage(Message message) {
058: try {
059: MessageExchange exchange;
060: NormalizedMessage nm;
061: // Create message
062: if (!isRequestor(message)) {
063: exchange = createExchange(message);
064: nm = exchange.createMessage();
065: exchange.setMessage(nm, "in");
066: message.setContent(MessageExchange.class, exchange);
067: } else {
068: exchange = message.getContent(MessageExchange.class);
069: if (exchange == null) {
070: throw new IllegalStateException("Content of type "
071: + MessageExchange.class
072: + " not found on message");
073: }
074: if (message.getContent(Exception.class) == null) {
075: nm = exchange.createMessage();
076: exchange.setMessage(nm, "out");
077: } else {
078: exchange.setFault(exchange.createFault());
079: nm = exchange.getFault();
080: }
081: }
082: // Put headers
083: toNMSHeaders(nm, message);
084:
085: // copy wsa headers if present
086: toNMSWSAHeaders(nm, message);
087:
088: // Put attachments
089: toNMSAttachments(nm, message);
090: // Put subject
091: nm.setSecuritySubject(message.get(Subject.class));
092: // Put main source
093: getContent(nm, message);
094: // Register new content
095: message.setContent(NormalizedMessage.class, nm);
096: } catch (JBIException e) {
097: throw new Fault(e);
098: }
099: }
100:
101: /**
102: * Create the JBI exchange
103: */
104: private MessageExchange createExchange(Message message)
105: throws JBIException {
106: URI mep;
107: BindingOperationInfo operation = message.getExchange().get(
108: BindingOperationInfo.class);
109: if (operation != null) {
110: if (operation.getOutput() == null) {
111: if (operation.getFaults().size() == 0) {
112: mep = MessageExchangeSupport.IN_ONLY;
113: } else {
114: mep = MessageExchangeSupport.ROBUST_IN_ONLY;
115: }
116: } else {
117: mep = MessageExchangeSupport.IN_OUT;
118: }
119: } else {
120: mep = (URI) message.get(OPERATION_MEP);
121: }
122: if (mep == null) {
123: throw new NullPointerException("MEP not found");
124: }
125: MessageExchangeFactory mef = message.getExchange().get(
126: MessageExchangeFactory.class);
127: if (mef == null) {
128: DeliveryChannel dv = message.getExchange().get(
129: DeliveryChannel.class);
130: if (dv == null) {
131: ComponentContext cc = message.getExchange().get(
132: ComponentContext.class);
133: if (cc == null) {
134: throw new NullPointerException(
135: "MessageExchangeFactory or DeliveryChannel or ComponentContext not found");
136: }
137: dv = cc.getDeliveryChannel();
138: }
139: mef = dv.createExchangeFactory();
140: }
141: MessageExchange me = mef.createExchange(mep);
142: me.setOperation(operation.getName());
143: return me;
144: }
145:
146: private void toNMSWSAHeaders(NormalizedMessage normalizedMessage,
147: Message soapMessage) {
148: SoapMessage message = null;
149: if (!(soapMessage instanceof SoapMessage)) {
150: return;
151: } else {
152: message = (SoapMessage) soapMessage;
153: }
154:
155: if (message.get(WSAUtils.WSA_HEADERS_INBOUND) != null) {
156: normalizedMessage.setProperty(WSAUtils.WSA_HEADERS_INBOUND,
157: WSAUtils.getAsMap((AddressingProperties) message
158: .get(WSAUtils.WSA_HEADERS_INBOUND)));
159: }
160:
161: }
162:
163: /**
164: * Convert SoapMessage headers to NormalizedMessage headers
165: */
166: private void toNMSHeaders(NormalizedMessage normalizedMessage,
167: Message soapMessage) {
168: SoapMessage message = null;
169: if (!(soapMessage instanceof SoapMessage)) {
170: return;
171: } else {
172: message = (SoapMessage) soapMessage;
173: }
174: Map<String, Object> headers = new HashMap<String, Object>();
175: for (Header header : message.getHeaders()) {
176: headers.put(QNameUtil.toString(header.getName()), header
177: .getObject());
178: }
179:
180: normalizedMessage.setProperty(JbiConstants.PROTOCOL_HEADERS,
181: headers);
182:
183: }
184:
185: /**
186: * Convert SoapMessage attachments to NormalizedMessage attachments
187: */
188: private void toNMSAttachments(NormalizedMessage normalizedMessage,
189: Message soapMessage) throws MessagingException {
190: if (soapMessage.getAttachments() != null) {
191: for (Attachment att : soapMessage.getAttachments()) {
192: normalizedMessage.addAttachment(att.getId(), att
193: .getDataHandler());
194: }
195: }
196: }
197:
198: /**
199: * Extract the content as a jaxp Source
200: */
201: private void getContent(NormalizedMessage nm, Message message)
202: throws MessagingException {
203: Exception e = message.getContent(Exception.class);
204: if (e == null) {
205: nm.setContent(message.getContent(Source.class));
206: /*
207: * } else if (e instanceof SoapFault) { SoapFault fault =
208: * (SoapFault) e; nm.setContent(fault.getDetails());
209: * nm.setProperty(JbiConstants.SOAP_FAULT_CODE, fault.getCode());
210: * nm.setProperty(JbiConstants.SOAP_FAULT_NODE, fault.getNode());
211: * nm.setProperty(JbiConstants.SOAP_FAULT_REASON,
212: * fault.getReason()); nm.setProperty(JbiConstants.SOAP_FAULT_ROLE,
213: * fault.getRole()); nm.setProperty(JbiConstants.SOAP_FAULT_SUBCODE,
214: * fault.getSubcode());
215: */
216: }
217: }
218:
219: protected boolean isRequestor(Message message) {
220: return Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE));
221: }
222:
223: }
|