View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
9    *
10   *  This program is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *  GNU General Public License for more details.
14   *
15   *  You should have received a copy of the GNU General Public License
16   *  along with this program; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.xnap.util;
21  
22  import java.util.HashSet;
23  import java.util.Hashtable;
24  
25  import org.xnap.XNap;
26  
27  public class FiniteStateMachine extends AbstractStateMachine
28  {
29  
30      //--- Constant(s) ---
31  
32      //--- Data field(s) ---
33  
34      //private static Logger logger = Logger.getLogger(FiniteStateMachine.class);
35  
36      private Hashtable successorsByState;
37  
38      //--- Constructor(s) ---
39  
40      public FiniteStateMachine(State initialState, Hashtable successorsByState)
41      {
42  		super(initialState);
43  
44  		this.successorsByState = successorsByState;
45      }
46  
47      public FiniteStateMachine(State initialState)
48      {
49  		this(initialState, new Hashtable());
50      }
51  
52      //--- Method(s) ---
53  
54      public synchronized void putState(State state, HashSet successors)
55      {
56  		successorsByState.put(state, new HashSet(successors));
57      }
58  
59      /***
60       */
61      protected synchronized void canChange(State oldState, State newState)
62      {
63  		HashSet successors = (HashSet)successorsByState.get(oldState);
64  		if (successors == null || !successors.contains(newState)) {
65  			stateChangedFailed(oldState, newState);
66  		}
67      }
68  
69      /***
70       * Does nothing. Subclasses should overwrite this method.
71       */
72      protected synchronized void stateChanged(State oldState, State newState)
73      {
74      }
75  
76      /***
77       * Throws an IllegalOperationException. Subclasses can
78       * overwrite this method.
79       *
80       * @exception IllegalOperationException thrown if the state transition
81       *            is not valid */
82      protected synchronized void stateChangedFailed(State oldState, 
83  												   State newState)
84      {
85  		//logger.debug("state change failed: " + oldState + " -> " + newState);
86  		throw new IllegalOperationException
87  			(XNap.tr("Operation not allowed: "
88  					 + oldState + " -> " + newState));
89      }
90  
91      //--- Static Method(s) ---    
92      
93      public static Hashtable createStateTable(State[][] table)
94      {
95  		Hashtable stateTable = new Hashtable();
96  
97  		for (int i = 0; i < table.length; i++) {
98  			HashSet set = new HashSet();
99  			State[] row = table[i];
100 			for (int j = 1; j < row.length; j++) {
101 				set.add(row[j]);
102 			}
103 			stateTable.put(row[0], set);
104 		}
105 
106 		return stateTable;
107     }
108 
109 }