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