KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > corba > se > impl > orbutil > fsm > StateEngineImpl


1 /*
2  * @(#)StateEngineImpl.java 1.20 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.corba.se.impl.orbutil.fsm ;
9
10 import java.util.HashMap JavaDoc ;
11 import java.util.HashSet JavaDoc ;
12 import java.util.Set JavaDoc ;
13 import java.util.Iterator JavaDoc ;
14
15 import org.omg.CORBA.INTERNAL JavaDoc ;
16
17 import com.sun.corba.se.impl.orbutil.ORBUtility ;
18
19 import com.sun.corba.se.spi.orbutil.fsm.Input ;
20 import com.sun.corba.se.spi.orbutil.fsm.Guard ;
21 import com.sun.corba.se.spi.orbutil.fsm.Action ;
22 import com.sun.corba.se.spi.orbutil.fsm.ActionBase ;
23 import com.sun.corba.se.spi.orbutil.fsm.State ;
24 import com.sun.corba.se.spi.orbutil.fsm.StateEngine ;
25 import com.sun.corba.se.spi.orbutil.fsm.StateImpl ;
26 import com.sun.corba.se.spi.orbutil.fsm.FSM ;
27 import com.sun.corba.se.spi.orbutil.fsm.FSMImpl ;
28
29 import com.sun.corba.se.impl.orbutil.fsm.GuardedAction ;
30
31 /**
32  * Encodes the state transition function for a finite state machine.
33  *
34  * @author Ken Cavanaugh
35  */

