1
2
3
4
5
6
7 package org.mule.registry;
8
9 import org.mule.api.MuleContext;
10 import org.mule.api.MuleException;
11 import org.mule.api.NamedObject;
12 import org.mule.api.agent.Agent;
13 import org.mule.api.config.MuleProperties;
14 import org.mule.api.construct.FlowConstruct;
15 import org.mule.api.endpoint.EndpointBuilder;
16 import org.mule.api.endpoint.EndpointFactory;
17 import org.mule.api.endpoint.ImmutableEndpoint;
18 import org.mule.api.lifecycle.Disposable;
19 import org.mule.api.lifecycle.Initialisable;
20 import org.mule.api.lifecycle.InitialisationException;
21 import org.mule.api.lifecycle.LifecycleException;
22 import org.mule.api.model.Model;
23 import org.mule.api.registry.AbstractServiceDescriptor;
24 import org.mule.api.registry.MuleRegistry;
25 import org.mule.api.registry.RegistrationException;
26 import org.mule.api.registry.ResolverException;
27 import org.mule.api.registry.ServiceDescriptor;
28 import org.mule.api.registry.ServiceDescriptorFactory;
29 import org.mule.api.registry.ServiceException;
30 import org.mule.api.registry.ServiceType;
31 import org.mule.api.registry.TransformerResolver;
32 import org.mule.api.service.Service;
33 import org.mule.api.transformer.DataType;
34 import org.mule.api.transformer.DiscoverableTransformer;
35 import org.mule.api.transformer.Transformer;
36 import org.mule.api.transformer.TransformerException;
37 import org.mule.api.transport.Connector;
38 import org.mule.config.i18n.CoreMessages;
39 import org.mule.transformer.types.SimpleDataType;
40 import org.mule.util.SpiUtils;
41 import org.mule.util.StringUtils;
42 import org.mule.util.UUID;
43
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.Comparator;
48 import java.util.Iterator;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Properties;
52
53 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
54
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57
58
59
60
61
62 public class MuleRegistryHelper implements MuleRegistry
63 {
64 protected transient Log logger = LogFactory.getLog(MuleRegistryHelper.class);
65
66
67
68
69 private DefaultRegistryBroker registry;
70
71
72
73
74 protected ConcurrentHashMap exactTransformerCache = new ConcurrentHashMap(8);
75 protected ConcurrentHashMap transformerListCache = new ConcurrentHashMap(8);
76
77 private MuleContext muleContext;
78
79 public MuleRegistryHelper(DefaultRegistryBroker registry, MuleContext muleContext)
80 {
81 this.registry = registry;
82 this.muleContext = muleContext;
83 }
84
85
86
87
88 public void initialise() throws InitialisationException
89 {
90
91
92
93
94 }
95
96
97
98
99 public void dispose()
100 {
101 transformerListCache.clear();
102 exactTransformerCache.clear();
103 }
104
105 public void fireLifecycle(String phase) throws LifecycleException
106 {
107 if(Initialisable.PHASE_NAME.equals(phase))
108 {
109 registry.initialise();
110 }
111 else if(Disposable.PHASE_NAME.equals(phase))
112 {
113 registry.dispose();
114 }
115 else
116 {
117 registry.fireLifecycle(phase);
118 }
119 }
120
121
122
123
124 public Connector lookupConnector(String name)
125 {
126 return (Connector) registry.lookupObject(name);
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163 public EndpointBuilder lookupEndpointBuilder(String name)
164 {
165 Object o = registry.lookupObject(name);
166 if (o instanceof EndpointBuilder)
167 {
168 logger.debug("Global endpoint EndpointBuilder for name: " + name + " found");
169 return (EndpointBuilder) o;
170 }
171 else
172 {
173 logger.debug("No endpoint builder with the name: " + name + " found.");
174 return null;
175 }
176 }
177
178
179
180
181 public EndpointFactory lookupEndpointFactory()
182 {
183 return (EndpointFactory) registry.lookupObject(MuleProperties.OBJECT_MULE_ENDPOINT_FACTORY);
184 }
185
186
187
188
189 public Transformer lookupTransformer(String name)
190 {
191 return (Transformer) registry.lookupObject(name);
192 }
193
194
195
196
197
198
199
200
201 @Deprecated
202 public Transformer lookupTransformer(Class inputType, Class outputType) throws TransformerException
203 {
204 return lookupTransformer(new SimpleDataType(inputType), new SimpleDataType(outputType));
205 }
206
207
208
209
210
211
212
213
214 @Deprecated
215 public List<Transformer> lookupTransformers(Class input, Class output)
216 {
217 return lookupTransformers(new SimpleDataType(input), new SimpleDataType(output));
218 }
219
220
221
222
223 public Transformer lookupTransformer(DataType source, DataType result) throws TransformerException
224 {
225 final String dataTypePairHash = getDataTypeSourceResultPairHash(source, result);
226 Transformer cachedTransformer = (Transformer) exactTransformerCache.get(dataTypePairHash);
227 if (cachedTransformer != null)
228 {
229 return cachedTransformer;
230 }
231
232 Transformer trans = resolveTransformer(source, result);
233
234 if (trans != null)
235 {
236 Transformer concurrentlyAddedTransformer = (Transformer) exactTransformerCache.putIfAbsent(
237 dataTypePairHash, trans);
238 if (concurrentlyAddedTransformer != null)
239 {
240 return concurrentlyAddedTransformer;
241 }
242 else
243 {
244 return trans;
245 }
246 }
247 else
248 {
249 throw new TransformerException(CoreMessages.noTransformerFoundForMessage(source, result));
250 }
251 }
252
253 protected Transformer resolveTransformer(DataType source, DataType result) throws TransformerException
254 {
255 List<TransformerResolver> resolvers = (List<TransformerResolver>) lookupObjects(TransformerResolver.class);
256 Collections.sort(resolvers, new TransformerResolverComparator());
257
258 for (TransformerResolver resolver : resolvers)
259 {
260 try
261 {
262 Transformer trans = resolver.resolve(source, result);
263 if (trans != null)
264 {
265 return trans;
266 }
267 }
268 catch (ResolverException e)
269 {
270 throw new TransformerException(CoreMessages.noTransformerFoundForMessage(source, result), e);
271 }
272 }
273 return null;
274 }
275
276
277
278
279 public List<Transformer> lookupTransformers(DataType source, DataType result)
280 {
281 final String dataTypePairHash = getDataTypeSourceResultPairHash(source, result);
282
283 List<Transformer> results = (List<Transformer>) transformerListCache.get(dataTypePairHash);
284 if (results != null)
285 {
286 return results;
287 }
288
289 results = new ArrayList<Transformer>(2);
290 Collection<Transformer> transformers = registry.lookupObjects(Transformer.class);
291 for (Transformer t : transformers)
292 {
293
294
295
296 if (!(t instanceof DiscoverableTransformer))
297 {
298 continue;
299 }
300 DataType dt = t.getReturnDataType();
301 if (result.isCompatibleWith(dt) && t.isSourceDataTypeSupported(source))
302 {
303 results.add(t);
304 }
305 }
306
307 List<Transformer> concurrentlyAddedTransformers = (List<Transformer>) transformerListCache.putIfAbsent(
308 dataTypePairHash, results);
309 if (concurrentlyAddedTransformers != null)
310 {
311 return concurrentlyAddedTransformers;
312 }
313 else
314 {
315 return results;
316 }
317 }
318
319
320
321
322 public Model lookupModel(String name)
323 {
324 return (Model) registry.lookupObject(name);
325 }
326
327
328
329
330 public Model lookupSystemModel()
331 {
332 return lookupModel(MuleProperties.OBJECT_SYSTEM_MODEL);
333 }
334
335
336
337
338 public Collection<Model> getModels()
339 {
340 return registry.lookupObjects(Model.class);
341 }
342
343
344
345
346 public Collection<Connector> getConnectors()
347 {
348 return registry.lookupObjects(Connector.class);
349 }
350
351
352
353
354 public Collection<Agent> getAgents()
355 {
356 return registry.lookupObjects(Agent.class);
357 }
358
359
360
361
362 public Collection<ImmutableEndpoint> getEndpoints()
363 {
364 return registry.lookupObjects(ImmutableEndpoint.class);
365 }
366
367
368
369
370 public Collection<Transformer> getTransformers()
371 {
372 return registry.lookupObjects(Transformer.class);
373 }
374
375
376
377
378 public Agent lookupAgent(String name)
379 {
380 return (Agent) registry.lookupObject(name);
381 }
382
383
384
385
386 public Service lookupService(String name)
387 {
388 return (Service) registry.lookupObject(name);
389 }
390
391
392
393
394 public Collection<Service> lookupServices()
395 {
396 return lookupObjects(Service.class);
397 }
398
399
400
401
402 public Collection<Service> lookupServices(String model)
403 {
404 Collection<Service> services = lookupServices();
405 List<Service> modelServices = new ArrayList<Service>();
406 Iterator it = services.iterator();
407 Service service;
408 while (it.hasNext())
409 {
410 service = (Service) it.next();
411 if (model.equals(service.getModel().getName()))
412 {
413 modelServices.add(service);
414 }
415 }
416 return modelServices;
417 }
418
419
420
421
422 public FlowConstruct lookupFlowConstruct(String name)
423 {
424 return (FlowConstruct) registry.lookupObject(name);
425 }
426
427
428
429
430 public Collection<FlowConstruct> lookupFlowConstructs()
431 {
432 return lookupObjects(FlowConstruct.class);
433 }
434
435
436
437
438 public final void registerTransformer(Transformer transformer) throws MuleException
439 {
440 registry.registerObject(getName(transformer), transformer, Transformer.class);
441 notifyTransformerResolvers(transformer, TransformerResolver.RegistryAction.ADDED);
442 }
443
444 protected void notifyTransformerResolvers(Transformer t, TransformerResolver.RegistryAction action)
445 {
446 if (t instanceof DiscoverableTransformer)
447 {
448 Collection<TransformerResolver> resolvers = lookupObjects(TransformerResolver.class);
449 for (TransformerResolver resolver : resolvers)
450 {
451 resolver.transformerChange(t, action);
452 }
453 transformerListCache.clear();
454 exactTransformerCache.clear();
455 }
456 }
457
458
459
460
461 public ServiceDescriptor lookupServiceDescriptor(ServiceType type, String name, Properties overrides) throws ServiceException
462 {
463 String key = new AbstractServiceDescriptor.Key(name, overrides).getKey();
464
465
466 ServiceDescriptor sd = (ServiceDescriptor) registry.lookupObject(key);
467
468 synchronized (this)
469 {
470 if (sd == null)
471 {
472 sd = createServiceDescriptor(type, name, overrides);
473 try
474 {
475 registry.registerObject(key, sd, ServiceDescriptor.class);
476 }
477 catch (RegistrationException e)
478 {
479 throw new ServiceException(e.getI18nMessage(), e);
480 }
481 }
482 }
483 return sd;
484 }
485
486 protected ServiceDescriptor createServiceDescriptor(ServiceType type, String name, Properties overrides) throws ServiceException
487 {
488
489 String scheme = name;
490 if (name.contains(":"))
491 {
492 scheme = name.substring(0, name.indexOf(":"));
493 }
494
495 Properties props = SpiUtils.findServiceDescriptor(type, scheme);
496 if (props == null)
497 {
498 throw new ServiceException(CoreMessages.failedToLoad(type + " " + scheme));
499 }
500
501 return ServiceDescriptorFactory.create(type, name, props, overrides, muleContext,
502 muleContext.getExecutionClassLoader());
503 }
504
505
506
507
508 public void registerAgent(Agent agent) throws MuleException
509 {
510 registry.registerObject(getName(agent), agent, Agent.class);
511 }
512
513
514
515
516 public void registerConnector(Connector connector) throws MuleException
517 {
518 registry.registerObject(getName(connector), connector, Connector.class);
519 }
520
521
522
523
524 public void registerEndpoint(ImmutableEndpoint endpoint) throws MuleException
525 {
526 registry.registerObject(getName(endpoint), endpoint, ImmutableEndpoint.class);
527 }
528
529
530
531
532 public void registerEndpointBuilder(String name, EndpointBuilder builder) throws MuleException
533 {
534 registry.registerObject(name, builder, EndpointBuilder.class);
535 }
536
537
538
539
540 public void registerModel(Model model) throws MuleException
541 {
542 registry.registerObject(getName(model), model, Model.class);
543 }
544
545
546
547
548 public void registerService(Service service) throws MuleException
549 {
550 registry.registerObject(getName(service), service, Service.class);
551 }
552
553
554
555
556 public void unregisterService(String serviceName) throws MuleException
557 {
558 registry.unregisterObject(serviceName, Service.class);
559 }
560
561
562
563
564 public void registerFlowConstruct(FlowConstruct flowConstruct) throws MuleException
565 {
566 registry.registerObject(getName(flowConstruct), flowConstruct, FlowConstruct.class);
567 }
568
569
570
571
572 public void unregisterFlowConstruct(String flowConstructName) throws MuleException
573 {
574 registry.unregisterObject(flowConstructName, FlowConstruct.class);
575 }
576
577
578
579
580 public void unregisterAgent(String agentName) throws MuleException
581 {
582 registry.unregisterObject(agentName, Agent.class);
583 }
584
585
586
587
588 public void unregisterConnector(String connectorName) throws MuleException
589 {
590 registry.unregisterObject(connectorName, Connector.class);
591 }
592
593
594
595
596 public void unregisterEndpoint(String endpointName) throws MuleException
597 {
598 registry.unregisterObject(endpointName, ImmutableEndpoint.class);
599 }
600
601
602
603
604 public void unregisterModel(String modelName) throws MuleException
605 {
606 registry.unregisterObject(modelName, Model.class);
607 }
608
609
610
611
612 public void unregisterTransformer(String transformerName) throws MuleException
613 {
614 Transformer transformer = lookupTransformer(transformerName);
615 notifyTransformerResolvers(transformer, TransformerResolver.RegistryAction.REMOVED);
616 registry.unregisterObject(transformerName, Transformer.class);
617
618 }
619
620
621
622
623 public Object applyProcessorsAndLifecycle(Object object) throws MuleException
624 {
625 object = applyProcessors(object);
626 object = applyLifecycle(object);
627 return object;
628 }
629
630
631
632
633 public Object applyProcessors(Object object) throws MuleException
634 {
635 return registry.getTransientRegistry().applyProcessors(object, null);
636 }
637
638
639
640
641 public Object applyProcessors(Object object, int flags) throws MuleException
642 {
643 return registry.getTransientRegistry().applyProcessors(object, flags);
644 }
645
646
647
648
649 public Object applyLifecycle(Object object) throws MuleException
650 {
651 return registry.getTransientRegistry().applyLifecycle(object);
652 }
653
654 public Object applyLifecycle(Object object, String phase) throws MuleException
655 {
656 return registry.getTransientRegistry().applyLifecycle(object, phase);
657 }
658
659
660
661
662
663
664
665
666 public <T> T lookupObject(Class<T> type) throws RegistrationException
667 {
668 return registry.lookupObject(type);
669 }
670
671 @SuppressWarnings("unchecked")
672 public <T> T lookupObject(String key)
673 {
674 return (T) registry.lookupObject(key);
675 }
676
677
678
679
680 public <T> Collection<T> lookupObjects(Class<T> type)
681 {
682 return registry.lookupObjects(type);
683 }
684
685
686
687
688 public <T> Collection<T> lookupObjectsForLifecycle(Class<T> type)
689 {
690 return registry.lookupObjectsForLifecycle(type);
691 }
692
693 @SuppressWarnings("unchecked")
694 public <T> T get(String key)
695 {
696 return (T)registry.get(key);
697 }
698
699 public <T> Map<String, T> lookupByType(Class<T> type)
700 {
701 return registry.lookupByType(type);
702 }
703
704
705
706
707 public void registerObject(String key, Object value, Object metadata) throws RegistrationException
708 {
709 registry.registerObject(key, value, metadata);
710 }
711
712
713
714
715 public void registerObject(String key, Object value) throws RegistrationException
716 {
717 registry.registerObject(key, value);
718 }
719
720
721
722
723 public void registerObjects(Map objects) throws RegistrationException
724 {
725 registry.registerObjects(objects);
726 }
727
728
729
730
731 public void unregisterObject(String key, Object metadata) throws RegistrationException
732 {
733 registry.unregisterObject(key, metadata);
734 }
735
736
737
738
739 public void unregisterObject(String key) throws RegistrationException
740 {
741 registry.unregisterObject(key);
742 }
743
744
745
746
747
748
749
750
751 protected String getName(Object obj)
752 {
753 String name = null;
754 if (obj instanceof NamedObject)
755 {
756 name = ((NamedObject) obj).getName();
757 }
758 else if (obj instanceof FlowConstruct)
759 {
760 name = ((FlowConstruct) obj).getName();
761 }
762 if (StringUtils.isBlank(name))
763 {
764 name = obj.getClass().getName() + ":" + UUID.getUUID();
765 }
766 return name;
767 }
768
769
770
771
772
773
774
775
776 public String getRegistryId()
777 {
778 return this.toString();
779 }
780
781
782
783
784 public boolean isReadOnly()
785 {
786 return false;
787 }
788
789
790
791
792 public boolean isRemote()
793 {
794 return false;
795 }
796
797 private String getDataTypeSourceResultPairHash(DataType<?> source, DataType<?> result)
798 {
799 return source.getClass().getName() + source.hashCode() + ":" + result.getClass().getName()
800 + result.hashCode();
801 }
802
803 private class TransformerResolverComparator implements Comparator<TransformerResolver>
804 {
805 public int compare(TransformerResolver transformerResolver, TransformerResolver transformerResolver1)
806 {
807 if (transformerResolver.getClass().equals(TypeBasedTransformerResolver.class))
808 {
809 return 1;
810 }
811
812 if (transformerResolver1.getClass().equals(TypeBasedTransformerResolver.class))
813 {
814 return -1;
815 }
816 return 0;
817 }
818 }
819 }
820
821