|
|||||||||||||||||||
| 30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
| Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
| ProcessControllerImpl.java | 43.5% | 71.2% | 63% | 63.2% |
|
||||||||||||||
| 1 |
/*
|
|
| 2 |
* $Id: ProcessControllerImpl.java,v 1.1 2004/12/15 14:18:10 patforna Exp $
|
|
| 3 |
*
|
|
| 4 |
* Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
|
|
| 5 |
* Berne University of Applied Sciences
|
|
| 6 |
* School of Engineering and Information Technology
|
|
| 7 |
* All rights reserved.
|
|
| 8 |
*/
|
|
| 9 |
package bexee.core;
|
|
| 10 |
|
|
| 11 |
import java.util.Collection;
|
|
| 12 |
import java.util.Iterator;
|
|
| 13 |
import java.util.List;
|
|
| 14 |
import java.util.Map;
|
|
| 15 |
|
|
| 16 |
import javax.wsdl.Binding;
|
|
| 17 |
import javax.wsdl.Definition;
|
|
| 18 |
import javax.wsdl.Message;
|
|
| 19 |
import javax.wsdl.Operation;
|
|
| 20 |
import javax.wsdl.Part;
|
|
| 21 |
import javax.wsdl.Port;
|
|
| 22 |
import javax.wsdl.PortType;
|
|
| 23 |
import javax.wsdl.extensions.ExtensibilityElement;
|
|
| 24 |
import javax.wsdl.extensions.soap.SOAPAddress;
|
|
| 25 |
import javax.xml.namespace.QName;
|
|
| 26 |
import javax.xml.rpc.ParameterMode;
|
|
| 27 |
|
|
| 28 |
import org.apache.axis.Constants;
|
|
| 29 |
import org.apache.axis.client.Call;
|
|
| 30 |
import org.apache.axis.client.Service;
|
|
| 31 |
import org.apache.commons.logging.Log;
|
|
| 32 |
import org.apache.commons.logging.LogFactory;
|
|
| 33 |
|
|
| 34 |
import bexee.event.Event;
|
|
| 35 |
import bexee.model.activity.Activity;
|
|
| 36 |
import bexee.model.activity.Assign;
|
|
| 37 |
import bexee.model.activity.Compensate;
|
|
| 38 |
import bexee.model.activity.Empty;
|
|
| 39 |
import bexee.model.activity.Flow;
|
|
| 40 |
import bexee.model.activity.Invoke;
|
|
| 41 |
import bexee.model.activity.Receive;
|
|
| 42 |
import bexee.model.activity.Reply;
|
|
| 43 |
import bexee.model.activity.Sequence;
|
|
| 44 |
import bexee.model.activity.Switch;
|
|
| 45 |
import bexee.model.elements.BpelCase;
|
|
| 46 |
import bexee.model.elements.Copy;
|
|
| 47 |
import bexee.model.elements.Correlation;
|
|
| 48 |
import bexee.model.elements.CorrelationPattern;
|
|
| 49 |
import bexee.model.elements.From;
|
|
| 50 |
import bexee.model.elements.Link;
|
|
| 51 |
import bexee.model.elements.PartnerLink;
|
|
| 52 |
import bexee.model.elements.PartnerLinks;
|
|
| 53 |
import bexee.model.elements.To;
|
|
| 54 |
import bexee.model.elements.Variable;
|
|
| 55 |
import bexee.model.elements.Variables;
|
|
| 56 |
import bexee.model.process.BPELProcess;
|
|
| 57 |
import bexee.model.process.Process;
|
|
| 58 |
|
|
| 59 |
/**
|
|
| 60 |
* The default imlementation of the <code>ProcessController</code>.
|
|
| 61 |
*
|
|
| 62 |
* @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:10 $
|
|
| 63 |
* @author Patric Fornasier
|
|
| 64 |
* @author Pawel Kowalski
|
|
| 65 |
*/
|
|
| 66 |
public class ProcessControllerImpl implements ProcessController { |
|
| 67 |
|
|
| 68 |
private static Log log = LogFactory.getLog(ProcessControllerImpl.class); |
|
| 69 |
|
|
| 70 |
//**************************************************/
|
|
| 71 |
// processor entry method
|
|
| 72 |
//**************************************************/
|
|
| 73 |
|
|
| 74 | 4 |
public void processMessage(ProcessInstance instance, BexeeMessage message) { |
| 75 |
|
|
| 76 | 4 |
log.info("Processing a ProcessInstance");
|
| 77 |
|
|
| 78 |
// initialize objects
|
|
| 79 |
//
|
|
| 80 | 4 |
ProcessContext ctx = instance.getContext(); |
| 81 | 4 |
BPELProcess process = instance.getProcess(); |
| 82 |
|
|
| 83 | 4 |
ctx.setMessage(message); |
| 84 |
|
|
| 85 |
// start processing process elements
|
|
| 86 | 4 |
try {
|
| 87 | 4 |
process.getProcess().accept(this, instance);
|
| 88 |
} catch (AwaitMessageException e) {
|
|
| 89 | 0 |
e.printStackTrace(); |
| 90 |
} catch (Exception e) {
|
|
| 91 | 0 |
e.printStackTrace(); |
| 92 |
} |
|
| 93 |
} |
|
| 94 |
|
|
| 95 |
//**************************************************/
|
|
| 96 |
// process the Process
|
|
| 97 |
//**************************************************/
|
|
| 98 |
|
|
| 99 | 4 |
public void process(Process process, ProcessInstance instance) |
| 100 |
throws Exception {
|
|
| 101 |
|
|
| 102 | 4 |
log.info("Processing a Process");
|
| 103 |
|
|
| 104 |
// process all child elements
|
|
| 105 | 4 |
Variables variables = process.getVariables(); |
| 106 | 4 |
if (variables != null) { |
| 107 | 4 |
variables.accept(this, instance);
|
| 108 |
} |
|
| 109 |
|
|
| 110 | 4 |
PartnerLinks partnerLinks = process.getPartnerLinks(); |
| 111 | 4 |
if (partnerLinks != null) { |
| 112 | 4 |
partnerLinks.accept(this, instance);
|
| 113 |
} |
|
| 114 |
|
|
| 115 | 4 |
Activity activity = process.getActivity(); |
| 116 |
// there must be one root activity of this process
|
|
| 117 | 4 |
if (activity != null) { |
| 118 | 4 |
activity.accept(this, instance);
|
| 119 |
} else {
|
|
| 120 | 0 |
throw new MissingActivityException(); |
| 121 |
} |
|
| 122 |
} |
|
| 123 |
|
|
| 124 |
//**************************************************/
|
|
| 125 |
// process structured activities
|
|
| 126 |
//**************************************************/
|
|
| 127 |
|
|
| 128 | 4 |
public void process(Sequence sequence, ProcessInstance instance) |
| 129 |
throws Exception {
|
|
| 130 |
|
|
| 131 | 4 |
log(sequence); |
| 132 |
|
|
| 133 |
// process all activities in sequence
|
|
| 134 | 4 |
List activities = sequence.getActivities(); |
| 135 | 4 |
for (Iterator iter = activities.iterator(); iter.hasNext();) {
|
| 136 | 18 |
Activity activity = (Activity) iter.next(); |
| 137 | 18 |
activity.accept(this, instance);
|
| 138 |
} |
|
| 139 |
} |
|
| 140 |
|
|
| 141 |
/**
|
|
| 142 |
* This is the implementation of the Flow activity which is used for
|
|
| 143 |
* parallel execution. In this primitive implementation we don't use any
|
|
| 144 |
* thread pooling mechanisms. In a more sophisticated version of the
|
|
| 145 |
* ProcessController, we might make use of the
|
|
| 146 |
* http://jakarta.apache.org/commons/pool/ library for thread pooling.
|
|
| 147 |
*/
|
|
| 148 | 4 |
public void process(Flow flow, ProcessInstance instance) throws Exception { |
| 149 |
|
|
| 150 | 4 |
log(flow); |
| 151 |
|
|
| 152 | 4 |
List activities = flow.getActivities(); |
| 153 | 4 |
int activitiesCount = activities.size();
|
| 154 | 4 |
Thread[] flowThreads = new Thread[activitiesCount];
|
| 155 |
|
|
| 156 |
// execute activities in separate threads
|
|
| 157 |
// for parallelity
|
|
| 158 |
//
|
|
| 159 | 4 |
for (int i = 0; i < activitiesCount; i++) { |
| 160 | 8 |
Activity activity = (Activity) activities.get(i); |
| 161 | 8 |
flowThreads[i] = new FlowThread(this, instance, activity); |
| 162 | 8 |
flowThreads[i].start(); |
| 163 |
} |
|
| 164 |
|
|
| 165 |
// wait for termination of all started FlowThreads
|
|
| 166 | 4 |
for (int i = 0; i < flowThreads.length; i++) { |
| 167 | 8 |
flowThreads[i].join(); |
| 168 |
} |
|
| 169 |
|
|
| 170 |
/**
|
|
| 171 |
* TODO because the run() Thread method is not allowed to throw
|
|
| 172 |
* Exceptions, it is necessary to check the status of each executed
|
|
| 173 |
* Thread in order to know wheter it finished its taks correctly or
|
|
| 174 |
* failed.
|
|
| 175 |
*/
|
|
| 176 |
} |
|
| 177 |
|
|
| 178 |
/**
|
|
| 179 |
* A default implementation of the
|
|
| 180 |
* <code>process(Switch, ProcessInstance)</code> method.
|
|
| 181 |
*
|
|
| 182 |
*/
|
|
| 183 | 0 |
public void process(Switch bpelSwitch, ProcessInstance instance) |
| 184 |
throws Exception {
|
|
| 185 |
|
|
| 186 | 0 |
List bpelCases = bpelSwitch.getCases(); |
| 187 | 0 |
for (Iterator iter = bpelCases.iterator(); iter.hasNext();) {
|
| 188 | 0 |
BpelCase bpelCase = (BpelCase) iter.next(); |
| 189 | 0 |
if (bpelCase.getBooleanExpression().evaluate()) {
|
| 190 | 0 |
bpelCase.getCaseActivity().accept(this, instance);
|
| 191 | 0 |
return;
|
| 192 |
} |
|
| 193 |
} |
|
| 194 |
|
|
| 195 | 0 |
Activity otherwise = bpelSwitch.getOtherwise(); |
| 196 | 0 |
if (otherwise != null) { |
| 197 | 0 |
otherwise.accept(this, instance);
|
| 198 |
} |
|
| 199 |
} |
|
| 200 |
|
|
| 201 |
//**************************************************/
|
|
| 202 |
// process atomic activities
|
|
| 203 |
//**************************************************/
|
|
| 204 |
|
|
| 205 | 4 |
public void process(Receive receive, ProcessInstance instance) |
| 206 |
throws AwaitMessageException {
|
|
| 207 |
|
|
| 208 | 4 |
log(receive); |
| 209 |
|
|
| 210 |
// get process context
|
|
| 211 | 4 |
ProcessContext ctx = instance.getContext(); |
| 212 | 4 |
BPELProcess process = instance.getProcess(); |
| 213 |
|
|
| 214 | 4 |
Event event = ctx.getEvent(receive); |
| 215 | 4 |
if (event == null) { |
| 216 |
|
|
| 217 | 4 |
BexeeMessage message = ctx.removeMessage(); |
| 218 |
|
|
| 219 | 4 |
if (message == null) { |
| 220 | 0 |
throw new AwaitMessageException(receive); |
| 221 |
} else {
|
|
| 222 | 4 |
event = new Event(receive);
|
| 223 |
|
|
| 224 |
// copy received value into context
|
|
| 225 | 4 |
Variable var = receive.getVariable(); |
| 226 | 4 |
ctx.setVariable(var, message.getParts()); |
| 227 |
|
|
| 228 | 4 |
ctx.addEvent(event); |
| 229 |
} |
|
| 230 |
} |
|
| 231 |
} |
|
| 232 |
|
|
| 233 | 6 |
public void process(Assign assign, ProcessInstance instance) |
| 234 |
throws Exception {
|
|
| 235 |
|
|
| 236 | 6 |
log(assign); |
| 237 |
|
|
| 238 | 6 |
BPELProcess process = instance.getProcess(); |
| 239 | 6 |
ProcessContext ctx = instance.getContext(); |
| 240 |
|
|
| 241 | 6 |
Event event = ctx.getEvent(assign); |
| 242 | 6 |
if (event == null) { |
| 243 |
|
|
| 244 |
// event creation
|
|
| 245 | 6 |
event = new Event(assign);
|
| 246 |
|
|
| 247 |
// get the copy of this assign
|
|
| 248 | 6 |
Copy copy = assign.getCopy(); |
| 249 |
|
|
| 250 |
// get from information
|
|
| 251 | 6 |
From from = copy.getFrom(); |
| 252 | 6 |
Variable fromVar = from.getVariable(); |
| 253 | 6 |
String fromVarPart = from.getPart(); |
| 254 |
|
|
| 255 |
// get to information
|
|
| 256 | 6 |
To to = copy.getTo(); |
| 257 | 6 |
Variable toVar = to.getVariable(); |
| 258 | 6 |
String toVarPart = to.getPart(); |
| 259 |
|
|
| 260 |
// get the from variable part and assign it
|
|
| 261 | 6 |
Object variablePart = ctx.getVariablePart(fromVar, fromVarPart); |
| 262 |
|
|
| 263 |
// this is some magic just for demonstration purposes
|
|
| 264 |
//
|
|
| 265 | 6 |
String responseString = "";
|
| 266 |
|
|
| 267 | 6 |
if (assign.getName() != null |
| 268 |
&& assign.getName().indexOf("Response") != -1) {
|
|
| 269 | 2 |
Collection varIds = ctx.getVariablesIdentifiers(); |
| 270 | 2 |
for (Iterator iter = varIds.iterator(); iter.hasNext();) {
|
| 271 | 6 |
Variable variable = (Variable) iter.next(); |
| 272 | 6 |
Collection parts = ctx.getVariable(variable).values(); |
| 273 | 6 |
for (Iterator iterator = parts.iterator(); iterator
|
| 274 |
.hasNext();) {
|
|
| 275 | 6 |
Object element = (Object) iterator.next(); |
| 276 | 6 |
if (element != null) { |
| 277 | 6 |
responseString += "} {" + element.toString();
|
| 278 |
} |
|
| 279 |
} |
|
| 280 |
} |
|
| 281 | 2 |
variablePart = responseString; |
| 282 |
} |
|
| 283 |
|
|
| 284 | 6 |
ctx.setVariablePart(toVar, toVarPart, variablePart); |
| 285 | 6 |
ctx.addEvent(event); |
| 286 |
} |
|
| 287 |
} |
|
| 288 |
|
|
| 289 | 8 |
public void process(Invoke invoke, ProcessInstance instance) |
| 290 |
throws Exception {
|
|
| 291 |
|
|
| 292 | 8 |
log(invoke); |
| 293 |
|
|
| 294 |
// initialize objects
|
|
| 295 |
//
|
|
| 296 | 8 |
ProcessContext ctx = instance.getContext(); |
| 297 | 8 |
BPELProcess process = instance.getProcess(); |
| 298 |
|
|
| 299 | 8 |
Event event = ctx.getEvent(invoke); |
| 300 | 8 |
if (event == null) { |
| 301 |
|
|
| 302 |
// event creation
|
|
| 303 | 8 |
event = new Event(invoke);
|
| 304 |
|
|
| 305 |
// get in variable value
|
|
| 306 | 8 |
Variable inVar = invoke.getInputVariable(); |
| 307 | 8 |
Map inVarParts = ctx.getVariable(inVar); |
| 308 | 8 |
Object[] variablePartsAsArray = inVarParts.values().toArray(); |
| 309 |
|
|
| 310 |
// get out variable value
|
|
| 311 | 8 |
Variable outVar = invoke.getOutputVariable(); |
| 312 | 8 |
Map outVarParts = ctx.getVariable(outVar); |
| 313 |
|
|
| 314 |
// get infos about the web service to be invoked
|
|
| 315 | 8 |
String operationName = invoke.getOperation(); |
| 316 | 8 |
QName portTypeName = invoke.getPortType(); |
| 317 |
|
|
| 318 |
// traverse definition in order to find information about the call
|
|
| 319 | 8 |
Definition definition = findWSDL(portTypeName, process); |
| 320 | 8 |
PortType portType = definition.getPortType(portTypeName); |
| 321 | 8 |
Operation operationType = portType.getOperation(operationName, |
| 322 |
null, null); |
|
| 323 | 8 |
Message inMessage = operationType.getInput().getMessage(); |
| 324 | 8 |
Object[] messageParts = inMessage.getParts().values().toArray(); |
| 325 |
|
|
| 326 | 8 |
Binding binding = findBinding(definition, portTypeName); |
| 327 | 8 |
Port port = findPort(definition, binding); |
| 328 | 8 |
SOAPAddress soapAddress = findSOAPAddress(port); |
| 329 |
|
|
| 330 |
// build service call
|
|
| 331 | 8 |
Service service = new Service();
|
| 332 | 8 |
Call call = (Call) service.createCall(); |
| 333 | 8 |
call.setTargetEndpointAddress(soapAddress.getLocationURI()); |
| 334 | 8 |
call.setPortName(invoke.getPortType()); |
| 335 | 8 |
call.setOperationName(invoke.getOperation()); |
| 336 |
|
|
| 337 |
// add parameters to the call
|
|
| 338 | 8 |
for (int i = 0; i < messageParts.length; i++) { |
| 339 | 8 |
Part messagePart = (Part) messageParts[i]; |
| 340 | 8 |
call.addParameter(messagePart.getName(), messagePart |
| 341 |
.getTypeName(), ParameterMode.IN); |
|
| 342 |
} |
|
| 343 | 8 |
call.setReturnType(Constants.XSD_STRING); |
| 344 |
|
|
| 345 |
// this will be the result of the invoke
|
|
| 346 | 8 |
Object result = null;
|
| 347 |
|
|
| 348 |
// call synchronously
|
|
| 349 | 8 |
if (invoke.isSynchronous()) {
|
| 350 | 8 |
result = call.invoke(variablePartsAsArray); |
| 351 |
} |
|
| 352 |
// call asynchronously
|
|
| 353 |
else {
|
|
| 354 |
// TODO asynchronous call in new thread
|
|
| 355 |
} |
|
| 356 |
|
|
| 357 |
// assign result to the variable
|
|
| 358 | 0 |
Variable variable = invoke.getOutputVariable(); |
| 359 | 0 |
Message outMessage = operationType.getOutput().getMessage(); |
| 360 | 0 |
Object[] outparts = outMessage.getParts().values().toArray(); |
| 361 | 0 |
for (int i = 0; i < outparts.length; i++) { |
| 362 | 0 |
Part messagePart = (Part) messageParts[i]; |
| 363 | 0 |
ctx.setVariablePart(variable, messagePart.getName(), result); |
| 364 |
} |
|
| 365 |
|
|
| 366 | 0 |
ctx.addEvent(event); |
| 367 |
} |
|
| 368 |
} |
|
| 369 |
|
|
| 370 | 8 |
private Definition findWSDL(QName portTypeName, BPELProcess process) {
|
| 371 |
|
|
| 372 | 8 |
Definition definition = null;
|
| 373 | 8 |
Binding binding = null;
|
| 374 |
|
|
| 375 |
// find the right binding for the portType
|
|
| 376 |
//
|
|
| 377 | 8 |
Collection wsdlCollection = process.getPartnerWSDL(); |
| 378 | 8 |
mainloop: for (Iterator iter = wsdlCollection.iterator(); iter
|
| 379 |
.hasNext();) {
|
|
| 380 | 8 |
definition = (Definition) iter.next(); |
| 381 | 8 |
Collection bindings = definition.getBindings().values(); |
| 382 | 8 |
for (Iterator iterator = bindings.iterator(); iterator.hasNext();) {
|
| 383 | 8 |
binding = (Binding) iterator.next(); |
| 384 | 8 |
if (binding.getPortType().getQName().equals(portTypeName)) {
|
| 385 | 8 |
break mainloop;
|
| 386 |
} |
|
| 387 |
} |
|
| 388 |
} |
|
| 389 | 8 |
return definition;
|
| 390 |
} |
|
| 391 |
|
|
| 392 | 8 |
private Binding findBinding(Definition definition, QName portTypeName) {
|
| 393 |
|
|
| 394 | 8 |
Binding binding = null;
|
| 395 |
|
|
| 396 | 8 |
Collection bindings = definition.getBindings().values(); |
| 397 | 8 |
for (Iterator iterator = bindings.iterator(); iterator.hasNext();) {
|
| 398 | 8 |
binding = (Binding) iterator.next(); |
| 399 | 8 |
if (binding.getPortType().getQName().equals(portTypeName)) {
|