KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > providers > soap > axis > AxisMessageReceiver


1 /*
2  * $Id: AxisMessageReceiver.java 4259 2006-12-14 03:12:07Z aperepel $
3  * --------------------------------------------------------------------------------------
4  * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
5  *
6  * The software in this package is published under the terms of the MuleSource MPL
7  * license, a copy of which has been included with this distribution in the
8  * LICENSE.txt file.
9  */

10
11 package org.mule.providers.soap.axis;
12
13 import org.apache.axis.AxisProperties;
14 import org.apache.axis.constants.Style;
15 import org.apache.axis.constants.Use;
16 import org.apache.axis.description.OperationDesc;
17 import org.apache.axis.description.ParameterDesc;
18 import org.apache.axis.handlers.soap.SOAPService;
19 import org.apache.axis.providers.java.JavaProvider;
20 import org.apache.axis.wsdl.fromJava.Namespaces;
21 import org.apache.commons.lang.StringUtils;
22 import org.mule.config.i18n.Message;
23 import org.mule.config.i18n.Messages;
24 import org.mule.impl.MuleDescriptor;
25 import org.mule.providers.AbstractMessageReceiver;
26 import org.mule.providers.soap.NamedParameter;
27 import org.mule.providers.soap.ServiceProxy;
28 import org.mule.providers.soap.SoapMethod;
29 import org.mule.providers.soap.axis.extensions.MuleMsgProvider;
30 import org.mule.providers.soap.axis.extensions.MuleRPCProvider;
31 import org.mule.umo.UMOComponent;
32 import org.mule.umo.UMOException;
33 import org.mule.umo.endpoint.UMOEndpoint;
34 import org.mule.umo.endpoint.UMOEndpointURI;
35 import org.mule.umo.lifecycle.InitialisationException;
36 import org.mule.umo.provider.UMOConnector;
37
38 import javax.xml.rpc.ParameterMode JavaDoc;
39
40 import java.util.HashMap JavaDoc;
41 import java.util.Iterator JavaDoc;
42 import java.util.List JavaDoc;
43 import java.util.Map JavaDoc;
44
45 /**
46  * <code>AxisMessageReceiver</code> is used to register a component as a service
47  * with a Axis server.
48  */

