KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * $Id: AxisConnector.java 3798 2006-11-04 04:07:14Z 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.client.Call;
14 import org.apache.axis.configuration.SimpleProvider;
15 import org.apache.axis.deployment.wsdd.WSDDConstants;
16 import org.apache.axis.deployment.wsdd.WSDDProvider;
17 import org.apache.axis.encoding.TypeMappingRegistryImpl;
18 import org.apache.axis.encoding.ser.BeanDeserializerFactory;
19 import org.apache.axis.encoding.ser.BeanSerializerFactory;
20 import org.apache.axis.handlers.soap.SOAPService;
21 import org.apache.axis.server.AxisServer;
22 import org.apache.axis.wsdl.fromJava.Namespaces;
23 import org.apache.axis.wsdl.fromJava.Types;
24 import org.mule.MuleManager;
25 import org.mule.config.ExceptionHelper;
26 import org.mule.config.i18n.Messages;
27 import org.mule.impl.MuleDescriptor;
28 import org.mule.impl.endpoint.MuleEndpoint;
29 import org.mule.impl.internal.notifications.ModelNotification;
30 import org.mule.impl.internal.notifications.ModelNotificationListener;
31 import org.mule.providers.AbstractServiceEnabledConnector;
32 import org.mule.providers.http.servlet.ServletConnector;
33 import org.mule.providers.service.ConnectorFactory;
34 import org.mule.providers.soap.MethodFixInterceptor;
35 import org.mule.providers.soap.axis.extensions.MuleConfigProvider;
36 import org.mule.providers.soap.axis.extensions.MuleTransport;
37 import org.mule.providers.soap.axis.extensions.WSDDFileProvider;
38 import org.mule.providers.soap.axis.extensions.WSDDJavaMuleProvider;
39 import org.mule.umo.UMOComponent;
40 import org.mule.umo.UMOException;
41 import org.mule.umo.endpoint.UMOEndpoint;
42 import org.mule.umo.endpoint.UMOEndpointURI;
43 import org.mule.umo.lifecycle.InitialisationException;
44 import org.mule.umo.manager.UMOServerNotification;
45 import org.mule.umo.provider.UMOMessageReceiver;
46 import org.mule.util.ClassUtils;
47
48 import javax.xml.namespace.QName JavaDoc;
49 import java.util.ArrayList JavaDoc;
50 import java.util.HashMap JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.Map JavaDoc;
54
55 /**
56  * <code>AxisConnector</code> is used to maintain one or more Services for Axis
57  * server instance. <p/> Some of the Axis specific service initialisation code was
58  * adapted from the Ivory project (http://ivory.codehaus.org). Thanks guys :)
59  *
60  * @author <a HREF="mailto:ross.mason@symphonysoft.com">Ross Mason</a>
61  * @version $Revision: 3798 $
62  */

