1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.spring.events;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.MessageExchangePattern;
16 import org.mule.RequestContext;
17 import org.mule.api.MuleContext;
18 import org.mule.api.MuleEventContext;
19 import org.mule.api.MuleException;
20 import org.mule.api.MuleRuntimeException;
21 import org.mule.api.MuleSession;
22 import org.mule.api.config.MuleProperties;
23 import org.mule.api.config.ThreadingProfile;
24 import org.mule.api.context.MuleContextAware;
25 import org.mule.api.endpoint.EndpointBuilder;
26 import org.mule.api.endpoint.EndpointFactory;
27 import org.mule.api.endpoint.EndpointURI;
28 import org.mule.api.endpoint.InboundEndpoint;
29 import org.mule.api.endpoint.MalformedEndpointException;
30 import org.mule.api.endpoint.OutboundEndpoint;
31 import org.mule.api.lifecycle.Callable;
32 import org.mule.api.lifecycle.Initialisable;
33 import org.mule.api.lifecycle.InitialisationException;
34 import org.mule.api.model.Model;
35 import org.mule.api.routing.filter.ObjectFilter;
36 import org.mule.api.service.Service;
37 import org.mule.api.source.CompositeMessageSource;
38 import org.mule.api.transformer.Transformer;
39 import org.mule.api.transformer.TransformerException;
40 import org.mule.api.transport.Connector;
41 import org.mule.component.DefaultJavaComponent;
42 import org.mule.config.QueueProfile;
43 import org.mule.endpoint.MuleEndpointURI;
44 import org.mule.model.seda.SedaModel;
45 import org.mule.model.seda.SedaService;
46 import org.mule.module.spring.i18n.SpringMessages;
47 import org.mule.object.SingletonObjectFactory;
48 import org.mule.routing.filters.WildcardFilter;
49 import org.mule.service.ServiceCompositeMessageSource;
50 import org.mule.session.DefaultMuleSession;
51 import org.mule.util.ClassUtils;
52
53 import java.beans.ExceptionListener;
54 import java.util.ArrayList;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Set;
59
60 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet;
61 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
62 import org.apache.commons.logging.Log;
63 import org.apache.commons.logging.LogFactory;
64 import org.springframework.beans.BeansException;
65 import org.springframework.context.ApplicationContext;
66 import org.springframework.context.ApplicationContextAware;
67 import org.springframework.context.ApplicationEvent;
68 import org.springframework.context.ApplicationListener;
69 import org.springframework.context.event.ApplicationEventMulticaster;
70 import org.springframework.context.event.ContextClosedEvent;
71 import org.springframework.context.event.ContextRefreshedEvent;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public class MuleEventMulticaster
121 implements ApplicationEventMulticaster, ApplicationContextAware, MuleContextAware, Callable, Initialisable
122 {
123 public static final String EVENT_MULTICASTER_DESCRIPTOR_NAME = "muleEventMulticasterDescriptor";
124
125
126
127
128 protected static final Log logger = LogFactory.getLog(MuleEventMulticaster.class);
129
130
131
132
133 protected final Set listeners = new CopyOnWriteArraySet();
134
135
136
137
138 protected boolean asynchronous = false;
139
140
141
142
143 protected ExecutorService asyncPool = null;
144
145
146
147
148
149
150
151
152 protected String[] subscriptions = null;
153
154
155
156
157 protected ApplicationContext applicationContext;
158
159
160
161
162 protected Service service;
163
164
165
166
167 protected Class subscriptionFilter = WildcardFilter.class;
168
169
170
171
172 protected ExceptionListener exceptionListener = new LoggingExceptionListener();
173
174 protected MuleContext muleContext;
175
176 public void setMuleContext(MuleContext context)
177 {
178 this.muleContext = context;
179 }
180
181 public void initialise() throws InitialisationException
182 {
183 if (asynchronous)
184 {
185 if (asyncPool == null)
186 {
187 asyncPool = muleContext.getDefaultThreadingProfile().createPool("spring-events");
188 }
189 }
190 else
191 {
192 if (asyncPool != null)
193 {
194 asyncPool.shutdown();
195 asyncPool = null;
196 }
197 }
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211 public void addApplicationListener(ApplicationListener listener)
212 {
213 Object listenerToAdd = listener;
214
215 if (asynchronous)
216 {
217 listenerToAdd = new AsynchronousEventListener(asyncPool, listener);
218 }
219
220 listeners.add(listenerToAdd);
221 }
222
223
224
225
226
227
228 public void removeApplicationListener(ApplicationListener listener)
229 {
230 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
231 {
232 ApplicationListener applicationListener = (ApplicationListener) iterator.next();
233 if (applicationListener instanceof AsynchronousEventListener)
234 {
235 if (((AsynchronousEventListener) applicationListener).getListener().equals(listener))
236 {
237 listeners.remove(applicationListener);
238 return;
239 }
240 }
241 else
242 {
243 if (applicationListener.equals(listener))
244 {
245 listeners.remove(applicationListener);
246 return;
247 }
248 }
249 }
250 listeners.remove(listener);
251 }
252
253
254 public void addApplicationListenerBean(String s)
255 {
256 Object listener = applicationContext.getBean(s);
257 if(listener instanceof ApplicationListener)
258 {
259 addApplicationListener((ApplicationListener)listener);
260 }
261 else
262 {
263 throw new IllegalArgumentException(SpringMessages.beanNotInstanceOfApplicationListener(s).getMessage());
264 }
265 }
266
267 public void removeApplicationListenerBean(String s)
268 {
269 Object listener = applicationContext.getBean(s);
270 if(listener instanceof ApplicationListener)
271 {
272 removeApplicationListener((ApplicationListener)listener);
273 }
274 else
275 {
276 throw new IllegalArgumentException(SpringMessages.beanNotInstanceOfApplicationListener(s).getMessage());
277 }
278 }
279
280
281
282
283 public void removeAllListeners()
284 {
285 listeners.clear();
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 public void multicastEvent(ApplicationEvent e)
302 {
303 MuleApplicationEvent muleEvent = null;
304
305 if (e instanceof ContextRefreshedEvent)
306 {
307 try
308 {
309 registerMulticasterComponent();
310 }
311 catch (MuleException ex)
312 {
313 throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), ex);
314 }
315 }
316 else if (e instanceof ContextClosedEvent)
317 {
318 if (!muleContext.isDisposing() && !muleContext.isDisposed())
319 {
320 muleContext.dispose();
321 }
322 return;
323 }
324 else if (e instanceof MuleApplicationEvent)
325 {
326 muleEvent = (MuleApplicationEvent) e;
327
328
329 if (muleEvent.getMuleEventContext() == null)
330 {
331 try
332 {
333 dispatchEvent(muleEvent);
334 }
335 catch (ApplicationEventException e1)
336 {
337 exceptionListener.exceptionThrown(e1);
338 }
339 return;
340 }
341 }
342
343 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
344 {
345 ApplicationListener listener = (ApplicationListener) iterator.next();
346 if (muleEvent != null)
347 {
348
349
350
351 if (listener instanceof AsynchronousEventListener)
352 {
353 AsynchronousEventListener asyncListener = (AsynchronousEventListener) listener;
354 if (asyncListener.getListener() instanceof MuleSubscriptionEventListener)
355 {
356 if (isSubscriptionMatch(muleEvent.getEndpoint(),
357 ((MuleSubscriptionEventListener) asyncListener.getListener()).getSubscriptions()))
358 {
359 asyncListener.onApplicationEvent(muleEvent);
360 }
361 }
362 else if (asyncListener.getListener() instanceof MuleEventListener)
363 {
364 asyncListener.onApplicationEvent(muleEvent);
365 }
366 else if (!(asyncListener.getListener() instanceof MuleEventListener))
367 {
368 asyncListener.onApplicationEvent(e);
369 }
370
371 }
372 else if (listener instanceof MuleSubscriptionEventListener)
373 {
374 if (isSubscriptionMatch(muleEvent.getEndpoint(),
375 ((MuleSubscriptionEventListener) listener).getSubscriptions()))
376 {
377 listener.onApplicationEvent(muleEvent);
378 }
379 }
380 else if (listener instanceof MuleEventListener)
381 {
382 listener.onApplicationEvent(muleEvent);
383 }
384 }
385 else if (listener instanceof AsynchronousEventListener
386 && !(((AsynchronousEventListener) listener).getListener() instanceof MuleEventListener))
387 {
388 listener.onApplicationEvent(e);
389 }
390 else if (!(listener instanceof MuleEventListener))
391 {
392 listener.onApplicationEvent(e);
393 }
394 else
395 {
396
397
398 for (int i = 0; i < listener.getClass().getInterfaces().length; i++)
399 {
400 if (listener.getClass().getInterfaces()[i].equals(ApplicationListener.class))
401 {
402 listener.onApplicationEvent(e);
403 break;
404 }
405 }
406
407 }
408 }
409 }
410
411
412
413
414
415
416
417
418 private boolean isSubscriptionMatch(String endpoint, String[] subscriptions)
419 {
420 for (int i = 0; i < subscriptions.length; i++)
421 {
422 String subscription = subscriptions[i];
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 ObjectFilter filter = createFilter(subscription);
442 if (filter.accept(endpoint))
443 {
444 return true;
445 }
446 }
447 return false;
448 }
449
450
451
452
453
454
455 public boolean isAsynchronous()
456 {
457 return asynchronous;
458 }
459
460
461
462
463
464
465 public void setAsynchronous(boolean asynchronous)
466 {
467 this.asynchronous = asynchronous;
468 }
469
470
471
472
473
474
475
476 public Object onCall(MuleEventContext context) throws TransformerException, MalformedEndpointException
477 {
478 multicastEvent(new MuleApplicationEvent(context.getMessage().getPayload(), context, applicationContext));
479 context.setStopFurtherProcessing(true);
480 return null;
481 }
482
483
484
485
486
487
488
489
490 protected void dispatchEvent(MuleApplicationEvent applicationEvent) throws ApplicationEventException
491 {
492 OutboundEndpoint endpoint;
493 try
494 {
495 endpoint = muleContext.getEndpointFactory().getOutboundEndpoint(
496 applicationEvent.getEndpoint());
497 }
498 catch (MuleException e)
499 {
500 throw new ApplicationEventException("Failed to get endpoint for endpointUri: "
501 + applicationEvent.getEndpoint(), e);
502 }
503 if (endpoint != null)
504 {
505 try
506 {
507
508
509
510
511 DefaultMuleMessage message = new DefaultMuleMessage(applicationEvent.getSource(),
512 applicationEvent.getProperties(), muleContext);
513
514
515 if (applicationEvent.getMuleEventContext() != null)
516 {
517
518 applicationEvent.getMuleEventContext().setStopFurtherProcessing(true);
519 applicationEvent.getMuleEventContext().dispatchEvent(message, endpoint);
520 }
521 else
522 {
523 MuleSession session = new DefaultMuleSession(service, muleContext);
524 DefaultMuleEvent event = new DefaultMuleEvent(message, endpoint, session);
525 RequestContext.setEvent(event);
526
527 if (endpoint.getTransformers() != null)
528 {
529 message = new DefaultMuleMessage(applicationEvent.getSource(),
530 applicationEvent.getProperties(), muleContext);
531 message.applyTransformers(event, endpoint.getTransformers());
532 }
533 endpoint.process(new DefaultMuleEvent(message, endpoint, session));
534 }
535 }
536 catch (Exception e1)
537 {
538 throw new ApplicationEventException("Failed to dispatch event: " + e1.getMessage(), e1);
539 }
540 }
541 else
542 {
543 throw new ApplicationEventException("Failed endpoint using name: "
544 + applicationEvent.getEndpoint());
545 }
546 }
547
548
549
550
551
552
553
554 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
555 {
556 this.applicationContext = applicationContext;
557 }
558
559 protected void registerMulticasterComponent() throws MuleException
560 {
561
562 if (service == null)
563 {
564 service = getDefaultService();
565 setSubscriptionsOnService(service);
566 muleContext.getRegistry().registerService(service);
567 }
568 }
569
570 protected void setSubscriptionsOnService(Service service) throws MuleException
571 {
572 String[] subscriptions;
573 List endpoints = new ArrayList();
574 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
575 {
576 ApplicationListener listener = (ApplicationListener) iterator.next();
577 if (listener instanceof AsynchronousEventListener)
578 {
579 listener = ((AsynchronousEventListener) listener).getListener();
580 }
581 if (listener instanceof MuleSubscriptionEventListener)
582 {
583 subscriptions = ((MuleSubscriptionEventListener) listener).getSubscriptions();
584 for (int i = 0; i < subscriptions.length; i++)
585 {
586 if (subscriptions[i].indexOf("*") == -1 && MuleEndpointURI.isMuleUri(subscriptions[i]))
587 {
588 boolean isSoap = registerAsSoap(subscriptions[i], listener);
589
590 if (!isSoap)
591 {
592 endpoints.add(subscriptions[i]);
593 }
594 }
595 }
596 }
597 }
598 if (endpoints.size() > 0)
599 {
600 String endpoint;
601 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
602 {
603 endpoint = (String) iterator.next();
604
605 InboundEndpoint ep = muleContext.getEndpointFactory().getInboundEndpoint(
606 endpoint);
607
608
609
610 if (((ServiceCompositeMessageSource) service.getMessageSource()).getEndpoint(ep.getName()) == null)
611 {
612 ((ServiceCompositeMessageSource) service.getMessageSource()).addSource(ep);
613 }
614 }
615 }
616 }
617
618 private boolean registerAsSoap(String endpoint, Object listener) throws MuleException
619 {
620 if (endpoint.startsWith("soap") || endpoint.startsWith("axis") || endpoint.startsWith("cxf"))
621 {
622 EndpointURI ep = new MuleEndpointURI(endpoint, muleContext);
623
624
625 String serviceName = null;
626 if (ep.getPath() != null)
627 {
628 String path = ep.getPath();
629 if (path.endsWith("/"))
630 {
631 path = path.substring(0, path.length() - 1);
632 }
633 int i = path.lastIndexOf("/");
634 if (i > -1)
635 {
636 serviceName = path.substring(i + 1);
637 }
638 }
639 else
640 {
641 serviceName = service.getName();
642 }
643
644 String newEndpoint = endpoint;
645 int i = newEndpoint.indexOf(serviceName);
646 newEndpoint = newEndpoint.substring(0, i - 1);
647 SedaService s = new SedaService(muleContext);
648 s.setName(serviceName);
649 s.setModel(muleContext.getRegistry().lookupSystemModel());
650 s.setQueueProfile(new QueueProfile());
651 ((CompositeMessageSource) s.getMessageSource()).addSource(
652 muleContext.getEndpointFactory().getInboundEndpoint(newEndpoint));
653 final DefaultJavaComponent component = new DefaultJavaComponent(new SingletonObjectFactory(listener));
654 component.setMuleContext(muleContext);
655 s.setComponent(component);
656 muleContext.getRegistry().registerService(s);
657 return true;
658 }
659 else
660 {
661 return false;
662 }
663 }
664
665 protected void registerConnectors() throws MuleException
666 {
667 if (!muleContext.isInitialised())
668 {
669
670 Map connectors = applicationContext.getBeansOfType(Connector.class, true, true);
671 if (connectors.size() > 0)
672 {
673 Map.Entry entry;
674 Connector c;
675 for (Iterator iterator = connectors.entrySet().iterator(); iterator.hasNext();)
676 {
677 entry = (Map.Entry) iterator.next();
678 c = (Connector) entry.getValue();
679 if (c.getName() == null)
680 {
681 c.setName(entry.getKey().toString());
682 }
683 muleContext.getRegistry().registerConnector(c);
684 }
685 }
686 }
687 }
688
689 protected void registerTransformers() throws MuleException
690 {
691 if (!muleContext.isInitialised())
692 {
693
694 Map transformers = applicationContext.getBeansOfType(Transformer.class, true, true);
695 if (transformers.size() > 0)
696 {
697 Map.Entry entry;
698 Transformer t;
699 for (Iterator iterator = transformers.entrySet().iterator(); iterator.hasNext();)
700 {
701 entry = (Map.Entry) iterator.next();
702 t = (Transformer) entry.getValue();
703 if (t.getName() == null)
704 {
705 t.setName(entry.getKey().toString());
706 }
707 muleContext.getRegistry().registerTransformer(t);
708 }
709 }
710 }
711 }
712
713 protected Service getDefaultService() throws MuleException
714 {
715
716
717 Model model = muleContext.getRegistry().lookupModel(MuleProperties.OBJECT_SYSTEM_MODEL);
718 if (model == null)
719 {
720 model = new SedaModel();
721 model.setName(MuleProperties.OBJECT_SYSTEM_MODEL);
722 muleContext.getRegistry().registerModel(model);
723 }
724 Service service = muleContext.getRegistry().lookupService(EVENT_MULTICASTER_DESCRIPTOR_NAME);
725 if (service != null)
726 {
727 muleContext.getRegistry().unregisterService(service.getName());
728 }
729 service = new SedaService(muleContext);
730 service.setName(EVENT_MULTICASTER_DESCRIPTOR_NAME);
731 service.setModel(model);
732 if (subscriptions == null)
733 {
734 logger.info("No receive endpoints have been set, using default '*'");
735 ((CompositeMessageSource) service.getMessageSource()).addSource(
736 muleContext.getEndpointFactory().getInboundEndpoint("vm://*"));
737 }
738 else
739 {
740
741 ServiceCompositeMessageSource messageRouter = (ServiceCompositeMessageSource) service.getMessageSource();
742
743 for (int i = 0; i < subscriptions.length; i++)
744 {
745 String subscription = subscriptions[i];
746
747 EndpointFactory endpointFactory = muleContext.getRegistry().lookupEndpointFactory();
748 EndpointBuilder endpointBuilder = endpointFactory.getEndpointBuilder(subscription);
749 endpointBuilder.setExchangePattern(MessageExchangePattern.fromSyncFlag(!asynchronous));
750 InboundEndpoint endpoint = endpointFactory.getInboundEndpoint(endpointBuilder);
751
752 messageRouter.addSource(endpoint);
753 }
754 }
755 DefaultJavaComponent component = new DefaultJavaComponent(new SingletonObjectFactory(this));
756 component.setMuleContext(muleContext);
757 service.setComponent(component);
758 return service;
759 }
760
761 protected ObjectFilter createFilter(String pattern)
762 {
763 try
764 {
765 if (getSubscriptionFilter() == null)
766 {
767 setSubscriptionFilter(WildcardFilter.class);
768 }
769 return (ObjectFilter) ClassUtils.instanciateClass(getSubscriptionFilter(), pattern);
770 }
771 catch (Exception e)
772 {
773 exceptionListener.exceptionThrown(e);
774 return new WildcardFilter(pattern);
775 }
776 }
777
778
779
780
781
782
783
784 public Class getSubscriptionFilter()
785 {
786 return subscriptionFilter;
787 }
788
789
790
791
792
793
794 public void setSubscriptionFilter(Class subscriptionFilter)
795 {
796 this.subscriptionFilter = subscriptionFilter;
797 }
798
799
800
801
802
803
804
805
806
807
808 public String[] getSubscriptions()
809 {
810 return subscriptions;
811 }
812
813
814
815
816
817
818
819
820
821
822 public void setSubscriptions(String[] subscriptions)
823 {
824 this.subscriptions = subscriptions;
825 }
826
827 protected void setExceptionListener(ExceptionListener listener)
828 {
829 if (listener != null)
830 {
831 this.exceptionListener = listener;
832 }
833 else
834 {
835 throw new IllegalArgumentException("exceptionListener may not be null");
836 }
837 }
838
839 private static class LoggingExceptionListener implements ExceptionListener
840 {
841 public LoggingExceptionListener()
842 {
843 super();
844 }
845
846 public void exceptionThrown(Exception e)
847 {
848 logger.error(e.getMessage(), e);
849 }
850 }
851 }