1 package org.jbpm.graph.exe; 2 3 import java.io.*; 4 import java.util.*; 5 import org.jbpm.graph.def.*; 6 import org.jbpm.graph.log.*; 7 import org.jbpm.logging.exe.*; 8 import org.jbpm.logging.log.*; 9 10 16 public class Token implements Serializable { 17 18 private static final long serialVersionUID = 1L; 19 20 long id = 0; 21 protected String name = null; 22 protected Date start = null; 23 protected Date end = null; 24 protected Node node = null; 25 protected Date nodeEnter = null; 26 protected ProcessInstance processInstance = null; 27 protected Token parent = null; 28 protected Map children = null; 29 protected List comments = null; 30 protected ProcessInstance subProcessInstance = null; 31 protected int nextLogIndex = 0; 32 boolean isAbleToReactivateParent = true; 33 boolean isTerminationImplicit = false; 34 35 transient List logs = null; 40 transient CompositeLog currentOperationLog = null; 41 42 45 public Token() { 46 } 47 48 51 public Token(ProcessInstance processInstance) { 52 this.start = new Date(); 53 this.processInstance = processInstance; 54 this.node = processInstance.getProcessDefinition().getStartState(); 55 this.isTerminationImplicit = processInstance.getProcessDefinition().isTerminationImplicit(); 56 } 57 58 61 public Token(Token parent, String name) { 62 this.start = new Date(); 63 this.processInstance = parent.getProcessInstance(); 64 this.name = name; 65 this.node = parent.node; 66 this.parent = parent; 67 parent.addChild(this); 68 this.isTerminationImplicit = parent.isTerminationImplicit; 69 this.currentOperationLog = parent.currentOperationLog; 70 71 parent.addLog(new TokenCreateLog(this)); 72 } 73 74 77 private void addChild(Token token) { 78 if (children==null) { 79 children = new HashMap(); 80 } 81 children.put(token.getName(), token); 82 } 83 84 88 public void signal() { 89 if ( (node == null) || (node.getDefaultLeavingTransition() == null)) { 90 throw new IllegalStateException ("couldn't signal token '" + this + "' : couldn't leave node '" + node + "' over its default transition"); 91 } 92 signal(node.getDefaultLeavingTransition()); 93 } 94 95 99 public void signal(String transitionName) { 100 if ((node == null) || (node.getLeavingTransition(transitionName) == null)) { 101 throw new IllegalStateException ("couldn't signal token '" + this + "' : couldn't leave node '" + node + "' over the its transition '" + transitionName 102 + "'"); 103 } 104 signal(node.getLeavingTransition(transitionName)); 105 } 106 107 111 public void signal(Transition transition) { 112 if (transition == null) { 113 throw new IllegalArgumentException ("couldn't signal without specifying a leaving transition : transition is null"); 114 } 115 116 startCompositeLog(new SignalLog(transition)); 117 try { 118 119 ExecutionContext executionContext = new ExecutionContext(this); 121 122 Node signalNode = node; 124 signalNode.fireEvent(Event.EVENTTYPE_BEFORE_SIGNAL, executionContext); 125 126 node.leave(executionContext, transition); 128 129 checkImplicitTermination(); 131 132 signalNode.fireEvent(Event.EVENTTYPE_AFTER_SIGNAL, executionContext); 134 135 } finally { 136 endCompositeLog(); 137 } 138 } 139 140 145 public void end() { 146 end(true); 147 } 148 149 155 public void end(boolean verifyParentTermination) { 156 if (end==null) { 158 159 isAbleToReactivateParent = false; 161 162 this.end = new Date(); 165 166 if (children != null) { 168 Iterator iter = children.values().iterator(); 169 while (iter.hasNext()) { 170 Token child = (Token) iter.next(); 171 if (!child.hasEnded()) { 172 child.end(); 173 } 174 } 175 } 176 177 if (parent!=null) { 179 parent.addLog(new TokenEndLog(this)); 181 } 182 183 if (verifyParentTermination) { 184 notifyParentOfTokenEnd(); 187 } 188 } 189 } 190 191 193 public void addComment(String message) { 194 addComment(new Comment(message)); 195 } 196 197 public void addComment(Comment comment) { 198 if (comments==null) comments = new ArrayList(); 199 comments.add(comment); 200 comment.setToken(this); 201 } 202 203 public List getComments() { 204 return comments; 205 } 206 207 209 212 private void notifyParentOfTokenEnd() { 213 if (isRoot()) { 214 processInstance.end(); 215 } else { 216 217 if (!parent.hasActiveChildren()) { 218 parent.end(); 219 } 220 } 221 } 222 223 226 public boolean hasActiveChildren() { 227 boolean foundActiveChildToken = false; 228 Iterator iter = children.values().iterator(); 231 while ((iter.hasNext()) && (!foundActiveChildToken)) { 232 Token child = (Token) iter.next(); 233 if (!child.hasEnded()) { 234 foundActiveChildToken = true; 235 } 236 } 237 return foundActiveChildToken; 238 } 239 240 242 245 public void addLog(ProcessLog processLog) { 246 LoggingInstance li = (LoggingInstance) processInstance.getInstance(LoggingInstance.class); 247 if (li != null) { 248 processLog.setToken(this); 249 li.addLog(processLog); 250 } 251 } 252 256 public void startCompositeLog(CompositeLog compositeLog) { 257 LoggingInstance li = (LoggingInstance) processInstance.getInstance(LoggingInstance.class); 258 if (li != null) { 259 compositeLog.setToken(this); 260 li.startCompositeLog(compositeLog); 261 } 262 } 263 266 public void endCompositeLog() { 267 LoggingInstance li = (LoggingInstance) processInstance.getInstance(LoggingInstance.class); 268 if (li != null) { 269 li.endCompositeLog(); 270 } 271 } 272 273 275 public String toString() { 276 return "Token("+getFullName()+")"; 277 } 278 279 public boolean hasEnded() { 280 return (end != null); 281 } 282 283 public boolean isRoot() { 284 return (parent == null); 285 } 286 287 public boolean hasParent() { 288 return (parent != null); 289 } 290 291 public boolean hasChild(String name) { 292 return (children != null ? children.containsKey(name) : false); 293 } 294 295 public Token getChild(String name) { 296 Token child = null; 297 if (children != null) { 298 child = (Token) children.get(name); 299 } 300 return child; 301 } 302 303 public String getFullName() { 304 if (parent==null) return "/"; 305 if (parent.getParent()==null) return "/"+name; 306 return parent.getFullName()+"/"+name; 307 } 308 309 public List getChildrenAtNode(Node aNode) { 310 List foundChildren = new ArrayList(); 311 getChildrenAtNode(aNode, foundChildren); 312 return foundChildren; 313 } 314 315 private void getChildrenAtNode(Node aNode, List foundTokens) { 316 if(aNode.equals(node)) { 317 foundTokens.add(this); 318 } 319 else if(children != null && !children.isEmpty()) { 320 for(Iterator it = children.values().iterator(); it.hasNext();) { 321 Token aChild = (Token)it.next(); 322 aChild.getChildrenAtNode(aNode, foundTokens); 323 } 324 } 325 } 326 327 public Token findToken(String relativeTokenPath) { 328 if (relativeTokenPath == null) 329 return null; 330 String path = relativeTokenPath.trim(); 331 if (("".equals(path)) || (".".equals(path))) { 332 return this; 333 } 334 if ("..".equals(path)) { 335 return parent; 336 } 337 if (path.startsWith("/")) { 338 Token root = processInstance.getRootToken(); 339 return root.findToken(path.substring(1)); 340 } 341 if (path.startsWith("./")) { 342 return findToken(path.substring(2)); 343 } 344 if (path.startsWith("../")) { 345 if (parent != null) { 346 return parent.findToken(path.substring(3)); 347 } 348 return null; 349 } 350 int slashIndex = path.indexOf('/'); 351 if (slashIndex == -1) { 352 return (Token) (children != null ? children.get(path) : null); 353 } 354 Token token = null; 355 String name = path.substring(0, slashIndex); 356 token = (Token) children.get(name); 357 if (token != null) { 358 return token.findToken(path.substring(slashIndex + 1)); 359 } 360 return null; 361 } 362 363 public Map getActiveChildren() { 364 Map activeChildren = new HashMap(); 365 if (children != null) { 366 Iterator iter = children.entrySet().iterator(); 367 while (iter.hasNext()) { 368 Map.Entry entry = (Map.Entry) iter.next(); 369 Token child = (Token) entry.getValue(); 370 if (!child.hasEnded()) { 371 String childName = (String ) entry.getKey(); 372 activeChildren.put(childName, child); 373 } 374 } 375 } 376 return activeChildren; 377 } 378 379 public void checkImplicitTermination() { 380 if (isTerminationImplicit && node.hasNoLeavingTransitions()) { 381 end(); 382 383 if (processInstance.isTerminatedImplicitly()) { 384 processInstance.end(); 385 } 386 } 387 } 388 389 public boolean isTerminatedImplicitly() { 390 if (end != null) return true; 391 392 Map leavingTransitions = node.getLeavingTransitionsMap(); 393 if ((leavingTransitions != null) && (leavingTransitions.size() > 0)) { 394 return false; 396 } 397 398 Iterator iter = getActiveChildren().values().iterator(); 400 while (iter.hasNext()) { 401 Token child = (Token) iter.next(); 402 if (!child.isTerminatedImplicitly()) { 403 return false; 404 } 405 } 406 return true; 408 } 409 410 public int nextLogIndex() { 411 return nextLogIndex++; 412 } 413 414 417 public long getId() { 418 return id; 419 } 420 public Date getStart() { 421 return start; 422 } 423 public Date getEnd() { 424 return end; 425 } 426 public String getName() { 427 return name; 428 } 429 public ProcessInstance getProcessInstance() { 430 return processInstance; 431 } 432 public Map getChildren() { 433 return children; 434 } 435 public Node getNode() { 436 return node; 437 } 438 public void setNode(Node node) { 439 this.node = node; 440 } 441 public Token getParent() { 442 return parent; 443 } 444 public void setParent(Token parent) { 445 this.parent = parent; 446 } 447 public void setProcessInstance(ProcessInstance processInstance) { 448 this.processInstance = processInstance; 449 } 450 public ProcessInstance getSubProcessInstance() { 451 return subProcessInstance; 452 } 453 public void setSubProcessInstance(ProcessInstance subProcessInstance) { 454 this.subProcessInstance = subProcessInstance; 455 } 456 public Date getNodeEnter() { 457 return nodeEnter; 458 } 459 public void setNodeEnter(Date nodeEnter) { 460 this.nodeEnter = nodeEnter; 461 } 462 public boolean isAbleToReactivateParent() { 463 return isAbleToReactivateParent; 464 } 465 public void setAbleToReactivateParent(boolean isAbleToReactivateParent) { 466 this.isAbleToReactivateParent = isAbleToReactivateParent; 467 } 468 public boolean isTerminationImplicit() { 469 return isTerminationImplicit; 470 } 471 public void setTerminationImplicit(boolean isTerminationImplicit) { 472 this.isTerminationImplicit = isTerminationImplicit; 473 } 474 } 476 | Popular Tags |