KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mule > providers > service > ConnectorFactory


1 /*
2  * $Id: ConnectorFactory.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.service;
12
13 import org.apache.commons.logging.Log;
14 import org.apache.commons.logging.LogFactory;
15 import org.mule.MuleException;
16 import org.mule.MuleManager;
17 import org.mule.config.i18n.Message;
18 import org.mule.config.i18n.Messages;
19 import org.mule.impl.endpoint.MuleEndpoint;
20 import org.mule.providers.AbstractServiceEnabledConnector;
21 import org.mule.umo.endpoint.EndpointException;
22 import org.mule.umo.endpoint.UMOEndpoint;
23 import org.mule.umo.endpoint.UMOEndpointURI;
24 import org.mule.umo.endpoint.UMOImmutableEndpoint;
25 import org.mule.umo.provider.UMOConnector;
26 import org.mule.umo.transformer.UMOTransformer;
27 import org.mule.util.BeanUtils;
28 import org.mule.util.ClassUtils;
29 import org.mule.util.MuleObjectHelper;
30 import org.mule.util.ObjectFactory;
31 import org.mule.util.PropertiesUtils;
32 import org.mule.util.SpiUtils;
33 import org.mule.util.ObjectNameHelper;
34
35 import java.io.IOException JavaDoc;
36 import java.io.InputStream JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.Map JavaDoc;
40 import java.util.Properties JavaDoc;
41
42 /**
43  * <code>ConnectorFactory</code> can be used for generically creating endpoints
44  * from an url. Note that for some endpoints, the url alone is not enough to create
45  * the endpoint if a connector for the endpoint has not already been configured with
46  * the Mule Manager.
47  *
48  * @author <a HREF="mailto:ross.mason@symphonysoft.com">Ross Mason</a>
49  * @version $Revision: 4259 $
50  */

