I've updated to the code to be Spring 1.0 compatible:
For the fileupload sample application this produces the following output:Code:package test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashSet; import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.core.io.FileSystemResource; import org.springframework.webflow.definition.StateDefinition; import org.springframework.webflow.definition.TransitionDefinition; import org.springframework.webflow.engine.Flow; import org.springframework.webflow.engine.Transition; import org.springframework.webflow.engine.TransitionableState; import org.springframework.webflow.engine.builder.BaseFlowServiceLocator; import org.springframework.webflow.engine.builder.FlowArtifactLookupException; import org.springframework.webflow.engine.builder.FlowAssembler; import org.springframework.webflow.engine.builder.FlowBuilder; import org.springframework.webflow.engine.builder.xml.XmlFlowBuilder; import org.springframework.webflow.engine.support.EventIdTransitionCriteria; public class SwfViz { private static Set<StateDefinition> visitedStates = new HashSet<StateDefinition>(); private static Flow flow; public static void main(String[] args) { if (args.length != 1) { System.err.println("usage: SwfViz flowFileName"); } else { flow = loadFlow(args[0]); printStateTransitions(flow.getStartState()); } } private static Flow loadFlow(String flowFileName) { FlowBuilder builder = new XmlFlowBuilder( new FileSystemResource(flowFileName), new BaseFlowServiceLocator() { @Override public Flow getSubflow(String id) throws FlowArtifactLookupException { return new Flow(id); } @Override public BeanFactory getBeanFactory() throws UnsupportedOperationException { return new BeanFactory() { public Object getBean(String name) throws BeansException { return new Object(); } public Object getBean(String name, Class requiredType) throws BeansException { return Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] { requiredType }, new InvocationHandler() { public Object invoke(Object obj, Method method, Object[] args) throws Throwable { return null; } }); } public boolean containsBean(String name) { return true; } public boolean isSingleton(String name) throws NoSuchBeanDefinitionException { return false; } public Class getType(String name) throws NoSuchBeanDefinitionException { return Object.class; } public String[] getAliases(String name) { return new String[0]; } }; } }); return new FlowAssembler("flow", builder).assembleFlow(); } public static void printStateTransitions(StateDefinition state) { if (visitedStates.contains(state)) { return; } visitedStates.add(state); if (state instanceof TransitionableState) { TransitionableState transitionableState = (TransitionableState)state; for (TransitionDefinition transitionDefinition : transitionableState.getTransitions()) { Transition transition = (Transition)transitionDefinition; String eventId = ((EventIdTransitionCriteria)transition.getMatchingCriteria()).getEventId(); String targetStateId = transition.getTargetStateResolver().toString(); System.out.println(state.getId() + "->" + targetStateId + "[label=\"" + eventId + "\"];"); printStateTransitions(flow.getState(targetStateId)); } } } }
This implementation is limited though, so it will only work on basic flows:selectFile->uploadFile[label="submit"];
uploadFile->selectFile[label="success"];
uploadFile->selectFile[label="error"];
* only EventIdTransitionCriteria are supported
* only DefaultTargetStateResolver is supported
Erwin


Reply With Quote