63 public class AxisConnector extends AbstractServiceEnabledConnector implements ModelNotificationListener
64 {
65     /* Register the AxisFault Exception reader if this class gets loaded */
66     static
67     {
68         ExceptionHelper.registerExceptionReader(new AxisFaultExceptionReader());
69     }
70
71     public static final QName JavaDoc QNAME_MULE_PROVIDER = new QName JavaDoc(WSDDConstants.URI_WSDD_JAVA, "Mule");
72     public static final QName JavaDoc QNAME_MULE_TYPE_MAPPINGS = new QName JavaDoc("http://www.muleumo.org/ws/mappings",
73         "Mule");
74     public static final String JavaDoc DEFAULT_MULE_NAMESPACE_URI = "http://www.muleumo.org";
75
76     public static final String JavaDoc DEFAULT_MULE_AXIS_SERVER_CONFIG = "mule-axis-server-config.wsdd";
77     public static final String JavaDoc DEFAULT_MULE_AXIS_CLIENT_CONFIG = "mule-axis-client-config.wsdd";
78     public static final String JavaDoc AXIS_SERVICE_COMPONENT_NAME = "_axisServiceComponent";
79     public static final String JavaDoc AXIS_SERVICE_PROPERTY = "_axisService";
80     public static final String JavaDoc AXIS_CLIENT_CONFIG_PROPERTY = "clientConfig";
81
82     public static final String JavaDoc SERVICE_PROPERTY_COMPONENT_NAME = "componentName";
83     public static final String JavaDoc SERVICE_PROPERTY_SERVCE_PATH = "servicePath";
84
85     public static final String JavaDoc WSDL_URL_PROPERTY = "wsdlUrl";
86
87     private String JavaDoc serverConfig;
88     private AxisServer axisServer;
89     private SimpleProvider serverProvider;
90     private String JavaDoc clientConfig;
91     private SimpleProvider clientProvider;
92
93     private List JavaDoc beanTypes;
94     private MuleDescriptor axisDescriptor;
95     /**
96      * These protocols will be set on client invocations. by default Mule uses it's
97      * own transports rather that Axis's. This is only because it gives us more
98      * flexibility inside Mule and simplifies the code
99      */

100     private Map JavaDoc axisTransportProtocols;
101
102     /**
103      * A store of registered servlet services that need to have their endpoints
104      * re-written with the 'real' http url instead of the servlet:// one. This is
105      * only required to ensure wsdl is generated correctly. I would like a clearer
106      * way of doing this so I can remove this workaround
107      */

108     private List JavaDoc servletServices = new ArrayList JavaDoc();
109
110     private List JavaDoc supportedSchemes;
111
112     private boolean doAutoTypes = true;
113
114     private boolean treatMapAsNamedParams = true;
115
116     public AxisConnector()
117     {
118         super();
119         registerProtocols();
120
121     }
122
123     protected void registerProtocols()
124     {
125         // Default supported schemes, these can be restricted
126
// through configuration
127
supportedSchemes = new ArrayList JavaDoc();
128         supportedSchemes.add("http");
129         supportedSchemes.add("https");
130         supportedSchemes.add("servlet");
131         supportedSchemes.add("vm");
132         supportedSchemes.add("jms");
133         supportedSchemes.add("xmpp");
134         supportedSchemes.add("smtp");
135         supportedSchemes.add("smtps");
136         supportedSchemes.add("pop3");
137         supportedSchemes.add("pop3s");
138         supportedSchemes.add("imap");
139         supportedSchemes.add("imaps");
140         supportedSchemes.add("ssl");
141         supportedSchemes.add("tcp");
142
143         for (Iterator JavaDoc iterator = supportedSchemes.iterator(); iterator.hasNext();)
144         {
145             String JavaDoc s = (String JavaDoc)iterator.next();
146             registerSupportedProtocol(s);
147         }
148     }
149
150     public void doInitialise() throws InitialisationException
151     {
152         super.doInitialise();
153
154         axisTransportProtocols = new HashMap JavaDoc();
155
156         try
157         {
158             for (Iterator JavaDoc iterator = supportedSchemes.iterator(); iterator.hasNext();)
159             {
160                 String JavaDoc s = (String JavaDoc)iterator.next();
161                 axisTransportProtocols.put(s, MuleTransport.getTransportClass(s));
162                 registerSupportedProtocol(s);
163             }
164             MuleManager.getInstance().registerListener(this);
165         }
166         catch (Exception JavaDoc e)
167         {
168             throw new InitialisationException(e, this);
169         }
170
171         if (serverConfig == null)
172         {
173             serverConfig = DEFAULT_MULE_AXIS_SERVER_CONFIG;
174         }
175         if (clientConfig == null)
176         {
177             clientConfig = DEFAULT_MULE_AXIS_CLIENT_CONFIG;
178         }
179         serverProvider = createAxisProvider(serverConfig);
180         clientProvider = createAxisProvider(clientConfig);
181
182         // Create the AxisServer
183
axisServer = new AxisServer(serverProvider);
184         axisServer.setOption("axis.doAutoTypes", Boolean.valueOf(doAutoTypes));
185
186         // Register the Mule service serverProvider
187
WSDDProvider.registerProvider(QNAME_MULE_PROVIDER, new WSDDJavaMuleProvider(this));
188
189         try
190         {
191             registerTransportTypes();
192         }
193         catch (ClassNotFoundException JavaDoc e)
194         {
195             throw new InitialisationException(new org.mule.config.i18n.Message(
196                 Messages.CANT_LOAD_X_FROM_CLASSPATH_FILE, e.getMessage()), e, this);
197         }
198
199         // Overload the UrlHandlers provided by Axis so Mule can use its transports
200
// to move
201
// Soap messages around
202
String JavaDoc handlerPkgs = System.getProperty("java.protocol.handler.pkgs", null);
203         if (handlerPkgs != null)
204         {
205             if (!handlerPkgs.endsWith("|"))
206             {
207                 handlerPkgs += "|";
208             }
209             handlerPkgs = "org.mule.providers.soap.axis.transport|" + handlerPkgs;
210             System.setProperty("java.protocol.handler.pkgs", handlerPkgs);
211             logger.debug("Setting java.protocol.handler.pkgs to: " + handlerPkgs);
212         }
213
214         try
215         {
216             registerTypes((TypeMappingRegistryImpl)axisServer.getTypeMappingRegistry(), beanTypes);
217         }
218         catch (ClassNotFoundException JavaDoc e)
219         {
220             throw new InitialisationException(e, this);
221         }
222     }
223
224     protected void registerTransportTypes() throws ClassNotFoundException JavaDoc
225     {
226         // Register Transport handlers
227
// By default these will alll be handled by Mule, however some companies may
228
// have
229
// their own they wish to use
230
for (Iterator JavaDoc iterator = getAxisTransportProtocols().keySet().iterator(); iterator.hasNext();)
231         {
232             String JavaDoc protocol = (String JavaDoc)iterator.next();
233             Object JavaDoc temp = getAxisTransportProtocols().get(protocol);
234             Class JavaDoc clazz = null;
235             if (temp instanceof String JavaDoc)
236             {
237                 clazz = ClassUtils.loadClass(temp.toString(), getClass());
238             }
239             else
240             {
241                 clazz = (Class JavaDoc)temp;
242             }
243             Call.setTransportForProtocol(protocol, clazz);
244         }
245     }
246
247     protected SimpleProvider createAxisProvider(String JavaDoc config) throws InitialisationException
248     {
249         // Use our custom file provider that does not require services to be declared
250
// ni the WSDD. Thi only affects the
251
// client side as the client will fallback to the FileProvider when invoking
252
// a service.
253
WSDDFileProvider fileProvider = new WSDDFileProvider(config);
254         fileProvider.setSearchClasspath(true);
255         /*
256          * Wrap the FileProvider with a SimpleProvider so we can prgrammatically
257          * configure the Axis server (you can only use wsdd descriptors with the
258          * FileProvider)
259          */

260         return new MuleConfigProvider(fileProvider);
261     }
262
263     public String JavaDoc getProtocol()
264     {
265         return "axis";
266     }
267
268     /**
269      * The method determines the key used to store the receiver against.
270      *
271      * @param component the component for which the endpoint is being registered
272      * @param endpoint the endpoint being registered for the component
273      * @return the key to store the newly created receiver against. In this case it
274      * is the component name, which is equivilent to the Axis service name.
275      */

276     protected Object JavaDoc getReceiverKey(UMOComponent component, UMOEndpoint endpoint)
277     {
278         if (endpoint.getEndpointURI().getPort() == -1)
279         {
280             return component.getDescriptor().getName();
281         }
282         else
283         {
284             return endpoint.getEndpointURI().getAddress() + "/" + component.getDescriptor().getName();
285         }
286     }
287
288     public UMOMessageReceiver createReceiver(UMOComponent component, UMOEndpoint endpoint) throws Exception JavaDoc
289     {
290         // this is always initialisaed as synchronous as ws invocations should
291
// always execute in a single thread unless the endpont has explicitly
292
// been set to run asynchronously
293
if (!endpoint.isSynchronousSet() && !endpoint.isSynchronous())
294         {
295             if (logger.isDebugEnabled())
296             {
297                 logger.debug("overriding endpoint synchronicity and setting it to true. Web service requests are executed in a single thread");
298             }
299             endpoint.setSynchronous(true);
300         }
301
302         return super.createReceiver(component, endpoint);
303     }
304
305     protected void unregisterReceiverWithMuleService(UMOMessageReceiver receiver, UMOEndpointURI ep)
306         throws UMOException
307     {
308         String JavaDoc endpointKey = getCounterEndpointKey(receiver.getEndpointURI());
309
310         for (Iterator JavaDoc iterator = axisDescriptor.getInboundRouter().getEndpoints().iterator(); iterator.hasNext();)
311         {
312             UMOEndpoint umoEndpoint = (UMOEndpoint)iterator.next();
313             if (endpointKey.startsWith(umoEndpoint.getEndpointURI().getAddress()))
314             {
315                 logger.info("Unregistering Axis endpoint: " + endpointKey + " for service: "
316                             + receiver.getComponent().getDescriptor().getName());
317             }
318             try
319             {
320                 umoEndpoint.getConnector()
321                     .unregisterListener(receiver.getComponent(), receiver.getEndpoint());
322             }
323             catch (Exception JavaDoc e)
324             {
325                 logger.error("Failed to unregister Axis endpoint: " + endpointKey + " for service: "
326                              + receiver.getComponent().getDescriptor().getName() + ". Error is: "
327                              + e.getMessage(), e);
328             }
329             // TODO why break? For does not loop.
330
break;
331         }
332     }
333
334     protected void registerReceiverWithMuleService(UMOMessageReceiver receiver, UMOEndpointURI ep)
335         throws UMOException
336     {
337         // If this is the first receiver we need to create the Axis service
338
// component
339
// this will be registered with Mule when the Connector starts
340
if (axisDescriptor == null)
341         {
342             // See if the axis descriptor has already been added. This allows
343
// developers to override the default configuration, say to increase
344
// the threadpool
345
axisDescriptor = (MuleDescriptor)MuleManager.getInstance().getModel().getDescriptor(
346                 AXIS_SERVICE_COMPONENT_NAME);
347             if (axisDescriptor == null)
348             {
349                 axisDescriptor = createAxisDescriptor();
350             }
351             else
352             {
353                 // Lets unregister the 'template' instance, configure it and
354
// then register
355
// again later
356
MuleManager.getInstance().getModel().unregisterComponent(axisDescriptor);
357             }
358             // if the axis server hasn't been set, set it now. The Axis server
359
// may be set
360
// externally
361
if (axisDescriptor.getProperties().get("axisServer") == null)
362             {
363                 axisDescriptor.getProperties().put("axisServer", axisServer);
364             }
365             axisDescriptor.setContainerManaged(false);
366         }
367         String JavaDoc serviceName = receiver.getComponent().getDescriptor().getName();
368         // No determine if the endpointUri requires a new connector to be
369
// registed in the case of http we only need to register the new endpointUri
370
// if
371
// the port is different
372
// If we're using VM or Jms we just use the resource infor directly without
373
// appending a service name
374
String JavaDoc endpoint = null;
375         String JavaDoc scheme = ep.getScheme().toLowerCase();
376         if (scheme.equals("jms") || scheme.equals("vm"))
377         {
378             endpoint = ep.toString();
379         }
380         else
381         {
382             endpoint = receiver.getEndpointURI().getAddress() + "/" + serviceName;
383         }
384         if (logger.isDebugEnabled())
385         {
386             logger.debug("Modified endpoint with " + scheme + " scheme to " + endpoint);
387         }
388
389         // Default to using synchronous for socket based protocols unless the
390
// synchronous property has been set explicitly
391
boolean sync = false;
392         if (!receiver.getEndpoint().isSynchronousSet())
393         {
394             if (scheme.equals("http") || scheme.equals("https") || scheme.equals("ssl")
395                 || scheme.equals("tcp"))
396             {
397                 sync = true;
398             }
399         }
400         else
401         {
402             sync = receiver.getEndpoint().isSynchronous();
403         }
404
405         UMOEndpoint serviceEndpoint = new MuleEndpoint(endpoint, true);
406         serviceEndpoint.setSynchronous(sync);
407         serviceEndpoint.setName(ep.getScheme() + ":" + serviceName);
408         // set the filter on the axis endpoint on the real receiver endpoint
409
serviceEndpoint.setFilter(receiver.getEndpoint().getFilter());
410         // Remove the Axis filter now
411
receiver.getEndpoint().setFilter(null);
412
413         // set the Security filter on the axis endpoint on the real receiver endpoint
414
serviceEndpoint.setSecurityFilter(receiver.getEndpoint().getSecurityFilter());
415         // Remove the Axis Receiver Security filter now
416
receiver.getEndpoint().setSecurityFilter(null);
417
418         if (receiver.getEndpoint().getTransformer() != null)
419         {
420             serviceEndpoint.setTransformer(receiver.getEndpoint().getTransformer());
421             receiver.getEndpoint().setTransformer(null);
422         }
423         // propagate properties to the service endpoint
424
serviceEndpoint.getProperties().putAll(receiver.getEndpoint().getProperties());
425
426         axisDescriptor.getInboundRouter().addEndpoint(serviceEndpoint);
427
428     }
429
430     private String JavaDoc getCounterEndpointKey(UMOEndpointURI endpointURI)
431     {
432         StringBuffer JavaDoc endpointKey = new StringBuffer JavaDoc(64);
433
434         endpointKey.append(endpointURI.getScheme());
435         endpointKey.append("://");
436         endpointKey.append(endpointURI.getHost());
437         if (endpointURI.getPort() > -1)
438         {
439             endpointKey.append(":");
440             endpointKey.append(endpointURI.getPort());
441         }
442         return endpointKey.toString();
443     }
444
445     protected MuleDescriptor createAxisDescriptor()
446     {
447         MuleDescriptor axisDescriptor = (MuleDescriptor)MuleManager.getInstance().getModel().getDescriptor(
448             AXIS_SERVICE_COMPONENT_NAME);
449         if (axisDescriptor == null)
450         {
451             axisDescriptor = new MuleDescriptor(AXIS_SERVICE_COMPONENT_NAME);
452             axisDescriptor.setImplementation(AxisServiceComponent.class.getName());
453         }
454         return axisDescriptor;
455     }
456
457     /**
458      * Template method to perform any work when starting the connectoe
459      *
460      * @throws org.mule.umo.UMOException if the method fails
461      */

462     protected void doStart() throws UMOException
463     {
464         axisServer.start();
465     }
466
467     /**
468      * Template method to perform any work when stopping the connectoe
469      *
470      * @throws org.mule.umo.UMOException if the method fails
471      */

472     protected void doStop() throws UMOException
473     {
474         axisServer.stop();
475         // UMOModel model = MuleManager.getInstance().getModel();
476
// model.unregisterComponent(model.getDescriptor(AXIS_SERVICE_COMPONENT_NAME));
477
}
478
479     public String JavaDoc getServerConfig()
480     {
481         return serverConfig;
482     }
483
484     public void setServerConfig(String JavaDoc serverConfig)
485     {
486         this.serverConfig = serverConfig;
487     }
488
489     public List JavaDoc getBeanTypes()
490     {
491         return beanTypes;
492     }
493
494     public void setBeanTypes(List JavaDoc beanTypes)
495     {
496         this.beanTypes = beanTypes;
497     }
498
499     public String JavaDoc getClientConfig()
500     {
501         return clientConfig;
502     }
503
504     public void setClientConfig(String JavaDoc clientConfig)
505     {
506         this.clientConfig = clientConfig;
507     }
508
509     public AxisServer getAxisServer()
510     {
511         return axisServer;
512     }
513
514     public void setAxisServer(AxisServer axisServer)
515     {
516         this.axisServer = axisServer;
517     }
518
519     public SimpleProvider getServerProvider()
520     {
521         return serverProvider;
522     }
523
524     public void setServerProvider(SimpleProvider serverProvider)
525     {
526         this.serverProvider = serverProvider;
527     }
528
529     public SimpleProvider getClientProvider()
530     {
531         return clientProvider;
532     }
533
534     public void setClientProvider(SimpleProvider clientProvider)
535     {
536         this.clientProvider = clientProvider;
537     }
538
539     public Map JavaDoc getAxisTransportProtocols()
540     {
541         return axisTransportProtocols;
542     }
543
544     public void setAxisTransportProtocols(Map JavaDoc axisTransportProtocols)
545     {
546         this.axisTransportProtocols.putAll(axisTransportProtocols);
547     }
548
549     void addServletService(SOAPService service)
550     {
551         servletServices.add(service);
552     }
553
554     public List JavaDoc getSupportedSchemes()
555     {
556         return supportedSchemes;
557     }
558
559     public void setSupportedSchemes(List JavaDoc supportedSchemes)
560     {
561         this.supportedSchemes = supportedSchemes;
562     }
563
564     public boolean isDoAutoTypes()
565     {
566         return doAutoTypes;
567     }
568
569     public void setDoAutoTypes(boolean doAutoTypes)
570     {
571         this.doAutoTypes = doAutoTypes;
572     }
573
574     void registerTypes(TypeMappingRegistryImpl registry, List JavaDoc types) throws ClassNotFoundException JavaDoc
575     {
576         if (types != null)
577         {
578             Class JavaDoc clazz;
579             for (Iterator JavaDoc iterator = types.iterator(); iterator.hasNext();)
580             {
581                 clazz = ClassUtils.loadClass(iterator.next().toString(), getClass());
582                 String JavaDoc localName = Types.getLocalNameFromFullName(clazz.getName());
583                 QName JavaDoc xmlType = new QName JavaDoc(Namespaces.makeNamespace(clazz.getName()), localName);
584
585                 registry.getDefaultTypeMapping().register(clazz, xmlType,
586                     new BeanSerializerFactory(clazz, xmlType), new BeanDeserializerFactory(clazz, xmlType));
587             }
588         }
589     }
590
591     public boolean isTreatMapAsNamedParams()
592     {
593         return treatMapAsNamedParams;
594     }
595
596     public void setTreatMapAsNamedParams(boolean treatMapAsNamedParams)
597     {
598         this.treatMapAsNamedParams = treatMapAsNamedParams;
599     }
600
601     public void onNotification(UMOServerNotification notification)
602     {
603         if (notification.getAction() == ModelNotification.MODEL_STARTED)
604         {
605             // We need to register the Axis service component once the model
606
// starts because
607
// when the model starts listeners on components are started, thus
608
// all listener
609
// need to be registered for this connector before the Axis service
610
// component
611
// is registered.
612
// The implication of this is that to add a new service and a
613
// different http port the
614
// model needs to be restarted before the listener is available
615
if (!MuleManager.getInstance().getModel().isComponentRegistered(AXIS_SERVICE_COMPONENT_NAME))
616             {
617                 try
618                 {
619                     // Descriptor might be null if no inbound endpoints have been
620
// register for the Axis connector
621
if (axisDescriptor == null)
622                     {
623                         axisDescriptor = createAxisDescriptor();
624                     }
625                     axisDescriptor.addInterceptor(new MethodFixInterceptor());
626                     MuleManager.getInstance().getModel().registerComponent(axisDescriptor);
627                     // We have to perform a small hack here to rewrite servlet://
628
// endpoints with the
629
// real http:// address
630
for (Iterator JavaDoc iterator = servletServices.iterator(); iterator.hasNext();)
631                     {
632                         SOAPService service = (SOAPService)iterator.next();
633                         ServletConnector servletConnector = (ServletConnector)ConnectorFactory.getConnectorByProtocol("servlet");
634                         String JavaDoc url = servletConnector.getServletUrl();
635                         if (url != null)
636                         {
637                             service.getServiceDescription().setEndpointURL(url + "/" + service.getName());
638                         }
639                         else
640                         {
641                             logger.error("The servletUrl property on the ServletConntector has not been set this means that wsdl generation for service '"
642                                          + service.getName() + "' may be incorrect");
643                         }
644                     }
645                     servletServices.clear();
646                     servletServices = null;
647
648                 }
649                 catch (UMOException e)
650                 {
651                     handleException(e);
652                 }
653             }
654         }
655     }
656 }
657
Popular Tags