package ee.telekom.workflow.graph.core; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.apache.commons.lang3.ObjectUtils; import ee.telekom.workflow.graph.Graph; import ee.telekom.workflow.graph.Node; import ee.telekom.workflow.graph.Transition; import ee.telekom.workflow.graph.WorkflowException; public class GraphImpl implements Graph{ private String name; private int version; private Node startNode; private Map<Integer, Node> nodeById = new LinkedHashMap<>(); private Map<Integer, List<Transition>> transitionsByStartNode = new LinkedHashMap<>(); public GraphImpl( String name, int version ){ this.name = name; this.version = version; } @Override public String getName(){ return name; } @Override public int getVersion(){ return version; } @Override public Node getStartNode(){ return startNode; } @Override public Node getNode( int id ){ return nodeById.get( id ); } @Override public Collection<Node> getNodes(){ return new ArrayList<>( nodeById.values() ); } @Override public List<Transition> getTransitions(){ List<Transition> allTransitions = new LinkedList<>(); for( List<Transition> transitions : transitionsByStartNode.values() ){ allTransitions.addAll( transitions ); } return allTransitions; } @Override public List<Transition> getOutputTransitions( Node node ){ List<Transition> result = transitionsByStartNode.get( node.getId() ); if( result != null ){ return result; } else{ return Collections.emptyList(); } } @Override public Transition getOutputTransitions( Node node, String name ){ for( Transition transition : getOutputTransitions( node ) ){ if( ObjectUtils.equals( transition.getName(), name ) ){ return transition; } } return null; } public void setStartNode( Node startNode ){ this.startNode = startNode; addNode( startNode ); } public void addNode( Node node ){ Node previous = nodeById.get( node.getId() ); if( previous != null && previous != node ){ throw new WorkflowException( "Workflow " + name + ":" + version + " already contains a node with id " + node.getId() ); } nodeById.put( node.getId(), node ); } public void addTransition( Transition transition ){ Transition previous = getOutputTransitions( transition.getStartNode(), transition.getName() ); if( previous != null && previous != transition ){ throw new WorkflowException( "Workflow " + name + ":" + version + " already contains a transition from node " + transition.getStartNode() + " with name " + transition.getName() ); } if( !contains( transition.getStartNode() ) ){ throw new WorkflowException( "Workflow " + name + ":" + version + " does not contain the start node of transition " + transition ); } if( !contains( transition.getStartNode() ) ){ throw new WorkflowException( "Workflow " + name + ":" + version + " does not contain the end node of transition " + transition ); } Integer nodeId = transition.getStartNode().getId(); List<Transition> outputTransitions = transitionsByStartNode.get( nodeId ); if( outputTransitions == null ){ outputTransitions = new ArrayList<Transition>( 1 ); transitionsByStartNode.put( nodeId, outputTransitions ); } outputTransitions.add( transition ); } private boolean contains( Node node ){ Node sameIdNode = nodeById.get( node.getId() ); return sameIdNode != null && sameIdNode == node; } }