summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Branson <andrew.branson@cern.ch>2013-10-27 00:27:24 +0200
committerAndrew Branson <andrew.branson@cern.ch>2013-10-27 00:27:24 +0200
commit30cd736670a579985890d8c2dfe363bacbad7568 (patch)
tree152b34486ed4a77c6d6a3a49c13b796ae669f512
parent0f892332b19ba8741a7db66a5c4daa386b2b5c1e (diff)
Beta?
-rw-r--r--src/main/java/com/c2kernel/lifecycle/ActivitySlotDef.java10
-rw-r--r--src/main/java/com/c2kernel/lifecycle/AndSplitDef.java2
-rw-r--r--src/main/java/com/c2kernel/lifecycle/WfCastorHashMap.java6
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/Activity.java34
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/CompositeActivity.java11
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/OrSplit.java2
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/WfVertex.java6
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/XOrSplit.java2
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/predefined/PredefinedStep.java10
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/State.java5
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/StateMachine.java41
-rw-r--r--src/main/java/com/c2kernel/lifecycle/instance/stateMachine/Transition.java21
-rw-r--r--src/main/java/com/c2kernel/process/Bootstrap.java4
-rw-r--r--src/main/java/com/c2kernel/utils/StateMachineCache.java1
-rw-r--r--src/main/resources/boot/CA/ModuleWorkflow.xml2
-rw-r--r--src/main/resources/boot/CA/ServerItemWorkflow.xml5
-rw-r--r--src/main/resources/boot/OD/StateMachine.xsd98
-rw-r--r--src/main/resources/boot/SM/CompositeActivity.xml4
-rw-r--r--src/main/resources/boot/SM/Default.xml10
-rw-r--r--src/main/resources/boot/SM/PredefinedStep.xml2
-rw-r--r--src/main/resources/boot/allbootitems.txt7
-rw-r--r--src/main/resources/boot/property/SMProp.xml5
-rw-r--r--src/main/resources/mapFiles/JobListMap.xml2
-rw-r--r--src/main/resources/mapFiles/ModuleMap.xml6
-rw-r--r--src/main/resources/mapFiles/StateMachineMap.xml18
-rw-r--r--src/test/java/MainTest.java16
-rw-r--r--src/test/resources/TestStateMachine.xml12
27 files changed, 214 insertions, 128 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(), "");
diff --git a/src/main/resources/boot/CA/ModuleWorkflow.xml b/src/main/resources/boot/CA/ModuleWorkflow.xml
index 20ce685..1eb3ee4 100644
--- a/src/main/resources/boot/CA/ModuleWorkflow.xml
+++ b/src/main/resources/boot/CA/ModuleWorkflow.xml
@@ -49,7 +49,7 @@
<OutEdgeId>4</OutEdgeId>
<Properties>
<KeyValuePair Key="Name" String="EditModuleDefinition"/>
- <KeyValuePair Key="Version" String="0"/>
+ <KeyValuePair Key="Version" Integer="0"/>
</Properties>
<activityDef>EditModuleDefinition</activityDef>
</ActivitySlotDef>
diff --git a/src/main/resources/boot/CA/ServerItemWorkflow.xml b/src/main/resources/boot/CA/ServerItemWorkflow.xml
index 085f8ab..b27b3cb 100644
--- a/src/main/resources/boot/CA/ServerItemWorkflow.xml
+++ b/src/main/resources/boot/CA/ServerItemWorkflow.xml
@@ -24,7 +24,6 @@
<OutEdgeId>19</OutEdgeId>
<Properties>
<KeyValuePair Key="LastNum" String="2"/>
- <KeyValuePair Key="RoutingScriptVersion" String=""/>
<KeyValuePair Key="RoutingScriptName" String="javascript:true;"/>
</Properties>
</LoopDef>
@@ -39,7 +38,6 @@
<OutEdgeId>18</OutEdgeId>
<Properties>
<KeyValuePair Key="LastNum" String="2"/>
- <KeyValuePair Key="RoutingScriptVersion" String=""/>
<KeyValuePair Key="RoutingScriptName" String="javascript:true;"/>
</Properties>
</LoopDef>
@@ -78,7 +76,6 @@
<OutEdgeId>10</OutEdgeId>
<OutEdgeId>11</OutEdgeId>
<Properties>
- <KeyValuePair Key="RoutingScriptVersion" String=""/>
<KeyValuePair Key="RoutingScriptName" String=""/>
</Properties>
</AndSplitDef>
@@ -94,6 +91,7 @@
<KeyValuePair Key="Prefill" Boolean="false"/>
<KeyValuePair Key="Prefill Version" String="-1"/>
<KeyValuePair Key="Name" String="CreateNewAgent"/>
+ <KeyValuePair Key="Version" Integer="0"/>
</Properties>
<activityDef>CreateNewAgent</activityDef>
</ActivitySlotDef>
@@ -109,6 +107,7 @@
<KeyValuePair Key="Prefill" Boolean="false"/>
<KeyValuePair Key="Prefill Version" String="-1"/>
<KeyValuePair Key="Name" String="CreateNewItem"/>
+ <KeyValuePair Key="Version" Integer="0"/>
</Properties>
<activityDef>CreateNewItem</activityDef>
</ActivitySlotDef>
diff --git a/src/main/resources/boot/OD/StateMachine.xsd b/src/main/resources/boot/OD/StateMachine.xsd
index d59070c..a7f8c04 100644
--- a/src/main/resources/boot/OD/StateMachine.xsd
+++ b/src/main/resources/boot/OD/StateMachine.xsd
@@ -1,52 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
- <xs:element name="StateMachine">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="State" maxOccurs="unbounded">
- <xs:complexType>
- <xs:attribute name="id" type="xs:int" use="required"/>
- <xs:attribute name="name" type="xs:string" use="required"/>
- <xs:attribute name="finished" type="xs:string"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="Transition" maxOccurs="unbounded">
- <xs:complexType>
- <xs:sequence>
- <xs:element name="Outcome">
- <xs:complexType>
- <xs:attribute name="name" type="xs:string" use="required"/>
- <xs:attribute name="version" type="xs:int" use="required"/>
- </xs:complexType>
- </xs:element>
- <xs:element name="Script">
- <xs:complexType>
- <xs:attribute name="name" type="xs:string" use="required"/>
- <xs:attribute name="version" type="xs:int" use="required"/>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- <xs:attribute name="id" type="xs:int" use="required"/>
- <xs:attribute name="name" type="xs:string" use="required"/>
- <xs:attribute name="origin" type="xs:int" use="required"/>
- <xs:attribute name="target" type="xs:int" use="required"/>
- <xs:attribute name="enablingProperty" type="xs:string"/>
- <xs:attribute name="roleOverride" type="xs:string"/>
- <xs:attribute name="reservation">
- <xs:simpleType>
- <xs:restriction base="xs:string">
- <xs:enumeration value="set"/>
- <xs:enumeration value="clear"/>
- <xs:enumeration value="preserve"/>
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- <xs:attribute name="initialState" type="xs:string"/>
- </xs:complexType>
- </xs:element>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ elementFormDefault="qualified">
+ <xs:element name="StateMachine">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="State" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="id" type="xs:int" use="required" />
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="proceeds" type="xs:boolean" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Transition" maxOccurs="unbounded" minOccurs="0">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="Outcome" maxOccurs="1" minOccurs="0">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="version" type="xs:string" use="required" />
+ <xs:attribute name="required" type="xs:boolean" use="optional" />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="Script" maxOccurs="1" minOccurs="0">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="version" type="xs:string" use="required" />
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="id" type="xs:int" use="required" />
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="origin" type="xs:int" use="required" />
+ <xs:attribute name="target" type="xs:int" use="required" />
+ <xs:attribute name="enablingProperty" type="xs:string" />
+ <xs:attribute name="roleOverride" type="xs:string" />
+ <xs:attribute name="reservation">
+ <xs:simpleType>
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="set" />
+ <xs:enumeration value="clear" />
+ <xs:enumeration value="preserve" />
+ </xs:restriction>
+ </xs:simpleType>
+ </xs:attribute>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute name="initialState" type="xs:string" />
+ </xs:complexType>
+ </xs:element>
</xs:schema>
diff --git a/src/main/resources/boot/SM/CompositeActivity.xml b/src/main/resources/boot/SM/CompositeActivity.xml
index a713c27..2ed5c4d 100644
--- a/src/main/resources/boot/SM/CompositeActivity.xml
+++ b/src/main/resources/boot/SM/CompositeActivity.xml
@@ -3,8 +3,8 @@
<State id="1" name="Started"/>
<State id="2" name="Finished" proceeds="true"/>
- <Transition id="0" name="Start" origin="0" terminus="1"/>
- <Transition id="1" name="Complete" origin="1" terminus="2"/>
+ <Transition id="0" name="Start" origin="0" target="1"/>
+ <Transition id="1" name="Complete" origin="1" target="2"/>
</StateMachine>
diff --git a/src/main/resources/boot/SM/Default.xml b/src/main/resources/boot/SM/Default.xml
index f074926..893bfe8 100644
--- a/src/main/resources/boot/SM/Default.xml
+++ b/src/main/resources/boot/SM/Default.xml
@@ -4,19 +4,19 @@
<State id="2" name="Finished" proceeds="true"/>
<State id="3" name="Suspended"/>
- <Transition id="0" name="Done" origin="0" terminus="2">
+ <Transition id="0" name="Done" origin="0" target="2">
<Outcome name="${SchemaType}" version="${SchemaVersion}"/>
<Script name="${ScriptName}" version="${ScriptVersion}"/>
</Transition>
- <Transition id="1" name="Start" origin="0" terminus="1" reservation="set"/>
- <Transition id="2" name="Complete" origin="1" terminus="2" reservation="clear">
+ <Transition id="1" name="Start" origin="0" target="1" reservation="set"/>
+ <Transition id="2" name="Complete" origin="1" target="2" reservation="clear">
<Outcome name="${SchemaType}" version="${SchemaVersion}"/>
<Script name="${ScriptName}" version="${ScriptVersion}"/>
</Transition>
- <Transition id="3" name="Suspend" origin="1" terminus="3">
+ <Transition id="3" name="Suspend" origin="1" target="3">
<Outcome name="Errors" version="0"/>
</Transition>
- <Transition id="4" name="Resume" origin="3" terminus="1" roleOverride="Admin" reservation="preserve"/>
+ <Transition id="4" name="Resume" origin="3" target="1" roleOverride="Admin" reservation="preserve"/>
</StateMachine>
diff --git a/src/main/resources/boot/SM/PredefinedStep.xml b/src/main/resources/boot/SM/PredefinedStep.xml
index 0cc418a..f62fd09 100644
--- a/src/main/resources/boot/SM/PredefinedStep.xml
+++ b/src/main/resources/boot/SM/PredefinedStep.xml
@@ -1,6 +1,6 @@
<StateMachine initialState="0">
<State id="0" name="Available"/>
- <Transition id="0" name="Done" origin="0" terminus="0">
+ <Transition id="0" name="Done" origin="0" target="0">
<Outcome name="PredefinedStepOutcome" version="0"/>
</Transition>
</StateMachine>
diff --git a/src/main/resources/boot/allbootitems.txt b/src/main/resources/boot/allbootitems.txt
index 4fdcbdc..194eb61 100644
--- a/src/main/resources/boot/allbootitems.txt
+++ b/src/main/resources/boot/allbootitems.txt
@@ -1,4 +1,6 @@
-
+SM/Default
+SM/PredefinedStep
+SM/CompositeActivity
OD/CompositeActivityDef
OD/ElementaryActivityDef
OD/Module
@@ -10,9 +12,6 @@ OD/Schema
OD/Script
OD/Errors
OD/StateMachine
-SM/Default
-SM/PredefinedStep
-SM/CompositeActivity
EA/AssignNewVersionFromLast
EA/EditActivityDef
EA/EditSchema
diff --git a/src/main/resources/boot/property/SMProp.xml b/src/main/resources/boot/property/SMProp.xml
new file mode 100644
index 0000000..8581e74
--- /dev/null
+++ b/src/main/resources/boot/property/SMProp.xml
@@ -0,0 +1,5 @@
+<AllProperties>
+ <PropertyDescription Name="Name" IsClassIdentifier="false" DefaultValue="" IsMutable="false"/>
+ <PropertyDescription Name="Type" IsClassIdentifier="true" DefaultValue="StateMachine" IsMutable="false"/>
+ <PropertyDescription Name="Module" IsClassIdentifier="false" DefaultValue="" IsMutable="false"/>
+</AllProperties>
diff --git a/src/main/resources/mapFiles/JobListMap.xml b/src/main/resources/mapFiles/JobListMap.xml
index 84d40ae..d09f7cc 100644
--- a/src/main/resources/mapFiles/JobListMap.xml
+++ b/src/main/resources/mapFiles/JobListMap.xml
@@ -18,7 +18,7 @@
<bind-xml name="StepPath" node="attribute"/>
</field>
<field name="transition" type="com.c2kernel.lifecycle.instance.stateMachine.Transition" direct="false" get-method="getTransition" set-method="setTransition">
- <bind-xml name="Transition" node="attribute"/>
+ <bind-xml name="Transition" node="element"/>
</field>
<field name="agentName" type="string" direct="false" get-method="getAgentName" set-method="setAgentName">
<bind-xml name="AgentName" node="attribute"/>
diff --git a/src/main/resources/mapFiles/ModuleMap.xml b/src/main/resources/mapFiles/ModuleMap.xml
index 541b393..45f6cbe 100644
--- a/src/main/resources/mapFiles/ModuleMap.xml
+++ b/src/main/resources/mapFiles/ModuleMap.xml
@@ -17,12 +17,12 @@
<field name="imports" direct="true" type="com.c2kernel.process.module.ModuleImports">
<bind-xml name="Imports" node="element" />
</field>
- <field name="config" collection="arraylist" direct="true" type="com.c2kernel.process.module.ModuleConfig">
+ <field name="config" collection="arraylist" direct="true" type="com.c2kernel.process.module.ModuleConfig">
<bind-xml name="Config" node="element" />
</field>
- <field name="scripts" collection="arraylist" direct="true" type="com.c2kernel.process.module.ModuleScript">
+ <field name="scripts" collection="arraylist" direct="true" type="com.c2kernel.process.module.ModuleScript">
<bind-xml name="Script" node="element" />
- </field>
+ </field>
</class>
<class name="com.c2kernel.process.module.ModuleImports">
<map-to xml="Imports"/>
diff --git a/src/main/resources/mapFiles/StateMachineMap.xml b/src/main/resources/mapFiles/StateMachineMap.xml
index 53f24e1..023dfb4 100644
--- a/src/main/resources/mapFiles/StateMachineMap.xml
+++ b/src/main/resources/mapFiles/StateMachineMap.xml
@@ -3,12 +3,12 @@
<class name="com.c2kernel.lifecycle.instance.stateMachine.StateMachine">
<map-to xml="StateMachine" />
<field name="states" type="com.c2kernel.lifecycle.instance.stateMachine.State"
- collection="arraylist" container="false" direct="false">
+ collection="arraylist" direct="false" get-method="getStates" set-method="setStates">
<bind-xml name="State" node="element" />
</field>
<field name="transitions"
type="com.c2kernel.lifecycle.instance.stateMachine.Transition"
- collection="arraylist" container="false" direct="false">
+ collection="arraylist" direct="false">
<bind-xml name="Transition" node="element" />
</field>
<field name="initialStateCode" type="integer">
@@ -16,6 +16,7 @@
</field>
</class>
<class name="com.c2kernel.lifecycle.instance.stateMachine.State">
+ <map-to xml="State"/>
<field name="id" type="integer" direct="false">
<bind-xml name="id" node="attribute" />
</field>
@@ -23,10 +24,11 @@
<bind-xml name="name" node="attribute" />
</field>
<field name="finished" type="boolean" direct="false">
- <bind-xml name="finishedd" node="attribute" />
+ <bind-xml name="proceeds" node="attribute" />
</field>
</class>
<class name="com.c2kernel.lifecycle.instance.stateMachine.Transition">
+ <map-to xml="Transition"/>
<field name="id" type="integer" direct="false">
<bind-xml name="id" node="attribute" />
</field>
@@ -48,18 +50,15 @@
<field name="reservation" type="string" direct="false">
<bind-xml name="reservation" node="attribute" />
</field>
- <field name="outcome"
- type="com.c2kernel.lifecycle.instance.stateMachine.TransitionOutcome"
- direct="false" container="false">
+ <field name="outcome" type="com.c2kernel.lifecycle.instance.stateMachine.TransitionOutcome" direct="false">
<bind-xml name="Outcome" node="element" />
</field>
- <field name="script"
- type="com.c2kernel.lifecycle.instance.stateMachine.TransitionScript"
- direct="false" container="false">
+ <field name="script" type="com.c2kernel.lifecycle.instance.stateMachine.TransitionScript" direct="false">
<bind-xml name="Script" node="element" />
</field>
</class>
<class name="com.c2kernel.lifecycle.instance.stateMachine.TransitionOutcome">
+ <map-to xml="Outcome"/>
<field name="schemaName" type="string" direct="false">
<bind-xml name="name" node="attribute" />
</field>
@@ -71,6 +70,7 @@
</field>
</class>
<class name="com.c2kernel.lifecycle.instance.stateMachine.TransitionScript">
+ <map-to xml="Script"/>
<field name="scriptName" type="string" direct="false">
<bind-xml name="name" node="attribute" />
</field>
diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java
index 99e293a..309f0cf 100644
--- a/src/test/java/MainTest.java
+++ b/src/test/java/MainTest.java
@@ -17,6 +17,13 @@ import com.c2kernel.utils.Resource;
public class MainTest {
+ public static void main(String[] args) throws Exception {
+ MainTest me = new MainTest();
+ me.testBootItems();
+ me.testScriptParsing();
+ me.testStateMachine();
+ }
+
public MainTest() throws Exception {
Logger.addLogStream(System.out, 1);
Properties props = FileStringUtility.loadConfigFile(MainTest.class.getResource("properties.conf").getPath());
@@ -31,6 +38,7 @@ public class MainTest {
validators.put("CA", new OutcomeValidator(getSchema("CompositeActivityDef", 0, "boot/OD/CompositeActivityDef.xsd")));
validators.put("EA", new OutcomeValidator(getSchema("ElementaryActivityDef", 0, "boot/OD/ElementaryActivityDef.xsd")));
validators.put("SC", new OutcomeValidator(getSchema("Script", 0, "boot/OD/Script.xsd")));
+ validators.put("SM", new OutcomeValidator(getSchema("StateMachine", 0, "boot/OD/StateMachine.xsd")));
validators.put("OD", new SchemaValidator());
String bootItems = FileStringUtility.url2String(Resource.getKernelResourceURL("boot/allbootitems.txt"));
@@ -50,7 +58,7 @@ public class MainTest {
}
assert errors.length()==0;
- if (false) if (itemType.equals("CA") || itemType.equals("EA")) {
+ if (itemType.equals("CA") || itemType.equals("EA") || itemType.equals("SM")) {
Logger.msg(1, "Remarshalling "+thisItem);
long then = System.currentTimeMillis();
Object unmarshalled = Gateway.getMarshaller().unmarshall(data);
@@ -61,7 +69,7 @@ public class MainTest {
castorTime+=(now-then);
errors = validator.validate(remarshalled);
if (errors.length() > 0) {
- Logger.error("Remarshalled resource "+thisItem+" has errors :"+errors);
+ Logger.error("Remarshalled resource "+thisItem+" has errors :"+errors+"\nRemarshalled form:\n"+remarshalled);
}
assert errors.length()==0;
@@ -104,8 +112,10 @@ public class MainTest {
}
public void testStateMachine() throws Exception {
+ Logger.msg("Validating test state machine");
String smXml = FileStringUtility.url2String(MainTest.class.getResource("TestStateMachine.xml"));
StateMachine sm = (StateMachine)Gateway.getMarshaller().unmarshall(smXml);
- assert sm!=null;
+ sm.validate();
+ assert sm.isCoherent();
}
}
diff --git a/src/test/resources/TestStateMachine.xml b/src/test/resources/TestStateMachine.xml
index 7dd6115..be188cb 100644
--- a/src/test/resources/TestStateMachine.xml
+++ b/src/test/resources/TestStateMachine.xml
@@ -4,16 +4,16 @@
<State id="2" name="Finished" proceeds="true"/>
<State id="3" name="Suspended"/>
- <Transition id="0" name="Start" origin="0" terminus="1"/>
- <Transition id="1" name="Ignore" origin="1" terminus="0" enablingProperty="Ignorable"/>
- <Transition id="2" name="Complete" origin="1" terminus="2">
- <Outcome name="${SchemaType}" version="${SchemaVersion}"/>
+ <Transition id="0" name="Start" origin="0" target="1"/>
+ <Transition id="1" name="Ignore" origin="1" target="0" enablingProperty="Ignorable"/>
+ <Transition id="2" name="Complete" origin="1" target="2">
+ <Outcome name="${SchemaType}" version="${SchemaVersion}" required="true"/>
<Script name="${ScriptName}" version="${ScriptVersion}"/>
</Transition>
- <Transition id="2" name="Suspend" origin="1" terminus="3">
+ <Transition id="2" name="Suspend" origin="1" target="3">
<Outcome name="Errors" version="0"/>
</Transition>
- <Transition id="3" name="Retry" origin="3" terminus="1" roleOverride="Admin"/>
+ <Transition id="3" name="Retry" origin="3" target="1" roleOverride="Admin"/>
</StateMachine>