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