summaryrefslogtreecommitdiff
path: root/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm
diff options
context:
space:
mode:
Diffstat (limited to 'src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm')
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Action.java55
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/ActionBase.java32
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSM.java56
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMImpl.java114
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMTest.java227
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Guard.java102
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/GuardBase.java32
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Input.java41
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/InputImpl.java32
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/State.java56
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngine.java109
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngineFactory.java42
-rw-r--r--src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateImpl.java98
13 files changed, 996 insertions, 0 deletions
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Action.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Action.java
new file mode 100644
index 0000000..296602e
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Action.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm;
+
+/**
+ * Description goes here
+ *
+ * @author Ken Cavanaugh
+ */
+public interface Action
+{
+ /** Called by the state engine to perform an action
+ * before a state transition takes place. The FSM is
+ * passed so that the Action may set the next state in
+ * cases when that is required. FSM and Input together
+ * allow actions to be written that depend on the state and
+ * input, but this should generally be avoided, as the
+ * reason for a state machine in the first place is to cleanly
+ * separate the actions and control flow. Note that an
+ * action should complete in a timely manner. If the state machine
+ * is used for concurrency control with multiple threads, the
+ * action must not allow multiple threads to run simultaneously
+ * in the state machine, as the state could be corrupted.
+ * Any exception thrown by the Action for the transition
+ * will be propagated to doIt.
+ * @param fsm the state machine causing this action.
+ * @param in the input that caused the transition.
+ */
+ public void doIt( FSM fsm, Input in ) ;
+}
+
+// end of Action.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/ActionBase.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/ActionBase.java
new file mode 100644
index 0000000..5b590eb
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/ActionBase.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import com.sun.corba.se.impl.orbutil.fsm.NameBase ;
+
+public abstract class ActionBase extends NameBase implements Action {
+ public ActionBase( String name ) { super( name ) ; }
+}
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSM.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSM.java
new file mode 100644
index 0000000..4ca832f
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSM.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+/**
+ * An FSM is used to represent an instance of a finite state machine
+ * which has a transition function represented by an instance of
+ * StateEngine. An instance of an FSM may be created either by calling
+ * StateEngine.makeFSM( startState ) on a state engine, or by extending FSMImpl and
+ * using a constructor. Using FSMImpl as a base class is convenient if
+ * additional state is associated with the FSM beyond that encoded
+ * by the current state. This is especially convenient if an action
+ * needs some additional information. For example, counters are best
+ * handled by special actions rather than encoding a bounded counter
+ * in a state machine. It is also possible to create a class that
+ * implements the FSM interface by delegating to an FSM instance
+ * created by StateEngine.makeFSM.
+ *
+ * @author Ken Cavanaugh
+ */
+public interface FSM
+{
+ /** Get the current state of this FSM.
+ */
+ public State getState() ;
+
+ /** Perform the action and transition to the next state based
+ * on the current state of the FSM and the input.
+ */
+ public void doIt( Input in ) ;
+}
+
+// end of FSM.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMImpl.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMImpl.java
new file mode 100644
index 0000000..1674eba
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMImpl.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import java.util.Set ;
+import java.util.HashSet ;
+
+import com.sun.corba.se.spi.orbutil.fsm.Input ;
+import com.sun.corba.se.spi.orbutil.fsm.StateEngine ;
+import com.sun.corba.se.impl.orbutil.fsm.StateEngineImpl ;
+import com.sun.corba.se.impl.orbutil.ORBUtility ;
+import com.sun.corba.se.spi.orbutil.fsm.FSM ;
+
+/**
+ * This is the main class that represents an instance of a state machine
+ * using a state engine. It may be used as a base class, in which case
+ * the guards and actions have access to the derived class.
+ *
+ * @author Ken Cavanaugh
+ */
+public class FSMImpl implements FSM
+{
+ private boolean debug ;
+ private State state ;
+ private StateEngineImpl stateEngine ;
+
+ /** Create an instance of an FSM using the StateEngine
+ * in a particular start state.
+ */
+ public FSMImpl( StateEngine se, State startState )
+ {
+ this( se, startState, false ) ;
+ }
+
+ public FSMImpl( StateEngine se, State startState, boolean debug )
+ {
+ state = startState ;
+ stateEngine = (StateEngineImpl)se ;
+ this.debug = debug ;
+ }
+
+ /** Return the current state.
+ */
+ public State getState()
+ {
+ return state ;
+ }
+
+ /** Perform the transition for the given input in the current state. This proceeds as follows:
+ * <p>Let S be the current state of the FSM.
+ * If there are guarded actions for S with input in, evaluate their guards successively until
+ * all have been evaluted, or one returns a non-DISABLED Result.
+ * <ol>
+ * <li>If a DEFERED result is returned, retry the input
+ * <li>If a ENABLED result is returned, the action for the guarded action
+ * is the current action
+ * <li>Otherwise there is no enabled action. If S has a default action and next state, use them; otherwise
+ * use the state engine default action (the next state is always the current state).
+ * </ol>
+ * After the action is available, the transition proceeds as follows:
+ * <ol>
+ * <li>If the next state is not the current state, execute the current state postAction method.
+ * <li>Execute the action.
+ * <li>If the next state is not the current state, execute the next state preAction method.
+ * <li>Set the current state to the next state.
+ * </ol>
+ */
+ public void doIt( Input in )
+ {
+ stateEngine.doIt( this, in, debug ) ;
+ }
+
+ // Methods for use only by StateEngineImpl
+
+ public void internalSetState( State nextState )
+ {
+ if (debug) {
+ ORBUtility.dprint( this, "Calling internalSetState with nextState = " +
+ nextState ) ;
+ }
+
+ state = nextState ;
+
+ if (debug) {
+ ORBUtility.dprint( this, "Exiting internalSetState with state = " +
+ state ) ;
+ }
+ }
+}
+
+// end of FSMImpl.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMTest.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMTest.java
new file mode 100644
index 0000000..1f3f36d
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/FSMTest.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import com.sun.corba.se.spi.orbutil.fsm.Input ;
+import com.sun.corba.se.spi.orbutil.fsm.Action ;
+import com.sun.corba.se.spi.orbutil.fsm.Guard ;
+import com.sun.corba.se.spi.orbutil.fsm.StateEngine ;
+import com.sun.corba.se.spi.orbutil.fsm.StateImpl ;
+import com.sun.corba.se.spi.orbutil.fsm.StateEngineFactory ;
+import com.sun.corba.se.spi.orbutil.fsm.FSM ;
+
+class TestInput {
+ TestInput( Input value, String msg )
+ {
+ this.value = value ;
+ this.msg = msg ;
+ }
+
+ public String toString()
+ {
+ return "Input " + value + " : " + msg ;
+ }
+
+ public Input getInput()
+ {
+ return value ;
+ }
+
+ Input value ;
+ String msg ;
+}
+
+class TestAction1 implements Action
+{
+ public void doIt( FSM fsm, Input in )
+ {
+ System.out.println( "TestAction1:" ) ;
+ System.out.println( "\tlabel = " + label ) ;
+ System.out.println( "\toldState = " + oldState ) ;
+ System.out.println( "\tnewState = " + newState ) ;
+ if (label != in)
+ throw new Error( "Unexcepted Input " + in ) ;
+ if (oldState != fsm.getState())
+ throw new Error( "Unexpected old State " + fsm.getState() ) ;
+ }
+
+ public TestAction1( State oldState, Input label, State newState )
+ {
+ this.oldState = oldState ;
+ this.newState = newState ;
+ this.label = label ;
+ }
+
+ private State oldState ;
+ private Input label ;
+ private State newState ;
+}
+
+class TestAction2 implements Action
+{
+ private State oldState ;
+ private State newState ;
+
+ public void doIt( FSM fsm, Input in )
+ {
+ System.out.println( "TestAction2:" ) ;
+ System.out.println( "\toldState = " + oldState ) ;
+ System.out.println( "\tnewState = " + newState ) ;
+ System.out.println( "\tinput = " + in ) ;
+ if (oldState != fsm.getState())
+ throw new Error( "Unexpected old State " + fsm.getState() ) ;
+ }
+
+ public TestAction2( State oldState, State newState )
+ {
+ this.oldState = oldState ;
+ this.newState = newState ;
+ }
+}
+
+class TestAction3 implements Action {
+ private State oldState ;
+ private Input label ;
+
+ public void doIt( FSM fsm, Input in )
+ {
+ System.out.println( "TestAction1:" ) ;
+ System.out.println( "\tlabel = " + label ) ;
+ System.out.println( "\toldState = " + oldState ) ;
+ if (label != in)
+ throw new Error( "Unexcepted Input " + in ) ;
+ }
+
+ public TestAction3( State oldState, Input label )
+ {
+ this.oldState = oldState ;
+ this.label = label ;
+ }
+}
+
+class NegateGuard implements Guard {
+ Guard guard ;
+
+ public NegateGuard( Guard guard )
+ {
+ this.guard = guard ;
+ }
+
+ public Guard.Result evaluate( FSM fsm, Input in )
+ {
+ return guard.evaluate( fsm, in ).complement() ;
+ }
+}
+
+class MyFSM extends FSMImpl {
+ public MyFSM( StateEngine se )
+ {
+ super( se, FSMTest.STATE1 ) ;
+ }
+
+ public int counter = 0 ;
+}
+
+public class FSMTest {
+ public static final State STATE1 = new StateImpl( "1" ) ;
+ public static final State STATE2 = new StateImpl( "2" ) ;
+ public static final State STATE3 = new StateImpl( "3" ) ;
+ public static final State STATE4 = new StateImpl( "4" ) ;
+
+ public static final Input INPUT1 = new InputImpl( "1" ) ;
+ public static final Input INPUT2 = new InputImpl( "2" ) ;
+ public static final Input INPUT3 = new InputImpl( "3" ) ;
+ public static final Input INPUT4 = new InputImpl( "4" ) ;
+
+ private Guard counterGuard = new Guard() {
+ public Guard.Result evaluate( FSM fsm, Input in )
+ {
+ MyFSM mfsm = (MyFSM) fsm ;
+ return Guard.Result.convert( mfsm.counter < 3 ) ;
+ }
+ } ;
+
+ private static void add1( StateEngine se, State oldState, Input in, State newState )
+ {
+ se.add( oldState, in, new TestAction1( oldState, in, newState ), newState ) ;
+ }
+
+ private static void add2( StateEngine se, State oldState, State newState )
+ {
+ se.setDefault( oldState, new TestAction2( oldState, newState ), newState ) ;
+ }
+
+ public static void main( String[] args )
+ {
+ TestAction3 ta3 = new TestAction3( STATE3, INPUT1 ) ;
+
+ StateEngine se = StateEngineFactory.create() ;
+ add1( se, STATE1, INPUT1, STATE1 ) ;
+ add2( se, STATE1, STATE2 ) ;
+
+ add1( se, STATE2, INPUT1, STATE2 ) ;
+ add1( se, STATE2, INPUT2, STATE2 ) ;
+ add1( se, STATE2, INPUT3, STATE1 ) ;
+ add1( se, STATE2, INPUT4, STATE3 ) ;
+
+ se.add( STATE3, INPUT1, ta3, STATE3 ) ;
+ se.add( STATE3, INPUT1, ta3, STATE4 ) ;
+ add1( se, STATE3, INPUT2, STATE1 ) ;
+ add1( se, STATE3, INPUT3, STATE2 ) ;
+ add1( se, STATE3, INPUT4, STATE2 ) ;
+
+ MyFSM fsm = new MyFSM( se ) ;
+ TestInput in11 = new TestInput( INPUT1, "1.1" ) ;
+ TestInput in12 = new TestInput( INPUT1, "1.2" ) ;
+ TestInput in21 = new TestInput( INPUT2, "2.1" ) ;
+ TestInput in22 = new TestInput( INPUT2, "2.2" ) ;
+ TestInput in31 = new TestInput( INPUT3, "3.1" ) ;
+ TestInput in32 = new TestInput( INPUT3, "3.2" ) ;
+ TestInput in33 = new TestInput( INPUT3, "3.3" ) ;
+ TestInput in41 = new TestInput( INPUT4, "4.1" ) ;
+
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in12.getInput() ) ;
+ fsm.doIt( in41.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in22.getInput() ) ;
+ fsm.doIt( in31.getInput() ) ;
+ fsm.doIt( in33.getInput() ) ;
+ fsm.doIt( in41.getInput() ) ;
+ fsm.doIt( in41.getInput() ) ;
+ fsm.doIt( in41.getInput() ) ;
+ fsm.doIt( in22.getInput() ) ;
+ fsm.doIt( in32.getInput() ) ;
+ fsm.doIt( in41.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in12.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ fsm.doIt( in11.getInput() ) ;
+ }
+}
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Guard.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Guard.java
new file mode 100644
index 0000000..2fd467c
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Guard.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm;
+
+/**
+ *
+ * @author Ken Cavanaugh
+ */
+public interface Guard
+{
+ public static final class Complement extends GuardBase {
+ private Guard guard ;
+
+ public Complement( GuardBase guard )
+ {
+ super( "not(" + guard.getName() + ")" ) ;
+ this.guard = guard ;
+ }
+
+ public Result evaluate( FSM fsm, Input in )
+ {
+ return guard.evaluate( fsm, in ).complement() ;
+ }
+ }
+
+ public static final class Result {
+ private String name ;
+
+ private Result( String name )
+ {
+ this.name = name ;
+ }
+
+ public static Result convert( boolean res )
+ {
+ return res ? ENABLED : DISABLED ;
+ }
+
+ public Result complement()
+ {
+ if (this == ENABLED)
+ return DISABLED ;
+ else if (this == DISABLED)
+ return ENABLED ;
+ else
+ return DEFERED ;
+ }
+
+ public String toString()
+ {
+ return "Guard.Result[" + name + "]" ;
+ }
+
+ public static final Result ENABLED = new Result( "ENABLED" ) ;
+ public static final Result DISABLED = new Result( "DISABLED" ) ;
+ public static final Result DEFERED = new Result( "DEFERED" ) ;
+ }
+
+ /** Called by the state engine to determine whether a
+ * transition is enabled, defered, or disabled.
+ * The result is interpreted as follows:
+ * <ul>
+ * <li>ENABLED if the transition is ready to proceed
+ * <li>DISABLED if the transition is not ready to proceed
+ * <li>DEFERED if the action associated with the transition
+ * is to be deferred. This means that the input will not be
+ * acted upon, but rather it will be saved for later execution.
+ * Typically this is implemented using a CondVar wait, and the
+ * blocked thread represents the defered input. The defered
+ * input is retried when the thread runs again.
+ * </ul>
+ *
+ * @param fsm is the state machine causing this action.
+ * @param in is the input that caused the transition.
+ */
+ public Result evaluate( FSM fsm, Input in ) ;
+}
+
+// end of Action.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/GuardBase.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/GuardBase.java
new file mode 100644
index 0000000..b84abb9
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/GuardBase.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import com.sun.corba.se.impl.orbutil.fsm.NameBase ;
+
+public abstract class GuardBase extends NameBase implements Guard {
+ public GuardBase( String name ) { super( name ) ; }
+}
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Input.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Input.java
new file mode 100644
index 0000000..9f39958
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/Input.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm;
+
+/**
+ * This interface must be implemented by any class that is used as
+ * an input to a FSM. The FSM only needs the identity of this
+ * object, so all that is really needs is the default equals implementation.
+ * The toString() method should also be overridden to give a concise
+ * description or name of the input.
+ *
+ * @author Ken Cavanaugh
+ */
+public interface Input
+{
+}
+
+// end of Input.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/InputImpl.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/InputImpl.java
new file mode 100644
index 0000000..28bbe86
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/InputImpl.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import com.sun.corba.se.impl.orbutil.fsm.NameBase ;
+
+public class InputImpl extends NameBase implements Input {
+ public InputImpl( String name ) { super( name ) ; }
+}
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/State.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/State.java
new file mode 100644
index 0000000..53ea514
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/State.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+/**
+ * This interface must be implemented by any class that is used as
+ * a state in a FSM. The FSM only needs the identity of this
+ * object, so all that is really needs is the default equals implementation.
+ * The toString() method should also be overridden to give a concise
+ * description or name of the state. The StateImpl class handles this.
+ * <P>
+ * Pre- and post- actions are taken only on completed transitions between
+ * different states. Assume that the FSM is in state A, and the FSM will
+ * transition to state B under input I with action X. If A != B and X completes
+ * successfully, then after X completes execution, A.postAction is executed,
+ * followed by B.preAction.
+ *
+ * @author Ken Cavanaugh
+ */
+public interface State
+{
+ /** Method that defines action that occurs whenever this state is entered.
+ * Any exceptions thrown by this method are ignored.
+ */
+ void preAction( FSM fsm ) ;
+
+ /** Method that defines action that occurs whenever this state is exited.
+ * Any exceptions thrown by this method are ignored.
+ */
+ void postAction( FSM fsm ) ;
+}
+
+// end of State.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngine.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngine.java
new file mode 100644
index 0000000..e9d8624
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngine.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm;
+
+/**
+ * A StateEngine defines the state transition function for a
+ * finite state machine (FSM). A FSM always has a current state.
+ * In response to an Input, the FSM performs an Action and
+ * makes a transition to a new state. Note that any object can
+ * be used as an input if it supports the Input interface.
+ * For example, a protocol message may be an input. The FSM
+ * uses only the result of calling getLabel on the Input to
+ * drive the transition.
+ * <p>
+ * The function can be non-deterministic
+ * in that the same input may cause transitions to different new
+ * states from the current state. In this case, the action that
+ * is executed for the transition must set the correct new state.
+ *
+ * @author Ken Cavanaugh
+ */
+public interface StateEngine
+{
+ /** Add a new transition (old,in,guard,act,new) to the state engine.
+ * Multiple calls to add with the same old and in are permitted,
+ * in which case only a transition in which the guard evaluates to
+ * true will be taken. If no such transition is enabled, a default
+ * will be taken. If more than one transition is enabled, one will
+ * be chosen arbitrarily.
+ * This method can only be called before done(). An attempt to
+ * call it after done() results in an IllegalStateException.
+ */
+ public StateEngine add( State oldState, Input input, Guard guard,
+ Action action, State newState ) throws IllegalStateException ;
+
+ /** Add a transition with a guard that always evaluates to true.
+ */
+ public StateEngine add( State oldState, Input input,
+ Action action, State newState ) throws IllegalStateException ;
+
+ /** Set the default transition and action for a state.
+ * This transition will be used if no more specific transition was
+ * defined for the actual input. Repeated calls to this method
+ * simply change the default.
+ * This method can only be called before done(). An attempt to
+ * call it after done() results in an IllegalStateException.
+ */
+ public StateEngine setDefault( State oldState, Action action, State newState )
+ throws IllegalStateException ;
+
+ /** Equivalent to setDefault( oldState, act, newState ) where act is an
+ * action that does nothing.
+ */
+ public StateEngine setDefault( State oldState, State newState )
+ throws IllegalStateException ;
+
+ /** Euaivalent to setDefault( oldState, oldState )
+ */
+ public StateEngine setDefault( State oldState )
+ throws IllegalStateException ;
+
+ /** Set the default action used in this state engine. This is the
+ * action that is called whenever there is no applicable transition.
+ * Normally this would simply flag an error. This method can only
+ * be called before done(). An attempt to
+ * call it after done() results in an IllegalStateException.
+ */
+ public void setDefaultAction( Action act ) throws IllegalStateException ;
+
+ /** Called after all transitions have been added to the state engine.
+ * This provides an opportunity for the implementation to optimize
+ * its representation before the state engine is used. This method
+ * may only be called once. An attempt to call it more than once
+ * results in an IllegalStateException.
+ */
+ public void done() throws IllegalStateException ;
+
+ /** Create an instance of a FSM that uses this state engine.
+ * The initial state of the FSM will be the stateState specified
+ * here. This method can only be called after done(). An attempt
+ * to call it before done results in an IllegalStateException.
+ */
+ public FSM makeFSM( State startState ) throws IllegalStateException ;
+}
+
+// end of StateEngine.java
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngineFactory.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngineFactory.java
new file mode 100644
index 0000000..d2e8f2b
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateEngineFactory.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm;
+
+import com.sun.corba.se.impl.orbutil.fsm.StateEngineImpl ;
+
+/**
+ * Factory for creating the standard state machine implementation.
+ *
+ * @author Ken Cavanaugh
+ */
+public class StateEngineFactory {
+ private StateEngineFactory() {}
+
+ public static StateEngine create()
+ {
+ return new StateEngineImpl() ;
+ }
+}
diff --git a/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateImpl.java b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateImpl.java
new file mode 100644
index 0000000..49df29a
--- /dev/null
+++ b/src/java.corba/share/classes/com/sun/corba/se/spi/orbutil/fsm/StateImpl.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.corba.se.spi.orbutil.fsm ;
+
+import com.sun.corba.se.impl.orbutil.fsm.NameBase ;
+
+import java.util.Map ;
+import java.util.HashMap ;
+import java.util.Set ;
+import java.util.HashSet ;
+
+import com.sun.corba.se.impl.orbutil.fsm.GuardedAction ;
+import com.sun.corba.se.impl.orbutil.fsm.NameBase ;
+
+/** Base class for all states in a StateEngine. This must be used
+* as the base class for all states in transitions added to a StateEngine.
+*/
+public class StateImpl extends NameBase implements State {
+ private Action defaultAction ;
+ private State defaultNextState ;
+ private Map inputToGuardedActions ;
+
+ public StateImpl( String name )
+ {
+ super( name ) ;
+ defaultAction = null ;
+ inputToGuardedActions = new HashMap() ;
+ }
+
+ public void preAction( FSM fsm )
+ {
+ }
+
+ public void postAction( FSM fsm )
+ {
+ }
+
+ // Methods for use only by StateEngineImpl.
+
+ public State getDefaultNextState()
+ {
+ return defaultNextState ;
+ }
+
+ public void setDefaultNextState( State defaultNextState )
+ {
+ this.defaultNextState = defaultNextState ;
+ }
+
+ public Action getDefaultAction()
+ {
+ return defaultAction ;
+ }
+
+ public void setDefaultAction( Action defaultAction )
+ {
+ this.defaultAction = defaultAction ;
+ }
+
+ public void addGuardedAction( Input in, GuardedAction ga )
+ {
+ Set gas = (Set)inputToGuardedActions.get( in ) ;
+ if (gas == null) {
+ gas = new HashSet() ;
+ inputToGuardedActions.put( in, gas ) ;
+ }
+
+ gas.add( ga ) ;
+ }
+
+ public Set getGuardedActions( Input in )
+ {
+ return (Set)inputToGuardedActions.get( in ) ;
+ }
+}