1
2
3
4
5
6
7
8
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.api.transport.PropertyScope;
20 import org.mule.config.i18n.MessageFactory;
21 import org.mule.module.bpm.Process;
22 import org.mule.transport.AbstractMessageDispatcher;
23 import org.mule.transport.NullPayload;
24 import org.mule.util.StringUtils;
25
26 import java.util.HashMap;
27 import java.util.Map;
28
29
30
31
32
33
34 public class ProcessMessageDispatcher extends AbstractMessageDispatcher
35 {
36 private ProcessConnector connector;
37
38 public ProcessMessageDispatcher(OutboundEndpoint endpoint)
39 {
40 super(endpoint);
41 this.connector = (ProcessConnector)endpoint.getConnector();
42 }
43
44
45
46
47
48
49 @Override
50 public MuleMessage doSend(MuleEvent event) throws Exception
51 {
52 Object process = processAction(event);
53
54 if (process != null)
55 {
56 MuleMessage msg = new DefaultMuleMessage(process, connector.getMuleContext());
57 msg.setProperty(Process.PROPERTY_PROCESS_ID, connector.getBpms().getId(process), PropertyScope.SESSION);
58 return msg;
59 }
60 else
61 {
62 throw new DispatchException(
63 MessageFactory.createStaticMessage("Synchronous process invocation must return the new process state."),
64 event, this);
65 }
66 }
67
68
69
70
71 @Override
72 public void doDispatch(MuleEvent event) throws Exception
73 {
74 processAction(event);
75 }
76
77 protected Object processAction(MuleEvent event) throws Exception
78 {
79
80 Object process;
81
82
83 Map processVariables = new HashMap();
84 if (event != null)
85 {
86 populateProcessVariables(event, processVariables, PropertyScope.INVOCATION);
87 populateProcessVariables(event, processVariables, PropertyScope.OUTBOUND);
88
89 Object payload = event.getMessage().getPayload();
90 if (payload != null && !(payload instanceof NullPayload))
91 {
92
93 processVariables.put(Process.PROCESS_VARIABLE_INCOMING, payload);
94
95
96 String originatingEndpoint = event.getMessage().getInboundProperty(MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY);
97 if (StringUtils.isNotEmpty(originatingEndpoint))
98 {
99 processVariables.put(Process.PROCESS_VARIABLE_INCOMING_SOURCE, originatingEndpoint);
100 }
101 }
102 }
103
104
105 Object processType = event.getMessage().getSessionProperty(Process.PROPERTY_PROCESS_TYPE);
106 if (processType == null)
107 {
108 processType = event.getMessage().getInvocationProperty(Process.PROPERTY_PROCESS_TYPE);
109 }
110 if (processType == null)
111 {
112 processType = event.getMessage().getInboundProperty(Process.PROPERTY_PROCESS_TYPE);
113 }
114 processVariables.remove(Process.PROPERTY_PROCESS_TYPE);
115
116 String processIdField = connector.getProcessIdField();
117 if (StringUtils.isEmpty(processIdField))
118 {
119 processIdField = Process.PROPERTY_PROCESS_ID;
120 }
121
122 Object processId;
123 processId = event.getMessage().getSessionProperty(processIdField);
124 if (processId == null)
125 {
126 processId = event.getMessage().getInvocationProperty(processIdField);
127 }
128 if (processId == null)
129 {
130 processId = event.getMessage().getInboundProperty(processIdField);
131 }
132 processVariables.remove(processIdField);
133
134
135 String action = event.getMessage().getInvocationProperty(Process.PROPERTY_ACTION, Process.ACTION_ADVANCE);
136 processVariables.remove(Process.PROPERTY_ACTION);
137
138 Object transition = event.getMessage().getInvocationProperty(Process.PROPERTY_TRANSITION);
139 processVariables.remove(Process.PROPERTY_TRANSITION);
140
141
142
143 String temp;
144 temp = event.getEndpoint().getEndpointURI().getHost();
145 if (StringUtils.isNotEmpty(temp))
146 {
147 processType = temp;
148 }
149 temp = event.getEndpoint().getEndpointURI().getPath();
150 if (StringUtils.isNotEmpty(temp))
151 {
152
153 if (temp.startsWith("/"))
154 {
155 temp = StringUtils.right(temp, temp.length() - 1);
156 }
157
158 if (temp.indexOf("/") != -1)
159 {
160 throw new IllegalArgumentException("Unexpected format in the path of the URL: " + temp);
161 }
162 processId = temp;
163 }
164
165
166
167 logger.debug("Message received: payload = " + event.getMessage().getPayload().getClass().getName() + " processType = " + processType + " processId = " + processId + " action = " + action);
168
169
170 if (processId == null || action.equals(Process.ACTION_START))
171 {
172 if (processType != null)
173 {
174 process = connector.getBpms().startProcess(processType, transition, processVariables);
175 if ((process != null) && logger.isInfoEnabled())
176 {
177 logger.info("New process started, ID = " + connector.getBpms().getId(process));
178 }
179 }
180 else
181 {
182 throw new IllegalArgumentException("Process type is missing, cannot start a new process.");
183 }
184 }
185
186
187 else if (action.equals(Process.ACTION_UPDATE))
188 {
189 if (processId != null)
190 {
191 process = connector.getBpms().updateProcess(processId, processVariables);
192 if ((process != null) && logger.isInfoEnabled())
193 {
194 logger.info("Process variables updated, ID = " + connector.getBpms().getId(process));
195 }
196 }
197 else
198 {
199 throw new IllegalArgumentException("Process ID is missing, cannot update process.");
200 }
201 }
202
203
204 else if (action.equals(Process.ACTION_ABORT))
205 {
206 if (processId != null)
207 {
208 connector.getBpms().abortProcess(processId);
209 process = NullPayload.getInstance();
210 logger.info("Process aborted, ID = " + processId);
211 }
212 else
213 {
214 throw new IllegalArgumentException("Process ID is missing, cannot abort process.");
215 }
216 }
217
218
219 else
220 {
221 if (processId != null)
222 {
223 process = connector.getBpms().advanceProcess(processId, transition, processVariables);
224 if ((process != null) && logger.isInfoEnabled())
225 {
226 logger.info("Process advanced, ID = " + connector.getBpms().getId(process)
227 + ", new state = " + connector.getBpms().getState(process));
228 }
229 }
230 else
231 {
232 throw new IllegalArgumentException("Process ID is missing, cannot advance process.");
233 }
234 }
235
236 return process;
237 }
238
239 protected void populateProcessVariables(MuleEvent event, Map processVariables, PropertyScope propertyScope)
240 {
241 for (String propertyName : event.getMessage().getPropertyNames(propertyScope))
242 {
243
244 if (!propertyName.equals(MuleProperties.MULE_SESSION_PROPERTY))
245 {
246 processVariables.put(propertyName, event.getMessage().getProperty(propertyName, propertyScope));
247 }
248 }
249 }
250 }