package com.c2kernel.lifecycle.instance.stateMachine; 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; public class StateMachine implements DescriptionObject { 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(); } public void setStates(ArrayList newStates) { this.states = newStates; validate(); } 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 = isCoherent && trans.resolveStates(stateCodes); } } public ArrayList getStates() { return states; } public ArrayList getTransitions() { return transitions; } public State getInitialState() { return initialState; } public void setInitialState(State initialState) { this.initialState = initialState; initialStateCode = initialState.getId(); } public int getInitialStateCode() { return initialStateCode; } public void setInitialStateCode(int initialStateCode) { this.initialStateCode = initialStateCode; initialState = stateCodes.get(initialStateCode); if (initialState == null) isCoherent = false; } @Override public String getName() { return name; } @Override public int getVersion() { return version; } @Override public void setName(String name) { this.name = name; } @Override public void setVersion(int version) { this.version = version; } 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; } }