36 public class StateEngineImpl implements StateEngine
37 {
38     // An action that does nothing at all.
39
private static Action emptyAction = new ActionBase( "Empty" )
40     {
41     public void doIt( FSM fsm, Input in )
42     {
43     }
44     } ;
45
46     private boolean initializing ;
47     private Action defaultAction ;
48
49     public StateEngineImpl()
50     {
51     initializing = true ;
52     defaultAction = new ActionBase("Invalid Transition")
53         {
54         public void doIt( FSM fsm, Input in )
55         {
56             throw new INTERNAL JavaDoc(
57             "Invalid transition attempted from " +
58                 fsm.getState() + " under " + in ) ;
59         }
60         } ;
61     }
62
63     public StateEngine add( State oldState, Input input, Guard guard, Action action,
64     State newState ) throws IllegalArgumentException JavaDoc,
65     IllegalStateException JavaDoc
66     {
67     mustBeInitializing() ;
68
69     StateImpl oldStateImpl = (StateImpl)oldState ;
70     GuardedAction ga = new GuardedAction( guard, action, newState ) ;
71     oldStateImpl.addGuardedAction( input, ga ) ;
72
73     return this ;
74     }
75
76     public StateEngine add( State oldState, Input input, Action action,
77     State newState ) throws IllegalArgumentException JavaDoc,
78     IllegalStateException JavaDoc
79     {
80     mustBeInitializing() ;
81
82     StateImpl oldStateImpl = (StateImpl)oldState ;
83     GuardedAction ta = new GuardedAction( action, newState ) ;
84     oldStateImpl.addGuardedAction( input, ta ) ;
85
86     return this ;
87     }
88
89     public StateEngine setDefault( State oldState, Action action, State newState )
90     throws IllegalArgumentException JavaDoc, IllegalStateException JavaDoc
91     {
92     mustBeInitializing() ;
93
94     StateImpl oldStateImpl = (StateImpl)oldState ;
95     oldStateImpl.setDefaultAction( action ) ;
96     oldStateImpl.setDefaultNextState( newState ) ;
97
98     return this ;
99     }
100
101     public StateEngine setDefault( State oldState, State newState )
102     throws IllegalArgumentException JavaDoc, IllegalStateException JavaDoc
103     {
104     return setDefault( oldState, emptyAction, newState ) ;
105     }
106
107     public StateEngine setDefault( State oldState )
108     throws IllegalArgumentException JavaDoc, IllegalStateException JavaDoc
109     {
110     return setDefault( oldState, oldState ) ;
111     }
112
113     public void done() throws IllegalStateException JavaDoc
114     {
115     mustBeInitializing() ;
116
117     // optimize FSM here if desired. For example,
118
// we could choose different strategies for implementing
119
// the state transition function based on the distribution
120
// of values for states and input labels.
121

122     initializing = false ;
123     }
124
125     public void setDefaultAction( Action act ) throws IllegalStateException JavaDoc
126     {
127     mustBeInitializing() ;
128     defaultAction = act ;
129     }
130
131     public void doIt( FSM fsm, Input in, boolean debug )
132     {
133     // This method is present only for debugging.
134
// innerDoIt does the actual transition.
135

136     if (debug)
137         ORBUtility.dprint( this, "doIt enter: currentState = " +
138         fsm.getState() + " in = " + in ) ;
139
140     try {
141         innerDoIt( fsm, in, debug ) ;
142     } finally {
143         if (debug)
144         ORBUtility.dprint( this, "doIt exit" ) ;
145     }
146     }
147
148     private StateImpl getDefaultNextState( StateImpl currentState )
149     {
150     // Use the currentState defaults if
151
// set, otherwise use the state engine default.
152
StateImpl nextState = (StateImpl)currentState.getDefaultNextState() ;
153     if (nextState == null)
154         // The state engine default never changes the state
155
nextState = currentState ;
156
157     return nextState ;
158     }
159
160     private Action getDefaultAction( StateImpl currentState )
161     {
162     Action action = currentState.getDefaultAction() ;
163     if (action == null)
164         action = defaultAction ;
165
166     return action ;
167     }
168
169     private void innerDoIt( FSM fsm, Input in, boolean debug )
170     {
171     if (debug) {
172         ORBUtility.dprint( this, "Calling innerDoIt with input " + in ) ;
173     }
174
175     // Locals needed for performing the state transition, once we determine
176
// the required transition.
177
StateImpl currentState = null ;
178     StateImpl nextState = null ;
179     Action action = null ;
180
181     // Do until no guard has deferred.
182
boolean deferral = false ;
183     do {
184         deferral = false ; // clear this after each deferral!
185
currentState = (StateImpl)fsm.getState() ;
186         nextState = getDefaultNextState( currentState ) ;
187         action = getDefaultAction( currentState ) ;
188
189         if (debug) {
190         ORBUtility.dprint( this, "currentState = " + currentState ) ;
191         ORBUtility.dprint( this, "in = " + in ) ;
192         ORBUtility.dprint( this, "default nextState = " + nextState ) ;
193         ORBUtility.dprint( this, "default action = " + action ) ;
194         }
195
196         Set JavaDoc gas = currentState.getGuardedActions(in) ;
197         if (gas != null) {
198         Iterator JavaDoc iter = gas.iterator() ;
199
200         // Search for a guard that is not DISABLED.
201
// All DISABLED means use defaults.
202
while (iter.hasNext()) {
203             GuardedAction ga = (GuardedAction)iter.next() ;
204             Guard.Result gr = ga.getGuard().evaluate( fsm, in ) ;
205             if (debug)
206             ORBUtility.dprint( this,
207                 "doIt: evaluated " + ga + " with result " + gr ) ;
208
209             if (gr == Guard.Result.ENABLED) {
210             // ga has the next state and action.
211
nextState = (StateImpl)ga.getNextState() ;
212             action = ga.getAction() ;
213             if (debug) {
214                 ORBUtility.dprint( this, "nextState = " + nextState ) ;
215                 ORBUtility.dprint( this, "action = " + action ) ;
216             }
217             break ;
218             } else if (gr == Guard.Result.DEFERED) {
219             deferral = true ;
220             break ;
221             }
222         }
223         }
224     } while (deferral) ;
225
226     performStateTransition( fsm, in, nextState, action, debug ) ;
227     }
228
229     private void performStateTransition( FSM fsm, Input in,
230     StateImpl nextState, Action action, boolean debug )
231     {
232     StateImpl currentState = (StateImpl)fsm.getState() ;
233
234     // Perform the state transition. Pre and post actions are only
235
// performed if the state changes (see UML hidden transitions).
236

237     boolean different = !currentState.equals( nextState ) ;
238
239     if (different) {
240         if (debug)
241         ORBUtility.dprint( this,
242             "doIt: executing postAction for state " + currentState ) ;
243         try {
244         currentState.postAction( fsm ) ;
245         } catch (Throwable JavaDoc thr) {
246         if (debug)
247             ORBUtility.dprint( this,
248             "doIt: postAction threw " + thr ) ;
249
250         if (thr instanceof ThreadDeath JavaDoc)
251             throw (ThreadDeath JavaDoc)thr ;
252         }
253     }
254
255     try {
256         // Note that action may be null in a transition, which simply
257
// means that no action is needed. Note that action.doIt may
258
// throw an exception, in which case the exception is
259
// propagated after making sure that the transition is properly
260
// completed.
261
if (action != null)
262         action.doIt( fsm, in ) ;
263     } finally {
264         if (different) {
265         if (debug)
266             ORBUtility.dprint( this,
267             "doIt: executing preAction for state " + nextState ) ;
268
269         try {
270             nextState.preAction( fsm ) ;
271         } catch (Throwable JavaDoc thr) {
272             if (debug)
273             ORBUtility.dprint( this,
274                 "doIt: preAction threw " + thr ) ;
275
276             if (thr instanceof ThreadDeath JavaDoc)
277             throw (ThreadDeath JavaDoc)thr ;
278         }
279
280         ((FSMImpl)fsm).internalSetState( nextState ) ;
281         }
282
283         if (debug)
284         ORBUtility.dprint( this, "doIt: state is now " + nextState ) ;
285     }
286     }
287
288     public FSM makeFSM( State startState ) throws IllegalStateException JavaDoc
289     {
290     mustNotBeInitializing() ;
291
292     return new FSMImpl( this, startState ) ;
293     }
294
295     private void mustBeInitializing() throws IllegalStateException JavaDoc
296     {
297     if (!initializing)
298         throw new IllegalStateException JavaDoc(
299         "Invalid method call after initialization completed" ) ;
300     }
301
302     private void mustNotBeInitializing() throws IllegalStateException JavaDoc
303     {
304     if (initializing)
305         throw new IllegalStateException JavaDoc(
306         "Invalid method call before initialization completed" ) ;
307     }
308 }
309
310 // end of StateEngineImpl.java
311

312
Popular Tags