summaryrefslogtreecommitdiff
path: root/src/main/java/com/c2kernel/lifecycle/instance/stateMachine
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/c2kernel/lifecycle/instance/stateMachine')
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java60
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java247
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/States.java40
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java292
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionOutcome.java36
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionResource.java9
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionScript.java27
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transitions.java41
8 files changed, 557 insertions, 195 deletions
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java
new file mode 100644
index 0000000..fd712f4
--- /dev/null
+++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java
@@ -0,0 +1,60 @@
+package com.c2kernel.lifecycle.instance.stateMachine;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Set;
+
+public class State implements Serializable {
+
+ int id;
+ String name;
+ boolean finished = false; // If true, this state deactivates the current activity and the lifecycle proceeds
+
+ HashMap<Integer, Transition> possibleTransitions;
+
+ public State() {
+ possibleTransitions = new HashMap<Integer, Transition>();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return id+": "+name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public boolean isFinished() {
+ return finished;
+ }
+
+ public void setFinished(boolean finished) {
+ this.finished = finished;
+ }
+
+ public HashMap<Integer, Transition> getPossibleTransitions() {
+ return possibleTransitions;
+ }
+
+ protected void addPossibleTransition(Transition possibleTransition) {
+ possibleTransitions.put(possibleTransition.getId(), possibleTransition);
+ }
+
+ public Set<Integer> getPossibleTransitionIds() {
+ return possibleTransitions.keySet();
+ }
+}
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<State> states;
+ private ArrayList<Transition> transitions;
+ private final HashMap<Integer, State> stateCodes;
+ private final HashMap<Integer, Transition> transitionCodes;
+
+ State initialState;
+ int initialStateCode;
+ boolean isCoherent = false;
+
+ public StateMachine() {
+ states = new ArrayList<State>();
+ transitions = new ArrayList<Transition>();
+ stateCodes = new HashMap<Integer, State>();
+ transitionCodes = new HashMap<Integer, Transition>();
}
-
- /** 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<State> newStates) {
+ this.states = newStates;
+ validate();
}
-
- /**
- * @see java.lang.Object#Object()
- */
- public StateMachine()
- {
+
+ public void setTransitions(ArrayList<Transition> 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<State> getStates() {
+ return states;
+ }
+
+ public ArrayList<Transition> 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<cmpt;i++) result[i] = trans[i];
- return result;
+ public void setInitialStateCode(int initialStateCode) {
+ this.initialStateCode = initialStateCode;
+ initialState = stateCodes.get(initialStateCode);
+ if (initialState == null) isCoherent = false;
}
- /**
- * Method traverse.
- * @param transition
- * @return boolean
- */
- public boolean traverse(int transition)
- {
- int newState = getCurrentMachine()[state][transition];
- if (newState > -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<Transition, String> getPossibleTransitions(Activity act, AgentPath agent) throws ObjectNotFoundException, InvalidDataException {
+ HashMap<Transition, String> returnList = new HashMap<Transition, String>();
+ 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
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/States.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/States.java
deleted file mode 100644
index b142e35..0000000
--- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/States.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.c2kernel.lifecycle.instance.stateMachine;
-
-
-/**
- * @author XSeb74
- *
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
- */
-public class States
-{
- public final static int WAITING = 0;
- public final static int RESERVED = 1;
- public final static int STARTED = 2;
- public final static int SUSPENDED = 3;
- public final static int FINISHED = 4;
- public final static int RWAITING = 5;
- public final static int RRESERVED = 6;
- public final static int RSTARTED = 7;
- public final static int RSUSPENDED = 8;
-
- //everything less that this constant is NOT a repeating state
- public final static int REPEATSTATESTART = 5;
-
- public static final String[] states = { "Waiting", "Reserved", "Started", "Suspended", "Finished", "Waiting(R)", "Reserved(R)", "Started(R)", "Suspended(R)" };
-
- public static String getStateName(int state)
- {
- try
- {
- return states[state];
- }
- catch (ArrayIndexOutOfBoundsException ex)
- {
- return "Invalid State: " + state;
- }
- }
-}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java
new file mode 100644
index 0000000..9922c7c
--- /dev/null
+++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java
@@ -0,0 +1,292 @@
+package com.c2kernel.lifecycle.instance.stateMachine;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.c2kernel.common.AccessRightsException;
+import com.c2kernel.common.InvalidDataException;
+import com.c2kernel.common.ObjectNotFoundException;
+import com.c2kernel.lifecycle.instance.Activity;
+import com.c2kernel.lookup.AgentPath;
+import com.c2kernel.lookup.RolePath;
+import com.c2kernel.persistency.outcome.Schema;
+import com.c2kernel.process.Gateway;
+import com.c2kernel.utils.CastorHashMap;
+import com.c2kernel.utils.LocalObjectLoader;
+import com.c2kernel.utils.Logger;
+
+public class Transition implements Serializable {
+
+ int id;
+ String name;
+
+ int originStateId;
+ int targetStateId;
+ State originState;
+ State targetState;
+ String reservation;
+
+ String enabledProp; // Boolean property that permits this transition e.g. 'Skippable'
+
+ // activation properties
+ boolean requiresActive = true; // Whether the activity must be active for this transition to be available
+ boolean finishing; // whether the target state is a finishing state;
+
+ // permissions
+ String roleOverride;
+
+ TransitionOutcome outcome;
+ TransitionScript script;
+
+ public Transition() {
+ }
+
+
+ public Transition(int id, String name, int originStateId, int targetStateId) {
+ super();
+ this.id = id;
+ this.name = name;
+ this.originStateId = originStateId;
+ this.targetStateId = targetStateId;
+ }
+
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public State getOriginState() {
+ return originState;
+ }
+
+ public void setOriginState(State originState) {
+ this.originState = originState;
+ }
+
+ public State getTargetState() {
+ return targetState;
+ }
+
+ public void setTargetState(State targetState) {
+ this.targetState = targetState;
+ finishing = targetState.finished;
+ }
+
+ public String getEnabledProp() {
+ return enabledProp;
+ }
+
+ public void setEnabledProp(String enabledProp) {
+ this.enabledProp = enabledProp;
+ }
+
+ public boolean isRequiresActive() {
+ return requiresActive;
+ }
+
+ public boolean isFinishing() {
+ return finishing;
+ }
+
+ public void setRequiresActive(boolean requiresActive) {
+ this.requiresActive = requiresActive;
+ }
+
+ public String getRoleOverride() {
+ return roleOverride;
+ }
+
+ public void setRoleOverride(String roleOverride) {
+ this.roleOverride = roleOverride;
+ }
+
+ public TransitionOutcome getOutcome() {
+ return outcome;
+ }
+
+ public void setOutcome(TransitionOutcome outcome) {
+ this.outcome = outcome;
+ }
+
+ public TransitionScript getScript() {
+ return script;
+ }
+
+ public void setScript(TransitionScript script) {
+ this.script = script;
+ }
+
+ public String getReservation() {
+ return reservation;
+ }
+
+ public void setReservation(String reservation) {
+ this.reservation = reservation;
+ }
+
+ protected boolean resolveStates(HashMap<Integer, State> states) {
+ boolean allFound = true;
+ if (states.keySet().contains(originStateId)) {
+ originState = states.get(originStateId);
+ originState.addPossibleTransition(this);
+ }
+ else
+ allFound = false;
+ if (states.keySet().contains(targetStateId))
+ targetState = states.get(targetStateId);
+ else
+ allFound = false;
+ return allFound;
+ }
+
+ public int getOriginStateId() {
+ return originStateId;
+ }
+
+ public void setOriginStateId(int originStateId) {
+ this.originStateId = originStateId;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public int getTargetStateId() {
+ return targetStateId;
+ }
+
+ public void setTargetStateId(int targetStateId) {
+ this.targetStateId = targetStateId;
+ }
+
+ public String getPerformingRole(Activity act, AgentPath agent) throws ObjectNotFoundException, AccessRightsException {
+
+ // check available
+ if (!isEnabled(act.getProperties()))
+ throw new AccessRightsException("Transition '"+name+"' is disabled by the '"+enabledProp+"' property.", "");
+
+ // check active
+ if (isRequiresActive() && !act.getActive())
+ throw new AccessRightsException("Activity must be active to perform this transition", "");
+
+ RolePath role = null;
+ String overridingRole = resolveValue(roleOverride, act.getProperties());
+ boolean override = overridingRole != null;
+ boolean isOwner = false, isOwned = true;
+
+ // Check agent name
+ String agentName = act.getCurrentAgentName();
+ if (agentName != null && agentName.length() >0) {
+ if (agent.getAgentName().equals(agentName))
+ isOwner = true;
+ }
+ else isOwned = false;
+
+ // determine transition role
+ if (override) {
+ role = Gateway.getLDAPLookup().getRoleManager().getRolePath(overridingRole);
+ }
+ else {
+ String actRole = act.getCurrentAgentRole();
+ if (actRole != null && actRole.length() > 0)
+ role = Gateway.getLDAPLookup().getRoleManager().getRolePath(actRole);
+ }
+
+ // Decide the access
+ if (isOwned && !override && !isOwner)
+ throw new AccessRightsException("Agent '"+agent.getAgentName()
+ +"' cannot perform this transition because the activity '"+act.getName()+"' is currently owned by "+agentName, null);
+
+ if (role != null) {
+ if (agent.hasRole(role))
+ return role.getName();
+ else if (agent.hasRole("Admin"))
+ return "Admin";
+ else
+ throw new AccessRightsException("Agent '"+agent.getAgentName()
+ +"' does not hold a suitable role '"+role.getName()+"' for the activity "+act.getName(), null);
+ }
+ else
+ return null;
+ }
+
+ public String getReservation(Activity act, AgentPath agent) {
+ if (reservation == null || reservation.length() == 0)
+ reservation = targetState.finished?"clear":"set";
+
+ String reservedAgent = act.getCurrentAgentName();
+ if (reservation.equals("set"))
+ reservedAgent = agent.getAgentName();
+ else if (reservation.equals("clear"))
+ reservedAgent = "";
+ return reservedAgent;
+
+ }
+
+ private static String resolveValue(String key, CastorHashMap props) {
+ if (key==null) return null;
+ String result = key;
+ Pattern propField = Pattern.compile("\\$\\{(.+?)\\}");
+ Matcher propMatcher = propField.matcher(result);
+ while (propMatcher.find()) {
+ String propName = propMatcher.group(1);
+ Object propValue = props.get(propName);
+ Logger.debug("Replacing Property "+propName+" as "+propValue);
+ String propValString = propValue==null?"":propValue.toString();
+ result = result.replace("${"+propName+"}", propValString);
+ }
+ return result;
+ }
+
+ public boolean isEnabled(CastorHashMap props) {
+ if (enabledProp == null)
+ return true;
+ return (Boolean)props.get(enabledProp);
+ }
+
+ public boolean hasOutcome() {
+ return outcome!=null
+ && outcome.schemaName!=null && outcome.schemaName.length()>0
+ && outcome.schemaVersion!=null && outcome.schemaVersion.length()>0;
+ }
+
+ public Schema getSchema(CastorHashMap actProps) throws InvalidDataException, ObjectNotFoundException {
+ if (hasOutcome())
+ try {
+ return LocalObjectLoader.getSchema(resolveValue(outcome.schemaName, actProps),
+ Integer.parseInt(resolveValue(outcome.schemaVersion, actProps)));
+ } catch (NumberFormatException ex) {
+ throw new InvalidDataException("Bad schema version number: "+outcome.schemaVersion+" ("+resolveValue(outcome.schemaVersion, actProps), "");
+ }
+ else
+ return null;
+ }
+
+ public String getScriptName(CastorHashMap actProps) {
+ return resolveValue(script.scriptName, actProps);
+ }
+
+ public int getScriptVersion(CastorHashMap actProps) throws InvalidDataException {
+ try {
+ return Integer.parseInt(resolveValue(script.scriptVersion, actProps));
+ } catch (NumberFormatException ex) {
+ throw new InvalidDataException("Bad Script version number: "+script.scriptVersion+" ("+resolveValue(script.scriptVersion, actProps));
+ }
+ }
+
+ public boolean hasScript() {
+ return script!=null
+ && script.scriptName!=null && script.scriptName.length()>0
+ && script.scriptVersion!=null && script.scriptVersion.length()>0;
+ }
+}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionOutcome.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionOutcome.java
new file mode 100644
index 0000000..71ba3b3
--- /dev/null
+++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionOutcome.java
@@ -0,0 +1,36 @@
+package com.c2kernel.lifecycle.instance.stateMachine;
+
+public class TransitionOutcome extends TransitionResource {
+
+ // schema properties
+ String schemaName, schemaVersion; // Name & version of the schema of the data required for this transition.
+ boolean required = true; // If true, then the data must be supplied to perform the transition, otherwise it is optional
+
+ public TransitionOutcome() {
+ }
+
+ public String getSchemaName() {
+ return schemaName;
+ }
+
+ public void setSchemaName(String schemaName) {
+ this.schemaName = schemaName;
+ }
+
+ public String getSchemaVersion() {
+ return schemaVersion;
+ }
+
+ public void setSchemaVersion(String schemaVersion) {
+ this.schemaVersion = schemaVersion;
+ }
+
+ public boolean isRequired() {
+ return required;
+ }
+
+ public void setRequired(boolean required) {
+ this.required = required;
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionResource.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionResource.java
new file mode 100644
index 0000000..f644a4c
--- /dev/null
+++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionResource.java
@@ -0,0 +1,9 @@
+package com.c2kernel.lifecycle.instance.stateMachine;
+
+public class TransitionResource {
+
+ public TransitionResource() {
+ // TODO Auto-generated constructor stub
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionScript.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionScript.java
new file mode 100644
index 0000000..9585102
--- /dev/null
+++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/TransitionScript.java
@@ -0,0 +1,27 @@
+package com.c2kernel.lifecycle.instance.stateMachine;
+
+public class TransitionScript extends TransitionResource {
+
+ // script properties
+ String scriptName, scriptVersion; // Name & version of the script to be run by the agent during this transition
+
+ public TransitionScript() {
+ }
+
+ public String getScriptName() {
+ return scriptName;
+ }
+
+ public void setScriptName(String scriptName) {
+ this.scriptName = scriptName;
+ }
+
+ public String getScriptVersion() {
+ return scriptVersion;
+ }
+
+ public void setScriptVersion(String scriptVersion) {
+ this.scriptVersion = scriptVersion;
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transitions.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transitions.java
deleted file mode 100644
index 4239baa..0000000
--- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transitions.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package com.c2kernel.lifecycle.instance.stateMachine;
-
-import com.c2kernel.utils.Language;
-
-/**
- * @author XSeb74
- *
- * To change this generated comment edit the template variable "typecomment":
- * Window>Preferences>Java>Templates.
- * To enable and disable the creation of type comments go to
- * Window>Preferences>Java>Code Generation.
- */
-public class Transitions
-{
- public final static int RESERVE = 0;
- public final static int START = 1;
- public final static int SKIP = 2;
- public final static int DONE = 3;
- public final static int COMPLETE = 4;
- public final static int SUSPEND = 5;
- public final static int REASSIGN = 6;
- public final static int RESUME = 7;
- public final static int REPEAT = 8;
- public final static int IGNORE = 9;
- public final static int PROCEED = 10;
- public final static int ACTIVATION = 11;
-
- private static String[] transitions = { "reserve", "start", "skip", "done", "complete", "suspend", "reassign", "resume", "repeat","ignore","proceed","activation" };
-
- public static String getTransitionName(int trans)
- {
- try
- {
- return Language.translate(transitions[trans]);
- }
- catch (ArrayIndexOutOfBoundsException ex)
- {
- return "Invalid Transition: " + trans;
- }
- }
-}