Coverage Report - org.mule.transport.bpm.ProcessMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
ProcessMessageDispatcher
0%
0/71
0%
0/50
4.857
 
 1  
 /*
 2  
  * $Id: ProcessMessageDispatcher.java 10961 2008-02-22 19:01:02Z dfeist $
 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.transport.bpm;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.endpoint.OutboundEndpoint;
 18  
 import org.mule.api.transport.DispatchException;
 19  
 import org.mule.config.i18n.MessageFactory;
 20  
 import org.mule.transport.AbstractMessageDispatcher;
 21  
 import org.mule.transport.NullPayload;
 22  
 import org.mule.util.StringUtils;
 23  
 
 24  
 import java.util.HashMap;
 25  
 import java.util.Iterator;
 26  
 import java.util.Map;
 27  
 
 28  
 /**
 29  
  * Initiates or advances a workflow process from an outgoing Mule event.
 30  
  */
 31  
 public class ProcessMessageDispatcher extends AbstractMessageDispatcher
 32  
 {
 33  
     private ProcessConnector connector;
 34  
 
 35  
     public ProcessMessageDispatcher(OutboundEndpoint endpoint)
 36  
     {
 37  0
         super(endpoint);
 38  0
         this.connector = (ProcessConnector)endpoint.getConnector();
 39  0
     }
 40  
 
 41  
     /**
 42  
      * Performs a synchronous action on the BPMS.
 43  
      * 
 44  
      * @return an object representing the new state of the process
 45  
      */
 46  
     public MuleMessage doSend(MuleEvent event) throws Exception
 47  
     {
 48  0
         Object process = processAction(event);
 49  
 
 50  0
         if (process != null)
 51  
         {
 52  0
             MuleMessage msg = new DefaultMuleMessage(process);
 53  0
             msg.setProperty(ProcessConnector.PROPERTY_PROCESS_ID, connector.getBpms().getId(process));
 54  0
             return msg;
 55  
         }
 56  
         else
 57  
         {
 58  0
             throw new DispatchException(MessageFactory
 59  
                 .createStaticMessage("Synchronous process invocation must return the new process state."),
 60  
                 event.getMessage(), event.getEndpoint());
 61  
         }
 62  
     }
 63  
 
 64  
     /**
 65  
      * Performs an asynchronous action on the BPMS.
 66  
      */
 67  
     public void doDispatch(MuleEvent event) throws Exception
 68  
     {
 69  0
         processAction(event);
 70  0
     }
 71  
 
 72  
     protected Object processAction(MuleEvent event) throws Exception
 73  
     {
 74  
         // An object representing the new state of the process
 75  0
         Object process = null;
 76  
 
 77  
         // Create a map of process variables based on the message properties.
 78  0
         Map processVariables = new HashMap();
 79  0
         if (event != null)
 80  
         {
 81  
             String propertyName;
 82  0
             for (Iterator iterator = event.getMessage().getPropertyNames().iterator(); iterator.hasNext();)
 83  
             {
 84  0
                 propertyName = (String)iterator.next();
 85  0
                 processVariables.put(propertyName, event.getMessage().getProperty(propertyName));
 86  
             }
 87  
 
 88  0
             Object payload = event.transformMessage();
 89  0
             if (payload != null && !(payload instanceof NullPayload))
 90  
             {
 91  
                 // Store the message's payload as a process variable.
 92  0
                 processVariables.put(ProcessConnector.PROCESS_VARIABLE_INCOMING, payload);
 93  
 
 94  
                 // Store the endpoint on which the message was received as a process
 95  
                 // variable.
 96  0
                 String originatingEndpoint = event.getMessage().getStringProperty(
 97  
                     MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY, null);
 98  0
                 if (StringUtils.isNotEmpty(originatingEndpoint))
 99  
                 {
 100  0
                     processVariables.put(ProcessConnector.PROCESS_VARIABLE_INCOMING_SOURCE,
 101  
                         originatingEndpoint);
 102  
                 }
 103  
             }
 104  
         }
 105  
 
 106  
         // Retrieve the parameters
 107  0
         Object processType = event.getProperty(ProcessConnector.PROPERTY_PROCESS_TYPE, /* exhaustiveSearch */
 108  
         true);
 109  0
         processVariables.remove(ProcessConnector.PROPERTY_PROCESS_TYPE);
 110  
 
 111  
         // TODO MULE-1220 The processId for BPM is sort of like a session and so we could probably use
 112  
         // Mule's SessionHandler interface for managing this.  
 113  
         Object processId;
 114  0
         String processIdField = connector.getProcessIdField();
 115  0
         if (StringUtils.isNotEmpty(processIdField))
 116  
         {
 117  0
             processId = event.getProperty(processIdField, /* exhaustiveSearch */false);
 118  
         }
 119  
         // If processId is explicitly set for the message, this overrides the
 120  
         // processIdField.
 121  0
         processId = event.getProperty(ProcessConnector.PROPERTY_PROCESS_ID, /* exhaustiveSearch */true);
 122  0
         processVariables.remove(ProcessConnector.PROPERTY_PROCESS_ID);
 123  
 
 124  
         // Default action is "advance"
 125  0
         String action = event.getMessage().getStringProperty(ProcessConnector.PROPERTY_ACTION,
 126  
             ProcessConnector.ACTION_ADVANCE);
 127  0
         processVariables.remove(ProcessConnector.PROPERTY_ACTION);
 128  
 
 129  0
         Object transition = event.getMessage().getProperty(ProcessConnector.PROPERTY_TRANSITION);
 130  0
         processVariables.remove(ProcessConnector.PROPERTY_TRANSITION);
 131  
 
 132  
         // Decode the URI, for example:
 133  
         // bpm://testProcess/4561?action=advance
 134  
         String temp;
 135  0
         temp = event.getEndpoint().getEndpointURI().getHost();
 136  0
         if (StringUtils.isNotEmpty(temp))
 137  
         {
 138  0
             processType = temp;
 139  
         }
 140  0
         temp = event.getEndpoint().getEndpointURI().getPath();
 141  0
         if (StringUtils.isNotEmpty(temp))
 142  
         {
 143  
             // Strip the leading "/" from the path.
 144  0
             if (temp.startsWith("/"))
 145  
             {
 146  0
                 temp = StringUtils.right(temp, temp.length() - 1);
 147  
             }
 148  
             // If there are any remaining "/", we don't know what to do with them.
 149  0
             if (temp.indexOf("/") != -1)
 150  
             {
 151  0
                 throw new IllegalArgumentException("Unexpected format in the path of the URL: " + temp);
 152  
             }
 153  0
             processId = temp;
 154  
         }
 155  
 
 156  
         // //////////////////////////////////////////////////////////////////////
 157  
 
 158  
         // Start a new process.
 159  0
         if (processId == null || action.equals(ProcessConnector.ACTION_START))
 160  
         {
 161  0
             if (processType != null)
 162  
             {
 163  0
                 process = connector.getBpms().startProcess(processType, transition, processVariables);
 164  0
                 if ((process != null) && logger.isInfoEnabled())
 165  
                 {
 166  0
                     logger.info("New process started, ID = " + connector.getBpms().getId(process));
 167  
                 }
 168  
             }
 169  
             else
 170  
             {
 171  0
                 throw new IllegalArgumentException("Process type is missing, cannot start a new process.");
 172  
             }
 173  
         }
 174  
 
 175  
         // Don't advance the process, just update the process variables.
 176  0
         else if (action.equals(ProcessConnector.ACTION_UPDATE))
 177  
         {
 178  0
             if (processId != null)
 179  
             {
 180  0
                 process = connector.getBpms().updateProcess(processId, processVariables);
 181  0
                 if ((process != null) && logger.isInfoEnabled())
 182  
                 {
 183  0
                     logger.info("Process variables updated, ID = " + connector.getBpms().getId(process));
 184  
                 }
 185  
             }
 186  
             else
 187  
             {
 188  0
                 throw new IllegalArgumentException("Process ID is missing, cannot update process.");
 189  
             }
 190  
         }
 191  
 
 192  
         // Abort the running process (end abnormally).
 193  0
         else if (action.equals(ProcessConnector.ACTION_ABORT))
 194  
         {
 195  0
             if (processId != null)
 196  
             {
 197  0
                 connector.getBpms().abortProcess(processId);
 198  0
                 process = NullPayload.getInstance();
 199  0
                 logger.info("Process aborted, ID = " + processId);
 200  
             }
 201  
             else
 202  
             {
 203  0
                 throw new IllegalArgumentException("Process ID is missing, cannot abort process.");
 204  
             }
 205  
         }
 206  
 
 207  
         // Advance the already-running process one step.
 208  
         else
 209  
         {
 210  0
             if (processId != null)
 211  
             {
 212  0
                 process = connector.getBpms().advanceProcess(processId, transition, processVariables);
 213  0
                 if ((process != null) && logger.isInfoEnabled())
 214  
                 {
 215  0
                     logger.info("Process advanced, ID = " + connector.getBpms().getId(process)
 216  
                                     + ", new state = " + connector.getBpms().getState(process));
 217  
                 }
 218  
             }
 219  
             else
 220  
             {
 221  0
                 throw new IllegalArgumentException("Process ID is missing, cannot advance process.");
 222  
             }
 223  
         }
 224  
 
 225  0
         return process;
 226  
     }
 227  
 
 228  
     protected void doConnect() throws Exception
 229  
     {
 230  
         /* nop */
 231  0
     }
 232  
 
 233  
     protected void doDisconnect() throws Exception
 234  
     {
 235  
         /* nop */
 236  0
     }
 237  
 
 238  
     protected void doDispose()
 239  
     {
 240  
         /* nop */
 241  0
     }
 242  
 
 243  
 }