Coverage Report - org.mule.extras.client.MuleClient
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleClient
0%
0/227
0%
0/82
2.543
MuleClient$1
0%
0/2
N/A
2.543
MuleClient$2
0%
0/2
N/A
2.543
 
 1  
 /*
 2  
  * $Id: MuleClient.java 10228 2008-01-05 03:15:38Z 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.client;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.config.ConfigurationBuilder;
 15  
 import org.mule.config.ConfigurationException;
 16  
 import org.mule.config.MuleConfiguration;
 17  
 import org.mule.config.MuleProperties;
 18  
 import org.mule.config.builders.MuleXmlConfigurationBuilder;
 19  
 import org.mule.config.builders.QuickConfigurationBuilder;
 20  
 import org.mule.config.i18n.CoreMessages;
 21  
 import org.mule.extras.client.i18n.ClientMessages;
 22  
 import org.mule.impl.MuleEvent;
 23  
 import org.mule.impl.MuleMessage;
 24  
 import org.mule.impl.MuleSession;
 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.security.MuleCredentials;
 29  
 import org.mule.providers.AbstractConnector;
 30  
 import org.mule.providers.service.TransportFactory;
 31  
 import org.mule.umo.FutureMessageResult;
 32  
 import org.mule.umo.MessagingException;
 33  
 import org.mule.umo.UMODescriptor;
 34  
 import org.mule.umo.UMOEvent;
 35  
 import org.mule.umo.UMOException;
 36  
 import org.mule.umo.UMOMessage;
 37  
 import org.mule.umo.UMOSession;
 38  
 import org.mule.umo.endpoint.UMOEndpoint;
 39  
 import org.mule.umo.endpoint.UMOEndpointURI;
 40  
 import org.mule.umo.lifecycle.Disposable;
 41  
 import org.mule.umo.manager.UMOManager;
 42  
 import org.mule.umo.provider.DispatchException;
 43  
 import org.mule.umo.provider.ReceiveException;
 44  
 import org.mule.umo.provider.UMOConnector;
 45  
 import org.mule.umo.provider.UMOStreamMessageAdapter;
 46  
 import org.mule.umo.transformer.UMOTransformer;
 47  
 import org.mule.util.MuleObjectHelper;
 48  
 import org.mule.util.StringUtils;
 49  
 
 50  
 import java.util.ArrayList;
 51  
 import java.util.HashMap;
 52  
 import java.util.Iterator;
 53  
 import java.util.List;
 54  
 import java.util.Map;
 55  
 
 56  
 import edu.emory.mathcs.backport.java.util.concurrent.Callable;
 57  
 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
 58  
 
 59  
 import org.apache.commons.logging.Log;
 60  
 import org.apache.commons.logging.LogFactory;
 61  
 
 62  
 /**
 63  
  * <code>MuleClient</code> is a simple interface for Mule clients to send and
 64  
  * receive events from a Mule Server. In most Mule applications events are triggered
 65  
  * by some external occurrence such as a message being received on a queue or file
 66  
  * being copied to a directory. The Mule client allows the user to send and receive
 67  
  * events programmatically through its Api.
 68  
  * <p>
 69  
  * The client defines a UMOEndpointURI which is used to determine how a message is
 70  
  * sent of received. The url defines the protocol, the endpointUri destination of the
 71  
  * message and optionally the endpoint to use when dispatching the event. For
 72  
  * example:
 73  
  * <p>
 74  
  * <code>vm://my.object</code> dispatches to a <code>my.object</code> destination
 75  
  * using the VM endpoint. There needs to be a global VM endpoint registered for the
 76  
  * message to be sent.
 77  
  * <p>
 78  
  * <code>jms://jmsProvider/orders.topic</code> dispatches a JMS message via the
 79  
  * globally registered jmsProvider over a topic destination called
 80  
  * <code>orders.topic</code>.
 81  
  * <p>
 82  
  * <code>jms://orders.topic</code> is equivalent to the above except that the
 83  
  * endpoint is determined by the protocol, so the first JMS endpoint is used.
 84  
  * <p>
 85  
  * Note that there must be a configured MuleManager for this client to work. It will
 86  
  * use the one available using <code>MuleManager.getInstance()</code>
 87  
  * 
 88  
  * @see org.mule.impl.endpoint.MuleEndpointURI
 89  
  */
 90  
 public class MuleClient implements Disposable
 91  
 {
 92  
     /**
 93  
      * logger used by this class
 94  
      */
 95  0
     protected static final Log logger = LogFactory.getLog(MuleClient.class);
 96  
 
 97  
     /**
 98  
      * the local UMOManager instance
 99  
      */
 100  
     private UMOManager manager;
 101  
 
 102  
     /**
 103  
      * an Executor for async messages (optional), currently always delegated to
 104  
      * MuleManager's default WorkManager
 105  
      */
 106  0
     private Executor asyncExecutor = null;
 107  
 
 108  0
     private List dispatchers = new ArrayList();
 109  
 
 110  
     // configuration helper for the client
 111  0
     QuickConfigurationBuilder builder = null;
 112  
 
 113  
     private MuleCredentials user;
 114  
 
 115  
     /**
 116  
      * Creates a default Mule client that will use the default serverEndpoint to
 117  
      * connect to a remote server instance.
 118  
      * 
 119  
      * @throws UMOException
 120  
      */
 121  
     public MuleClient() throws UMOException
 122  0
     {
 123  0
         init(/* startManager */true);
 124  0
     }
 125  
 
 126  
     /**
 127  
      * Creates a default Mule client that will use the default serverEndpoint to
 128  
      * connect to a remote server instance.
 129  
      * 
 130  
      * @param startManager start the Mule Manager if it has not yet been initialised
 131  
      * @throws UMOException
 132  
      */
 133  
     public MuleClient(boolean startManager) throws UMOException
 134  0
     {
 135  0
         init(startManager);
 136  0
     }
 137  
 
 138  
     /**
 139  
      * Configures a Mule CLient instance using the the default
 140  
      * MuleXmlConfigurationBuilder to parse the config resources
 141  
      * 
 142  
      * @param configResources a config resource location to configure this client
 143  
      *            with
 144  
      * @throws ConfigurationException is there is a MuleManager instance already
 145  
      *             running in this JVM or if the builder fails to configure the
 146  
      *             Manager
 147  
      */
 148  
     public MuleClient(String configResources) throws UMOException
 149  
     {
 150  0
         this(configResources, new MuleXmlConfigurationBuilder());
 151  0
     }
 152  
 
 153  
     /**
 154  
      * Configures a new MuleClient and either uses an existing Manager running in
 155  
      * this JVM or creates a new empty manager
 156  
      * 
 157  
      * @param user the username to use when connecting to a remote server instance
 158  
      * @param password the password for the user
 159  
      * @throws UMOException
 160  
      */
 161  
     public MuleClient(String user, String password) throws UMOException
 162  0
     {
 163  0
         init(/* startManager */true);
 164  0
         this.user = new MuleCredentials(user, password.toCharArray());
 165  0
     }
 166  
 
 167  
     /**
 168  
      * Configures a Mule Client instance
 169  
      * 
 170  
      * @param configResources a config resource location to configure this client
 171  
      *            with
 172  
      * @param builder the configuration builder to use
 173  
      * @throws ConfigurationException is there is a MuleManager instance already
 174  
      *             running in this JVM or if the builder fails to configure the
 175  
      *             Manager
 176  
      */
 177  
     public MuleClient(String configResources, ConfigurationBuilder builder) throws ConfigurationException
 178  0
     {
 179  0
         if (MuleManager.isInstanciated())
 180  
         {
 181  0
             throw new ConfigurationException(ClientMessages.managerIsAlreadyConfigured());
 182  
         }
 183  0
         if (builder == null)
 184  
         {
 185  0
             logger.info("Builder passed in was null, using default builder: "
 186  
                         + MuleXmlConfigurationBuilder.class.getName());
 187  0
             builder = new MuleXmlConfigurationBuilder();
 188  
         }
 189  0
         manager = builder.configure(configResources, null);
 190  0
     }
 191  
 
 192  
     /**
 193  
      * Configures a Mule Client instance
 194  
      * 
 195  
      * @param configResources a config resource location to configure this client
 196  
      *            with
 197  
      * @param builder the configuration builder to use
 198  
      * @param user the username to use when connecting to a remote server instance
 199  
      * @param password the password for the user
 200  
      * @throws ConfigurationException is there is a MuleManager instance already
 201  
      *             running in this JVM or if the builder fails to configure the
 202  
      *             Manager
 203  
      */
 204  
     public MuleClient(String configResources, ConfigurationBuilder builder, String user, String password)
 205  
         throws ConfigurationException
 206  
     {
 207  0
         this(configResources, builder);
 208  0
         this.user = new MuleCredentials(user, password.toCharArray());
 209  0
     }
 210  
 
 211  
     /**
 212  
      * Initialises a default MuleManager for use by the client.
 213  
      * 
 214  
      * @param startManager start the Mule Manager if it has not yet been initialised
 215  
      * @throws UMOException
 216  
      */
 217  
     private void init(boolean startManager) throws UMOException
 218  
     {
 219  
         // if we are creating a server for this client then set client mode
 220  
         // this will disable Admin connections by default;
 221  
         // If there is no local manager present create a default manager
 222  0
         if (MuleManager.isInstanciated())
 223  
         {
 224  0
             if (logger.isInfoEnabled())
 225  
             {
 226  0
                 logger.info("There is already a manager locally available to this client, no need to create a new one");
 227  
             }
 228  
         }
 229  
         else
 230  
         {
 231  0
             MuleManager.getConfiguration().setClientMode(true);
 232  0
             if (logger.isInfoEnabled())
 233  
             {
 234  0
                 logger.info("There is no manager instance locally available for this client, creating a new Manager");
 235  
             }
 236  
         }
 237  
 
 238  0
         manager = MuleManager.getInstance();
 239  0
         asyncExecutor = manager.getWorkManager();
 240  0
         builder = new QuickConfigurationBuilder();
 241  
 
 242  0
         if (!manager.isInitialised() && startManager == true)
 243  
         {
 244  0
             if (logger.isInfoEnabled()) logger.info("Starting Mule Manager for this client");
 245  0
             ((MuleManager)manager).start();
 246  
         }
 247  0
     }
 248  
 
 249  
     /**
 250  
      * Dispatches an event asynchronously to a endpointUri via a mule server. the Url
 251  
      * determines where to dispathc the event to, this can be in the form of
 252  
      * 
 253  
      * @param url the Mule url used to determine the destination and transport of the
 254  
      *            message
 255  
      * @param payload the object that is the payload of the event
 256  
      * @param messageProperties any properties to be associated with the payload. In
 257  
      *            the case of Jms you could set the JMSReplyTo property in these
 258  
      *            properties.
 259  
      * @throws org.mule.umo.UMOException
 260  
      */
 261  
     public void dispatch(String url, Object payload, Map messageProperties) throws UMOException
 262  
     {
 263  0
         dispatch(url, new MuleMessage(payload, messageProperties));
 264  0
     }
 265  
 
 266  
     /**
 267  
      * Dispatches an event asynchronously to a endpointUri via a mule server. the Url
 268  
      * determines where to dispathc the event to, this can be in the form of
 269  
      * 
 270  
      * @param url the Mule url used to determine the destination and transport of the
 271  
      *            message
 272  
      * @param message the message to send
 273  
      * @throws org.mule.umo.UMOException
 274  
      */
 275  
     public void dispatch(String url, UMOMessage message) throws UMOException
 276  
     {
 277  0
         UMOEvent event = getEvent(message, url, false, false);
 278  
         try
 279  
         {
 280  0
             event.getSession().dispatchEvent(event);
 281  
         }
 282  0
         catch (UMOException e)
 283  
         {
 284  0
             throw e;
 285  
         }
 286  0
         catch (Exception e)
 287  
         {
 288  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 289  
                 event.getMessage(), event.getEndpoint(), e);
 290  0
         }
 291  0
     }
 292  
 
 293  
     /**
 294  
      * Dispatches a Stream event asynchronously to a endpointUri via a mule server.
 295  
      * the Url determines where to dispathc the event to, this can be in the form of
 296  
      * 
 297  
      * @param url the Mule url used to determine the destination and transport of the
 298  
      *            message
 299  
      * @param message the message to send
 300  
      * @throws org.mule.umo.UMOException
 301  
      */
 302  
     public void dispatchStream(String url, UMOStreamMessageAdapter message) throws UMOException
 303  
     {
 304  0
         UMOEvent event = getEvent(new MuleMessage(message), url, false, true);
 305  
         try
 306  
         {
 307  0
             event.getSession().dispatchEvent(event);
 308  
         }
 309  0
         catch (UMOException e)
 310  
         {
 311  0
             throw e;
 312  
         }
 313  0
         catch (Exception e)
 314  
         {
 315  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 316  
                 event.getMessage(), event.getEndpoint(), e);
 317  0
         }
 318  0
     }
 319  
 
 320  
     public UMOStreamMessageAdapter sendStream(String url, UMOStreamMessageAdapter message)
 321  
         throws UMOException
 322  
     {
 323  0
         return sendStream(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 324  
     }
 325  
 
 326  
     /**
 327  
      * Sends a streaming event synchronously to a endpointUri via a mule server and a
 328  
      * resulting stream is set on the passed Stream Mesage Adapter.
 329  
      * 
 330  
      * @param url the Mule url used to determine the destination and transport of the
 331  
      *            message
 332  
      * @param message The message to send
 333  
      * @param timeout The time in milliseconds the the call should block waiting for
 334  
      *            a response
 335  
      * @throws org.mule.umo.UMOException
 336  
      */
 337  
     public UMOStreamMessageAdapter sendStream(String url, UMOStreamMessageAdapter message, int timeout)
 338  
         throws UMOException
 339  
     {
 340  0
         UMOEvent event = getEvent(new MuleMessage(message), url, true, true);
 341  0
         event.setTimeout(timeout);
 342  
         try
 343  
         {
 344  0
             UMOMessage result = event.getSession().sendEvent(event);
 345  0
             if (result != null)
 346  
             {
 347  0
                 if (result.getAdapter() instanceof UMOStreamMessageAdapter)
 348  
                 {
 349  0
                     return (UMOStreamMessageAdapter)result.getAdapter();
 350  
                 }
 351  
                 else
 352  
                 {
 353  
                     // todo i18n (though this case should never happen...)
 354  0
                     throw new IllegalStateException(
 355  
                         "Mismatch of stream states. A stream was used for outbound channel, but a stream was not used for the response");
 356  
                 }
 357  
             }
 358  
         }
 359  0
         catch (UMOException e)
 360  
         {
 361  0
             throw e;
 362  
         }
 363  0
         catch (Exception e)
 364  
         {
 365  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 366  
                 event.getMessage(), event.getEndpoint(), e);
 367  0
         }
 368  0
         return null;
 369  
     }
 370  
 
 371  
     /**
 372  
      * sends an event synchronously to a components
 373  
      * 
 374  
      * @param component the name of the Mule components to send to
 375  
      * @param transformers a comma separated list of transformers to apply to the
 376  
      *            result message
 377  
      * @param payload the object that is the payload of the event
 378  
      * @param messageProperties any properties to be associated with the payload. as
 379  
      *            null
 380  
      * @return the result message if any of the invocation
 381  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 382  
      *             transfromers cannot be found
 383  
      */
 384  
     public UMOMessage sendDirect(String component, String transformers, Object payload, Map messageProperties)
 385  
         throws UMOException
 386  
     {
 387  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 388  0
         return sendDirect(component, transformers, message);
 389  
     }
 390  
 
 391  
     /**
 392  
      * sends an event synchronously to a components
 393  
      * 
 394  
      * @param component the name of the Mule components to send to
 395  
      * @param transformers a comma separated list of transformers to apply to the
 396  
      *            result message
 397  
      * @param message the message to send
 398  
      * @return the result message if any of the invocation
 399  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 400  
      *             transfromers cannot be found
 401  
      */
 402  
     public UMOMessage sendDirect(String component, String transformers, UMOMessage message)
 403  
         throws UMOException
 404  
     {
 405  0
         boolean compregistered = ModelHelper.isComponentRegistered(component);
 406  0
         if (!compregistered)
 407  
         {
 408  0
             throw new MessagingException(
 409  
                 CoreMessages.objectNotRegisteredWithManager("Component '" + component + "'"), 
 410  
                 message);
 411  
         }
 412  0
         UMOTransformer trans = null;
 413  0
         if (transformers != null)
 414  
         {
 415  0
             trans = MuleObjectHelper.getTransformer(transformers, ",");
 416  
         }
 417  
 
 418  0
         if (!MuleManager.getConfiguration().isSynchronous())
 419  
         {
 420  0
             logger.warn("The mule manager is running synchronously, a null message payload will be returned");
 421  
         }
 422  0
         UMOSession session = new MuleSession(ModelHelper.getComponent(component));
 423  0
         UMOEndpoint endpoint = getDefaultClientEndpoint(session.getComponent().getDescriptor(),
 424  
             message.getPayload());
 425  0
         UMOEvent event = new MuleEvent(message, endpoint, session, true);
 426  
 
 427  0
         if (logger.isDebugEnabled())
 428  
         {
 429  0
             logger.debug("MuleClient sending event direct to: " + component + ". Event is: " + event);
 430  
         }
 431  
 
 432  0
         UMOMessage result = event.getComponent().sendEvent(event);
 433  
 
 434  0
         if (logger.isDebugEnabled())
 435  
         {
 436  0
             logger.debug("Result of MuleClient sendDirect is: "
 437  
                          + (result == null ? "null" : result.getPayload()));
 438  
         }
 439  
 
 440  0
         if (result != null && trans != null)
 441  
         {
 442  0
             return new MuleMessage(trans.transform(result.getPayload()));
 443  
         }
 444  
         else
 445  
         {
 446  0
             return result;
 447  
         }
 448  
     }
 449  
 
 450  
     /**
 451  
      * dispatches an event asynchronously to the components
 452  
      * 
 453  
      * @param component the name of the Mule components to dispatch to
 454  
      * @param payload the object that is the payload of the event
 455  
      * @param messageProperties any properties to be associated with the payload. as
 456  
      *            null
 457  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 458  
      *             transfromers cannot be found
 459  
      */
 460  
     public void dispatchDirect(String component, Object payload, Map messageProperties) throws UMOException
 461  
     {
 462  0
         dispatchDirect(component, new MuleMessage(payload, messageProperties));
 463  0
     }
 464  
 
 465  
     /**
 466  
      * dispatches an event asynchronously to the components
 467  
      * 
 468  
      * @param component the name of the Mule components to dispatch to
 469  
      * @param message the message to send
 470  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 471  
      *             transfromers cannot be found
 472  
      */
 473  
     public void dispatchDirect(String component, UMOMessage message) throws UMOException
 474  
     {
 475  0
         boolean compregistered = ModelHelper.isComponentRegistered(component);
 476  0
         if (!compregistered)
 477  
         {
 478  0
             throw new MessagingException(
 479  
                 CoreMessages.objectNotRegisteredWithManager("Component '" + component + "'"), 
 480  
                 message);
 481  
         }
 482  0
         UMOSession session = new MuleSession(ModelHelper.getComponent(component));
 483  0
         UMOEndpoint endpoint = getDefaultClientEndpoint(session.getComponent().getDescriptor(),
 484  
             message.getPayload());
 485  0
         UMOEvent event = new MuleEvent(message, endpoint, session, true);
 486  
 
 487  0
         if (logger.isDebugEnabled())
 488  
         {
 489  0
             logger.debug("MuleClient dispatching event direct to: " + component + ". Event is: " + event);
 490  
         }
 491  
 
 492  0
         event.getComponent().dispatchEvent(event);
 493  0
     }
 494  
 
 495  
     /**
 496  
      * sends an event request to a Url, making the result of the event trigger
 497  
      * available as a Future result that can be accessed later by client code.
 498  
      * 
 499  
      * @param url the url to make a request on
 500  
      * @param payload the object that is the payload of the event
 501  
      * @param messageProperties any properties to be associated with the payload. as
 502  
      *            null
 503  
      * @return the result message if any of the invocation
 504  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 505  
      *             transfromers cannot be found
 506  
      */
 507  
     public FutureMessageResult sendAsync(final String url, final Object payload, final Map messageProperties)
 508  
         throws UMOException
 509  
     {
 510  0
         return sendAsync(url, payload, messageProperties, 0);
 511  
     }
 512  
 
 513  
     /**
 514  
      * sends an event request to a Url, making the result of the event trigger
 515  
      * available as a Future result that can be accessed later by client code.
 516  
      * 
 517  
      * @param url the url to make a request on
 518  
      * @param message the message to send
 519  
      * @return the result message if any of the invocation
 520  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 521  
      *             transfromers cannot be found
 522  
      */
 523  
     public FutureMessageResult sendAsync(final String url, final UMOMessage message) throws UMOException
 524  
     {
 525  0
         return sendAsync(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 526  
     }
 527  
 
 528  
     /**
 529  
      * sends an event request to a Url, making the result of the event trigger
 530  
      * available as a Future result that can be accessed later by client code.
 531  
      * 
 532  
      * @param url the url to make a request on
 533  
      * @param payload the object that is the payload of the event
 534  
      * @param messageProperties any properties to be associated with the payload. as
 535  
      *            null
 536  
      * @param timeout how long to block in milliseconds waiting for a result
 537  
      * @return the result message if any of the invocation
 538  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 539  
      *             transfromers cannot be found
 540  
      */
 541  
     public FutureMessageResult sendAsync(final String url,
 542  
                                          final Object payload,
 543  
                                          final Map messageProperties,
 544  
                                          final int timeout) throws UMOException
 545  
     {
 546  0
         return sendAsync(url, new MuleMessage(payload, messageProperties), timeout);
 547  
     }
 548  
 
 549  
     /**
 550  
      * sends an event request to a Url, making the result of the event trigger
 551  
      * available as a Future result that can be accessed later by client code.
 552  
      * 
 553  
      * @param url the url to make a request on
 554  
      * @param message the message to send
 555  
      * @param timeout how long to block in milliseconds waiting for a result
 556  
      * @return the result message if any of the invocation
 557  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 558  
      *             transfromers cannot be found
 559  
      */
 560  
     public FutureMessageResult sendAsync(final String url, final UMOMessage message, final int timeout)
 561  
         throws UMOException
 562  
     {
 563  0
         Callable call = new Callable()
 564  
         {
 565  0
             public Object call() throws Exception
 566  
             {
 567  0
                 return send(url, message, timeout);
 568  
             }
 569  
         };
 570  
 
 571  0
         FutureMessageResult result = new FutureMessageResult(call);
 572  
 
 573  0
         if (asyncExecutor != null)
 574  
         {
 575  0
             result.setExecutor(asyncExecutor);
 576  
         }
 577  
 
 578  0
         result.execute();
 579  0
         return result;
 580  
     }
 581  
 
 582  
     /**
 583  
      * sends an event to a components on a local Mule instance, while making the
 584  
      * result of the event trigger available as a Future result that can be accessed
 585  
      * later by client code. If forwardDirectRequests flag s set and the components
 586  
      * is not found on the local Mule instance it will forward to a remote server.
 587  
      * Users can endpoint a url to a remote Mule server in the constructor of a Mule
 588  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 589  
      * 
 590  
      * @param component the name of the Mule components to send to
 591  
      * @param transformers a comma separated list of transformers to apply to the
 592  
      *            result message
 593  
      * @param payload the object that is the payload of the event
 594  
      * @param messageProperties any properties to be associated with the payload. as
 595  
      *            null
 596  
      * @return the result message if any of the invocation
 597  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 598  
      *             transfromers cannot be found
 599  
      */
 600  
     public FutureMessageResult sendDirectAsync(final String component,
 601  
                                                String transformers,
 602  
                                                final Object payload,
 603  
                                                final Map messageProperties) throws UMOException
 604  
     {
 605  0
         return sendDirectAsync(component, transformers, new MuleMessage(payload, messageProperties));
 606  
     }
 607  
 
 608  
     /**
 609  
      * sends an event to a components on a local Mule instance, while making the
 610  
      * result of the event trigger available as a Future result that can be accessed
 611  
      * later by client code. If forwardDirectRequests flag s set and the components
 612  
      * is not found on the local Mule instance it will forward to a remote server.
 613  
      * Users can endpoint a url to a remote Mule server in the constructor of a Mule
 614  
      * client, by default the default Mule server url tcp://localhost:60504 is used.
 615  
      * 
 616  
      * @param component the name of the Mule components to send to
 617  
      * @param transformers a comma separated list of transformers to apply to the
 618  
      *            result message
 619  
      * @param message the message to send
 620  
      * @return the result message if any of the invocation
 621  
      * @throws org.mule.umo.UMOException if the dispatch fails or the components or
 622  
      *             transfromers cannot be found
 623  
      */
 624  
     public FutureMessageResult sendDirectAsync(final String component,
 625  
                                                String transformers,
 626  
                                                final UMOMessage message) throws UMOException
 627  
     {
 628  0
         Callable call = new Callable()
 629  
         {
 630  0
             public Object call() throws Exception
 631  
             {
 632  0
                 return sendDirect(component, null, message);
 633  
             }
 634  
         };
 635  
 
 636  0
         FutureMessageResult result = new FutureMessageResult(call);
 637  
 
 638  0
         if (asyncExecutor != null)
 639  
         {
 640  0
             result.setExecutor(asyncExecutor);
 641  
         }
 642  
 
 643  0
         if (StringUtils.isNotBlank(transformers))
 644  
         {
 645  0
             result.setTransformer(MuleObjectHelper.getTransformer(transformers, ","));
 646  
         }
 647  
 
 648  0
         result.execute();
 649  0
         return result;
 650  
     }
 651  
 
 652  
     /**
 653  
      * Sends an event synchronously to a endpointUri via a mule server and a
 654  
      * resulting message is returned.
 655  
      * 
 656  
      * @param url the Mule url used to determine the destination and transport of the
 657  
      *            message
 658  
      * @param payload the object that is the payload of the event
 659  
      * @param messageProperties any properties to be associated with the payload. In
 660  
      *            the case of Jms you could set the JMSReplyTo property in these
 661  
      *            properties.
 662  
      * @return A return message, this could be null if the the components invoked
 663  
      *         explicitly sets a return as null
 664  
      * @throws org.mule.umo.UMOException
 665  
      */
 666  
     public UMOMessage send(String url, Object payload, Map messageProperties) throws UMOException
 667  
     {
 668  0
         return send(url, payload, messageProperties, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 669  
     }
 670  
 
 671  
     /**
 672  
      * Sends an event synchronously to a endpointUri via a mule server and a
 673  
      * resulting message is returned.
 674  
      * 
 675  
      * @param url the Mule url used to determine the destination and transport of the
 676  
      *            message
 677  
      * @param message the Message for the event
 678  
      * @return A return message, this could be null if the the components invoked
 679  
      *         explicitly sets a return as null
 680  
      * @throws org.mule.umo.UMOException
 681  
      */
 682  
     public UMOMessage send(String url, UMOMessage message) throws UMOException
 683  
     {
 684  0
         return send(url, message, UMOEvent.TIMEOUT_NOT_SET_VALUE);
 685  
     }
 686  
 
 687  
     /**
 688  
      * Sends an event synchronously to a endpointUri via a mule server and a
 689  
      * resulting message is returned.
 690  
      * 
 691  
      * @param url the Mule url used to determine the destination and transport of the
 692  
      *            message
 693  
      * @param payload the object that is the payload of the event
 694  
      * @param messageProperties any properties to be associated with the payload. In
 695  
      *            the case of Jms you could set the JMSReplyTo property in these
 696  
      *            properties.
 697  
      * @param timeout The time in milliseconds the the call should block waiting for
 698  
      *            a response
 699  
      * @return A return message, this could be null if the the components invoked
 700  
      *         explicitly sets a return as null
 701  
      * @throws org.mule.umo.UMOException
 702  
      */
 703  
     public UMOMessage send(String url, Object payload, Map messageProperties, int timeout)
 704  
         throws UMOException
 705  
     {
 706  0
         if (messageProperties == null)
 707  
         {
 708  0
             messageProperties = new HashMap();
 709  
         }
 710  0
         if (messageProperties.get(MuleProperties.MULE_REMOTE_SYNC_PROPERTY) == null)
 711  
         {
 712  0
             messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
 713  
         }
 714  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 715  0
         return send(url, message, timeout);
 716  
     }
 717  
 
 718  
     /**
 719  
      * Sends an event synchronously to a endpointUri via a mule server and a
 720  
      * resulting message is returned.
 721  
      * 
 722  
      * @param url the Mule url used to determine the destination and transport of the
 723  
      *            message
 724  
      * @param message The message to send
 725  
      * @param timeout The time in milliseconds the the call should block waiting for
 726  
      *            a response
 727  
      * @return A return message, this could be null if the the components invoked
 728  
      *         explicitly sets a return as null
 729  
      * @throws org.mule.umo.UMOException
 730  
      */
 731  
     public UMOMessage send(String url, UMOMessage message, int timeout) throws UMOException
 732  
     {
 733  0
         UMOEvent event = getEvent(message, url, true, false);
 734  0
         event.setTimeout(timeout);
 735  
 
 736  
         try
 737  
         {
 738  0
             return event.getSession().sendEvent(event);
 739  
         }
 740  0
         catch (UMOException e)
 741  
         {
 742  0
             throw e;
 743  
         }
 744  0
         catch (Exception e)
 745  
         {
 746  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 747  
                 event.getMessage(), event.getEndpoint(), e);
 748  
         }
 749  
     }
 750  
 
 751  
     /**
 752  
      * Will receive an event from an endpointUri determined by the url
 753  
      * 
 754  
      * @param url the Mule url used to determine the destination and transport of the
 755  
      *            message
 756  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 757  
      *            receive will not wait at all and if set to -1 the receive will wait
 758  
      *            forever
 759  
      * @return the message received or null if no message was received
 760  
      * @throws org.mule.umo.UMOException
 761  
      */
 762  
     public UMOMessage receive(String url, long timeout) throws UMOException
 763  
     {
 764  0
         UMOEndpoint endpoint = getEndpoint(url, UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
 765  
         try
 766  
         {
 767  0
             UMOMessage message = endpoint.receive(timeout);
 768  0
             if (message != null && endpoint.getTransformer() != null)
 769  
             {
 770  0
                 if (endpoint.getTransformer().isSourceTypeSupported(message.getPayload().getClass()))
 771  
                 {
 772  0
                     message = new MuleMessage(endpoint.getTransformer().transform(message.getPayload()),
 773  
                         message);
 774  
                 }
 775  
             }
 776  0
             return message;
 777  
         }
 778  0
         catch (Exception e)
 779  
         {
 780  0
             throw new ReceiveException(endpoint, timeout, e);
 781  
         }
 782  
     }
 783  
 
 784  
     /**
 785  
      * Will receive an event from an endpointUri determined by the url
 786  
      * 
 787  
      * @param url the Mule url used to determine the destination and transport of the
 788  
      *            message
 789  
      * @param transformers A comma separated list of transformers used to apply to
 790  
      *            the result message
 791  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 792  
      *            receive will not wait at all and if set to -1 the receive will wait
 793  
      *            forever
 794  
      * @return the message received or null if no message was received
 795  
      * @throws org.mule.umo.UMOException
 796  
      */
 797  
     public UMOMessage receive(String url, String transformers, long timeout) throws UMOException
 798  
     {
 799  0
         return receive(url, MuleObjectHelper.getTransformer(transformers, ","), timeout);
 800  
     }
 801  
 
 802  
     /**
 803  
      * Will receive an event from an endpointUri determined by the url
 804  
      * 
 805  
      * @param url the Mule url used to determine the destination and transport of the
 806  
      *            message
 807  
      * @param transformer A transformer used to apply to the result message
 808  
      * @param timeout how long to block waiting to receive the event, if set to 0 the
 809  
      *            receive will not wait at all and if set to -1 the receive will wait
 810  
      *            forever
 811  
      * @return the message received or null if no message was received
 812  
      * @throws org.mule.umo.UMOException
 813  
      */
 814  
     public UMOMessage receive(String url, UMOTransformer transformer, long timeout) throws UMOException
 815  
     {
 816  0
         UMOMessage message = receive(url, timeout);
 817  0
         if (message != null && transformer != null)
 818  
         {
 819  0
             return new MuleMessage(transformer.transform(message.getPayload()));
 820  
         }
 821  
         else
 822  
         {
 823  0
             return message;
 824  
         }
 825  
     }
 826  
 
 827  
     /**
 828  
      * Packages a mule event for the current request
 829  
      * 
 830  
      * @param message the event payload
 831  
      * @param uri the destination endpointUri
 832  
      * @param synchronous whether the event will be synchronously processed
 833  
      * @param streaming
 834  
      * @return the UMOEvent
 835  
      * @throws UMOException
 836  
      */
 837  
     protected UMOEvent getEvent(UMOMessage message, String uri, boolean synchronous, boolean streaming)
 838  
         throws UMOException
 839  
     {
 840  0
         UMOEndpoint endpoint = getEndpoint(uri, UMOEndpoint.ENDPOINT_TYPE_SENDER);
 841  0
         if (!endpoint.getConnector().isStarted() && manager.isStarted())
 842  
         {
 843  0
             endpoint.getConnector().startConnector();
 844  
         }
 845  0
         endpoint.setStreaming(streaming);
 846  
         try
 847  
         {
 848  0
             MuleSession session = new MuleSession(message,
 849  
                 ((AbstractConnector)endpoint.getConnector()).getSessionHandler());
 850  
 
 851  0
             if (user != null)
 852  
             {
 853  0
                 message.setProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(
 854  
                     user.getUsername(), user.getPassword()));
 855  
             }
 856  0
             MuleEvent event = new MuleEvent(message, endpoint, session, synchronous);
 857  0
             return event;
 858  
         }
 859  0
         catch (Exception e)
 860  
         {
 861  0
             throw new DispatchException(CoreMessages.failedToCreate("Client event"), message, endpoint, e);
 862  
         }
 863  
     }
 864  
 
 865  
     protected UMOEndpoint getEndpoint(String uri, String type) throws UMOException
 866  
     {
 867  0
         UMOEndpoint endpoint = manager.lookupEndpoint(uri);
 868  0
         if (endpoint == null)
 869  
         {
 870  0
             endpoint = MuleEndpoint.getOrCreateEndpointForUri(uri, type);
 871  
         }
 872  0
         return endpoint;
 873  
     }
 874  
 
 875  
     protected UMOEndpoint getDefaultClientEndpoint(UMODescriptor descriptor, Object payload)
 876  
         throws UMOException
 877  
     {
 878  
         // as we are bypassing the message transport layer we need to check that
 879  0
         UMOEndpoint endpoint = descriptor.getInboundEndpoint();
 880  0
         if (endpoint != null)
 881  
         {
 882  0
             if (endpoint.getTransformer() != null)
 883  
             {
 884  0
                 if (endpoint.getTransformer().isSourceTypeSupported(payload.getClass()))
 885  
                 {
 886  0
                     return endpoint;
 887  
                 }
 888  
                 else
 889  
                 {
 890  0
                     endpoint = new MuleEndpoint(endpoint);
 891  0
                     endpoint.setTransformer(null);
 892  0
                     return endpoint;
 893  
                 }
 894  
             }
 895  
             else
 896  
             {
 897  0
                 return endpoint;
 898  
             }
 899  
         }
 900  
         else
 901  
         {
 902  0
             UMOConnector connector = null;
 903  0
             UMOEndpointURI defaultEndpointUri = new MuleEndpointURI("vm://mule.client");
 904  0
             connector = TransportFactory.createConnector(defaultEndpointUri);
 905  0
             manager.registerConnector(connector);
 906  0
             connector.startConnector();
 907  0
             endpoint = new MuleEndpoint("muleClientProvider", defaultEndpointUri, connector, null,
 908  
                 UMOEndpoint.ENDPOINT_TYPE_RECEIVER, 0, null, null);
 909  
         }
 910  
 
 911  0
         manager.registerEndpoint(endpoint);
 912  0
         return endpoint;
 913  
     }
 914  
 
 915  
     /**
 916  
      * Sends an event synchronously to a endpointUri via a mule server without
 917  
      * waiting for the result.
 918  
      * 
 919  
      * @param url the Mule url used to determine the destination and transport of the
 920  
      *            message
 921  
      * @param payload the object that is the payload of the event
 922  
      * @param messageProperties any properties to be associated with the payload. In
 923  
      *            the case of Jms you could set the JMSReplyTo property in these
 924  
      *            properties.
 925  
      * @throws org.mule.umo.UMOException
 926  
      */
 927  
     public void sendNoReceive(String url, Object payload, Map messageProperties) throws UMOException
 928  
     {
 929  0
         if (messageProperties == null)
 930  
         {
 931  0
             messageProperties = new HashMap();
 932  
         }
 933  0
         messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "false");
 934  0
         UMOMessage message = new MuleMessage(payload, messageProperties);
 935  0
         UMOEvent event = getEvent(message, url, true, false);
 936  
         try
 937  
         {
 938  0
             event.getSession().sendEvent(event);
 939  
         }
 940  0
         catch (UMOException e)
 941  
         {
 942  0
             throw e;
 943  
         }
 944  0
         catch (Exception e)
 945  
         {
 946  0
             throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), 
 947  
                 event.getMessage(), event.getEndpoint(), e);
 948  0
         }
 949  0
     }
 950  
 
 951  
     /**
 952  
      * Overriding methods may want to return a custom manager here
 953  
      * 
 954  
      * @return the UMOManager to use
 955  
      */
 956  
     public UMOManager getManager()
 957  
     {
 958  0
         return MuleManager.getInstance();
 959  
     }
 960  
 
 961  
     /**
 962  
      * Registers a java object as a Umo pcomponent that listens for events on the
 963  
      * given url. By default the ThreadingProfile for the components will be set so
 964  
      * that there will only be one thread of execution.
 965  
      * 
 966  
      * @param component any java object, Mule will it's endpointUri discovery to
 967  
      *            determine which event to invoke based on the evnet payload type
 968  
      * @param name The identifying name of the components. This can be used to later
 969  
      *            unregister it
 970  
      * @param listenerEndpoint The url endpointUri to listen to
 971  
      * @throws UMOException
 972  
      */
 973  
     public void registerComponent(Object component, String name, UMOEndpointURI listenerEndpoint)
 974  
         throws UMOException
 975  
     {
 976  0
         builder.registerComponentInstance(component, name, listenerEndpoint, null);
 977  0
     }
 978  
 
 979  
     /**
 980  
      * Registers a java object as a Umo pcomponent that listens for and sends events
 981  
      * on the given urls. By default the ThreadingProfile for the components will be
 982  
      * set so that there will only be one thread of execution.
 983  
      * 
 984  
      * @param component any java object, Mule will it's endpointUri discovery to
 985  
      *            determine which event to invoke based on the evnet payload type
 986  
      * @param name The identifying name of the components. This can be used to later
 987  
      *            unregister it
 988  
      * @param listenerEndpoint The url endpointUri to listen to
 989  
      * @param sendEndpoint The url endpointUri to dispatch to
 990  
      * @throws UMOException
 991  
      */
 992  
     public void registerComponent(Object component,
 993  
                                   String name,
 994  
                                   MuleEndpointURI listenerEndpoint,
 995  
                                   MuleEndpointURI sendEndpoint) throws UMOException
 996  
     {
 997  0
         builder.registerComponentInstance(component, name, listenerEndpoint, sendEndpoint);
 998  0
     }
 999  
 
 1000  
     /**
 1001  
      * Registers a user configured MuleDescriptor of a components to the server. If
 1002  
      * users want to register object instances with the server rather than class
 1003  
      * names that get created at runtime or reference to objects in the container,
 1004  
      * the user must call the descriptors setImplementationInstance() method - <code>
 1005  
      * MyBean implementation = new MyBean();
 1006  
      * descriptor.setImplementationInstance(implementation);
 1007  
      * </code>
 1008  
      * Calling this method is equivilent to calling UMOModel.registerComponent(..)
 1009  
      * 
 1010  
      * @param descriptor the componet descriptor to register
 1011  
      * @throws UMOException the descriptor is invalid or cannot be initialised or
 1012  
      *             started
 1013  
      * @see org.mule.umo.model.UMOModel
 1014  
      */
 1015  
     public void registerComponent(UMODescriptor descriptor) throws UMOException
 1016  
     {
 1017  0
         builder.registerComponent(descriptor);
 1018  0
     }
 1019  
 
 1020  
     /**
 1021  
      * Unregisters a previously register components. This will also unregister any
 1022  
      * listeners for the components Calling this method is equivilent to calling
 1023  
      * UMOModel.unregisterComponent(..)
 1024  
      * 
 1025  
      * @param name the name of the componet to unregister
 1026  
      * @throws UMOException if unregistering the components fails, i.e. The
 1027  
      *             underlying transport fails to unregister a listener. If the
 1028  
      *             components does not exist, this method should not throw an
 1029  
      *             exception.
 1030  
      * @see org.mule.umo.model.UMOModel
 1031  
      */
 1032  
     public void unregisterComponent(String name) throws UMOException
 1033  
     {
 1034  0
         builder.unregisterComponent(name);
 1035  0
     }
 1036  
 
 1037  
     public RemoteDispatcher getRemoteDispatcher(String serverEndpoint) throws UMOException
 1038  
     {
 1039  0
         RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint);
 1040  0
         rd.setExecutor(asyncExecutor);
 1041  0
         dispatchers.add(rd);
 1042  0
         return rd;
 1043  
     }
 1044  
 
 1045  
     public RemoteDispatcher getRemoteDispatcher(String serverEndpoint, String user, String password)
 1046  
         throws UMOException
 1047  
     {
 1048  0
         RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint, new MuleCredentials(user,
 1049  
             password.toCharArray()));
 1050  0
         rd.setExecutor(asyncExecutor);
 1051  0
         dispatchers.add(rd);
 1052  0
         return rd;
 1053  
     }
 1054  
 
 1055  
     /**
 1056  
      * Will dispose the MuleManager instance *IF* a new instance was created for this
 1057  
      * client. Otherwise this method only cleans up resources no longer needed
 1058  
      */
 1059  
     public void dispose()
 1060  
     {
 1061  0
         synchronized (dispatchers)
 1062  
         {
 1063  0
             for (Iterator iterator = dispatchers.iterator(); iterator.hasNext();)
 1064  
             {
 1065  0
                 RemoteDispatcher remoteDispatcher = (RemoteDispatcher)iterator.next();
 1066  0
                 remoteDispatcher.dispose();
 1067  0
                 remoteDispatcher = null;
 1068  0
             }
 1069  0
             dispatchers.clear();
 1070  0
         }
 1071  
         // Dispose the manager only if the manager was created for this client
 1072  0
         if (MuleManager.getConfiguration().isClientMode())
 1073  
         {
 1074  0
             manager.dispose();
 1075  
         }
 1076  0
     }
 1077  
 
 1078  
     public void setProperty(Object key, Object value)
 1079  
     {
 1080  0
         manager.setProperty(key, value);
 1081  0
     }
 1082  
 
 1083  
     public Object getProperty(Object key)
 1084  
     {
 1085  0
         return manager.getProperty(key);
 1086  
     }
 1087  
 
 1088  
     public MuleConfiguration getConfiguration()
 1089  
     {
 1090  0
         return MuleManager.getConfiguration();
 1091  
     }
 1092  
 }