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