/******************************************************************************* * Copyright (c) 2004, 2008 John Krasnay and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Krasnay - initial API and implementation *******************************************************************************/ package net.sf.vex.dom; import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * Represents a state in a deterministic finite automaton (DFA). A DFA * can be thought of as a directed graph, where each arc in the graph * represents a transition on an input symbol to a new state (i.e. a * node in the graph.) The DFA has a start state and one or more * accepting states. The DFA represents a grammar. If a sequence of * input symbols drives the DFA from the start state to one of the * accepting states, the sequence is a valid sentence in the grammar * represented by the DFA. * * <p>Within VEX, we use a DFA to validate the sequence of children of * a given element. A DFA is constructed for each element declaration * in the DTD.</p> */ public class DFAState implements Serializable { private boolean accepting = false; private Map transitions = new HashMap(); /** * Class constructor. */ public DFAState() { } /** * Return the state obtained by traversing the given list of symbols. * Returns null if the given sequence does not lead to a state in the DFA. * * @param sequence Sequence of symbols to use. */ public DFAState getState(List sequence) { DFAState state = this; Iterator iter = sequence.iterator(); while (iter.hasNext()) { state = state.getNextState(iter.next()); if (state == null) { break; } } return state; } /** * Adds an outgoing transition to the state. * * @param symbol Symbol that initiates the transition. * @param target State to which the transition leads. */ public void addTransition(Object symbol, DFAState target) { this.transitions.put(symbol, target); } /** * Returns the set of symbols that are valid for this state. */ public Set getValidSymbols() { return this.transitions.keySet(); } /** * Returns true if this is an accepting state of the DFA. */ public boolean isAccepting() { return this.accepting; } /** * Returns the next state given the given input symbol, or * null if there are no outgoing transitions corresponding to * the given symbol. * * @param symbol input symbol */ public DFAState getNextState(Object symbol) { return (DFAState) this.transitions.get(symbol); } /** * Sets the value of the accepting property. * * @param accepting true if this an accepting state of the DFA. */ public void setAccepting(boolean accepting) { this.accepting = accepting; } //========================================================= PRIVATE }