51
52 public class ConnectorFactory
53 {
54     public static final String JavaDoc PROVIDER_SERVICES_PATH = "org/mule/providers";
55
56     /**
57      * logger used by this class
58      */

59     protected static Log logger = LogFactory.getLog(ConnectorFactory.class);
60
61     public static final int GET_OR_CREATE_CONNECTOR = 0;
62     public static final int ALWAYS_CREATE_CONNECTOR = 1;
63     public static final int NEVER_CREATE_CONNECTOR = 2;
64     public static final int USE_CONNECTOR = 3;
65
66     private static Map JavaDoc csdCache = new HashMap JavaDoc();
67
68     public static UMOEndpoint createEndpoint(UMOEndpointURI uri, String JavaDoc type) throws EndpointException
69     {
70         String JavaDoc scheme = uri.getFullScheme();
71         UMOConnector connector = null;
72         try
73         {
74             if (uri.getCreateConnector() == ALWAYS_CREATE_CONNECTOR)
75             {
76                 connector = createConnector(uri);
77                 MuleManager.getInstance().registerConnector(connector);
78             }
79             else if (uri.getCreateConnector() == NEVER_CREATE_CONNECTOR)
80             {
81                 connector = getConnectorByProtocol(scheme);
82             }
83             else if (uri.getConnectorName() != null)
84             {
85                 connector = MuleManager.getInstance().lookupConnector(uri.getConnectorName());
86                 if (connector == null)
87                 {
88                     throw new ConnectorFactoryException(new Message(Messages.X_NOT_REGISTERED_WITH_MANAGER,
89                         "Connector: " + uri.getConnectorName()));
90                 }
91             }
92             else
93             {
94                 connector = getConnectorByProtocol(scheme);
95                 if (connector == null)
96                 {
97                     connector = createConnector(uri);
98                     MuleManager.getInstance().registerConnector(connector);
99                 }
100             }
101         }
102         catch (Exception JavaDoc e)
103         {
104             throw new ConnectorFactoryException(e);
105         }
106
107         if (connector == null)
108         {
109             Message m = new Message(Messages.FAILED_TO_CREATE_X_WITH_X, "Endpoint", "Uri: " + uri);
110             m.setNextMessage(new Message(Messages.X_IS_NULL, "connector"));
111             throw new ConnectorFactoryException(m);
112
113         }
114
115         UMOEndpoint endpoint = new MuleEndpoint();
116         endpoint.setConnector(connector);
117         endpoint.setEndpointURI(uri);
118         if (uri.getEndpointName() != null)
119         {
120             endpoint.setName(uri.getEndpointName());
121         }
122         String JavaDoc name = ObjectNameHelper.getEndpointName(endpoint);
123
124         endpoint.setName(name);
125
126         if (type != null)
127         {
128             endpoint.setType(type);
129             UMOTransformer trans = getTransformer(uri, connector,
130                 (UMOEndpoint.ENDPOINT_TYPE_RECEIVER.equals(type) ? 0 : 1));
131             endpoint.setTransformer(trans);
132             if (UMOEndpoint.ENDPOINT_TYPE_RECEIVER.equals(type))
133             {
134                 // set the response transformer
135
trans = getTransformer(uri, connector, 2);
136                 endpoint.setResponseTransformer(trans);
137             }
138         }
139         return endpoint;
140     }
141
142     /**
143      * @param url
144      * @param cnn
145      * @param type 0=inbound, 1=outbound, 2=response
146      * @return
147      * @throws ConnectorFactoryException
148      */

149     private static UMOTransformer getTransformer(UMOEndpointURI url, UMOConnector cnn, int type)
150         throws ConnectorFactoryException
151     {
152         UMOTransformer trans = null;
153         String JavaDoc transId = null;
154         if (type == 2)
155         {
156             transId = url.getResponseTransformers();
157         }
158         else
159         {
160             transId = url.getTransformers();
161         }
162
163         if (transId != null)
164         {
165             try
166             {
167                 trans = MuleObjectHelper.getTransformer(transId, ",");
168             }
169             catch (MuleException e)
170             {
171                 throw new ConnectorFactoryException(e);
172             }
173         }
174         else
175         {
176             // Get connector specific overrides to set on the descriptor
177
Properties JavaDoc overrides = new Properties JavaDoc();
178             if (cnn instanceof AbstractServiceEnabledConnector)
179             {
180                 Map JavaDoc so = ((AbstractServiceEnabledConnector)cnn).getServiceOverrides();
181                 if (so != null)
182                 {
183                     overrides.putAll(so);
184                 }
185             }
186
187             String JavaDoc scheme = url.getSchemeMetaInfo();
188
189             ConnectorServiceDescriptor csd = getServiceDescriptor(scheme, overrides);
190             if (type == 0)
191             {
192                 trans = csd.createInboundTransformer();
193             }
194             else if (type == 1)
195             {
196                 trans = csd.createOutboundTransformer();
197             }
198             else
199             {
200                 trans = csd.createResponseTransformer();
201             }
202         }
203         return trans;
204     }
205
206     /**
207      * Creates an uninitialied connector from the provided MuleEndpointURI. The
208      * scheme is used to determine what kind of connector to create. Any params set
209      * on the uri can be used to initialise bean properties on the created connector.
210      * <p/> Note that the initalise method will need to be called on the connector
211      * returned. This is so that developers can control when the connector
212      * initialisation takes place as this is likely to initialse all connecotr
213      * resources.
214      *
215      * @param url the MuleEndpointURI url to create the connector with
216      * @return a new Connector
217      * @throws ConnectorFactoryException
218      */

219     public static UMOConnector createConnector(UMOEndpointURI url) throws ConnectorFactoryException
220     {
221         String JavaDoc scheme = url.getSchemeMetaInfo();
222
223         UMOConnector connector = null;
224         ConnectorServiceDescriptor csd = getServiceDescriptor(scheme);
225         // Make sure we can create the endpoint/connector using this service
226
// method
227
if (csd.getServiceError() != null)
228         {
229             throw new ConnectorServiceException(Message.createStaticMessage(csd.getServiceError()));
230         }
231
232         // If this is a fineder service, lets find it before trying to create it
233
if (csd.getServiceFinder() != null)
234         {
235             csd = csd.createServiceFinder().findService(scheme, csd);
236         }
237         // if there is a factory, use it
238
try
239         {
240             if (csd.getConnectorFactory() != null)
241             {
242                 ObjectFactory factory = (ObjectFactory)ClassUtils.loadClass(csd.getConnectorFactory(),
243                     ConnectorFactory.class).newInstance();
244                 connector = (UMOConnector)factory.create();
245             }
246             else
247             {
248                 if (csd.getConnector() != null)
249                 {
250                     connector = (UMOConnector)ClassUtils.loadClass(csd.getConnector(), ConnectorFactory.class)
251                         .newInstance();
252                     if (connector instanceof AbstractServiceEnabledConnector)
253                     {
254                         ((AbstractServiceEnabledConnector)connector).initialiseFromUrl(url);
255                     }
256                 }
257                 else
258                 {
259                     throw new ConnectorFactoryException(new Message(Messages.X_NOT_SET_IN_SERVICE_X,
260                         "Connector", scheme));
261                 }
262             }
263         }
264         catch (ConnectorFactoryException e)
265         {
266             throw e;
267         }
268         catch (Exception JavaDoc e)
269         {
270             throw new ConnectorFactoryException(new Message(Messages.FAILED_TO_CREATE_X_WITH_X, "Endpoint",
271                 url), e);
272         }
273
274         connector.setName(ObjectNameHelper.getConnectorName(connector));
275
276         // set any manager default properties for the connector
277
// these are set on the Manager with a protocol i.e.
278
// jms.specification=1.1
279
Map JavaDoc props = new HashMap JavaDoc();
280         PropertiesUtils.getPropertiesWithPrefix(MuleManager.getInstance().getProperties(),
281             connector.getProtocol().toLowerCase(), props);
282         if (props.size() > 0)
283         {
284             props = PropertiesUtils.removeNamespaces(props);
285             BeanUtils.populateWithoutFail(connector, props, true);
286         }
287
288         return connector;
289     }
290
291     public static ConnectorServiceDescriptor getServiceDescriptor(String JavaDoc protocol)
292         throws ConnectorFactoryException
293     {
294         return getServiceDescriptor(protocol, null);
295     }
296
297     public static ConnectorServiceDescriptor getServiceDescriptor(String JavaDoc protocol, Properties JavaDoc overrides)
298         throws ConnectorFactoryException
299     {
300         ConnectorServiceDescriptor csd = (ConnectorServiceDescriptor)csdCache.get(new CSDKey(protocol,
301             overrides));
302         if (csd == null)
303         {
304
305             String JavaDoc location = SpiUtils.SERVICE_ROOT + PROVIDER_SERVICES_PATH;
306             InputStream JavaDoc is = SpiUtils.findServiceDescriptor(PROVIDER_SERVICES_PATH, protocol + ".properties",
307                 ConnectorFactory.class);
308
309
310             // TODO RM: this can be removed in Mule 2.0
311
if (is == null)
312             {
313                 //The legacy connector decriptors did did not use file extensions
314
is = SpiUtils.findServiceDescriptor(PROVIDER_SERVICES_PATH, protocol,
315                 ConnectorFactory.class);
316                 if(is==null)
317                 {
318                     logger.warn("The transport " + protocol + " is using a legacy style of descriptor. This needs to be updated."
319                      + " Future versions of Mule will not work with this connector descriptor.");
320                 }
321             }
322             try
323             {
324                 if (is != null)
325                 {
326                     Properties JavaDoc props = new Properties JavaDoc();
327                     props.load(is);
328                     csd = new ConnectorServiceDescriptor(protocol, location, props);
329                     // set any overides on the descriptor
330
csd.setOverrides(overrides);
331                     if (csd.getServiceFinder() != null)
332                     {
333                         ConnectorServiceFinder finder = csd.createServiceFinder();
334                         csd = finder.findService(protocol, csd);
335                     }
336                     csdCache.put(new CSDKey(csd.getProtocol(), overrides), csd);
337                 }
338                 else
339                 {
340                     throw new ConnectorServiceNotFoundException(location + "/" + protocol);
341                 }
342             }
343             catch (IOException JavaDoc e)
344             {
345                 throw new ConnectorFactoryException(new Message(Messages.FAILED_TO_ENDPOINT_FROM_LOCATION_X,
346                     location + "/" + protocol), e);
347             }
348         }
349         return csd;
350     }
351
352     public static UMOConnector getOrCreateConnectorByProtocol(UMOEndpointURI uri)
353         throws ConnectorFactoryException
354     {
355         return getOrCreateConnectorByProtocol(uri, uri.getCreateConnector());
356     }
357
358     public static UMOConnector getOrCreateConnectorByProtocol(UMOImmutableEndpoint endpoint)
359         throws ConnectorFactoryException
360     {
361         return getOrCreateConnectorByProtocol(endpoint.getEndpointURI(), endpoint.getCreateConnector());
362     }
363
364     private static UMOConnector getOrCreateConnectorByProtocol(UMOEndpointURI uri, int create)
365         throws ConnectorFactoryException
366     {
367         UMOConnector connector = getConnectorByProtocol(uri.getFullScheme());
368         if (ConnectorFactory.ALWAYS_CREATE_CONNECTOR == create
369             || (connector == null && create == ConnectorFactory.GET_OR_CREATE_CONNECTOR))
370         {
371             connector = ConnectorFactory.createConnector(uri);
372             try
373             {
374                 BeanUtils.populate(connector, uri.getParams());
375                 MuleManager.getInstance().registerConnector(connector);
376
377             }
378             catch (Exception JavaDoc e)
379             {
380                 throw new ConnectorFactoryException(new Message(Messages.FAILED_TO_SET_PROPERTIES_ON_X,
381                     "Connector"), e);
382             }
383         }
384         else if (create == ConnectorFactory.NEVER_CREATE_CONNECTOR && connector == null)
385         {
386             logger.warn("There is no connector for protocol: " + uri.getScheme()
387                         + " and 'createConnector' is set to NEVER. Returning null");
388         }
389         return connector;
390     }
391
392     public static UMOConnector getConnectorByProtocol(String JavaDoc protocol)
393     {
394         UMOConnector connector;
395         Map JavaDoc connectors = MuleManager.getInstance().getConnectors();
396         for (Iterator JavaDoc iterator = connectors.values().iterator(); iterator.hasNext();)
397         {
398             connector = (UMOConnector)iterator.next();
399             if (connector.supportsProtocol(protocol))
400             {
401                 return connector;
402             }
403         }
404         return null;
405     }
406
407     private static class CSDKey
408     {
409         private final Map JavaDoc overrides;
410         private final String JavaDoc protocol;
411
412         public CSDKey(String JavaDoc protocol, Map JavaDoc overrides)
413         {
414             this.overrides = overrides;
415             this.protocol = protocol;
416         }
417
418         public boolean equals(Object JavaDoc o)
419         {
420             if (this == o)
421             {
422                 return true;
423             }
424             if (!(o instanceof CSDKey))
425             {
426                 return false;
427             }
428
429             final CSDKey csdKey = (CSDKey)o;
430
431             if (overrides != null ? !overrides.equals(csdKey.overrides) : csdKey.overrides != null)
432             {
433                 return false;
434             }
435             if (!protocol.equals(csdKey.protocol))
436             {
437                 return false;
438             }
439
440             return true;
441         }
442
443         public int hashCode()
444         {
445             return 29 * (overrides != null ? overrides.hashCode() : 0) + protocol.hashCode();
446         }
447     }
448 }
449
Popular Tags