package org.jboss.util.state.xml;
import java.net.URL;
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.jboss.logging.Logger;
import org.jboss.util.state.StateMachine;
import org.jboss.util.state.State;
import org.jboss.util.state.Transition;
import org.jboss.util.xml.JBossEntityResolver;
public class StateMachineParser
{
private static Logger log = Logger.getLogger(StateMachineParser.class);
public StateMachine parse(URL source) throws DocumentException
{
SAXReader saxReader = new SAXReader();
saxReader.setEntityResolver(new JBossEntityResolver());
Document document = saxReader.read(source);
Element root = document.getRootElement();
String description = root.attributeValue("description");
Iterator i = root.elementIterator();
HashMap nameToStateMap = new HashMap();
HashMap nameToTransitionsMap = new HashMap();
HashSet states = new HashSet();
State startState = null;
while( i.hasNext() )
{
Element stateElement = (Element) i.next();
String stateName = stateElement.attributeValue("name");
State s = new State(stateName);
states.add(s);
nameToStateMap.put(stateName, s);
HashMap transitions = new HashMap();
Iterator it = stateElement.elementIterator();
while( it.hasNext() )
{
Element transElement = (Element) it.next();
String name = transElement.attributeValue("name");
String targetName = transElement.attributeValue("target");
transitions.put(name, targetName);
}
nameToTransitionsMap.put(stateName, transitions);
if( Boolean.valueOf(stateElement.attributeValue("isStartState")) == Boolean.TRUE )
startState = s;
}
Iterator transitions = nameToTransitionsMap.keySet().iterator();
StringBuffer resolveFailed = new StringBuffer();
while( transitions.hasNext() )
{
String stateName = (String) transitions.next();
State s = (State) nameToStateMap.get(stateName);
HashMap stateTransitions = (HashMap) nameToTransitionsMap.get(stateName);
Iterator it = stateTransitions.keySet().iterator();
while( it.hasNext() )
{
String name = (String) it.next();
String targetName = (String) stateTransitions.get(name);
State target = (State) nameToStateMap.get(targetName);
if( target == null )
{
String msg = "Failed to resolve target state: "+targetName+" for transition: "+name;
resolveFailed.append(msg);
log.debug(msg);
}
Transition t = new Transition(name, target);
s.addTransition(t);
}
}
if( resolveFailed.length() > 0 )
throw new DocumentException("Failed to resolve transition targets: "+resolveFailed);
StateMachine sm = new StateMachine(states, startState, description);
return sm;
}
}