From d43164830403245353080f5d6f838ed9f56d9a35 Mon Sep 17 00:00:00 2001 From: Andrew Branson Date: Mon, 18 Nov 2013 09:48:03 +0100 Subject: 3.0-SNAPSHOT (Will be first open source version) New StateMachine desc IssueID #28 --- .../instance/stateMachine/StateMachine.java | 247 +++++++++++---------- 1 file changed, 133 insertions(+), 114 deletions(-) (limited to 'src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java') diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java index ddfc838..c165e6f 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java @@ -1,137 +1,156 @@ package com.c2kernel.lifecycle.instance.stateMachine; -import java.io.Serializable; - +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import com.c2kernel.common.AccessRightsException; +import com.c2kernel.common.InvalidDataException; +import com.c2kernel.common.InvalidTransitionException; +import com.c2kernel.common.ObjectNotFoundException; import com.c2kernel.lifecycle.instance.Activity; +import com.c2kernel.lookup.AgentPath; +import com.c2kernel.utils.DescriptionObject; import com.c2kernel.utils.Logger; -/** - * @version $Revision: 1.30 $ $Date: 2004/06/04 09:39:19 $ - * @author $Author: sgaspard $ - */ -/** this class represents the link between 2 successive activities */ -public class StateMachine implements Serializable +public class StateMachine implements DescriptionObject { - public int state = 0; - private Activity activity; - - public static final String SKIPPABLE = "Skippable"; - public static final String REPEATABLE = "Repeatable"; - public static final String IGNORABLE = "Ignorable"; - - - /** - * Method StateMachine. - * @param act - */ - public StateMachine(Activity act) - { - activity = act; + public String name; + public int version; + + private ArrayList states; + private ArrayList transitions; + private final HashMap stateCodes; + private final HashMap transitionCodes; + + State initialState; + int initialStateCode; + boolean isCoherent = false; + + public StateMachine() { + states = new ArrayList(); + transitions = new ArrayList(); + stateCodes = new HashMap(); + transitionCodes = new HashMap(); } - - /** row : States from (WAITING,RESERVED,STARTED,SUSPENDED,FINISHED,RWAITING,RRESERVED,RSTARTED,RSUSPENDED) - * collumn : transition (RESERVE,START,SKIP,DONE,COMPLETE,SUSPEND,REASIGN,RESUME,REPEAT,IGNORE,PROCEED) - * cell : State that is reached (-1 if transition not allowed) - */ - private int[][] getCurrentMachine() - { - int [][] returnArray = - { /*RESERVE, START, SKIP, DONE,COMPLETE,SUSPEND,REASSIGN,RESUME, REPEAT, IGNORE, PROCEED*/ - /*0 WAITING*/ { 1,getActive()?2:-1,getSkippable()?4:-1,getActive()?4:-1, -1, -1, -1, -1, -1, -1, -1},/*0 WAITING*/ - /*1 RESERVED*/ { -1,getActive()?2:-1,getSkippable()?4:-1,getActive()?4:-1, -1, -1, -1, -1, -1, 0, -1},/*1 RESERVED*/ - /*2 STARTED*/ { -1, -1, -1, -1, 4, 3, -1, -1, -1,getIgnorable()?0:-1, -1},/*2 STARTED*/ - /*3 SUSPENDED*/ { -1, -1, -1, -1, -1, -1, 2, 2, -1,getIgnorable()?0:-1, -1},/*3 SUSPENDED*/ - /*4 FINISHED*/ { -1, -1, -1, -1, -1, -1, -1, -1,getRepeatable()?5:-1, -1,getActive()?4:-1},/*4 FINISHED*/ - /*5 RWAITING*/ { 6,getActive()?7:-1,getSkippable()?4:-1,getActive()?4:-1, -1, -1, -1, -1, -1, -1, -1},/*5 RWAITING*/ - /*6 RRESERVED*/ { -1,getActive()?7:-1,getSkippable()?4:-1,getActive()?4:-1, -1, -1, -1, -1, -1, -1, -1},/*6 RRESERVED*/ - /*7 RSTARTED*/ { -1, -1, -1, -1, 4, 8, -1, -1, -1,getIgnorable()?5:-1, -1},/*7 RSTARTED*/ - /*8 RSUSPENDED*/ { -1, -1, -1, -1, -1, -1, 8, 7, -1, -1, -1} /*8 RSUSPENDED*/ - }; - return returnArray; + + public void setStates(ArrayList newStates) { + this.states = newStates; + validate(); } - - /** - * @see java.lang.Object#Object() - */ - public StateMachine() - { + + public void setTransitions(ArrayList newTransitions) { + this.transitions = newTransitions; + validate(); + } + + public void validate() { + stateCodes.clear(); + transitionCodes.clear(); + isCoherent = true; + + for (State state : states) { + Logger.debug(6, "State "+state.id+": "+state.name); + stateCodes.put(state.getId(), state); + } + + if (stateCodes.containsKey(initialStateCode)) + initialState = stateCodes.get(initialStateCode); + else + isCoherent = false; + + for (Transition trans : transitions) { + Logger.debug(6, "Transition "+trans.id+": "+trans.name); + transitionCodes.put(trans.getId(), trans); + isCoherent &= trans.resolveStates(stateCodes); + } + + } + + public ArrayList getStates() { + return states; + } + + public ArrayList getTransitions() { + return transitions; + } + + public State getInitialState() { + return initialState; } - /** - * Method getCurrentState. - * @return String - */ - public int getCurrentState() - { - return state; + public void setInitialState(State initialState) { + this.initialState = initialState; + initialStateCode = initialState.getId(); } - /** - * Method possibleTransition. - * @return String[] - */ - public int[] possibleTransition() - { - int[] trans = new int[9]; - int cmpt = 0; - for (int i=0; i< getCurrentMachine()[state].length;i++) - if (getCurrentMachine()[state][i]!=-1) trans[cmpt++]=i; + public int getInitialStateCode() { + return initialStateCode; + } - int [] result = new int[cmpt]; - for (int i=0;i -1) { - state=newState; - return true; - } - Logger.msg("StateMachine.traverse() - Illegal transition "+Transitions.getTransitionName(transition)+" from "+States.getStateName(state)); - return false; - } - public int simulate(int transition) - { - return getCurrentMachine()[state][transition]; - } - /** - * Returns the ignorable. - * @return boolean - */ - public boolean getIgnorable() - { - return ((Boolean)activity.getProperties().get(IGNORABLE)).booleanValue(); + @Override + public String getName() { + return name; } - /** - * Returns the repeatable. - * @return boolean - */ - public boolean getRepeatable() - { - return ((Boolean)activity.getProperties().get(REPEATABLE)).booleanValue(); + @Override + public int getVersion() { + return version; + } + + public void setName(String name) { + this.name = name; } - /** - * Returns the skippable. - * @return boolean - */ - public boolean getSkippable() - { - return ((Boolean)activity.getProperties().get(SKIPPABLE)).booleanValue(); + public void setVersion(int version) { + this.version = version; } - public boolean getActive() - { - return activity.getActive(); - } + public Transition getTransition(int transitionID) { + return transitionCodes.get(transitionID); + } + + public State getState(int stateID) { + return stateCodes.get(stateID); + } + + public Map getPossibleTransitions(Activity act, AgentPath agent) throws ObjectNotFoundException, InvalidDataException { + HashMap returnList = new HashMap(); + State currentState = getState(act.getState()); + for (Integer transCode : currentState.getPossibleTransitionIds()) { + Transition possTrans = currentState.getPossibleTransitions().get(transCode); + try { + String role = possTrans.getPerformingRole(act, agent); + returnList.put(possTrans, role); + } catch (AccessRightsException ex) { + if (Logger.doLog(5)) + Logger.msg(5, "Transition '"+possTrans+"' not possible for "+agent.getAgentName()+": "+ex.getMessage()); + } + } + return returnList; + } -} + public State traverse(Activity act, Transition transition, AgentPath agent) throws InvalidTransitionException, AccessRightsException, ObjectNotFoundException, InvalidDataException { + State currentState = getState(act.getState()); + if (transition.originState.equals(currentState)) { + transition.getPerformingRole(act, agent); + return transition.targetState; + } + else + throw new InvalidTransitionException("Transition '"+transition.getName()+"' not valid from state '"+currentState.getName(), ""); + + } + + public boolean isCoherent() { + return isCoherent; + } + + +} \ No newline at end of file -- cgit v1.2.3