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