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