49
50 public class AxisMessageReceiver extends AbstractMessageReceiver
51 {
52     protected AxisConnector connector;
53     protected SOAPService service;
54
55     public AxisMessageReceiver(UMOConnector connector, UMOComponent component, UMOEndpoint endpoint)
56         throws InitialisationException
57     {
58         super(connector, component, endpoint);
59         this.connector = (AxisConnector)connector;
60         try
61         {
62             init();
63         }
64         catch (Exception JavaDoc e)
65         {
66             throw new InitialisationException(e, this);
67         }
68     }
69
70     protected void init() throws Exception JavaDoc
71     {
72         AxisProperties.setProperty("axis.doAutoTypes", String.valueOf(connector.isDoAutoTypes()));
73         MuleDescriptor descriptor = (MuleDescriptor)component.getDescriptor();
74         String JavaDoc style = (String JavaDoc)descriptor.getProperties().get("style");
75         String JavaDoc use = (String JavaDoc)descriptor.getProperties().get("use");
76         String JavaDoc doc = (String JavaDoc)descriptor.getProperties().get("documentation");
77
78         UMOEndpointURI uri = endpoint.getEndpointURI();
79         String JavaDoc serviceName = component.getDescriptor().getName();
80
81         SOAPService existing = this.connector.getAxisServer().getService(serviceName);
82         if (existing != null)
83         {
84             service = existing;
85             logger.debug("Using existing service for " + serviceName);
86         }
87         else
88         {
89             // Check if the style is message. If so, we need to create
90
// a message oriented provider
91
if (style != null && style.equalsIgnoreCase("message"))
92             {
93                 logger.debug("Creating Message Provider");
94                 service = new SOAPService(new MuleMsgProvider(connector));
95                 // } else if (style != null && style.equalsIgnoreCase("document")) {
96
// logger.debug("Creating Doc Provider");
97
// service = new SOAPService(new MuleDocLitProvider(connector));
98
}
99             else
100             {
101                 logger.debug("Creating RPC Provider");
102                 service = new SOAPService(new MuleRPCProvider(connector));
103             }
104
105             service.setEngine(connector.getAxisServer());
106         }
107
108         String JavaDoc servicePath = uri.getPath();
109         service.setOption(serviceName, this);
110         service.setOption(AxisConnector.SERVICE_PROPERTY_SERVCE_PATH, servicePath);
111         service.setOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME, serviceName);
112
113         service.setName(serviceName);
114
115         // Add any custom options from the Descriptor config
116
Map JavaDoc options = (Map JavaDoc)descriptor.getProperties().get("axisOptions");
117
118         // IF wsdl service name is not set, default to service name
119
if (options == null)
120         {
121             options = new HashMap JavaDoc(2);
122         }
123         if (options.get("wsdlServiceElement") == null)
124         {
125             options.put("wsdlServiceElement", serviceName);
126         }
127
128         Map.Entry JavaDoc entry;
129         for (Iterator JavaDoc iterator = options.entrySet().iterator(); iterator.hasNext();)
130         {
131             entry = (Map.Entry JavaDoc)iterator.next();
132             service.setOption(entry.getKey().toString(), entry.getValue());
133             logger.debug("Adding Axis option: " + entry);
134         }
135
136         // set method names
137
Class JavaDoc[] interfaces = ServiceProxy.getInterfacesForComponent(component);
138         if (interfaces.length == 0)
139         {
140             throw new InitialisationException(
141                 new Message(Messages.X_MUST_IMPLEMENT_AN_INTERFACE, serviceName), component);
142         }
143         // You must supply a class name if you want to restrict methods
144
// or specify the 'allowedMethods' property in the axisOptions property
145
String JavaDoc methodNames = "*";
146
147         Map JavaDoc methods = (Map JavaDoc)endpoint.getProperties().get("soapMethods");
148         if (methods == null)
149         {
150             methods = (Map JavaDoc)descriptor.getProperties().get("soapMethods");
151         }
152         if (methods != null)
153         {
154             Iterator JavaDoc i = methods.keySet().iterator();
155             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(64);
156             while (i.hasNext())
157             {
158                 String JavaDoc name = (String JavaDoc)i.next();
159                 Object JavaDoc m = methods.get(name);
160                 SoapMethod method = null;
161                 if (m instanceof List JavaDoc)
162                 {
163                     method = new SoapMethod(name, (List JavaDoc)m);
164                 }
165                 else
166                 {
167                     method = new SoapMethod(name, (String JavaDoc)m);
168                 }
169
170                 List JavaDoc namedParameters = method.getNamedParameters();
171                 ParameterDesc[] parameters = new ParameterDesc[namedParameters.size()];
172                 for (int j = 0; j < namedParameters.size(); j++)
173                 {
174                     NamedParameter parameter = (NamedParameter)namedParameters.get(j);
175                     byte mode = ParameterDesc.INOUT;
176                     if (parameter.getMode().equals(ParameterMode.IN))
177                     {
178                         mode = ParameterDesc.IN;
179                     }
180                     else if (parameter.getMode().equals(ParameterMode.OUT))
181                     {
182                         mode = ParameterDesc.OUT;
183                     }
184
185                     parameters[j] = new ParameterDesc(parameter.getName(), mode, parameter.getType());
186                 }
187
188                 service.getServiceDescription().addOperationDesc(
189                     new OperationDesc(method.getName().getLocalPart(), parameters, method.getReturnType()));
190                 buf.append(method.getName().getLocalPart() + ",");
191             }
192             methodNames = buf.toString();
193             methodNames = methodNames.substring(0, methodNames.length() - 1);
194         }
195         else
196         {
197             String JavaDoc[] methodNamesArray = ServiceProxy.getMethodNames(interfaces);
198             StringBuffer JavaDoc buf = new StringBuffer JavaDoc(64);
199             for (int i = 0; i < methodNamesArray.length; i++)
200             {
201                 buf.append(methodNamesArray[i]).append(",");
202             }
203             methodNames = buf.toString();
204             methodNames = methodNames.substring(0, methodNames.length() - 1);
205         }
206
207         String JavaDoc className = interfaces[0].getName();
208         // The namespace of the service.
209
// Todo use the service qname in Mule 2.0
210
String JavaDoc namespace = (String JavaDoc)descriptor.getProperties().get("serviceNamespace");
211         if (namespace == null)
212         {
213             namespace = Namespaces.makeNamespace(className);
214         }
215
216         // WSDL override
217
String JavaDoc wsdlFile = (String JavaDoc)descriptor.getProperties().get("wsdlFile");
218         if (wsdlFile != null)
219         {
220             service.getServiceDescription().setWSDLFile(wsdlFile);
221         }
222         /*
223          * Now we set up the various options for the SOAPService. We set:
224          * RPCProvider.OPTION_WSDL_SERVICEPORT In essense, this is our service name
225          * RPCProvider.OPTION_CLASSNAME This tells the serverProvider (whether it be
226          * an AvalonProvider or just JavaProvider) what class to load via
227          * "makeNewServiceObject". RPCProvider.OPTION_SCOPE How long the object
228          * loaded via "makeNewServiceObject" will persist - either request, session,
229          * or application. We use the default for now.
230          * RPCProvider.OPTION_WSDL_TARGETNAMESPACE A namespace created from the
231          * package name of the service. RPCProvider.OPTION_ALLOWEDMETHODS What
232          * methods the service can execute on our class. We don't set:
233          * RPCProvider.OPTION_WSDL_PORTTYPE RPCProvider.OPTION_WSDL_SERVICEELEMENT
234          */

235         setOptionIfNotset(service, JavaProvider.OPTION_WSDL_SERVICEPORT, serviceName);
236         setOptionIfNotset(service, JavaProvider.OPTION_CLASSNAME, className);
237         setOptionIfNotset(service, JavaProvider.OPTION_SCOPE, "Request");
238         if (StringUtils.isNotBlank(namespace))
239         {
240             setOptionIfNotset(service, JavaProvider.OPTION_WSDL_TARGETNAMESPACE, namespace);
241         }
242
243         // Set the allowed methods, allow all if there are none specified.
244
if (methodNames == null)
245         {
246             setOptionIfNotset(service, JavaProvider.OPTION_ALLOWEDMETHODS, "*");
247         }
248         else
249         {
250             setOptionIfNotset(service, JavaProvider.OPTION_ALLOWEDMETHODS, methodNames);
251         }
252
253         // Note that Axis has specific rules to how these two variables are
254
// combined. This is handled for us
255
// Set style: RPC/wrapped/Doc/Message
256

257         if (style != null)
258         {
259             Style s = Style.getStyle(style);
260             if (s == null)
261             {
262                 throw new InitialisationException(new Message(Messages.VALUE_X_IS_INVALID_FOR_X, style,
263                     "style"), this);
264             }
265             else
266             {
267                 service.setStyle(s);
268             }
269         }
270         // Set use: Endcoded/Literal
271
if (use != null)
272         {
273             Use u = Use.getUse(use);
274             if (u == null)
275             {
276                 throw new InitialisationException(new Message(Messages.VALUE_X_IS_INVALID_FOR_X, use, "use"),
277                     this);
278             }
279             else
280             {
281                 service.setUse(u);
282             }
283         }
284
285         service.getServiceDescription().setDocumentation(doc);
286
287         // Tell Axis to try and be intelligent about serialization.
288
// TypeMappingRegistryImpl registry = (TypeMappingRegistryImpl)
289
// service.getTypeMappingRegistry();
290
// TypeMappingImpl tm = (TypeMappingImpl) registry.();
291

292         // Handle complex bean type automatically
293
// registry.setDoAutoTypes( true );
294

295         // Axis 1.2 fix to handle autotypes properly
296
// AxisProperties.setProperty("axis.doAutoTypes",
297
// String.valueOf(connector.isDoAutoTypes()));
298

299         // TODO Load any explicitly defined bean types
300
// List types = (List) descriptor.getProperties().get("beanTypes");
301
// connector.registerTypes(registry, types);
302

303         service.setName(serviceName);
304
305         // Add initialisation callback for the Axis service
306
descriptor.addInitialisationCallback(new AxisInitialisationCallback(service));
307
308         if (uri.getScheme().equalsIgnoreCase("servlet"))
309         {
310             connector.addServletService(service);
311             String JavaDoc endpointUrl = uri.getAddress() + "/" + serviceName;
312             endpointUrl = endpointUrl.replaceFirst("servlet:", "http:");
313             service.getServiceDescription().setEndpointURL(endpointUrl);
314         }
315         else
316         {
317             service.getServiceDescription().setEndpointURL(uri.getAddress() + "/" + serviceName);
318         }
319         if (StringUtils.isNotBlank(namespace))
320         {
321             service.getServiceDescription().setDefaultNamespace(namespace);
322         }
323         service.init();
324         service.stop();
325     }
326
327     public void doConnect() throws Exception JavaDoc
328     {
329         // Tell the axis configuration about our new service.
330
connector.getServerProvider().deployService(service.getName(), service);
331         connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI());
332     }
333
334     public void doDisconnect() throws Exception JavaDoc
335     {
336         try
337         {
338             doStop();
339         }
340         catch (UMOException e)
341         {
342             logger.error(e.getMessage(), e);
343         }
344         // TODO: how do you undeploy an Axis service?
345

346         // Unregister the mule part of the service
347
connector.unregisterReceiverWithMuleService(this, endpoint.getEndpointURI());
348     }
349
350     public void doStart() throws UMOException
351     {
352         if (service != null)
353         {
354             service.start();
355         }
356     }
357
358     public void doStop() throws UMOException
359     {
360         if (service != null)
361         {
362             service.stop();
363         }
364     }
365
366     protected void setOptionIfNotset(SOAPService service, String JavaDoc option, Object JavaDoc value)
367     {
368         Object JavaDoc val = service.getOption(option);
369         if (val == null)
370         {
371             service.setOption(option, value);
372         }
373     }
374
375     public SOAPService getService()
376     {
377         return service;
378     }
379 }
380
Popular Tags