Coverage Report - org.mule.extras.spring.events.MuleEventMulticaster
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleEventMulticaster
72%
193/267
68%
117/172
4.172
MuleEventMulticaster$1
N/A
N/A
4.172
MuleEventMulticaster$LoggingExceptionListener
33%
1/3
N/A
4.172
 
 1  
 /*
 2  
  * $Id: MuleEventMulticaster.java 7963 2007-08-21 08:53:15Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.extras.spring.events;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.MuleRuntimeException;
 15  
 import org.mule.config.MuleConfiguration;
 16  
 import org.mule.config.ThreadingProfile;
 17  
 import org.mule.config.builders.QuickConfigurationBuilder;
 18  
 import org.mule.extras.spring.SpringContainerContext;
 19  
 import org.mule.extras.spring.i18n.SpringMessages;
 20  
 import org.mule.impl.MuleDescriptor;
 21  
 import org.mule.impl.MuleEvent;
 22  
 import org.mule.impl.MuleMessage;
 23  
 import org.mule.impl.MuleSession;
 24  
 import org.mule.impl.RequestContext;
 25  
 import org.mule.impl.endpoint.MuleEndpoint;
 26  
 import org.mule.impl.endpoint.MuleEndpointURI;
 27  
 import org.mule.impl.model.ModelHelper;
 28  
 import org.mule.impl.model.seda.SedaModel;
 29  
 import org.mule.providers.AbstractConnector;
 30  
 import org.mule.routing.filters.ObjectFilter;
 31  
 import org.mule.routing.filters.WildcardFilter;
 32  
 import org.mule.umo.UMOComponent;
 33  
 import org.mule.umo.UMODescriptor;
 34  
 import org.mule.umo.UMOEventContext;
 35  
 import org.mule.umo.UMOException;
 36  
 import org.mule.umo.UMOSession;
 37  
 import org.mule.umo.endpoint.MalformedEndpointException;
 38  
 import org.mule.umo.endpoint.UMOEndpoint;
 39  
 import org.mule.umo.endpoint.UMOEndpointURI;
 40  
 import org.mule.umo.lifecycle.InitialisationException;
 41  
 import org.mule.umo.manager.UMOManager;
 42  
 import org.mule.umo.model.UMOModel;
 43  
 import org.mule.umo.provider.UMOConnector;
 44  
 import org.mule.umo.routing.UMOInboundRouterCollection;
 45  
 import org.mule.umo.transformer.TransformerException;
 46  
 import org.mule.umo.transformer.UMOTransformer;
 47  
 import org.mule.util.ClassUtils;
 48  
 import org.mule.util.MapUtils;
 49  
 
 50  
 import java.beans.ExceptionListener;
 51  
 import java.util.ArrayList;
 52  
 import java.util.Iterator;
 53  
 import java.util.List;
 54  
 import java.util.Map;
 55  
 import java.util.Set;
 56  
 
 57  
 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet;
 58  
 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
 59  
 import org.apache.commons.logging.Log;
 60  
 import org.apache.commons.logging.LogFactory;
 61  
 import org.springframework.beans.BeansException;
 62  
 import org.springframework.beans.factory.DisposableBean;
 63  
 import org.springframework.context.ApplicationContext;
 64  
 import org.springframework.context.ApplicationContextAware;
 65  
 import org.springframework.context.ApplicationEvent;
 66  
 import org.springframework.context.ApplicationListener;
 67  
 import org.springframework.context.event.ApplicationEventMulticaster;
 68  
 import org.springframework.context.event.ContextClosedEvent;
 69  
 import org.springframework.context.event.ContextRefreshedEvent;
 70  
 import org.springframework.context.support.AbstractApplicationContext;
 71  
 
 72  
 /**
 73  
  * <code>MuleEventMulticaster</code> is an implementation of a Spring
 74  
  * ApplicationeventMulticaster. This implementation allows Mule event to be sent and
 75  
  * received through the Spring ApplicationContext. This allows any Spring bean to
 76  
  * receive and send events from any transport that Mule supports such as Jms, Http,
 77  
  * Tcp, Pop3, Smtp, File, etc. All a bean needs to do to receive and send events is
 78  
  * to implement MuleEventListener. Beans can also have subscriptions to certain
 79  
  * events by implementing MuleSubscriptionEventListener, where the bean can provide a
 80  
  * list of endpoints on which to receive events i.e. <code>
 81  
  * &lt;bean id="myListener" class="com.foo.MyListener"&gt;
 82  
  * &lt;property name="subscriptions"&gt;
 83  
  * &lt;list&gt;
 84  
  * &lt;value&gt;jms://customer.support&lt;/value&gt;
 85  
  * &lt;value&gt;pop3://support:123456@mail.mycompany.com&lt;/value&gt;
 86  
  * &lt;/list&gt;
 87  
  * &lt;/property&gt;
 88  
  * &lt;/bean&gt;
 89  
  * </code>
 90  
  * <p/> Endpoints are specified as a Mule Url which is used to register a listener
 91  
  * for the subscription In the previous version of the MuleEventMulticaster it was
 92  
  * possible to specify wildcard endpoints. This is still possible but you need to
 93  
  * tell the multicaster which specific endpoints to listen on and then your
 94  
  * subscription listeners can use wildcards. To register the specific endpoints on
 95  
  * the Event Multicaster you use the <i>subscriptions</i> property. <p/> <code>
 96  
  * &lt;bean id="applicationEventMulticaster" class="org.mule.extras.spring.events.MuleEventMulticaster"&gt;
 97  
  * &lt;property name="subscriptions"&gt;
 98  
  * &lt;list&gt;
 99  
  * &lt;value&gt;jms://orders.queue&lt;/value&gt;
 100  
  * &lt;value&gt;jms://another.orders.queue&lt;/value&gt;
 101  
  * &lt;/list&gt;
 102  
  * &lt;/property&gt;
 103  
  * &lt;/bean&gt;
 104  
  * <p/>
 105  
  * &lt;bean id="myListener" class="com.foo.MyListener"&gt;
 106  
  * &lt;property name="subscriptions"&gt;
 107  
  * &lt;list&gt;
 108  
  * &lt;value&gt;jms://*.orders.*.&lt;/value&gt;
 109  
  * &lt;/list&gt;
 110  
  * &lt;/property&gt;
 111  
  * &lt;/bean&gt;
 112  
  * <p/>
 113  
  * </code>
 114  
  * 
 115  
  * @see MuleEventListener
 116  
  * @see MuleSubscriptionEventListener
 117  
  * @see ApplicationEventMulticaster
 118  
  */
 119  
 
 120  58
 public class MuleEventMulticaster implements ApplicationEventMulticaster, ApplicationContextAware, DisposableBean
 121  
 {
 122  
     public static final String EVENT_MULTICASTER_DESCRIPTOR_NAME = "muleEventMulticasterDescriptor";
 123  
 
 124  
     /**
 125  
      * logger used by this class
 126  
      */
 127  16
     protected static final Log logger = LogFactory.getLog(MuleEventMulticaster.class);
 128  
 
 129  
     /**
 130  
      * The set of listeners for this Multicaster
 131  
      */
 132  58
     protected final Set listeners = new CopyOnWriteArraySet();
 133  
 
 134  
     /**
 135  
      * Determines whether events will be processed asynchronously
 136  
      */
 137  58
     protected boolean asynchronous = false;
 138  
 
 139  
     /**
 140  
      * An ExecutorService for handling asynchronous events
 141  
      */
 142  58
     protected ExecutorService asyncPool = null;
 143  
 
 144  
     /**
 145  
      * Any logical endpointUri mappings to register with mule. These allow for
 146  
      * friendly names to be used in place of urls i.e. email-orders ->
 147  
      * smtp://orders:password@restaurant.com
 148  
      */
 149  58
     protected Map endpointMappings = null;
 150  
 
 151  
     /**
 152  
      * A list of endpoints the eventMulticaster will receive events on Note that if
 153  
      * this eventMulticaster has a Mule Descriptor associated with it, these
 154  
      * endpoints are ignored and the ones on the Mule Descriptor are used. These are
 155  
      * here for convenience, the event multicaster will use these to create a default
 156  
      * MuleDescriptor for itself at runtime
 157  
      */
 158  58
     protected String[] subscriptions = null;
 159  
 
 160  
     /**
 161  
      * The Spring acpplication context
 162  
      */
 163  
     protected ApplicationContext applicationContext;
 164  
 
 165  
     /**
 166  
      * The Mule descriptor that belongs to this component instnace in Mule
 167  
      */
 168  
     protected UMODescriptor descriptor;
 169  
 
 170  
     /**
 171  
      * The mule instance compoennt for the Multicaster
 172  
      */
 173  
     protected UMOComponent component;
 174  
 
 175  
     /**
 176  
      * The filter used to match subscriptions
 177  
      */
 178  58
     protected Class subscriptionFilter = WildcardFilter.class;
 179  
 
 180  
     /**
 181  
      * Used to store parsed endpoints
 182  
      */
 183  58
     protected ExceptionListener exceptionListener = new LoggingExceptionListener();
 184  
 
 185  
     /**
 186  
      * Adds a listener to the the Multicaster. If asynchronous is set to true, an
 187  
      * <code>AsynchronousMessageListener</code> is used to wrap the listener. This
 188  
      * listener will be initialised with a threadpool. The configuration for the
 189  
      * threadpool can be set on this multicaster or inherited from the MuleManager
 190  
      * configuration, which is good for most cases.
 191  
      * 
 192  
      * @param listener the ApplicationListener to register with this Multicaster
 193  
      * @see AsynchronousEventListener
 194  
      * @see ThreadingProfile
 195  
      */
 196  
     public void addApplicationListener(ApplicationListener listener)
 197  
     {
 198  292
         Object listenerToAdd = listener;
 199  
 
 200  292
         if (asynchronous)
 201  
         {
 202  94
             listenerToAdd = new AsynchronousEventListener(asyncPool, listener);
 203  
         }
 204  
 
 205  292
         listeners.add(listenerToAdd);
 206  292
     }
 207  
 
 208  
     /**
 209  
      * Removes a listener from the multicaster
 210  
      * 
 211  
      * @param listener the listener to remove
 212  
      */
 213  
     public void removeApplicationListener(ApplicationListener listener)
 214  
     {
 215  6
         for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
 216  
         {
 217  6
             ApplicationListener applicationListener = (ApplicationListener)iterator.next();
 218  6
             if (applicationListener instanceof AsynchronousEventListener)
 219  
             {
 220  2
                 if (((AsynchronousEventListener)applicationListener).getListener().equals(listener))
 221  
                 {
 222  2
                     listeners.remove(applicationListener);
 223  2
                     return;
 224  
                 }
 225  
             }
 226  
             else
 227  
             {
 228  4
                 if (applicationListener.equals(listener))
 229  
                 {
 230  4
                     listeners.remove(applicationListener);
 231  4
                     return;
 232  
                 }
 233  
             }
 234  0
         }
 235  0
         listeners.remove(listener);
 236  0
     }
 237  
 
 238  
     /**
 239  
      * Removes all the listeners from the multicaster
 240  
      */
 241  
     public void removeAllListeners()
 242  
     {
 243  6
         listeners.clear();
 244  6
     }
 245  
 
 246  
     /**
 247  
      * Method is used to dispatch events to listeners registered with the
 248  
      * EventManager or dispatches events to Mule depending on the type and state of
 249  
      * the event received. If the event is not a Mule event it will be dispatched to
 250  
      * any listeners registered that are NOT MuleEventListeners. If the event is a
 251  
      * Mule event and there is no source event attached to it, it is assumed that the
 252  
      * event was dispatched by an object in the context using context.publishEvent()
 253  
      * and will be dispatched by Mule. If the event does have a source event attached
 254  
      * to it, it is assumed that the event was dispatched by Mule and will be
 255  
      * delivered to any listeners subscribed to the event.
 256  
      * 
 257  
      * @param e application event received by the context
 258  
      */
 259  
     public void multicastEvent(ApplicationEvent e)
 260  
     {
 261  466
         MuleApplicationEvent muleEvent = null;
 262  
         // if the context gets refreshed we need to reinitialise
 263  466
         if (e instanceof ContextRefreshedEvent)
 264  
         {
 265  
             // If the manager is being initialised from another context
 266  
             // don't try and initialise Mule
 267  58
             if (MuleManager.isInstanciated() && !MuleManager.getInstance().isInitialised())
 268  
             {
 269  
                 try
 270  
                 {
 271  2
                     registerMulticasterDescriptor();
 272  
                 }
 273  0
                 catch (UMOException ex)
 274  
                 {
 275  0
                     throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), ex);
 276  2
                 }
 277  
             }
 278  
             else
 279  
             {
 280  56
                 initMule();
 281  
             }
 282  
         }
 283  408
         else if (e instanceof ContextClosedEvent)
 284  
         {
 285  52
             MuleManager.getInstance().dispose();
 286  52
             return;
 287  
         }
 288  356
         else if (e instanceof MuleApplicationEvent)
 289  
         {
 290  346
             muleEvent = (MuleApplicationEvent)e;
 291  
             // If there is no Mule event the event didn't originate from Mule
 292  
             // so its an outbound event
 293  346
             if (muleEvent.getMuleEventContext() == null)
 294  
             {
 295  
                 try
 296  
                 {
 297  126
                     dispatchEvent(muleEvent);
 298  
                 }
 299  0
                 catch (ApplicationEventException e1)
 300  
                 {
 301  0
                     exceptionListener.exceptionThrown(e1);
 302  126
                 }
 303  126
                 return;
 304  
             }
 305  
         }
 306  
 
 307  288
         for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
 308  
         {
 309  1394
             ApplicationListener listener = (ApplicationListener)iterator.next();
 310  1394
             if (muleEvent != null)
 311  
             {
 312  
                 // As the asynchronous listener wraps the real listener we need to
 313  
                 // check the
 314  
                 // type of the wrapped listener, but invoke the Async listener
 315  1064
                 if (listener instanceof AsynchronousEventListener)
 316  
                 {
 317  348
                     AsynchronousEventListener asyncListener = (AsynchronousEventListener)listener;
 318  348
                     if (asyncListener.getListener() instanceof MuleSubscriptionEventListener)
 319  
                     {
 320  138
                         if (isSubscriptionMatch(muleEvent.getEndpoint(),
 321  
                             ((MuleSubscriptionEventListener)asyncListener.getListener()).getSubscriptions()))
 322  
                         {
 323  68
                             asyncListener.onApplicationEvent(muleEvent);
 324  
                         }
 325  
                     }
 326  210
                     else if (asyncListener.getListener() instanceof MuleEventListener)
 327  
                     {
 328  140
                         asyncListener.onApplicationEvent(muleEvent);
 329  
                     }
 330  70
                     else if (!(asyncListener.getListener() instanceof MuleEventListener))
 331  
                     {
 332  70
                         asyncListener.onApplicationEvent(e);
 333  
                     }
 334  
                     // Synchronous Event listener Checks
 335  348
                 }
 336  716
                 else if (listener instanceof MuleSubscriptionEventListener)
 337  
                 {
 338  284
                     if (isSubscriptionMatch(muleEvent.getEndpoint(),
 339  
                         ((MuleSubscriptionEventListener)listener).getSubscriptions()))
 340  
                     {
 341  140
                         listener.onApplicationEvent(muleEvent);
 342  
                     }
 343  
                 }
 344  432
                 else if (listener instanceof MuleEventListener)
 345  
                 {
 346  288
                     listener.onApplicationEvent(muleEvent);
 347  
                 }
 348  
             }
 349  330
             else if (listener instanceof AsynchronousEventListener
 350  
                      && !(((AsynchronousEventListener)listener).getListener() instanceof MuleEventListener))
 351  
             {
 352  20
                 listener.onApplicationEvent(e);
 353  
             }
 354  310
             else if (!(listener instanceof MuleEventListener))
 355  
             {
 356  46
                 listener.onApplicationEvent(e);
 357  
             }
 358  
             else
 359  
             {
 360  
                 // Finally only propagate the Application event if the
 361  
                 // ApplicationEvent interface is explicitly implemented
 362  608
                 for (int i = 0; i < listener.getClass().getInterfaces().length; i++)
 363  
                 {
 364  390
                     if (listener.getClass().getInterfaces()[i].equals(ApplicationListener.class))
 365  
                     {
 366  46
                         listener.onApplicationEvent(e);
 367  46
                         break;
 368  
                     }
 369  
                 }
 370  
 
 371  
             }
 372  1394
         }
 373  288
     }
 374  
 
 375  
     /**
 376  
      * Matches a subscription to the current event endpointUri
 377  
      * 
 378  
      * @param endpoint
 379  
      * @param subscriptions
 380  
      * @return
 381  
      */
 382  
     private boolean isSubscriptionMatch(String endpoint, String[] subscriptions)
 383  
     {
 384  636
         for (int i = 0; i < subscriptions.length; i++)
 385  
         {
 386  422
             String subscription = MapUtils.getString(MuleManager.getInstance().getEndpointIdentifiers(),
 387  
                 subscriptions[i], subscriptions[i]);
 388  
 
 389  
             // Subscriptions can be full Mule Urls or resource specific such as
 390  
             // my.queue
 391  
             // if it is a MuleEndpointURI we need to extract the Resource
 392  
             // specific part
 393  
             // if (MuleEndpointURI.isMuleUri(subscription)) {
 394  
             // UMOEndpointURI ep = (UMOEndpointURI) endpointsCache.get(subscription);
 395  
             // if (ep == null) {
 396  
             // try {
 397  
             // ep = new MuleEndpointURI(subscription);
 398  
             // } catch (MalformedEndpointException e) {
 399  
             // throw new IllegalArgumentException(e.getMessage());
 400  
             // }
 401  
             // endpointsCache.put(subscription, ep);
 402  
             // }
 403  
             // subscription = ep.getAddress();
 404  
             // }
 405  
 
 406  422
             ObjectFilter filter = createFilter(subscription);
 407  422
             if (filter.accept(endpoint))
 408  
             {
 409  208
                 return true;
 410  
             }
 411  
         }
 412  214
         return false;
 413  
     }
 414  
 
 415  
     /**
 416  
      * Determines whether events will be processed asynchronously
 417  
      * 
 418  
      * @return tru if asynchronous. The default is false
 419  
      */
 420  
     public boolean isAsynchronous()
 421  
     {
 422  0
         return asynchronous;
 423  
     }
 424  
 
 425  
     /**
 426  
      * Determines whether events will be processed asynchronously
 427  
      * 
 428  
      * @param asynchronous true if aysnchronous
 429  
      */
 430  
     public void setAsynchronous(boolean asynchronous)
 431  
     {
 432  18
         this.asynchronous = asynchronous;
 433  18
         if (asynchronous)
 434  
         {
 435  18
             if (asyncPool == null)
 436  
             {
 437  18
                 asyncPool = MuleManager.getConfiguration().getDefaultThreadingProfile().createPool(
 438  
                     "spring-events");
 439  
             }
 440  
         }
 441  
         else
 442  
         {
 443  0
             if (asyncPool != null)
 444  
             {
 445  0
                 asyncPool.shutdown();
 446  0
                 asyncPool = null;
 447  
             }
 448  
         }
 449  18
     }
 450  
 
 451  
     /**
 452  
      * This is the callback method used by Mule to give Mule events to this
 453  
      * Multicaster
 454  
      * 
 455  
      * @param context the context received by Mule
 456  
      */
 457  
     public void onMuleEvent(UMOEventContext context) throws TransformerException, MalformedEndpointException
 458  
     {
 459  220
         multicastEvent(new MuleApplicationEvent(context.getTransformedMessage(), context, applicationContext));
 460  220
         context.setStopFurtherProcessing(true);
 461  220
     }
 462  
 
 463  
     /**
 464  
      * Will dispatch an application event through Mule
 465  
      * 
 466  
      * @param applicationEvent the Spring event to be dispatched
 467  
      * @throws ApplicationEventException if the event cannot be dispatched i.e. if
 468  
      *             the underlying transport throws an exception
 469  
      */
 470  
     protected void dispatchEvent(MuleApplicationEvent applicationEvent) throws ApplicationEventException
 471  
     {
 472  126
         UMOEndpoint endpoint = null;
 473  
         try
 474  
         {
 475  126
             endpoint = MuleEndpoint.getOrCreateEndpointForUri(applicationEvent.getEndpoint(),
 476  
                 UMOEndpoint.ENDPOINT_TYPE_SENDER);
 477  
         }
 478  0
         catch (UMOException e)
 479  
         {
 480  0
             throw new ApplicationEventException("Failed to get endpoint for endpointUri: "
 481  
                                                 + applicationEvent.getEndpoint(), e);
 482  126
         }
 483  126
         if (endpoint != null)
 484  
         {
 485  
             try
 486  
             {
 487  
                 // if (applicationEvent.getEndpoint() != null) {
 488  
                 // endpoint.setEndpointURI(applicationEvent.getEndpoint());
 489  
                 // }
 490  
 
 491  126
                 MuleMessage message = new MuleMessage(applicationEvent.getSource(),
 492  
                     applicationEvent.getProperties());
 493  
                 // has dispatch been triggered using beanFactory.publish()
 494  
                 // without a current event
 495  126
                 if (applicationEvent.getMuleEventContext() != null)
 496  
                 {
 497  
                     // tell mule not to try and route this event itself
 498  0
                     applicationEvent.getMuleEventContext().setStopFurtherProcessing(true);
 499  0
                     applicationEvent.getMuleEventContext().dispatchEvent(message, endpoint);
 500  
                 }
 501  
                 else
 502  
                 {
 503  126
                     UMOSession session = new MuleSession(message,
 504  
                         ((AbstractConnector)endpoint.getConnector()).getSessionHandler(), component);
 505  126
                     RequestContext.setEvent(new MuleEvent(message, endpoint, session, false));
 506  
                     // transform if necessary
 507  126
                     if (endpoint.getTransformer() != null)
 508  
                     {
 509  6
                         message = new MuleMessage(endpoint.getTransformer().transform(
 510  
                             applicationEvent.getSource()), applicationEvent.getProperties());
 511  
                     }
 512  126
                     endpoint.dispatch(new MuleEvent(message, endpoint, session, false));
 513  
                 }
 514  
             }
 515  0
             catch (Exception e1)
 516  
             {
 517  0
                 throw new ApplicationEventException("Failed to dispatch event: " + e1.getMessage(), e1);
 518  126
             }
 519  
         }
 520  
         else
 521  
         {
 522  0
             throw new ApplicationEventException("Failed endpoint using name: "
 523  
                                                 + applicationEvent.getEndpoint());
 524  
         }
 525  126
     }
 526  
 
 527  
     /**
 528  
      * Set the current Spring application context
 529  
      * 
 530  
      * @param applicationContext
 531  
      * @throws BeansException
 532  
      */
 533  
     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
 534  
     {
 535  58
         this.applicationContext = applicationContext;
 536  58
     }
 537  
 
 538  
     protected void initMule()
 539  
     {
 540  
         try
 541  
         {
 542  
             // endpointsCache.clear();
 543  
             // See if there has been a discriptor explicitly configured
 544  56
             if (applicationContext.containsBean(EVENT_MULTICASTER_DESCRIPTOR_NAME))
 545  
             {
 546  0
                 descriptor = (UMODescriptor)applicationContext.getBean(EVENT_MULTICASTER_DESCRIPTOR_NAME);
 547  
             }
 548  
             // If the mule manager has been initialised in the contain
 549  
             // there is not need to do anything here
 550  56
             if (applicationContext.containsBean("muleManager"))
 551  
             {
 552  
                 // Register the multicaster descriptor
 553  20
                 registerMulticasterDescriptor();
 554  20
                 return;
 555  
             }
 556  36
             UMOManager manager = MuleManager.getInstance();
 557  36
             Map map = applicationContext.getBeansOfType(MuleConfiguration.class);
 558  36
             if (map != null && map.size() > 0)
 559  
             {
 560  36
                 MuleManager.setConfiguration((MuleConfiguration)map.values().iterator().next());
 561  
             }
 562  36
             if (!manager.isStarted())
 563  
             {
 564  36
                 MuleManager.getConfiguration().setSynchronous(!asynchronous);
 565  
                 // register any endpointUri mappings
 566  36
                 registerEndpointMappings();
 567  
             }
 568  
             // tell mule to load component definitions from spring
 569  36
             SpringContainerContext containerContext = new SpringContainerContext();
 570  36
             containerContext.setBeanFactory(applicationContext);
 571  36
             manager.setContainerContext(null);
 572  36
             manager.setContainerContext(containerContext);
 573  
 
 574  
             // see if there are any UMOConnectors to register
 575  36
             registerConnectors();
 576  
 
 577  
             // Next see if there are any UMOTransformers to register
 578  36
             registerTransformers();
 579  
 
 580  36
             registerGlobalEndpoints();
 581  
 
 582  
             // Register the multicaster descriptor
 583  36
             registerMulticasterDescriptor();
 584  
 
 585  36
             if (!manager.isStarted())
 586  
             {
 587  36
                 manager.start();
 588  
             }
 589  
         }
 590  0
         catch (UMOException e)
 591  
         {
 592  0
             throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), e);
 593  36
         }
 594  36
     }
 595  
 
 596  
     protected void registerMulticasterDescriptor() throws UMOException
 597  
     {
 598  
         // A discriptor hasn't been explicitly configured, so create a default
 599  58
         if (descriptor == null)
 600  
         {
 601  58
             descriptor = getDefaultDescriptor();
 602  58
             setSubscriptionsOnDescriptor((MuleDescriptor)descriptor);
 603  58
             component = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL).registerComponent(descriptor);
 604  
         }
 605  58
     }
 606  
 
 607  
     protected void setSubscriptionsOnDescriptor(MuleDescriptor descriptor) throws UMOException
 608  
     {
 609  58
         List endpoints = new ArrayList();
 610  58
         for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
 611  
         {
 612  280
             ApplicationListener listener = (ApplicationListener)iterator.next();
 613  280
             if (listener instanceof AsynchronousEventListener)
 614  
             {
 615  90
                 listener = ((AsynchronousEventListener)listener).getListener();
 616  
             }
 617  280
             if (listener instanceof MuleSubscriptionEventListener)
 618  
             {
 619  112
                 String[] subscriptions = ((MuleSubscriptionEventListener)listener).getSubscriptions();
 620  224
                 for (int i = 0; i < subscriptions.length; i++)
 621  
                 {
 622  112
                     if (subscriptions[i].indexOf("*") == -1 && MuleEndpointURI.isMuleUri(subscriptions[i]))
 623  
                     {
 624  56
                         boolean isSoap = registerAsSoap(subscriptions[i], listener);
 625  
 
 626  56
                         if (!isSoap)
 627  
                         {
 628  56
                             endpoints.add(subscriptions[i]);
 629  
                         }
 630  
                     }
 631  
                 }
 632  
             }
 633  280
         }
 634  58
         if (endpoints.size() > 0)
 635  
         {
 636  56
             for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
 637  
             {
 638  56
                 String endpoint = (String)iterator.next();
 639  56
                 MuleEndpoint ep = new MuleEndpoint(endpoint, true);
 640  
 
 641  
                 // check whether the endpoint has already been set on the MuleEventMulticastor
 642  56
                 if (descriptor.getInboundRouter().getEndpoint(ep.getName()) == null)
 643  
                 {
 644  56
                     descriptor.getInboundRouter().addEndpoint(ep);
 645  
                 }
 646  56
             }
 647  
         }
 648  58
     }
 649  
 
 650  
     private boolean registerAsSoap(String endpoint, Object listener) throws UMOException
 651  
     {
 652  56
         if (endpoint.startsWith("glue") || endpoint.startsWith("soap") || endpoint.startsWith("axis"))
 653  
         {
 654  0
             UMOEndpointURI ep = new MuleEndpointURI(endpoint);
 655  0
             QuickConfigurationBuilder builder = new QuickConfigurationBuilder();
 656  
 
 657  
             // get the service name from the URI path
 658  0
             String serviceName = null;
 659  0
             if (ep.getPath() != null)
 660  
             {
 661  0
                 String path = ep.getPath();
 662  0
                 if (path.endsWith("/"))
 663  
                 {
 664  0
                     path = path.substring(0, path.length() - 1);
 665  
                 }
 666  0
                 int i = path.lastIndexOf("/");
 667  0
                 if (i > -1)
 668  
                 {
 669  0
                     serviceName = path.substring(i + 1);
 670  
                 }
 671  0
             }
 672  
             else
 673  
             {
 674  0
                 serviceName = descriptor.getName();
 675  
             }
 676  
             // now strip off the service name
 677  0
             String newEndpoint = endpoint;
 678  0
             int i = newEndpoint.indexOf(serviceName);
 679  0
             newEndpoint = newEndpoint.substring(0, i - 1);
 680  0
             builder.registerComponentInstance(listener, serviceName, new MuleEndpointURI(newEndpoint));
 681  0
             return true;
 682  
         }
 683  
         else
 684  
         {
 685  56
             return false;
 686  
         }
 687  
     }
 688  
 
 689  
     protected void registerEndpointMappings() throws InitialisationException
 690  
     {
 691  
         // register any endpointUri mappings
 692  36
         if (endpointMappings != null)
 693  
         {
 694  36
             Map.Entry entry = null;
 695  36
             for (Iterator iterator = endpointMappings.entrySet().iterator(); iterator.hasNext();)
 696  
             {
 697  36
                 entry = (Map.Entry)iterator.next();
 698  36
                 MuleManager.getInstance().registerEndpointIdentifier((String)entry.getKey(),
 699  
                     (String)entry.getValue());
 700  
             }
 701  
         }
 702  36
     }
 703  
 
 704  
     protected void registerConnectors() throws UMOException
 705  
     {
 706  36
         if (!MuleManager.getInstance().isInitialised())
 707  
         {
 708  
             // Next see if there are any UMOConnectors to register
 709  36
             Map connectors = applicationContext.getBeansOfType(UMOConnector.class, true, true);
 710  36
             if (connectors.size() > 0)
 711  
             {
 712  
                 Map.Entry entry;
 713  
                 UMOConnector c;
 714  0
                 for (Iterator iterator = connectors.entrySet().iterator(); iterator.hasNext();)
 715  
                 {
 716  0
                     entry = (Map.Entry)iterator.next();
 717  0
                     c = (UMOConnector)entry.getValue();
 718  0
                     if (c.getName() == null)
 719  
                     {
 720  0
                         c.setName(entry.getKey().toString());
 721  
                     }
 722  0
                     MuleManager.getInstance().registerConnector(c);
 723  
                 }
 724  
             }
 725  
         }
 726  36
     }
 727  
 
 728  
     protected void registerGlobalEndpoints() throws UMOException
 729  
     {
 730  36
         if (!MuleManager.getInstance().isInitialised())
 731  
         {
 732  
             // Next see if there are any UMOConnectors to register
 733  36
             Map endpoints = applicationContext.getBeansOfType(UMOEndpoint.class, true, true);
 734  36
             if (endpoints.size() > 0)
 735  
             {
 736  
                 Map.Entry entry;
 737  
                 UMOEndpoint endpoint;
 738  0
                 for (Iterator iterator = endpoints.entrySet().iterator(); iterator.hasNext();)
 739  
                 {
 740  0
                     entry = (Map.Entry)iterator.next();
 741  0
                     endpoint = (UMOEndpoint)entry.getValue();
 742  0
                     if (endpoint.getName() == null)
 743  
                     {
 744  0
                         endpoint.setName(entry.getKey().toString());
 745  
                     }
 746  0
                     MuleManager.getInstance().registerEndpoint(endpoint);
 747  
                 }
 748  
             }
 749  
         }
 750  36
     }
 751  
 
 752  
     protected void registerTransformers() throws UMOException
 753  
     {
 754  36
         if (!MuleManager.getInstance().isInitialised())
 755  
         {
 756  
             // Next see if there are any UMOConnectors to register
 757  36
             Map transformers = applicationContext.getBeansOfType(UMOTransformer.class, true, true);
 758  36
             if (transformers.size() > 0)
 759  
             {
 760  
                 Map.Entry entry;
 761  
                 UMOTransformer t;
 762  0
                 for (Iterator iterator = transformers.entrySet().iterator(); iterator.hasNext();)
 763  
                 {
 764  0
                     entry = (Map.Entry)iterator.next();
 765  0
                     t = (UMOTransformer)entry.getValue();
 766  0
                     if (t.getName() == null)
 767  
                     {
 768  0
                         t.setName(entry.getKey().toString());
 769  
                     }
 770  0
                     MuleManager.getInstance().registerTransformer(t);
 771  
                 }
 772  
             }
 773  
         }
 774  36
     }
 775  
 
 776  
     protected UMODescriptor getDefaultDescriptor() throws UMOException
 777  
     {
 778  
         // When the the beanFactory is refreshed all the beans get
 779  
         // reloaded so we need to unregister the component from Mule
 780  58
         UMOModel model = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL);
 781  58
         if(model==null)
 782  
         {
 783  0
             model = new SedaModel();
 784  0
             model.setName(ModelHelper.SYSTEM_MODEL);
 785  0
             MuleManager.getInstance().registerModel(model);
 786  
         }
 787  58
         UMODescriptor descriptor = model.getDescriptor(EVENT_MULTICASTER_DESCRIPTOR_NAME);
 788  58
         if (descriptor != null)
 789  
         {
 790  0
             model.unregisterComponent(descriptor);
 791  
         }
 792  58
         descriptor = new MuleDescriptor(EVENT_MULTICASTER_DESCRIPTOR_NAME);
 793  58
         if (subscriptions == null)
 794  
         {
 795  0
             logger.info("No receive endpoints have been set, using default '*'");
 796  0
             descriptor.setInboundEndpoint(new MuleEndpoint("vm://*", true));
 797  
         }
 798  
         else
 799  
         {
 800  
             // Set multiple inbound subscriptions on the descriptor
 801  58
             UMOInboundRouterCollection messageRouter = descriptor.getInboundRouter();
 802  
 
 803  116
             for (int i = 0; i < subscriptions.length; i++)
 804  
             {
 805  58
                 String subscription = subscriptions[i];
 806  58
                 UMOEndpointURI endpointUri = new MuleEndpointURI(subscription);
 807  58
                 UMOEndpoint endpoint = MuleEndpoint.getOrCreateEndpointForUri(endpointUri,
 808  
                     UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
 809  58
                 if (!asynchronous)
 810  
                 {
 811  40
                     endpoint.setSynchronous(true);
 812  
                 }
 813  58
                 messageRouter.addEndpoint(endpoint);
 814  
             }
 815  
         }
 816  
         // set the implementation name to this bean so Mule will manage it
 817  58
         descriptor.setImplementation(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
 818  58
         return descriptor;
 819  
     }
 820  
 
 821  
     protected ObjectFilter createFilter(String pattern)
 822  
     {
 823  
         try
 824  
         {
 825  422
             if (getSubscriptionFilter() == null)
 826  
             {
 827  0
                 setSubscriptionFilter(WildcardFilter.class);
 828  
             }
 829  422
             ObjectFilter filter = (ObjectFilter)ClassUtils.instanciateClass(getSubscriptionFilter(),
 830  
                 new Object[]{pattern});
 831  422
             return filter;
 832  
         }
 833  0
         catch (Exception e)
 834  
         {
 835  0
             exceptionListener.exceptionThrown(e);
 836  0
             return new WildcardFilter(pattern);
 837  
         }
 838  
     }
 839  
 
 840  
     /**
 841  
      * the type of filter used to filter subscriptions
 842  
      * 
 843  
      * @return the class of the filter to use. The default is WildcardFilter
 844  
      * @see WildcardFilter
 845  
      */
 846  
     public Class getSubscriptionFilter()
 847  
     {
 848  844
         return subscriptionFilter;
 849  
     }
 850  
 
 851  
     /**
 852  
      * sets the type of filter used to filter subscriptions
 853  
      * 
 854  
      * @param subscriptionFilter the class of the filter to use.
 855  
      */
 856  
     public void setSubscriptionFilter(Class subscriptionFilter)
 857  
     {
 858  0
         this.subscriptionFilter = subscriptionFilter;
 859  0
     }
 860  
 
 861  
     /**
 862  
      * Any logical endpointUri mappings to register with mule. These allow for
 863  
      * friendly names to be used in place of urls i.e. email-orders ->
 864  
      * smtp://orders:password@restaurant.com
 865  
      * 
 866  
      * @return endpointMappings a map of logical names and endpoiut url strings
 867  
      */
 868  
     public Map getEndpointMappings()
 869  
     {
 870  0
         return endpointMappings;
 871  
     }
 872  
 
 873  
     /**
 874  
      * Any logical endpointUri mappings to register with mule. These allow for
 875  
      * friendly names to be used in place of urls i.e. email-orders ->
 876  
      * smtp://orders:password@restaurant.com
 877  
      * 
 878  
      * @param endpointMappings a map of logical names and endpoiut url strings
 879  
      */
 880  
     public void setEndpointMappings(Map endpointMappings)
 881  
     {
 882  56
         this.endpointMappings = endpointMappings;
 883  56
     }
 884  
 
 885  
     /**
 886  
      * A list of endpoints the eventMulticaster will receive events on Note that if
 887  
      * this eventMulticaster has a Mule Descriptor associated with it, these
 888  
      * endpoints are ignored and the ones on the Mule Descriptor are used. These are
 889  
      * here for convenience, the event multicaster will use these to create a default
 890  
      * MuleDescriptor for itself at runtime
 891  
      * 
 892  
      * @return endpoints List being listened on
 893  
      */
 894  
     public String[] getSubscriptions()
 895  
     {
 896  0
         return subscriptions;
 897  
     }
 898  
 
 899  
     /**
 900  
      * A list of endpoints the eventMulticaster will receive events on Note that if
 901  
      * this eventMulticaster has a Mule Descriptor associated with it, these
 902  
      * endpoints are ignored and the ones on the Mule Descriptor are used. These are
 903  
      * here for convenience, the event multicaster will use these to create a default
 904  
      * MuleDescriptor for itself at runtime
 905  
      * 
 906  
      * @param subscriptions a list of enpoints to listen on
 907  
      */
 908  
     public void setSubscriptions(String[] subscriptions)
 909  
     {
 910  58
         this.subscriptions = subscriptions;
 911  58
     }
 912  
 
 913  
     protected void setExceptionListener(ExceptionListener listener)
 914  
     {
 915  0
         if (listener != null)
 916  
         {
 917  0
             this.exceptionListener = listener;
 918  
         }
 919  
         else
 920  
         {
 921  0
             throw new IllegalArgumentException("exceptionListener may not be null");
 922  
         }
 923  0
     }
 924  
 
 925  58
     private class LoggingExceptionListener implements ExceptionListener
 926  
     {
 927  
         public void exceptionThrown(Exception e)
 928  
         {
 929  0
             logger.error(e.getMessage(), e);
 930  0
         }
 931  
     }
 932  
 
 933  
 
 934  
     public void destroy() throws Exception
 935  
     {
 936  58
         MuleManager.getInstance().dispose();
 937  58
     }
 938  
 }