KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jbpm > graph > def > Transition


1 package org.jbpm.graph.def;
2
3 import java.util.*;
4
5 import org.jbpm.graph.exe.*;
6 import org.jbpm.graph.log.*;
7
8 public class Transition extends GraphElement {
9
10   private static final long serialVersionUID = 1L;
11   
12   protected Node from = null;
13   protected Node to = null;
14
15   // event types //////////////////////////////////////////////////////////////
16

17   public static final String JavaDoc[] supportedEventTypes = new String JavaDoc[]{Event.EVENTTYPE_TRANSITION};
18   public String JavaDoc[] getSupportedEventTypes() {
19     return supportedEventTypes;
20   }
21
22   // constructors /////////////////////////////////////////////////////////////
23

24   public Transition() {
25   }
26
27   public Transition(String JavaDoc name) {
28     super(name);
29   }
30
31   // from /////////////////////////////////////////////////////////////////////
32

33   public Node getFrom() {
34     return from;
35   }
36
37   /**
38    * sets the from node unidirectionally. use {@link Node#addLeavingTransition(Transition)}
39    * to get bidirectional relations mgmt.
40    */

41   public void setFrom(Node from) {
42     this.from = from;
43   }
44
45   // to ///////////////////////////////////////////////////////////////////////
46

47   /**
48    * sets the to node unidirectionally. use {@link Node#addArrivingTransition(Transition)}
49    * to get bidirectional relations mgmt.
50    */

51   public void setTo(Node to) {
52     this.to = to;
53   }
54
55   public Node getTo() {
56     return to;
57   }
58
59   // behaviour ////////////////////////////////////////////////////////////////
60

61   /**
62    * passes execution over this transition.
63    */

64   public void take(ExecutionContext executionContext) {
65     // update the runtime context information
66
executionContext.getToken().setNode(null);
67     
68     Token token = executionContext.getToken();
69     
70     // start the transition log
71
TransitionLog transitionLog = new TransitionLog(this, executionContext.getTransitionSource());
72     token.startCompositeLog(transitionLog);
73     try {
74       
75       // fire leave events for superstates (if any)
76
fireSuperStateLeaveEvents(executionContext);
77       
78       // fire the transition event (if any)
79
fireEvent(Event.EVENTTYPE_TRANSITION, executionContext);
80       
81       // fire enter events for superstates (if any)
82
Node destination = fireSuperStateEnterEvents(executionContext);
83       // update the ultimate destinationNode of this transition
84
transitionLog.setDestinationNode(destination);
85       
86     } finally {
87       // end the transition log
88
token.endCompositeLog();
89     }
90     
91     // pass the token to the destinationNode node
92
to.enter(executionContext);
93   }
94
95   private Node fireSuperStateEnterEvents(ExecutionContext executionContext) {
96     // calculate the actual destinationNode node
97
Node destination = to;
98     while (destination instanceof SuperState) {
99       destination = (Node) ((SuperState) destination).getNodes().get(0);
100     }
101     
102     // performance optimisation: check if at least there is a candidate superstate to be entered.
103
if ( destination.getSuperState()!=null ) {
104       // collect all the superstates being left
105
List leavingSuperStates = collectAllSuperStates(destination, from);
106       // reverse the order so that events are fired from outer to inner superstates
107
Collections.reverse(leavingSuperStates);
108       // fire a superstate-enter event for all superstates being left
109
fireSuperStateEvents(leavingSuperStates, Event.EVENTTYPE_SUPERSTATE_ENTER, executionContext);
110     }
111     
112     return destination;
113   }
114
115   private void fireSuperStateLeaveEvents(ExecutionContext executionContext) {
116     // performance optimisation: check if at least there is a candidate superstate to be left.
117
if (executionContext.getTransitionSource().getSuperState()!=null) {
118       // collect all the superstates being left
119
List leavingSuperStates = collectAllSuperStates(executionContext.getTransitionSource(), to);
120       // fire a node-leave event for all superstates being left
121
fireSuperStateEvents(leavingSuperStates, Event.EVENTTYPE_SUPERSTATE_LEAVE, executionContext);
122     }
123   }
124
125   /**
126    * collect all superstates of a that do not contain node b.
127    */

128   private static List collectAllSuperStates(Node a, Node b) {
129     SuperState superState = a.getSuperState();
130     List leavingSuperStates = new ArrayList();
131     while (superState!=null) {
132       if (!superState.containsNode(b)) {
133         leavingSuperStates.add(superState);
134         superState = superState.getSuperState();
135       } else {
136         superState = null;
137       }
138     }
139     return leavingSuperStates;
140   }
141
142   /**
143    * fires the give event on all the superstates in the list.
144    */

145   private void fireSuperStateEvents(List superStates, String JavaDoc eventType, ExecutionContext executionContext) {
146     Iterator iter = superStates.iterator();
147     while (iter.hasNext()) {
148       SuperState leavingSuperState = (SuperState) iter.next();
149       leavingSuperState.fireEvent(eventType, executionContext);
150     }
151   }
152
153   // other
154
/////////////////////////////////////////////////////////////////////////////
155

156   public void setName(String JavaDoc name) {
157     if (from!=null) {
158       if ( from.hasLeavingTransition(name) ) {
159         throw new IllegalArgumentException JavaDoc("couldn't set name '"+name+"' on transition '"+this+"'cause the from-node of this transition has already another leaving transition with the same name");
160       }
161       Map fromLeavingTransitions = from.getLeavingTransitionsMap();
162       fromLeavingTransitions.remove(this.name);
163       fromLeavingTransitions.put(name,this);
164     }
165     this.name = name;
166   }
167
168   public GraphElement getParent() {
169     GraphElement parent = null;
170     if ( (from!=null)
171          && (to!=null) ) {
172       if (from==to) {
173         parent = from.getParent();
174       } else {
175         List fromParentChain = from.getParentChain();
176         List toParentChain = to.getParentChain();
177         Iterator fromIter = fromParentChain.iterator();
178         while ( fromIter.hasNext() && (parent==null) ) {
179           GraphElement fromParent = (GraphElement) fromIter.next();
180           Iterator toIter = toParentChain.iterator();
181           while ( toIter.hasNext() && (parent==null) ) {
182             GraphElement toParent = (GraphElement) toIter.next();
183             if (fromParent==toParent) {
184               parent = fromParent;
185             }
186           }
187         }
188       }
189     }
190     return parent;
191   }
192 }
193
Popular Tags