KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > servicemix > soap > SoapHelper


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.servicemix.soap;
18
19 import java.net.URI JavaDoc;
20 import java.util.Collections JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import javax.jbi.JBIException;
27 import javax.jbi.component.ComponentContext;
28 import javax.jbi.messaging.DeliveryChannel;
29 import javax.jbi.messaging.MessageExchange;
30 import javax.jbi.messaging.MessageExchangeFactory;
31 import javax.jbi.messaging.MessagingException;
32 import javax.jbi.messaging.NormalizedMessage;
33 import javax.jbi.servicedesc.ServiceEndpoint;
34 import javax.wsdl.Binding;
35 import javax.wsdl.Definition;
36 import javax.wsdl.Operation;
37 import javax.wsdl.Part;
38 import javax.wsdl.Port;
39 import javax.wsdl.PortType;
40 import javax.wsdl.Service;
41 import javax.wsdl.WSDLException;
42 import javax.wsdl.factory.WSDLFactory;
43 import javax.wsdl.xml.WSDLReader;
44 import javax.xml.namespace.QName JavaDoc;
45
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.apache.servicemix.jbi.jaxp.W3CDOMStreamWriter;
49 import org.apache.servicemix.soap.marshalers.JBIMarshaler;
50 import org.apache.servicemix.soap.marshalers.SoapMarshaler;
51 import org.apache.servicemix.soap.marshalers.SoapMessage;
52 import org.apache.servicemix.soap.marshalers.SoapWriter;
53 import org.w3c.dom.Document JavaDoc;
54
55 import com.ibm.wsdl.Constants;
56
57 /**
58  * Helper class for working with soap endpoints
59  *
60  * @author Guillaume Nodet
61  * @version $Revision: 1.5 $
62  * @since 3.0
63  */

