Java/Collections Data Structure/State Machine

Материал из Java эксперт
Версия от 10:23, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

The representation of a finite state machine

   <source lang="java">

/*

* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/

import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /**

* The representation of a finite state machine.
* 
* @author Scott.Stark@jboss.org
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") public class StateMachine implements Cloneable {

 /** A description of the state machine */
 private String description;
 /** The set of states making up the state machine */
 private HashSet states;
 /** The starting state */
 private State startState;
 /** The current state of the state machine */
 private State currentState;
 /**
  * Create a state machine given its states and start state.
  * 
  * @param states -
  *          Set<State> for the state machine
  * @param startState -
  *          the starting state
  */
 public StateMachine(Set states, State startState) {
   this(states, startState, null);
 }
 /**
  * Create a state machine given its states and start state.
  * 
  * @param states -
  *          Set<State> for the state machine
  * @param startState -
  *          the starting state
  * @param description -
  *          an optional description of the state machine
  */
 public StateMachine(Set states, State startState, String description) {
   this.states = new HashSet(states);
   this.startState = startState;
   this.currentState = startState;
   this.description = description;
 }
 /**
  * Make a copy of the StateMachine maintaining the current state.
  * 
  * @return a copy of the StateMachine.
  */
 public Object clone() {
   StateMachine clone = new StateMachine(states, startState, description);
   clone.currentState = currentState;
   return clone;
 }
 /**
  * Get the state machine description.
  * 
  * @return an possibly null description.
  */
 public String getDescription() {
   return description;
 }
 /**
  * Get the current state of the state machine.
  * 
  * @return the current state.
  */
 public State getCurrentState() {
   return currentState;
 }
 /**
  * Get the start state of the state machine.
  * 
  * @return the start state.
  */
 public State getStartState() {
   return startState;
 }
 /**
  * Get the states of the state machine.
  * 
  * @return the machine states.
  */
 public Set getStates() {
   return states;
 }
 /**
  * Transition to the next state given the name of a valid transition.
  * 
  * @param actionName -
  *          the name of transition that is valid for the current state.
  * @return the next state
  * @throws IllegalTransitionException
  */
 public State nextState(String actionName) throws IllegalTransitionException {
   Transition t = currentState.getTransition(actionName);
   if (t == null) {
     String msg = "No transition for action: "" + actionName + "" from state: ""
         + currentState.getName() + """;
     throw new IllegalTransitionException(msg);
   }
   State nextState = t.getTarget();
   System.out.println("nextState(" + actionName + ") = " + nextState);
   currentState = nextState;
   return currentState;
 }
 /**
  * Reset the state machine back to the start state
  * 
  * @return the start state
  */
 public State reset() {
   this.currentState = startState;
   return currentState;
 }
 public String toString() {
   StringBuffer tmp = new StringBuffer("StateMachine[:\n");
   tmp.append("\tCurrentState: " + currentState.getName());
   Iterator i = states.iterator();
   while (i.hasNext()) {
     tmp.append("\n").append(i.next());
   }
   tmp.append("]");
   return tmp.toString();
 }

} /*

* JBoss, Home of Professional Open Source Copyright 2005, JBoss Inc., and
* individual contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of individual
* contributors.
* 
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* 
* This software 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 Lesser General Public License for more
* details.
* 
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

/**

* The respresentation of a state in a state machine.
* 
* @author Scott.Stark@jboss.org
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") class State {

 /** The name of the state */
 private String name;
 /** HashMap<String, Transition> */
 private HashMap allowedTransitions = new HashMap();
 /** Arbitrary state data */
 private Object data;
 public State(String name) {
   this(name, null);
 }
 public State(String name, Map transitions) {
   this.name = name;
   if (transitions != null) {
     allowedTransitions.putAll(transitions);
   }
 }
 /**
  * Get the state name.
  * 
  * @return the name of the state.
  */
 public String getName() {
   return name;
 }
 public Object getData() {
   return data;
 }
 public void setData(Object data) {
   this.data = data;
 }
 /**
  * An accept state is indicated by no transitions
  * 
  * @return true if this is an accept state, false otherwise.
  */
 public boolean isAcceptState() {
   return allowedTransitions.size() == 0;
 }
 /**
  * Add a transition to the allowed transition map.
  * 
  * @param transition
  * @return this to allow chained addTransition calls
  */
 public State addTransition(Transition transition) {
   allowedTransitions.put(transition.getName(), transition);
   return this;
 }
 /**
  * Lookup an allowed transition given its name.
  * 
  * @param name -
  *          the name of a valid transition from this state.
  * @return the valid transition if it exists, null otherwise.
  */
 public Transition getTransition(String name) {
   Transition t = (Transition) allowedTransitions.get(name);
   return t;
 }
 /**
  * Get the Map<String, Transition> of allowed transitions for this state.
  * 
  * @return the allowed transitions map.
  */
 public Map getTransitions() {
   return allowedTransitions;
 }
 public String toString() {
   StringBuffer tmp = new StringBuffer("State(name=");
   tmp.append(name);
   Iterator i = allowedTransitions.entrySet().iterator();
   while (i.hasNext()) {
     Map.Entry e = (Map.Entry) i.next();
     tmp.append("\n\t on: ");
     tmp.append(e.getKey());
     Transition t = (Transition) e.getValue();
     tmp.append(" go to: ");
     tmp.append(t.getTarget().getName());
   }
   tmp.append(")");
   return tmp.toString();
 }

} /*

* JBoss, Home of Professional Open Source Copyright 2005, JBoss Inc., and
* individual contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of individual
* contributors.
* 
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* 
* This software 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 Lesser General Public License for more
* details.
* 
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

/**

* A representation of a transition from a state to another state.
* 
* @author Scott.Stark@jboss.org
* @version $Revision: 1958 $
*/

class Transition {

 private String name;
 private State target;
 public Transition(String name, State target) {
   this.name = name;
   this.target = target;
 }
 public String getName() {
   return name;
 }
 public State getTarget() {
   return target;
 }

} /*

* JBoss, Home of Professional Open Source Copyright 2005, JBoss Inc., and
* individual contributors as indicated by the @authors tag. See the
* copyright.txt in the distribution for a full listing of individual
* contributors.
* 
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
* 
* This software 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 Lesser General Public License for more
* details.
* 
* You should have received a copy of the GNU Lesser General Public License
* along with this software; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
* site: http://www.fsf.org.
*/

/**

* An exception thrown when an invalid transition is attempted from a state.
* 
* @author Scott.Stark@jboss.org
* @version $Revision: 2800 $
*/

class IllegalTransitionException extends Exception {

 /** The serialVersionUID */
 private static final long serialVersionUID = -3392564168782896452L;
 public IllegalTransitionException(String msg) {
   super(msg);
 }

}

 </source>