Coverage Report - org.mule.providers.bpm.ProcessConnector
 
Classes in this File Line Coverage Branch Coverage Complexity
ProcessConnector
27%
17/62
9%
2/22
1.81
 
 1  
 /*
 2  
  * $Id: ProcessConnector.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.providers.bpm;
 12  
 
 13  
 import org.mule.config.ConfigurationException;
 14  
 import org.mule.config.i18n.MessageFactory;
 15  
 import org.mule.extras.client.MuleClient;
 16  
 import org.mule.providers.AbstractConnector;
 17  
 import org.mule.umo.UMOException;
 18  
 import org.mule.umo.UMOMessage;
 19  
 import org.mule.umo.lifecycle.InitialisationException;
 20  
 import org.mule.util.ClassUtils;
 21  
 import org.mule.util.StringUtils;
 22  
 
 23  
 import java.util.Map;
 24  
 
 25  
 /**
 26  
  * The BPM provider allows Mule events to initiate and/or advance processes in an
 27  
  * external or embedded Business Process Management System (BPMS). It also allows
 28  
  * executing processes to generate Mule events.
 29  
  */
 30  14
 public class ProcessConnector extends AbstractConnector implements MessageService
 31  
 {
 32  
     /** The underlying BPMS */
 33  
     protected BPMS bpms;
 34  
 
 35  
     /** 
 36  
      * If the BPMS instance itself is not provided, it will be instantiated from this class 
 37  
      * (using the default constructor). 
 38  
      */
 39  
     protected String bpmsClass;
 40  
     
 41  
     /** This field will be used to correlate messages with processes. */
 42  
     protected String processIdField;
 43  
 
 44  
     /**
 45  
      * The global receiver allows an endpoint of type "bpm://*" to receive any
 46  
      * incoming message to the BPMS, regardless of the process. If this is false, the
 47  
      * process name must be specified for each endpoint, e.g. "bpm://MyProcess" will
 48  
      * only receive messages for the process "MyProcess".
 49  
      */
 50  14
     protected boolean allowGlobalReceiver = false;
 51  
 
 52  
     /**
 53  
      * If false, any message generated by the process is routed from the component on 
 54  
      * which it is received.  If true, a process can send messages to any endpoint
 55  
      * on any component.
 56  
      */
 57  14
     protected boolean allowGlobalDispatcher = false;
 58  
 
 59  
     public static final String PROPERTY_ENDPOINT = "endpoint";
 60  
     public static final String PROPERTY_PROCESS_TYPE = "processType";
 61  
     public static final String PROPERTY_PROCESS_ID = "processId";
 62  
     public static final String PROPERTY_ACTION = "action";
 63  
     public static final String PROPERTY_TRANSITION = "transition";
 64  
     public static final String PROPERTY_PROCESS_STARTED = "started";
 65  
     public static final String ACTION_START = "start";
 66  
     public static final String ACTION_ADVANCE = "advance";
 67  
     public static final String ACTION_UPDATE = "update";
 68  
     public static final String ACTION_ABORT = "abort";
 69  
     public static final String PROCESS_VARIABLE_INCOMING = "incoming";
 70  
     public static final String PROCESS_VARIABLE_INCOMING_SOURCE = "incomingSource";
 71  
     public static final String PROCESS_VARIABLE_DATA = "data";
 72  
 
 73  
     public static final String PROTOCOL = "bpm";
 74  
     public static final String GLOBAL_RECEIVER = PROTOCOL + "://*";
 75  
 
 76  14
     private MuleClient muleClient = null;
 77  
 
 78  
     public String getProtocol()
 79  
     {
 80  44
         return PROTOCOL;
 81  
     }
 82  
 
 83  
     protected void doInitialise() throws InitialisationException
 84  
     {
 85  
         try
 86  
         {
 87  14
             if (bpms == null)
 88  
             {
 89  0
                 if (bpmsClass != null)
 90  
                 {
 91  0
                     logger.info("Instantiating BPMS from the default constructor for " + bpmsClass);
 92  0
                     bpms = (BPMS) ClassUtils.instanciateClass(bpmsClass, new Object[0]);
 93  
                 }
 94  
                 else 
 95  
                 {
 96  0
                     throw new ConfigurationException(
 97  
                         MessageFactory.createStaticMessage("Either the bpms or bpmsClass property must be set for this connector."));
 98  
                 }
 99  
             }
 100  
 
 101  
             // Set a callback so that the BPMS may generate messages within Mule.
 102  14
             bpms.setMessageService(this);
 103  
             
 104  
             // The MuleClient is used as a global dispatcher.  
 105  
             // TODO MULE-1221 It would be cleaner to use something like the dynamic:// transport
 106  14
             if ((allowGlobalDispatcher == true) && (muleClient == null))
 107  
             {
 108  0
                 muleClient = new MuleClient(false);
 109  
             }
 110  
         }
 111  0
         catch (Exception e)
 112  
         {
 113  0
             throw new InitialisationException(e, this);
 114  14
         }
 115  14
     }
 116  
 
 117  
     protected void doDispose()
 118  
     {
 119  
         // template method
 120  14
     }
 121  
 
 122  
     protected void doConnect() throws Exception
 123  
     {
 124  
         // template method
 125  2
     }
 126  
 
 127  
     protected void doDisconnect() throws Exception
 128  
     {
 129  
         // template method
 130  2
     }
 131  
 
 132  
     protected void doStart() throws UMOException
 133  
     {
 134  
         // template method
 135  2
     }
 136  
 
 137  
     protected void doStop() throws UMOException
 138  
     {
 139  
         // template method
 140  2
     }
 141  
 
 142  
     /**
 143  
      * This method looks for a receiver based on the process name and ID. It searches
 144  
      * iteratively from the narrowest scope (match process name and ID) to the widest
 145  
      * scope (match neither - global receiver) possible.
 146  
      * 
 147  
      * @return ProcessMessageReceiver or null if no match is found
 148  
      */
 149  
     public ProcessMessageReceiver lookupReceiver(String processName, Object processId)
 150  
     {
 151  0
         ProcessMessageReceiver receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(processName, processId));
 152  0
         if (receiver == null)
 153  
         {
 154  0
             receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(processName, null));
 155  
         }
 156  0
         if (receiver == null)
 157  
         {
 158  0
             receiver = (ProcessMessageReceiver)lookupReceiver(toUrl(null, null));
 159  
         }
 160  0
         return receiver;
 161  
     }
 162  
 
 163  
     /**
 164  
      * Generate a URL based on the process name and ID such as "bpm://myProcess/2342"
 165  
      * If the parameters are missing, and <code>allowGlobalReceiver</code> is true,
 166  
      * the GLOBAL_RECEIVER is returned.
 167  
      */
 168  
     public String toUrl(String processName, Object processId)
 169  
     {
 170  0
         String url = getProtocol() + "://";
 171  0
         if (StringUtils.isNotEmpty(processName))
 172  
         {
 173  0
             url += processName;
 174  0
             if (processId != null)
 175  
             {
 176  0
                 url += "/" + processId;
 177  
             }
 178  
         }
 179  0
         else if (isAllowGlobalReceiver())
 180  
         {
 181  0
             return GLOBAL_RECEIVER;
 182  
         }
 183  
         else
 184  
         {
 185  0
             throw new IllegalArgumentException(
 186  
                 "No valid URL could be created for the given process name and ID: processName = " + processName + ", processId = " + processId);
 187  
         }
 188  0
         return url;
 189  
     }
 190  
 
 191  
     public UMOMessage generateMessage(String endpoint,
 192  
                                       Object payloadObject,
 193  
                                       Map messageProperties,
 194  
                                       boolean synchronous) throws Exception
 195  
     {
 196  0
         String processName = (String)messageProperties.get(ProcessConnector.PROPERTY_PROCESS_TYPE);
 197  0
         Object processId = messageProperties.get(ProcessConnector.PROPERTY_PROCESS_ID);
 198  
 
 199  
         // Look up a receiver for this process.
 200  0
         ProcessMessageReceiver receiver = lookupReceiver(processName, processId);
 201  0
         if (receiver == null)
 202  
         {
 203  0
             throw new ConfigurationException(MessageFactory
 204  
                 .createStaticMessage("No corresponding receiver found for processName = " + processName
 205  
                                 + ", processId = " + processId));
 206  
         }
 207  
 
 208  0
         if (synchronous)
 209  
         {
 210  
             // Send the process-generated Mule message synchronously.
 211  0
             return receiver.generateSynchronousEvent(endpoint, payloadObject, messageProperties);
 212  
         }
 213  
         else
 214  
         {
 215  
             // Dispatch the process-generated Mule message asynchronously.
 216  0
             receiver.generateAsynchronousEvent(endpoint, payloadObject, messageProperties);
 217  0
             return null;
 218  
         }
 219  
     }
 220  
 
 221  
     // //////////////////////////////////////////////////////////////////////////
 222  
     // Getters and Setters
 223  
     // //////////////////////////////////////////////////////////////////////////
 224  
 
 225  
     public BPMS getBpms()
 226  
     {
 227  0
         return bpms;
 228  
     }
 229  
 
 230  
     public void setBpms(BPMS bpms)
 231  
     {
 232  14
         this.bpms = bpms;
 233  14
     }
 234  
 
 235  
     public String getBpmsClass()
 236  
     {
 237  0
         return bpmsClass;
 238  
     }
 239  
 
 240  
     public void setBpmsClass(String bpmsClass)
 241  
     {
 242  0
         this.bpmsClass = bpmsClass;
 243  0
     }
 244  
 
 245  
     public MuleClient getMuleClient()
 246  
     {
 247  0
         return muleClient;
 248  
     }
 249  
 
 250  
     public boolean isAllowGlobalDispatcher()
 251  
     {
 252  0
         return allowGlobalDispatcher;
 253  
     }
 254  
 
 255  
     public void setAllowGlobalDispatcher(boolean allowGlobalDispatcher)
 256  
     {
 257  0
         this.allowGlobalDispatcher = allowGlobalDispatcher;
 258  0
     }
 259  
 
 260  
     public boolean isAllowGlobalReceiver()
 261  
     {
 262  0
         return allowGlobalReceiver;
 263  
     }
 264  
 
 265  
     public void setAllowGlobalReceiver(boolean allowGlobalReceiver)
 266  
     {
 267  0
         this.allowGlobalReceiver = allowGlobalReceiver;
 268  0
     }
 269  
 
 270  
     public String getProcessIdField()
 271  
     {
 272  0
         return processIdField;
 273  
     }
 274  
 
 275  
     public void setProcessIdField(String processIdField)
 276  
     {
 277  0
         this.processIdField = processIdField;
 278  0
     }
 279  
 }