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.DefaultMuleSession;
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.InboundRouterCollection;
36 import org.mule.api.routing.filter.ObjectFilter;
37 import org.mule.api.service.Service;
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.transport.AbstractConnector;
50 import org.mule.util.ClassUtils;
51
52 import java.beans.ExceptionListener;
53 import java.util.ArrayList;
54 import java.util.Iterator;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.Set;
58
59 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet;
60 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
61
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
255
256 public void removeAllListeners()
257 {
258 listeners.clear();
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 public void multicastEvent(ApplicationEvent e)
275 {
276 MuleApplicationEvent muleEvent = null;
277
278 if (e instanceof ContextRefreshedEvent)
279 {
280 try
281 {
282 registerMulticasterComponent();
283 }
284 catch (MuleException ex)
285 {
286 throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), ex);
287 }
288 }
289 else if (e instanceof ContextClosedEvent)
290 {
291 muleContext.dispose();
292 return;
293 }
294 else if (e instanceof MuleApplicationEvent)
295 {
296 muleEvent = (MuleApplicationEvent) e;
297
298
299 if (muleEvent.getMuleEventContext() == null)
300 {
301 try
302 {
303 dispatchEvent(muleEvent);
304 }
305 catch (ApplicationEventException e1)
306 {
307 exceptionListener.exceptionThrown(e1);
308 }
309 return;
310 }
311 }
312
313 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
314 {
315 ApplicationListener listener = (ApplicationListener) iterator.next();
316 if (muleEvent != null)
317 {
318
319
320
321 if (listener instanceof AsynchronousEventListener)
322 {
323 AsynchronousEventListener asyncListener = (AsynchronousEventListener) listener;
324 if (asyncListener.getListener() instanceof MuleSubscriptionEventListener)
325 {
326 if (isSubscriptionMatch(muleEvent.getEndpoint(),
327 ((MuleSubscriptionEventListener) asyncListener.getListener()).getSubscriptions()))
328 {
329 asyncListener.onApplicationEvent(muleEvent);
330 }
331 }
332 else if (asyncListener.getListener() instanceof MuleEventListener)
333 {
334 asyncListener.onApplicationEvent(muleEvent);
335 }
336 else if (!(asyncListener.getListener() instanceof MuleEventListener))
337 {
338 asyncListener.onApplicationEvent(e);
339 }
340
341 }
342 else if (listener instanceof MuleSubscriptionEventListener)
343 {
344 if (isSubscriptionMatch(muleEvent.getEndpoint(),
345 ((MuleSubscriptionEventListener) listener).getSubscriptions()))
346 {
347 listener.onApplicationEvent(muleEvent);
348 }
349 }
350 else if (listener instanceof MuleEventListener)
351 {
352 listener.onApplicationEvent(muleEvent);
353 }
354 }
355 else if (listener instanceof AsynchronousEventListener
356 && !(((AsynchronousEventListener) listener).getListener() instanceof MuleEventListener))
357 {
358 listener.onApplicationEvent(e);
359 }
360 else if (!(listener instanceof MuleEventListener))
361 {
362 listener.onApplicationEvent(e);
363 }
364 else
365 {
366
367
368 for (int i = 0; i < listener.getClass().getInterfaces().length; i++)
369 {
370 if (listener.getClass().getInterfaces()[i].equals(ApplicationListener.class))
371 {
372 listener.onApplicationEvent(e);
373 break;
374 }
375 }
376
377 }
378 }
379 }
380
381
382
383
384
385
386
387
388 private boolean isSubscriptionMatch(String endpoint, String[] subscriptions)
389 {
390 for (int i = 0; i < subscriptions.length; i++)
391 {
392 String subscription = subscriptions[i];
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 ObjectFilter filter = createFilter(subscription);
412 if (filter.accept(endpoint))
413 {
414 return true;
415 }
416 }
417 return false;
418 }
419
420
421
422
423
424
425 public boolean isAsynchronous()
426 {
427 return asynchronous;
428 }
429
430
431
432
433
434
435 public void setAsynchronous(boolean asynchronous)
436 {
437 this.asynchronous = asynchronous;
438 }
439
440
441
442
443
444
445
446 public Object onCall(MuleEventContext context) throws TransformerException, MalformedEndpointException
447 {
448 multicastEvent(new MuleApplicationEvent(context.transformMessage(), context, applicationContext));
449 context.setStopFurtherProcessing(true);
450 return null;
451 }
452
453
454
455
456
457
458
459
460 protected void dispatchEvent(MuleApplicationEvent applicationEvent) throws ApplicationEventException
461 {
462 OutboundEndpoint endpoint;
463 try
464 {
465 endpoint = muleContext.getRegistry().lookupEndpointFactory().getOutboundEndpoint(
466 applicationEvent.getEndpoint());
467 }
468 catch (MuleException e)
469 {
470 throw new ApplicationEventException("Failed to get endpoint for endpointUri: "
471 + applicationEvent.getEndpoint(), e);
472 }
473 if (endpoint != null)
474 {
475 try
476 {
477
478
479
480
481 DefaultMuleMessage message = new DefaultMuleMessage(applicationEvent.getSource(),
482 applicationEvent.getProperties());
483
484
485 if (applicationEvent.getMuleEventContext() != null)
486 {
487
488 applicationEvent.getMuleEventContext().setStopFurtherProcessing(true);
489 applicationEvent.getMuleEventContext().dispatchEvent(message, endpoint);
490 }
491 else
492 {
493 MuleSession session = new DefaultMuleSession(message,
494 ((AbstractConnector) endpoint.getConnector()).getSessionHandler(), service, muleContext);
495 RequestContext.setEvent(new DefaultMuleEvent(message, endpoint, session, false));
496
497 if (endpoint.getTransformers() != null)
498 {
499 message = new DefaultMuleMessage(applicationEvent.getSource(),
500 applicationEvent.getProperties());
501 message.applyTransformers(endpoint.getTransformers());
502 }
503 endpoint.dispatch(new DefaultMuleEvent(message, endpoint, session, false));
504 }
505 }
506 catch (Exception e1)
507 {
508 throw new ApplicationEventException("Failed to dispatch event: " + e1.getMessage(), e1);
509 }
510 }
511 else
512 {
513 throw new ApplicationEventException("Failed endpoint using name: "
514 + applicationEvent.getEndpoint());
515 }
516 }
517
518
519
520
521
522
523
524 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
525 {
526 this.applicationContext = applicationContext;
527 }
528
529 protected void registerMulticasterComponent() throws MuleException
530 {
531
532 if (service == null)
533 {
534 service = getDefaultService();
535 setSubscriptionsOnService(service);
536 muleContext.getRegistry().registerService(service);
537 }
538 }
539
540 protected void setSubscriptionsOnService(Service service) throws MuleException
541 {
542 String[] subscriptions;
543 List endpoints = new ArrayList();
544 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
545 {
546 ApplicationListener listener = (ApplicationListener) iterator.next();
547 if (listener instanceof AsynchronousEventListener)
548 {
549 listener = ((AsynchronousEventListener) listener).getListener();
550 }
551 if (listener instanceof MuleSubscriptionEventListener)
552 {
553 subscriptions = ((MuleSubscriptionEventListener) listener).getSubscriptions();
554 for (int i = 0; i < subscriptions.length; i++)
555 {
556 if (subscriptions[i].indexOf("*") == -1 && MuleEndpointURI.isMuleUri(subscriptions[i]))
557 {
558 boolean isSoap = registerAsSoap(subscriptions[i], listener);
559
560 if (!isSoap)
561 {
562 endpoints.add(subscriptions[i]);
563 }
564 }
565 }
566 }
567 }
568 if (endpoints.size() > 0)
569 {
570 String endpoint;
571 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
572 {
573 endpoint = (String) iterator.next();
574
575 InboundEndpoint ep = muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint(
576 endpoint);
577
578
579
580 if (service.getInboundRouter().getEndpoint(ep.getName()) == null)
581 {
582 service.getInboundRouter().addEndpoint(ep);
583 }
584 }
585 }
586 }
587
588 private boolean registerAsSoap(String endpoint, Object listener) throws MuleException
589 {
590 if (endpoint.startsWith("soap") || endpoint.startsWith("axis") || endpoint.startsWith("cxf"))
591 {
592 EndpointURI ep = new MuleEndpointURI(endpoint);
593
594
595 String serviceName = null;
596 if (ep.getPath() != null)
597 {
598 String path = ep.getPath();
599 if (path.endsWith("/"))
600 {
601 path = path.substring(0, path.length() - 1);
602 }
603 int i = path.lastIndexOf("/");
604 if (i > -1)
605 {
606 serviceName = path.substring(i + 1);
607 }
608 }
609 else
610 {
611 serviceName = service.getName();
612 }
613
614 String newEndpoint = endpoint;
615 int i = newEndpoint.indexOf(serviceName);
616 newEndpoint = newEndpoint.substring(0, i - 1);
617 SedaService s = new SedaService();
618 s.setName(serviceName);
619 s.setModel(muleContext.getRegistry().lookupSystemModel());
620 s.setQueueProfile(new QueueProfile());
621 s.getInboundRouter().addEndpoint(
622 muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint(newEndpoint));
623 s.setComponent(new DefaultJavaComponent(new SingletonObjectFactory(listener)));
624 muleContext.getRegistry().registerService(s);
625 return true;
626 }
627 else
628 {
629 return false;
630 }
631 }
632
633 protected void registerConnectors() throws MuleException
634 {
635 if (!muleContext.isInitialised())
636 {
637
638 Map connectors = applicationContext.getBeansOfType(Connector.class, true, true);
639 if (connectors.size() > 0)
640 {
641 Map.Entry entry;
642 Connector c;
643 for (Iterator iterator = connectors.entrySet().iterator(); iterator.hasNext();)
644 {
645 entry = (Map.Entry) iterator.next();
646 c = (Connector) entry.getValue();
647 if (c.getName() == null)
648 {
649 c.setName(entry.getKey().toString());
650 }
651 muleContext.getRegistry().registerConnector(c);
652 }
653 }
654 }
655 }
656
657 protected void registerTransformers() throws MuleException
658 {
659 if (!muleContext.isInitialised())
660 {
661
662 Map transformers = applicationContext.getBeansOfType(Transformer.class, true, true);
663 if (transformers.size() > 0)
664 {
665 Map.Entry entry;
666 Transformer t;
667 for (Iterator iterator = transformers.entrySet().iterator(); iterator.hasNext();)
668 {
669 entry = (Map.Entry) iterator.next();
670 t = (Transformer) entry.getValue();
671 if (t.getName() == null)
672 {
673 t.setName(entry.getKey().toString());
674 }
675 muleContext.getRegistry().registerTransformer(t);
676 }
677 }
678 }
679 }
680
681 protected Service getDefaultService() throws MuleException
682 {
683
684
685 Model model = muleContext.getRegistry().lookupModel(MuleProperties.OBJECT_SYSTEM_MODEL);
686 if (model == null)
687 {
688 model = new SedaModel();
689 model.setName(MuleProperties.OBJECT_SYSTEM_MODEL);
690 muleContext.getRegistry().registerModel(model);
691 }
692 Service service = muleContext.getRegistry().lookupService(EVENT_MULTICASTER_DESCRIPTOR_NAME);
693 if (service != null)
694 {
695 muleContext.getRegistry().unregisterService(service.getName());
696 }
697 service = new SedaService();
698 service.setName(EVENT_MULTICASTER_DESCRIPTOR_NAME);
699 service.setModel(model);
700 if (subscriptions == null)
701 {
702 logger.info("No receive endpoints have been set, using default '*'");
703 service.getInboundRouter().addEndpoint(
704 muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint("vm://*"));
705 }
706 else
707 {
708
709 InboundRouterCollection messageRouter = service.getInboundRouter();
710
711 for (int i = 0; i < subscriptions.length; i++)
712 {
713 String subscription = subscriptions[i];
714
715 EndpointFactory endpointFactory = muleContext.getRegistry().lookupEndpointFactory();
716 EndpointBuilder endpointBuilder = endpointFactory.getEndpointBuilder(subscription);
717 endpointBuilder.setSynchronous(!asynchronous);
718 InboundEndpoint endpoint = endpointFactory.getInboundEndpoint(endpointBuilder);
719
720 messageRouter.addEndpoint(endpoint);
721 }
722 }
723 service.setComponent(new DefaultJavaComponent(new SingletonObjectFactory(this)));
724 return service;
725 }
726
727 protected ObjectFilter createFilter(String pattern)
728 {
729 try
730 {
731 if (getSubscriptionFilter() == null)
732 {
733 setSubscriptionFilter(WildcardFilter.class);
734 }
735 ObjectFilter filter = (ObjectFilter) ClassUtils.instanciateClass(getSubscriptionFilter(),
736 new Object[]{pattern});
737 return filter;
738 }
739 catch (Exception e)
740 {
741 exceptionListener.exceptionThrown(e);
742 return new WildcardFilter(pattern);
743 }
744 }
745
746
747
748
749
750
751
752 public Class getSubscriptionFilter()
753 {
754 return subscriptionFilter;
755 }
756
757
758
759
760
761
762 public void setSubscriptionFilter(Class subscriptionFilter)
763 {
764 this.subscriptionFilter = subscriptionFilter;
765 }
766
767
768
769
770
771
772
773
774
775
776 public String[] getSubscriptions()
777 {
778 return subscriptions;
779 }
780
781
782
783
784
785
786
787
788
789
790 public void setSubscriptions(String[] subscriptions)
791 {
792 this.subscriptions = subscriptions;
793 }
794
795 protected void setExceptionListener(ExceptionListener listener)
796 {
797 if (listener != null)
798 {
799 this.exceptionListener = listener;
800 }
801 else
802 {
803 throw new IllegalArgumentException("exceptionListener may not be null");
804 }
805 }
806
807 private class LoggingExceptionListener implements ExceptionListener
808 {
809 public void exceptionThrown(Exception e)
810 {
811 logger.error(e.getMessage(), e);
812 }
813 }
814 }