diff options
Diffstat (limited to 'src/main/java/com')
14 files changed, 113 insertions, 42 deletions
diff --git a/src/main/java/com/c2kernel/lifecycle/ActivitySlotDef.java b/src/main/java/com/c2kernel/lifecycle/ActivitySlotDef.java index f2cabaa..9a3819b 100644 --- a/src/main/java/com/c2kernel/lifecycle/ActivitySlotDef.java +++ b/src/main/java/com/c2kernel/lifecycle/ActivitySlotDef.java @@ -39,7 +39,7 @@ public class ActivitySlotDef extends WfVertexDef public ActivitySlotDef()
{
getProperties().put("Name", "");
- getProperties().put("Version", "last");
+ getProperties().put("Version", 0);
}
public ActivityDef getTheActivityDef() throws ObjectNotFoundException, InvalidDataException
@@ -142,9 +142,13 @@ public class ActivitySlotDef extends WfVertexDef {
return (String) getProperties().get("Name");
}
- public int getActVersion()
+ public int getActVersion() throws InvalidDataException
{
- return (Integer) getProperties().get("Version");
+ Object verObj = getProperties().get("Version");
+ if (verObj instanceof Integer)
+ return (Integer)verObj;
+ else
+ throw new InvalidDataException("Version string was not an integer", "");
}
@Override
diff --git a/src/main/java/com/c2kernel/lifecycle/AndSplitDef.java b/src/main/java/com/c2kernel/lifecycle/AndSplitDef.java index af87b18..014fecc 100644 --- a/src/main/java/com/c2kernel/lifecycle/AndSplitDef.java +++ b/src/main/java/com/c2kernel/lifecycle/AndSplitDef.java @@ -20,7 +20,7 @@ public class AndSplitDef extends WfVertexDef {
mErrors = new Vector<String>(0, 1);
getProperties().put("RoutingScriptName", "");
- getProperties().put("RoutingScriptVersion", "");
+ getProperties().put("RoutingScriptVersion", -1);
}
/**
diff --git a/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java b/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java index e47fdc6..a52fcfe 100644 --- a/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java +++ b/src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java @@ -17,11 +17,11 @@ public class WfCastorHashMap extends CastorHashMap put("Agent Role", "");
put("Agent Name", "");
put("SchemaType", "");
- put("SchemaVersion", "");
+ put("SchemaVersion", -1);
put("ScriptName", "");
- put("ScriptVersion", "");
+ put("ScriptVersion", -1);
put("StateMachineName", "Default");
- put("StateMachineVersion", "0");
+ put("StateMachineVersion", 0);
put("Viewpoint", "");
}
}
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/Activity.java b/src/main/java/com/c2kernel/lifecycle/instance/Activity.java index 182882c..a386194 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/Activity.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/Activity.java @@ -30,6 +30,7 @@ import com.c2kernel.process.Gateway; import com.c2kernel.utils.DateUtility;
import com.c2kernel.utils.LocalObjectLoader;
import com.c2kernel.utils.Logger;
+import com.c2kernel.utils.Resource;
/**
* @version $Revision: 1.222 $ $Date: 2005/10/05 07:39:37 $
* @author $Author: abranson $
@@ -54,11 +55,16 @@ public class Activity extends WfVertex {
super();
setProperties(new WfCastorHashMap());
+ getProperties().put("StateMachineName", getDefaultSMName());
mErrors = new Vector<String>(0, 1);
mStateDate = new GTimeStamp();
DateUtility.setToNow(mStateDate);
}
+ protected String getDefaultSMName() {
+ return "Default";
+ }
+
/** add the activity which id is idNext as next of the current one */
void addNext(String idNext)
{
@@ -76,25 +82,39 @@ public class Activity extends WfVertex public StateMachine getStateMachine() throws InvalidDataException {
if (machine == null) {
String name = (String)getProperties().get("StateMachineName");
- String version = (String)getProperties().get("StateMachineVersion");
+ Integer version = (Integer)getProperties().get("StateMachineVersion");
try {
- machine = LocalObjectLoader.getStateMachine(name, Integer.parseInt(version));
+ machine = LocalObjectLoader.getStateMachine(name, version);
} catch (ObjectNotFoundException ex) {
+ if (name.equals(getDefaultSMName()) && version == 0) { // default state machine not imported yet. Fake it.
+ try {
+ String marshalledSM = Resource.getTextResource(null, "boot/SM/"+getDefaultSMName()+".xml");
+ StateMachine bootstrap = (StateMachine)Gateway.getMarshaller().unmarshall(marshalledSM);
+ bootstrap.validate();
+ machine = bootstrap;
+ return bootstrap;
+ } catch (Exception ex2) {
+ Logger.error(ex2);
+ throw new InvalidDataException("Could not bootstrap default state machine from resources.", "");
+ }
+ }
Logger.error(ex);
- throw new InvalidDataException("Error loading state machine '"+name+"' v"+version);
+ throw new InvalidDataException("Error loading state machine '"+name+"' v"+version, "");
}
}
return machine;
}
/** return the current State of the State machine (Used in Serialisation) */
- public int getState()
+ public int getState() throws InvalidDataException
{
+ if (state == -1)
+ state = getStateMachine().getInitialStateCode();
return state;
}
public String getStateName() throws InvalidDataException
{
- return getStateMachine().getState(state).getName();
+ return getStateMachine().getState(getState()).getName();
}
/** Sets a new State */
@@ -104,7 +124,7 @@ public class Activity extends WfVertex }
public boolean isFinished() throws InvalidDataException {
- return getStateMachine().getState(state).isFinished();
+ return getStateMachine().getState(getState()).isFinished();
}
@@ -350,7 +370,7 @@ public class Activity extends WfVertex Logger.debug(8, getPath() + " run " + getState());
if (!getActive()) setActive(true);
- boolean finished = getStateMachine().getState(state).isFinished();
+ boolean finished = getStateMachine().getState(getState()).isFinished();
if (finished)
{
runNext(agent, itemSysKey);
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/CompositeActivity.java b/src/main/java/com/c2kernel/lifecycle/instance/CompositeActivity.java index 2f475c7..f9ab0fe 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/CompositeActivity.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/CompositeActivity.java @@ -21,8 +21,7 @@ import com.c2kernel.utils.Logger; public class CompositeActivity extends Activity
{
- public static final int START = 0;
- public static final int COMPLETE = 1;
+
/*
* --------------------------------------------
* ----------------CONSTRUCTOR-----------------
@@ -34,6 +33,14 @@ public class CompositeActivity extends Activity setChildrenGraphModel(new GraphModel(new WfVertexOutlineCreator()));
setIsComposite(true);
}
+
+ // State machine
+ public static final int START = 0;
+ public static final int COMPLETE = 1;
+ @Override
+ protected String getDefaultSMName() {
+ return "CompositeActivity";
+ }
@Override
public void setChildrenGraphModel(GraphModel childrenGraph) {
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/OrSplit.java b/src/main/java/com/c2kernel/lifecycle/instance/OrSplit.java index cadf3a0..89f5ad2 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/OrSplit.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/OrSplit.java @@ -24,7 +24,7 @@ public class OrSplit extends Split {
String nexts;
String scriptName = (String) getProperties().get("RoutingScriptName");
- String scriptVersion = (String) getProperties().get("RoutingScriptVersion");
+ Integer scriptVersion = (Integer) getProperties().get("RoutingScriptVersion");
try {
nexts = this.evaluateScript(scriptName, scriptVersion, itemSysKey).toString();
} catch (ScriptingEngineException e) {
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/WfVertex.java b/src/main/java/com/c2kernel/lifecycle/instance/WfVertex.java index 271e8df..9ed5c8a 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/WfVertex.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/WfVertex.java @@ -112,7 +112,7 @@ public abstract class WfVertex extends GraphableVertex */
public abstract Next addNext(WfVertex vertex);
- protected Object evaluateScript(String scriptName, String scriptVersion, int itemSysKey) throws ScriptingEngineException
+ protected Object evaluateScript(String scriptName, int scriptVersion, int itemSysKey) throws ScriptingEngineException
{
try
@@ -172,14 +172,14 @@ public abstract class WfVertex extends GraphableVertex }
}
- private static Script getScript(String name, String version) throws ScriptingEngineException
+ private static Script getScript(String name, int version) throws ScriptingEngineException
{
if (name == null || name.length() == 0)
throw new ScriptingEngineException("Script name is empty");
Script script;
try
{
- script = new Script(name, Integer.parseInt(version));
+ script = new Script(name, version);
}
catch (NumberFormatException e)
{ // version not valid
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/XOrSplit.java b/src/main/java/com/c2kernel/lifecycle/instance/XOrSplit.java index 164fabc..a74a939 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/XOrSplit.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/XOrSplit.java @@ -33,7 +33,7 @@ public class XOrSplit extends Split ArrayList<DirectedEdge> nextsToFollow = new ArrayList<DirectedEdge>();
String nexts;
String scriptName = (String) getProperties().get("RoutingScriptName");
- String scriptVersion = (String) getProperties().get("RoutingScriptVersion");
+ int scriptVersion = (Integer) getProperties().get("RoutingScriptVersion");
try {
nexts = this.evaluateScript(scriptName, scriptVersion, itemSysKey).toString();
} catch (ScriptingEngineException e) {
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/predefined/PredefinedStep.java b/src/main/java/com/c2kernel/lifecycle/instance/predefined/PredefinedStep.java index 5369cb2..3cf73ba 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/predefined/PredefinedStep.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/predefined/PredefinedStep.java @@ -24,8 +24,7 @@ public abstract class PredefinedStep extends Activity /*******************************************************************************************************************************************************************************************************************************************************************************************************
* predefined Steps are always Active, and have only one transition subclasses could override this method (if necessary)
******************************************************************************************************************************************************************************************************************************************************************************************************/
- public static final int DONE = 0;
- public static final int AVAILABLE = 0;
+
private boolean isPredefined = false;
@Override
public boolean getActive()
@@ -35,6 +34,13 @@ public abstract class PredefinedStep extends Activity else
return super.getActive();
}
+
+ public static final int DONE = 0;
+ public static final int AVAILABLE = 0;
+ @Override
+ protected String getDefaultSMName() {
+ return "PredefinedStep";
+ }
@Override
public String getErrors()
diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java index 0325656..fd712f4 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java @@ -19,6 +19,11 @@ public class State implements Serializable { public String getName() {
return name;
}
+
+ @Override
+ public String toString() {
+ return id+": "+name;
+ }
public void setName(String name) {
this.name = name;
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 1506701..3896ac5 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java @@ -6,6 +6,7 @@ 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;
@@ -20,7 +21,6 @@ public class StateMachine implements DescriptionObject private ArrayList<State> states;
private ArrayList<Transition> transitions;
- private final HashMap<String, State> stateNames;
private final HashMap<Integer, State> stateCodes;
private final HashMap<Integer, Transition> transitionCodes;
@@ -31,32 +31,41 @@ public class StateMachine implements DescriptionObject public StateMachine() {
states = new ArrayList<State>();
transitions = new ArrayList<Transition>();
- stateNames = new HashMap<String, State>();
stateCodes = new HashMap<Integer, State>();
transitionCodes = new HashMap<Integer, Transition>();
}
public void setStates(ArrayList<State> newStates) {
-
- isCoherent = true;
this.states = newStates;
- stateNames.clear();
-
- for (State state : states)
- stateNames.put(state.getName(), state);
-
- for (Transition trans : transitions)
- isCoherent &= trans.resolveStates(stateNames);
-
+ validate();
}
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() {
@@ -112,7 +121,7 @@ public class StateMachine implements DescriptionObject return stateCodes.get(stateID);
}
- public Map<Transition, String> getPossibleTransitions(Activity act, AgentPath agent) throws ObjectNotFoundException {
+ 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()) {
@@ -128,7 +137,7 @@ public class StateMachine implements DescriptionObject return returnList;
}
- public State traverse(Activity act, Transition transition, AgentPath agent) throws InvalidTransitionException, AccessRightsException, ObjectNotFoundException {
+ 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);
@@ -139,5 +148,9 @@ public class StateMachine implements DescriptionObject }
+ public boolean isCoherent() {
+ return isCoherent;
+ }
+
}
\ No newline at end of file diff --git a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java index 01ede5a..e7bcba9 100644 --- a/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java +++ b/src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java @@ -2,6 +2,8 @@ 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;
@@ -13,6 +15,7 @@ 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 {
@@ -127,7 +130,7 @@ public class Transition implements Serializable { this.reservation = reservation;
}
- protected boolean resolveStates(HashMap<String, State> states) {
+ protected boolean resolveStates(HashMap<Integer, State> states) {
boolean allFound = true;
if (states.keySet().contains(originStateId)) {
originState = states.get(originStateId);
@@ -232,9 +235,17 @@ public class Transition implements Serializable { private static String resolveValue(String key, CastorHashMap props) {
if (key==null) return null;
- if (key.startsWith("$"))
- return (String)props.get(key.substring(1));
- return key;
+ 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) {
@@ -255,7 +266,7 @@ public class Transition implements Serializable { 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));
+ throw new InvalidDataException("Bad schema version number: "+outcome.schemaVersion+" ("+resolveValue(outcome.schemaVersion, actProps), "");
}
else
return null;
diff --git a/src/main/java/com/c2kernel/process/Bootstrap.java b/src/main/java/com/c2kernel/process/Bootstrap.java index b334d59..b37cc8a 100644 --- a/src/main/java/com/c2kernel/process/Bootstrap.java +++ b/src/main/java/com/c2kernel/process/Bootstrap.java @@ -209,6 +209,8 @@ public class Bootstrap return new DomainPath("/desc/Script/");
if (type.equals("OD"))
return new DomainPath("/desc/OutcomeDesc/");
+ if (type.equals("SM"))
+ return new DomainPath("/desc/StateMachine");
throw new Exception("Unknown bootstrap item type: "+type);
}
@@ -221,6 +223,8 @@ public class Bootstrap return "Schema";
if (type.equals("SC"))
return "Script";
+ if (type.equals("SM"))
+ return "StateMachine";
throw new Exception("Unknown bootstrap item type: "+type);
}
diff --git a/src/main/java/com/c2kernel/utils/StateMachineCache.java b/src/main/java/com/c2kernel/utils/StateMachineCache.java index 371df4d..d48d718 100644 --- a/src/main/java/com/c2kernel/utils/StateMachineCache.java +++ b/src/main/java/com/c2kernel/utils/StateMachineCache.java @@ -33,6 +33,7 @@ public class StateMachineCache extends DescriptionObjectCache<StateMachine> { }
try {
thisStateMachine = (StateMachine)Gateway.getMarshaller().unmarshall(marshalledSM);
+ thisStateMachine.validate();
} catch (Exception ex) {
Logger.error(ex);
throw new InvalidDataException("Could not unmarshall State Machine '"+name+"' v"+version+": "+ex.getMessage(), "");
|