64 public class SoapHelper {
65
66     private static final Log logger = LogFactory.getLog(SoapHelper.class);
67
68     public static final URI JavaDoc IN_ONLY = URI.create("http://www.w3.org/2004/08/wsdl/in-only");
69     public static final URI JavaDoc IN_OUT = URI.create("http://www.w3.org/2004/08/wsdl/in-out");
70     public static final URI JavaDoc ROBUST_IN_ONLY = URI.create("http://www.w3.org/2004/08/wsdl/robust-in-only");
71
72     private SoapEndpoint endpoint;
73     private List JavaDoc policies;
74     private JBIMarshaler jbiMarshaler;
75     private SoapMarshaler soapMarshaler;
76     private Map JavaDoc definitions;
77     private Map JavaDoc operationNames;
78
79     public SoapHelper(SoapEndpoint endpoint) {
80         this.policies = endpoint.getPolicies();
81         if (this.policies == null) {
82             this.policies = Collections.EMPTY_LIST;
83         }
84         this.definitions = new HashMap JavaDoc();
85         this.operationNames = new HashMap JavaDoc();
86         this.jbiMarshaler = new JBIMarshaler();
87         this.endpoint = endpoint;
88         boolean requireDom = false;
89         for (Iterator JavaDoc iter = policies.iterator(); iter.hasNext();) {
90             Handler handler = (Handler) iter.next();
91             requireDom |= handler.requireDOM();
92         }
93         this.soapMarshaler = new SoapMarshaler(endpoint.isSoap(), requireDom);
94         if (endpoint.isSoap() && "1.1".equals(endpoint.getSoapVersion())) {
95             this.soapMarshaler.setSoapUri(SoapMarshaler.SOAP_11_URI);
96         }
97     }
98     
99     public SoapMarshaler getSoapMarshaler() {
100         return this.soapMarshaler;
101     }
102     
103     public JBIMarshaler getJBIMarshaler() {
104         return this.jbiMarshaler;
105     }
106
107     public MessageExchange onReceive(Context context) throws Exception JavaDoc {
108         if (policies != null) {
109             for (Iterator JavaDoc it = policies.iterator(); it.hasNext();) {
110                 Handler policy = (Handler) it.next();
111                 policy.onReceive(context);
112             }
113         }
114
115         // If WS-A has not set informations, use the default ones
116
if (context.getProperty(Context.SERVICE) == null && context.getProperty(Context.INTERFACE) == null) {
117             // If no target endpoint / service / interface is defined
118
// we assume we use the same informations has defined on the
119
// external endpoint
120
if (endpoint.getTargetInterfaceName() == null && endpoint.getTargetService() == null
121                             && endpoint.getTargetEndpoint() == null) {
122                 context.setProperty(Context.INTERFACE, endpoint.getInterfaceName());
123                 context.setProperty(Context.SERVICE, endpoint.getService());
124                 context.setProperty(Context.ENDPOINT, endpoint.getEndpoint());
125             } else {
126                 context.setProperty(Context.INTERFACE, endpoint.getTargetInterfaceName());
127                 context.setProperty(Context.SERVICE, endpoint.getTargetService());
128                 context.setProperty(Context.ENDPOINT, endpoint.getTargetEndpoint());
129             }
130         }
131         Operation operation = findOperation(context);
132         if (context.getProperty(Context.OPERATION) == null) {
133             if (operation != null) {
134                 // the operation QName must be retrieved from the map
135
// so that we can have the right namespace
136
context.setProperty(Context.OPERATION, operationNames.get(operation));
137             } else if (endpoint.getDefaultOperation() != null) {
138                 context.setProperty(Context.OPERATION, endpoint.getDefaultOperation());
139             } else {
140                 // By default, use name of body element (i.e., RPC-style)
141
QName JavaDoc bodyName = context.getInMessage().getBodyName();
142                 context.setProperty(Context.OPERATION, bodyName);
143             }
144         }
145         URI JavaDoc mep = null;
146         if ( operation != null ) {
147             mep = getMep(operation);
148         }
149         if (mep == null) {
150             mep = endpoint.getDefaultMep();
151         }
152         MessageExchange exchange = createExchange(mep);
153         exchange.setService((QName JavaDoc) context.getProperty(Context.SERVICE));
154         exchange.setInterfaceName((QName JavaDoc) context.getProperty(Context.INTERFACE));
155         exchange.setOperation((QName JavaDoc) context.getProperty(Context.OPERATION));
156         if (context.getProperty(Context.ENDPOINT) != null) {
157             ComponentContext componentContext = endpoint.getServiceUnit().getComponent().getComponentContext();
158             QName JavaDoc serviceName = (QName JavaDoc) context.getProperty(Context.SERVICE);
159             String JavaDoc endpointName = (String JavaDoc) context.getProperty(Context.ENDPOINT);
160             ServiceEndpoint se = componentContext.getEndpoint(serviceName, endpointName);
161             if (se != null) {
162                 exchange.setEndpoint(se);
163             }
164         }
165         NormalizedMessage inMessage = exchange.createMessage();
166         jbiMarshaler.toNMS(inMessage, context.getInMessage());
167         exchange.setMessage(inMessage, "in");
168         return exchange;
169     }
170
171     public SoapMessage onReply(Context context, NormalizedMessage outMsg) throws Exception JavaDoc {
172         SoapMessage out = new SoapMessage();
173         if (context.getInMessage() != null) {
174             out.setEnvelopeName(context.getInMessage().getEnvelopeName());
175         }
176         jbiMarshaler.fromNMS(out, outMsg);
177         context.setOutMessage(out);
178         if (policies != null) {
179             for (Iterator JavaDoc it = policies.iterator(); it.hasNext();) {
180                 Handler policy = (Handler) it.next();
181                 policy.onReply(context);
182             }
183         }
184         return out;
185     }
186
187     public SoapMessage onFault(Context context, SoapFault fault) throws Exception JavaDoc {
188         SoapMessage soapFault = new SoapMessage();
189         soapFault.setFault(fault);
190         if (context == null) {
191             context = new Context();
192         }
193         if (context.getInMessage() != null) {
194             soapFault.setEnvelopeName(context.getInMessage().getEnvelopeName());
195         }
196         context.setFaultMessage(soapFault);
197         if (policies != null) {
198             for (Iterator JavaDoc it = policies.iterator(); it.hasNext();) {
199                 Handler policy = (Handler) it.next();
200                 policy.onFault(context);
201             }
202         }
203         return soapFault;
204     }
205
206     public void onSend(Context context) throws Exception JavaDoc {
207         if (policies != null) {
208             for (Iterator JavaDoc it = policies.iterator(); it.hasNext();) {
209                 Handler policy = (Handler) it.next();
210                 if (policy.requireDOM()) {
211                     SoapWriter writer = soapMarshaler.createWriter(context.getInMessage());
212                     W3CDOMStreamWriter domWriter = new W3CDOMStreamWriter();
213                     writer.writeSoapEnvelope(domWriter);
214                     context.getInMessage().setDocument(domWriter.getDocument());
215                 }
216                 policy.onSend(context);
217             }
218         }
219     }
220
221     public void onAnswer(Context context) throws Exception JavaDoc {
222         if (policies != null) {
223             for (Iterator JavaDoc it = policies.iterator(); it.hasNext();) {
224                 Handler policy = (Handler) it.next();
225                 policy.onAnswer(context);
226             }
227         }
228     }
229
230     public Context createContext(SoapMessage message) {
231         Context context = createContext();
232         context.setInMessage(message);
233         return context;
234     }
235     
236     public Context createContext() {
237         Context context = new Context();
238         context.setProperty(Context.AUTHENTICATION_SERVICE, endpoint.getAuthenticationService());
239         context.setProperty(Context.KEYSTORE_MANAGER, endpoint.getKeystoreManager());
240         return context;
241     }
242
243     protected MessageExchange createExchange(URI JavaDoc mep) throws MessagingException {
244         ComponentContext context = endpoint.getServiceUnit().getComponent().getComponentContext();
245         DeliveryChannel channel = context.getDeliveryChannel();
246         MessageExchangeFactory factory = channel.createExchangeFactory();
247         MessageExchange exchange = factory.createExchange(mep);
248         return exchange;
249     }
250
251     private URI JavaDoc getMep(Operation oper) {
252         URI JavaDoc mep = null;
253         if (oper != null) {
254             boolean output = oper.getOutput() != null && oper.getOutput().getMessage() != null
255                             && oper.getOutput().getMessage().getParts().size() > 0;
256             boolean faults = oper.getFaults().size() > 0;
257             if (output) {
258                 mep = IN_OUT;
259             } else if (faults) {
260                 mep = ROBUST_IN_ONLY;
261             } else {
262                 mep = IN_ONLY;
263             }
264         }
265         return mep;
266     }
267
268     protected Operation findOperation(Context context) throws Exception JavaDoc {
269         QName JavaDoc interfaceName = (QName JavaDoc) context.getProperty(Context.INTERFACE);
270         QName JavaDoc serviceName = (QName JavaDoc) context.getProperty(Context.SERVICE);
271         String JavaDoc endpointName = (String JavaDoc) context.getProperty(Context.ENDPOINT);
272         ComponentContext componentContext = endpoint.getServiceUnit().getComponent().getComponentContext();
273         QName JavaDoc bodyName = context.getInMessage().getBodyName();
274         
275         // Find target endpoint
276
ServiceEndpoint se = null;
277         if (serviceName != null && endpointName != null) {
278             se = componentContext.getEndpoint(serviceName, endpointName);
279         }
280         if (se == null && interfaceName != null) {
281             ServiceEndpoint[] ses = componentContext.getEndpoints(interfaceName);
282             if (ses != null && ses.length > 0) {
283                 se = ses[0];
284             }
285         }
286         
287         // Find WSDL description
288
Definition definition = null;
289         if (se == null) {
290             // Get this endpoint definition
291
definition = endpoint.getDefinition();
292         } else {
293             // Find endpoint description from the component context
294
definition = getDefinition(se);
295         }
296
297         // Find operation matching
298
if (definition != null) {
299             if (interfaceName != null) {
300                 PortType portType = definition.getPortType(interfaceName);
301                 if (portType != null) {
302                     return findOperationFor(portType, bodyName);
303                 }
304             } else if (definition.getService(serviceName) != null) {
305                 Service service = definition.getService(serviceName);
306                 Port port = service.getPort(endpointName);
307                 if (port != null) {
308                     Binding binding = port.getBinding();
309                     if (binding != null) {
310                         PortType portType = binding.getPortType();
311                         if (portType != null) {
312                             return findOperationFor(portType, bodyName);
313                         }
314                     }
315                 }
316             } else if (definition.getPortTypes().size() == 1) {
317                 PortType portType = (PortType) definition.getPortTypes().values().iterator().next();
318                 return findOperationFor(portType, bodyName);
319             }
320         }
321         return null;
322     }
323     
324     protected Operation findOperationFor(PortType portType, QName JavaDoc bodyName) {
325         List JavaDoc list = portType.getOperations();
326         for (int i = 0; i < list.size(); i++) {
327             Operation operation = (Operation) list.get(i);
328             if (operation.getInput() != null && operation.getInput().getMessage() != null) {
329                 Map JavaDoc parts = operation.getInput().getMessage().getParts();
330                 Iterator JavaDoc iter = parts.values().iterator();
331                 while (iter.hasNext()) {
332                     Part part = (Part) iter.next();
333                     QName JavaDoc elementName = part.getElementName();
334                     if (elementName != null && elementName.equals(bodyName)) {
335                         // found
336
operationNames.put(operation, new QName JavaDoc(portType.getQName().getNamespaceURI(), operation.getName()));
337                         return operation;
338                     }
339                 }
340             }
341         }
342         return null;
343     }
344
345     protected Definition getDefinition(ServiceEndpoint se) throws WSDLException, JBIException {
346         Definition definition;
347         ComponentContext componentContext = endpoint.getServiceUnit().getComponent().getComponentContext();
348             String JavaDoc key = se.getServiceName() + se.getEndpointName();
349             synchronized (definitions) {
350                 definition = (Definition) definitions.get(key);
351                 if (definition == null) {
352                     WSDLFactory factory = WSDLFactory.newInstance();
353                     Document JavaDoc description = componentContext.getEndpointDescriptor(se);
354                     if (description != null) {
355                         // Parse WSDL
356
WSDLReader reader = factory.newWSDLReader();
357                         reader.setFeature(Constants.FEATURE_VERBOSE, false);
358                         try {
359                             definition = reader.readWSDL(null, description);
360                         } catch (WSDLException e) {
361                             logger.info("Could not read wsdl from endpoint descriptor: " + e.getMessage());
362                             if (logger.isDebugEnabled()) {
363                                 logger.debug("Could not read wsdl from endpoint descriptor", e);
364                             }
365                         }
366                     }
367                     if (definition == null) {
368                         definition = factory.newDefinition();
369                     }
370                     definitions.put(key, definition);
371                 }
372             }
373         return definition;
374     }
375
376 }
377
Popular Tags