1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.service;
12
13 import org.mule.MuleException;
14 import org.mule.MuleManager;
15 import org.mule.config.i18n.CoreMessages;
16 import org.mule.config.i18n.Message;
17 import org.mule.config.i18n.MessageFactory;
18 import org.mule.impl.endpoint.MuleEndpoint;
19 import org.mule.providers.AbstractConnector;
20 import org.mule.umo.endpoint.EndpointException;
21 import org.mule.umo.endpoint.UMOEndpoint;
22 import org.mule.umo.endpoint.UMOEndpointURI;
23 import org.mule.umo.endpoint.UMOImmutableEndpoint;
24 import org.mule.umo.provider.UMOConnector;
25 import org.mule.umo.transformer.UMOTransformer;
26 import org.mule.util.BeanUtils;
27 import org.mule.util.ClassUtils;
28 import org.mule.util.MuleObjectHelper;
29 import org.mule.util.ObjectFactory;
30 import org.mule.util.ObjectNameHelper;
31 import org.mule.util.PropertiesUtils;
32 import org.mule.util.SpiUtils;
33
34 import java.io.IOException;
35 import java.io.InputStream;
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.Map;
39 import java.util.Properties;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43
44
45
46
47
48
49
50
51
52 public final class TransportFactory
53 {
54 public static final String PROVIDER_SERVICES_PATH = "org/mule/providers";
55
56
57
58
59 protected static final Log logger = LogFactory.getLog(TransportFactory.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
67 private static Map csdCache = new HashMap();
68
69
70 private TransportFactory ()
71 {
72
73 }
74
75 public static UMOEndpoint createEndpoint(UMOEndpointURI uri, String type) throws EndpointException
76 {
77 String scheme = uri.getFullScheme();
78 UMOConnector connector;
79 try
80 {
81 if (uri.getCreateConnector() == ALWAYS_CREATE_CONNECTOR)
82 {
83 connector = createConnector(uri);
84 MuleManager.getInstance().registerConnector(connector);
85 }
86 else if (uri.getCreateConnector() == NEVER_CREATE_CONNECTOR)
87 {
88 connector = getConnectorByProtocol(scheme);
89 }
90 else if (uri.getConnectorName() != null)
91 {
92 connector = MuleManager.getInstance().lookupConnector(uri.getConnectorName());
93 if (connector == null)
94 {
95 throw new TransportFactoryException(
96 CoreMessages.objectNotRegisteredWithManager("Connector: " + uri.getConnectorName()));
97 }
98 }
99 else
100 {
101 connector = getConnectorByProtocol(scheme);
102 if (connector == null)
103 {
104 connector = createConnector(uri);
105 MuleManager.getInstance().registerConnector(connector);
106 }
107 }
108 }
109 catch (Exception e)
110 {
111 throw new TransportFactoryException(e);
112 }
113
114 if (connector == null)
115 {
116 Message m = CoreMessages.failedToCreateObjectWith("Endpoint", "Uri: " + uri);
117 m.setNextMessage(CoreMessages.objectIsNull("connector"));
118 throw new TransportFactoryException(m);
119
120 }
121
122 UMOEndpoint endpoint = new MuleEndpoint();
123 endpoint.setConnector(connector);
124 endpoint.setEndpointURI(uri);
125 if (uri.getEndpointName() != null)
126 {
127 endpoint.setName(uri.getEndpointName());
128 }
129 String name = ObjectNameHelper.getEndpointName(endpoint);
130
131 endpoint.setName(name);
132
133 if (type != null)
134 {
135 endpoint.setType(type);
136 UMOTransformer trans = getTransformer(uri, connector,
137 (UMOEndpoint.ENDPOINT_TYPE_RECEIVER.equals(type) ? 0 : 1));
138 endpoint.setTransformer(trans);
139 if (UMOEndpoint.ENDPOINT_TYPE_RECEIVER.equals(type))
140 {
141
142 trans = getTransformer(uri, connector, 2);
143 endpoint.setResponseTransformer(trans);
144 }
145 }
146 return endpoint;
147 }
148
149
150
151
152
153
154
155
156 private static UMOTransformer getTransformer(UMOEndpointURI url, UMOConnector cnn, int type)
157 throws TransportFactoryException
158 {
159 UMOTransformer trans = null;
160 String transId;
161 if (type == 2)
162 {
163 transId = url.getResponseTransformers();
164 }
165 else
166 {
167 transId = url.getTransformers();
168 }
169
170 if (transId != null)
171 {
172 try
173 {
174 trans = MuleObjectHelper.getTransformer(transId, ",");
175 }
176 catch (MuleException e)
177 {
178 throw new TransportFactoryException(e);
179 }
180 }
181 else
182 {
183
184 Properties overrides = new Properties();
185 if (cnn instanceof AbstractConnector)
186 {
187 Map so = ((AbstractConnector) cnn).getServiceOverrides();
188 if (so != null)
189 {
190 overrides.putAll(so);
191 }
192 }
193
194 String scheme = url.getSchemeMetaInfo();
195
196
197
198 if (cnn instanceof AbstractConnector)
199 {
200 AbstractConnector aconn = (AbstractConnector) cnn;
201
202 if (type == 0)
203 {
204 trans = aconn.getDefaultInboundTransformer();
205 }
206 else if (type == 1)
207 {
208 trans = aconn.getDefaultOutboundTransformer();
209 }
210 else
211 {
212 trans = aconn.getDefaultResponseTransformer();
213 }
214 }
215
216 if (trans == null)
217 {
218 TransportServiceDescriptor csd = getServiceDescriptor(scheme, overrides);
219 if (type == 0)
220 {
221 trans = csd.createInboundTransformer();
222 }
223 else if (type == 1)
224 {
225 trans = csd.createOutboundTransformer();
226 }
227 else
228 {
229 trans = csd.createResponseTransformer();
230 }
231 }
232 }
233 return trans;
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249 public static UMOConnector createConnector(UMOEndpointURI url) throws TransportFactoryException
250 {
251 String scheme = url.getSchemeMetaInfo();
252
253 UMOConnector connector;
254 TransportServiceDescriptor csd = getServiceDescriptor(scheme);
255
256
257 if (csd.getServiceError() != null)
258 {
259 throw new TransportServiceException(MessageFactory.createStaticMessage(csd.getServiceError()));
260 }
261
262
263 if (csd.getServiceFinder() != null)
264 {
265 csd = csd.createServiceFinder().findService(scheme, csd);
266 }
267
268 try
269 {
270 if (csd.getConnectorFactory() != null)
271 {
272 ObjectFactory factory = (ObjectFactory) ClassUtils.loadClass(csd.getConnectorFactory(),
273 TransportFactory.class).newInstance();
274 connector = (UMOConnector) factory.create();
275 }
276 else
277 {
278 if (csd.getConnector() != null)
279 {
280 connector = (UMOConnector) ClassUtils.loadClass(csd.getConnector(), TransportFactory.class)
281 .newInstance();
282 if (connector instanceof AbstractConnector)
283 {
284 ((AbstractConnector) connector).initialiseFromUrl(url);
285 }
286 }
287 else
288 {
289 throw new TransportFactoryException(
290 CoreMessages.objectNotSetInService("Connector", scheme));
291 }
292 }
293 }
294 catch (TransportFactoryException e)
295 {
296 throw e;
297 }
298 catch (Exception e)
299 {
300 throw new TransportFactoryException(
301 CoreMessages.failedToCreateObjectWith("Endpoint", url), e);
302 }
303
304 connector.setName(ObjectNameHelper.getConnectorName(connector));
305
306
307
308
309 Map props = new HashMap();
310 PropertiesUtils.getPropertiesWithPrefix(MuleManager.getInstance().getProperties(),
311 connector.getProtocol().toLowerCase(), props);
312 if (props.size() > 0)
313 {
314 props = PropertiesUtils.removeNamespaces(props);
315 BeanUtils.populateWithoutFail(connector, props, true);
316 }
317
318 return connector;
319 }
320
321 public static TransportServiceDescriptor getServiceDescriptor(String protocol)
322 throws TransportFactoryException
323 {
324 return getServiceDescriptor(protocol, null);
325 }
326
327 public static synchronized TransportServiceDescriptor getServiceDescriptor(String protocol, Properties overrides)
328 throws TransportFactoryException
329 {
330 TransportServiceDescriptor csd = (TransportServiceDescriptor) csdCache.get(new CSDKey(protocol, overrides));
331 if (csd == null)
332 {
333 String location = SpiUtils.SERVICE_ROOT + PROVIDER_SERVICES_PATH;
334 InputStream is = SpiUtils.findServiceDescriptor(PROVIDER_SERVICES_PATH, protocol + ".properties",
335 TransportFactory.class);
336
337
338 if (is == null)
339 {
340
341 is = SpiUtils.findServiceDescriptor(PROVIDER_SERVICES_PATH, protocol,
342 TransportFactory.class);
343 if (is != null)
344 {
345 logger.warn("The transport " + protocol + " is using a legacy style descriptor."
346 + " This needs to be updated."
347 + " Future versions of Mule will not work with this descriptor.");
348 }
349 }
350 try
351 {
352 if (is != null)
353 {
354 Properties props = new Properties();
355 props.load(is);
356 csd = new TransportServiceDescriptor(protocol, location, props);
357
358 csd.setOverrides(overrides);
359 if (csd.getServiceFinder() != null)
360 {
361 TransportServiceFinder finder = csd.createServiceFinder();
362 csd = finder.findService(protocol, csd);
363 }
364 csdCache.put(new CSDKey(csd.getProtocol(), overrides), csd);
365 }
366 else
367 {
368 throw new TransportServiceNotFoundException(location + "/" + protocol);
369 }
370 }
371 catch (IOException e)
372 {
373 throw new TransportFactoryException(
374 CoreMessages.failedToCreateEndpointFromLocation(location + "/" + protocol), e);
375 }
376 }
377 return csd;
378 }
379
380 public static UMOConnector getOrCreateConnectorByProtocol(UMOEndpointURI uri)
381 throws TransportFactoryException
382 {
383 return getOrCreateConnectorByProtocol(uri, uri.getCreateConnector());
384 }
385
386 public static UMOConnector getOrCreateConnectorByProtocol(UMOImmutableEndpoint endpoint)
387 throws TransportFactoryException
388 {
389 return getOrCreateConnectorByProtocol(endpoint.getEndpointURI(), endpoint.getCreateConnector());
390 }
391
392 private static UMOConnector getOrCreateConnectorByProtocol(UMOEndpointURI uri, int create)
393 throws TransportFactoryException
394 {
395 final String connectorName = uri.getConnectorName();
396 UMOConnector connector = MuleManager.getInstance().lookupConnector(connectorName);
397 if (connector != null)
398 {
399 return connector;
400 }
401
402 connector = getConnectorByProtocol(uri.getFullScheme());
403 if (ALWAYS_CREATE_CONNECTOR == create
404 || (connector == null && create == GET_OR_CREATE_CONNECTOR))
405 {
406 connector = createConnector(uri);
407 try
408 {
409 BeanUtils.populate(connector, uri.getParams());
410 MuleManager.getInstance().registerConnector(connector);
411
412 }
413 catch (Exception e)
414 {
415 throw new TransportFactoryException(
416 CoreMessages.failedToSetPropertiesOn("Connector"), e);
417 }
418 }
419 else if (create == NEVER_CREATE_CONNECTOR && connector == null)
420 {
421 logger.warn("There is no connector for protocol: " + uri.getScheme()
422 + " and 'createConnector' is set to NEVER. Returning null");
423 }
424 return connector;
425 }
426
427 public static UMOConnector getConnectorByProtocol(String protocol)
428 {
429 UMOConnector connector;
430 UMOConnector resultConnector = null;
431 Map connectors = MuleManager.getInstance().getConnectors();
432 for (Iterator iterator = connectors.values().iterator(); iterator.hasNext();)
433 {
434 connector = (UMOConnector) iterator.next();
435 if (connector.supportsProtocol(protocol))
436 {
437 if (resultConnector == null)
438 {
439 resultConnector = connector;
440 }
441 else
442 {
443 throw new IllegalStateException(
444 CoreMessages.moreThanOneConnectorWithProtocol(protocol).getMessage());
445 }
446 }
447 }
448 return resultConnector;
449 }
450
451 private static class CSDKey
452 {
453 private final Map overrides;
454 private final String protocol;
455
456 public CSDKey(String protocol, Map overrides)
457 {
458 this.overrides = overrides;
459 this.protocol = protocol;
460 }
461
462
463 public boolean equals(Object o)
464 {
465 if (this == o)
466 {
467 return true;
468 }
469 if (!(o instanceof CSDKey))
470 {
471 return false;
472 }
473
474 final CSDKey csdKey = (CSDKey) o;
475
476 if (overrides != null ? !overrides.equals(csdKey.overrides) : csdKey.overrides != null)
477 {
478 return false;
479 }
480 return protocol.equals(csdKey.protocol);
481
482 }
483
484
485 public int hashCode()
486 {
487 return 29 * (overrides != null ? overrides.hashCode() : 0) + protocol.hashCode();
488 }
489 }
490 }