summaryrefslogtreecommitdiffstats
path: root/embedding/java
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-06-25 21:05:44 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2014-06-25 21:05:44 (GMT)
commite3767be4f9c5874d9c996200f2e9705ce31a5976 (patch)
treebe3d06f550286e23eeb3252277c1a2b7d12554ef /embedding/java
parent758bda908ded461c9d34d274a18454ffba4b7450 (diff)
downloaduscxml-e3767be4f9c5874d9c996200f2e9705ce31a5976.zip
uscxml-e3767be4f9c5874d9c996200f2e9705ce31a5976.tar.gz
uscxml-e3767be4f9c5874d9c996200f2e9705ce31a5976.tar.bz2
Work on bindings
- Introduced exceptions into C# and Java - Moved binding examples to /embedding - Interpreter will now throw exceptions, beware!
Diffstat (limited to 'embedding/java')
-rw-r--r--embedding/java/.classpath9
-rw-r--r--embedding/java/.gitignore1
-rw-r--r--embedding/java/.project17
-rw-r--r--embedding/java/lib/js.jarbin0 -> 1134765 bytes
-rw-r--r--embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAData.java110
-rw-r--r--embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAEvent.java126
-rw-r--r--embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java396
-rw-r--r--embedding/java/src/org/uscxml/tests/TestData.java23
-rw-r--r--embedding/java/src/org/uscxml/tests/datamodel/TestJavaScriptDataModel.java27
-rw-r--r--embedding/java/src/org/uscxml/tests/datamodel/TestW3CECMA.java41
-rw-r--r--embedding/java/src/org/uscxml/tests/execContent/TestCustomExecContent.java81
-rw-r--r--embedding/java/src/org/uscxml/tests/invoker/TestCustomInvoker.java69
-rw-r--r--embedding/java/src/org/uscxml/tests/ioprocessor/TestCustomIOProc.java54
13 files changed, 954 insertions, 0 deletions
diff --git a/embedding/java/.classpath b/embedding/java/.classpath
new file mode 100644
index 0000000..fa94b3c
--- /dev/null
+++ b/embedding/java/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/umundo"/>
+ <classpathentry kind="lib" path="lib/js.jar"/>
+ <classpathentry kind="lib" path="/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/uscxml.jar"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/embedding/java/.gitignore b/embedding/java/.gitignore
new file mode 100644
index 0000000..5e56e04
--- /dev/null
+++ b/embedding/java/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/embedding/java/.project b/embedding/java/.project
new file mode 100644
index 0000000..9aecdf8
--- /dev/null
+++ b/embedding/java/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>uscxml</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/embedding/java/lib/js.jar b/embedding/java/lib/js.jar
new file mode 100644
index 0000000..6f0dafb
--- /dev/null
+++ b/embedding/java/lib/js.jar
Binary files differ
diff --git a/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAData.java b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAData.java
new file mode 100644
index 0000000..56d7090
--- /dev/null
+++ b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAData.java
@@ -0,0 +1,110 @@
+package org.uscxml.datamodel.ecmascript;
+
+import org.mozilla.javascript.Scriptable;
+import org.uscxml.Data;
+
+public class ECMAData implements Scriptable {
+
+ protected Data data;
+ protected Scriptable parent;
+ protected Scriptable prototype;
+
+ public ECMAData(Data data) {
+ this.data = data;
+ }
+
+ @Override
+ public String getClassName() {
+ return "Data";
+ }
+
+ public Object unwrap(Data data) {
+ if (data.atom.length() > 0) {
+ return data.atom;
+ }
+ return new ECMAData(data);
+
+ }
+
+ @Override
+ public Object get(String name, Scriptable start) {
+ if (data.compound.containsKey(name))
+ return unwrap(data.compound.get(name));
+ return NOT_FOUND;
+ }
+
+ @Override
+ public Object get(int index, Scriptable start) {
+ if (data.array.size() > index)
+ return unwrap(data.array.get(index));
+ return NOT_FOUND;
+ }
+
+ @Override
+ public boolean has(String name, Scriptable start) {
+ return data.compound.containsKey(name);
+ }
+
+ @Override
+ public boolean has(int index, Scriptable start) {
+ return data.array.size() > index;
+ }
+
+ @Override
+ public void put(String name, Scriptable start, Object value) {
+ }
+
+ @Override
+ public void put(int index, Scriptable start, Object value) {
+ }
+
+ @Override
+ public void delete(String name) {
+ }
+
+ @Override
+ public void delete(int index) {
+ }
+
+ @Override
+ public Scriptable getPrototype() {
+ return prototype;
+ }
+
+ @Override
+ public void setPrototype(Scriptable prototype) {
+ this.prototype = prototype;
+ }
+
+ @Override
+ public Scriptable getParentScope() {
+ return parent;
+ }
+
+ @Override
+ public void setParentScope(Scriptable parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Object[] getIds() {
+ return data.compound.keySet().toArray();
+ }
+
+ @Override
+ public Object getDefaultValue(Class<?> hint) {
+ return "[object Data]";
+ }
+
+ @Override
+ public boolean hasInstance(Scriptable instance) {
+ Scriptable proto = instance.getPrototype();
+ while (proto != null) {
+ if (proto.equals(this))
+ return true;
+ proto = proto.getPrototype();
+ }
+ return false;
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAEvent.java b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAEvent.java
new file mode 100644
index 0000000..58fff72
--- /dev/null
+++ b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAEvent.java
@@ -0,0 +1,126 @@
+package org.uscxml.datamodel.ecmascript;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mozilla.javascript.Scriptable;
+import org.uscxml.Data;
+import org.uscxml.Event;
+import org.uscxml.ParamPair;
+import org.uscxml.ParamPairVector;
+
+public class ECMAEvent implements Scriptable {
+
+ protected Event event;
+ protected Scriptable parent;
+ protected Scriptable prototype;
+
+ protected Map<String, Object> members = new HashMap<String, Object>();
+
+ public ECMAEvent(Event event) {
+ this.event = event;
+
+ Data data = new Data(event.getData());
+
+ // insert params into event.data
+ ParamPairVector ppv = event.getParamPairs();
+ for (int i = 0; i < ppv.size(); i++) {
+ ParamPair pp = ppv.get(i);
+ data.compound.put(pp.getFirst(), new Data(pp.getSecond()));
+ }
+
+ members.put("type", event.getEventType().toString());
+ members.put("data", new ECMAData(data));
+ members.put("sendid", event.getSendId());
+ members.put("origin", event.getOrigin());
+ members.put("originType", event.getOriginType());
+ // add others as necessary
+
+ }
+
+ @Override
+ public String getClassName() {
+ return "Event";
+ }
+
+ @Override
+ public Object get(String name, Scriptable start) {
+ if (members.containsKey(name))
+ return members.get(name);
+ return NOT_FOUND;
+ }
+
+ @Override
+ public Object get(int index, Scriptable start) {
+ return NOT_FOUND;
+ }
+
+ @Override
+ public boolean has(String name, Scriptable start) {
+ return (members.containsKey(name));
+ }
+
+ @Override
+ public boolean has(int index, Scriptable start) {
+ return false;
+ }
+
+ @Override
+ public void put(String name, Scriptable start, Object value) {
+ }
+
+ @Override
+ public void put(int index, Scriptable start, Object value) {
+ }
+
+ @Override
+ public void delete(String name) {
+ }
+
+ @Override
+ public void delete(int index) {
+ }
+
+ @Override
+ public Scriptable getPrototype() {
+ return prototype;
+ }
+
+ @Override
+ public void setPrototype(Scriptable prototype) {
+ this.prototype = prototype;
+ }
+
+ @Override
+ public Scriptable getParentScope() {
+ return parent;
+ }
+
+ @Override
+ public void setParentScope(Scriptable parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public Object[] getIds() {
+ return members.keySet().toArray();
+ }
+
+ @Override
+ public Object getDefaultValue(Class<?> hint) {
+ return "[object Event]";
+ }
+
+ @Override
+ public boolean hasInstance(Scriptable instance) {
+ Scriptable proto = instance.getPrototype();
+ while (proto != null) {
+ if (proto.equals(this))
+ return true;
+ proto = proto.getPrototype();
+ }
+
+ return false;
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java
new file mode 100644
index 0000000..dcafcb9
--- /dev/null
+++ b/embedding/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java
@@ -0,0 +1,396 @@
+package org.uscxml.datamodel.ecmascript;
+
+import java.lang.reflect.Method;
+
+import org.mozilla.javascript.Callable;
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.EvaluatorException;
+import org.mozilla.javascript.FunctionObject;
+import org.mozilla.javascript.NativeJSON;
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+import org.mozilla.javascript.Undefined;
+import org.uscxml.Data;
+import org.uscxml.DataNative;
+import org.uscxml.Event;
+import org.uscxml.Interpreter;
+import org.uscxml.StringList;
+import org.uscxml.StringVector;
+import org.uscxml.WrappedDataModel;
+
+public class ECMAScriptDataModel extends WrappedDataModel {
+
+ public static boolean debug = true;
+
+ private class NullCallable implements Callable {
+ @Override
+ public Object call(Context context, Scriptable scope,
+ Scriptable holdable, Object[] objects) {
+ return objects[1];
+ }
+ }
+
+ public Context ctx;
+ public Scriptable scope;
+ public Interpreter interpreter;
+
+ public Data getScriptableAsData(Object object) {
+ Data data = new Data();
+
+ Scriptable s;
+ try {
+ s = (Scriptable) object;
+ String className = s.getClassName(); // ECMA class name
+ if (className.toLowerCase().equals("object")) {
+ ScriptableObject obj = (ScriptableObject) Context.toObject(s,
+ scope);
+ for (Object key : obj.getIds()) {
+ data.compound.put(Context.toString(key),
+ getScriptableAsData(obj.get(key)));
+ }
+ }
+ } catch (ClassCastException e) {
+ if (object instanceof Boolean) {
+ data.atom = (Context.toBoolean(object) ? "true" : "false");
+ data.type = Data.Type.INTERPRETED;
+ } else if (object instanceof String) {
+ data.atom = (String) object;
+ data.type = Data.Type.VERBATIM;
+ } else if (object instanceof Integer) {
+ data.atom = ((Integer) object).toString();
+ data.type = Data.Type.INTERPRETED;
+ } else {
+ throw new RuntimeException("Unhandled ECMA type "
+ + object.getClass().getName());
+ }
+ }
+
+ return data;
+ }
+
+ public ScriptableObject getDataAsScriptable(Data data) {
+ throw new UnsupportedOperationException("Not implemented");
+ }
+
+ public static boolean jsIn(String stateName) {
+ return true;
+ }
+
+ @Override
+ public WrappedDataModel create(Interpreter interpreter) {
+ /**
+ * Called when an SCXML interpreter wants an instance of this datamodel
+ * Be careful to instantiate attributes of instance returned and not
+ * *this*
+ */
+
+ ECMAScriptDataModel newDM = new ECMAScriptDataModel();
+ newDM.interpreter = interpreter;
+ newDM.ctx = Context.enter();
+
+ try {
+ newDM.scope = newDM.ctx.initStandardObjects();
+ } catch (Exception e) {
+ System.err.println(e);
+ }
+
+ newDM.scope.put("_name", newDM.scope, interpreter.getName());
+ newDM.scope.put("_sessionid", newDM.scope, interpreter.getSessionId());
+
+ // ioProcessors
+ {
+ Data ioProcs = new Data();
+ StringVector keys = interpreter.getIOProcessorKeys();
+ for (int i = 0; i < keys.size(); i++) {
+ ioProcs.compound.put(keys.get(i), new Data(interpreter
+ .getIOProcessors().get(keys.get(i))
+ .getDataModelVariables()));
+ }
+ newDM.scope
+ .put("_ioprocessors", newDM.scope, new ECMAData(ioProcs));
+ }
+
+ // invokers
+ {
+ Data invokers = new Data();
+ StringVector keys = interpreter.getInvokerKeys();
+ for (int i = 0; i < keys.size(); i++) {
+ invokers.compound.put(keys.get(i), new Data(interpreter
+ .getInvokers().get(keys.get(i))
+ .getDataModelVariables()));
+ }
+ newDM.scope
+ .put("_ioprocessors", newDM.scope, new ECMAData(invokers));
+ }
+
+ // In predicate (not working as static is required) see:
+ // http://stackoverflow.com/questions/3441947/how-do-i-call-a-method-of-a-java-instance-from-javascript/16479685#16479685
+ try {
+ Class[] parameters = new Class[] { String.class };
+ Method inMethod = ECMAScriptDataModel.class.getMethod("jsIn",
+ parameters);
+ FunctionObject inFunc = new FunctionObject("In", inMethod,
+ newDM.scope);
+ newDM.scope.put("In", newDM.scope, inFunc);
+ } catch (SecurityException e) {
+ System.err.println(e);
+ } catch (NoSuchMethodException e) {
+ System.err.println(e);
+ }
+
+ return newDM;
+ }
+
+ @Override
+ public StringList getNames() {
+ /**
+ * Register with the following names for the datamodel attribute at the
+ * scxml element. <scxml datamodel="one of these">
+ */
+ StringList ss = new StringList();
+ ss.add("ecmascript");
+ return ss;
+ }
+
+ @Override
+ public boolean validate(String location, String schema) {
+ /**
+ * Validate the datamodel. This make more sense for XML datamodels and
+ * is pretty much unused but required as per draft.
+ */
+ return true;
+ }
+
+ @Override
+ public void setEvent(Event event) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " setEvent");
+ }
+
+ /**
+ * Make the current event available as the variable _event in the
+ * datamodel.
+ */
+ ECMAEvent ecmaEvent = new ECMAEvent(event);
+ scope.put("_event", scope, ecmaEvent);
+ }
+
+ @Override
+ public DataNative getStringAsData(String content) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " getStringAsData");
+ }
+
+ /**
+ * Evaluate the string as a value expression and transform it into a
+ * JSON-like Data structure
+ */
+ if (content.length() == 0) {
+ return Data.toNative(new Data());
+ }
+
+ // is it a json expression?
+ try {
+ Object json = NativeJSON.parse(ctx, scope, content,
+ new NullCallable());
+ if (json != NativeJSON.NOT_FOUND) {
+ return Data.toNative(getScriptableAsData(json));
+ }
+ } catch (org.mozilla.javascript.EcmaError e) {
+ System.err.println(e);
+ }
+
+ // is it a function call or variable?
+ Object x = ctx.evaluateString(scope, content, "uscxml", 0, null);
+ if (x == Undefined.instance) {
+ // maybe a literal string?
+ x = ctx.evaluateString(scope, '"' + content + '"', "uscxml", 0,
+ null);
+ }
+ return Data.toNative(getScriptableAsData(x));
+ }
+
+ @Override
+ public long getLength(String expr) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " getLength");
+ }
+
+ /**
+ * Return the length of the expression if it were an array, used by
+ * foreach element.
+ */
+
+ Object x = scope.get(expr, scope);
+ if (x == Undefined.instance) {
+ return 0;
+ }
+
+ Scriptable result = Context.toObject(x, scope);
+ if (result.has("length", result)) {
+ return (long) Context.toNumber(result.get("length", result));
+ }
+ return 0;
+ }
+
+ @Override
+ public void setForeach(String item, String array, String index,
+ long iteration) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " setForeach");
+ }
+
+ /**
+ * Prepare an iteration of the foreach element, by setting the variable
+ * in index to the current iteration and setting the variable in item to
+ * the current item from array.
+ */
+
+ try {
+ // get the array object
+ Scriptable arr = (Scriptable) scope.get(array, scope);
+
+ if (arr.has((int) iteration, arr)) {
+ ctx.evaluateString(scope, item + '=' + array + '[' + iteration
+ + ']', "uscxml", 1, null);
+ if (index.length() > 0) {
+ ctx.evaluateString(scope, index + '=' + iteration,
+ "uscxml", 1, null);
+ }
+ } else {
+ handleException("");
+ }
+
+ } catch (ClassCastException e) {
+ System.err.println(e);
+ }
+ }
+
+ @Override
+ public void eval(String scriptElem, String expr) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " eval");
+ }
+
+ /**
+ * Evaluate the given expression in the datamodel. This is used foremost
+ * with script elements.
+ */
+ ctx.evaluateString(scope, expr, "uscxml", 1, null);
+
+ }
+
+ @Override
+ public String evalAsString(String expr) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " evalAsString: " + expr);
+ }
+
+ /**
+ * Evaluate the expression as a string e.g. for the log element.
+ */
+ if (!ctx.stringIsCompilableUnit(expr)) {
+ handleException("");
+ return "";
+ }
+ try {
+ Object result = ctx.evaluateString(scope, expr, "uscxml", 1, null);
+ return Context.toString(result);
+ } catch (IllegalStateException e) {
+ System.err.println(e);
+ handleException("");
+ } catch (EvaluatorException e) {
+ System.err.println(e);
+ handleException("");
+ }
+ return "";
+ }
+
+ @Override
+ public boolean evalAsBool(String elem, String expr) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " evalAsBool");
+ }
+
+ /**
+ * Evaluate the expression as a boolean for cond attributes in if and
+ * transition elements.
+ */
+ Object result = ctx.evaluateString(scope, expr, "uscxml", 1, null);
+ return Context.toBoolean(result);
+ }
+
+ @Override
+ public boolean isDeclared(String expr) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " isDeclared");
+ }
+
+ /**
+ * The interpreter is supposed to raise an error if we assign to an
+ * undeclared variable. This method is used to check whether a location
+ * from assign is declared.
+ */
+ Object x = scope.get(expr, scope);
+ return x != Scriptable.NOT_FOUND;
+ }
+
+ @Override
+ public void init(String dataElem, String location, String content) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " init");
+ }
+
+ /**
+ * Called when we pass data elements.
+ */
+ if (("null").equals(location))
+ return;
+
+ if (("null").equals(content) || content.length() == 0) {
+ scope.put(location, scope, Context.getUndefinedValue());
+ return;
+ }
+
+ try {
+ Object json = NativeJSON.parse(ctx, scope, content,
+ new NullCallable());
+ if (json != NativeJSON.NOT_FOUND) {
+ scope.put(location, scope, json);
+ } else {
+ scope.put(location, scope, content);
+ }
+ } catch (org.mozilla.javascript.EcmaError e) {
+ scope.put(location, scope, content);
+ }
+ }
+
+ @Override
+ public void assign(String assignElem, String location, String content) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " assign");
+ }
+
+ /**
+ * Called when we evaluate assign elements
+ */
+ if (("null").equals(location))
+ return;
+
+ if (("null").equals(content) || content.length() == 0) {
+ scope.put(location, scope, Context.getUndefinedValue());
+ return;
+ }
+
+ String expr = location + "=" + content;
+ ctx.evaluateString(scope, expr, "uscxml", 1, null);
+ }
+
+ public void handleException(String cause) {
+ Event exceptionEvent = new Event();
+ exceptionEvent.setName("error.execution");
+ exceptionEvent.setEventType(Event.Type.PLATFORM);
+
+ interpreter.receiveInternal(exceptionEvent);
+ }
+}
diff --git a/embedding/java/src/org/uscxml/tests/TestData.java b/embedding/java/src/org/uscxml/tests/TestData.java
new file mode 100644
index 0000000..44f1ce0
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/TestData.java
@@ -0,0 +1,23 @@
+package org.uscxml.tests;
+
+import org.uscxml.Data;
+import org.uscxml.DataNative;
+
+public class TestData {
+
+ public static void main(String[] args) {
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib");
+ {
+ Data data = Data.fromJSON("[1,2,3,4,5]");
+ DataNative nData2 = Data.toNative(data);
+ Data data2 = new Data(nData2);
+ System.out.println(data2);
+ }
+ {
+ Data data = Data.fromJSON("{ \"foo\": \"bar\", \"faz\": 12 }");
+ DataNative nData2 = Data.toNative(data);
+ Data data2 = new Data(nData2);
+ System.out.println(data2);
+ }
+ }
+}
diff --git a/embedding/java/src/org/uscxml/tests/datamodel/TestJavaScriptDataModel.java b/embedding/java/src/org/uscxml/tests/datamodel/TestJavaScriptDataModel.java
new file mode 100644
index 0000000..7cfa793
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/datamodel/TestJavaScriptDataModel.java
@@ -0,0 +1,27 @@
+package org.uscxml.tests.datamodel;
+
+import org.uscxml.Factory;
+import org.uscxml.Interpreter;
+import org.uscxml.InterpreterException;
+import org.uscxml.datamodel.ecmascript.ECMAScriptDataModel;
+
+public class TestJavaScriptDataModel {
+
+ public static void main(String[] args) throws InterpreterException {
+ // load JNI library from build directory
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib");
+
+ // register java datamodel at factory
+ ECMAScriptDataModel datamodel = new ECMAScriptDataModel();
+ Factory.getInstance().registerDataModel(datamodel);
+
+ // instantiate interpreter with document from file
+ Interpreter interpreter = Interpreter
+ .fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/uscxml/java/test-ecmascript-datamodel.scxml");
+
+ // wait until interpreter has finished
+ while (true)
+ interpreter.interpret();
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/tests/datamodel/TestW3CECMA.java b/embedding/java/src/org/uscxml/tests/datamodel/TestW3CECMA.java
new file mode 100644
index 0000000..c525fd1
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/datamodel/TestW3CECMA.java
@@ -0,0 +1,41 @@
+package org.uscxml.tests.datamodel;
+
+import java.io.File;
+
+import org.uscxml.Capabilities;
+import org.uscxml.Factory;
+import org.uscxml.Interpreter;
+import org.uscxml.InterpreterException;
+import org.uscxml.InterpreterOptions;
+import org.uscxml.datamodel.ecmascript.ECMAScriptDataModel;
+
+public class TestW3CECMA {
+
+ public static String testDir = "/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma";
+
+ public static void main(String[] args) throws InterpreterException {
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib");
+
+ ECMAScriptDataModel datamodel = new ECMAScriptDataModel();
+ Factory.getInstance().registerDataModel(datamodel);
+
+// while(true) {
+// System.out.println("### test235 #####");
+// Interpreter interpreter = Interpreter.fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test144.scxml");
+// interpreter.interpret();
+// }
+
+ File dir = new File(testDir);
+ File[] filesList = dir.listFiles();
+ for (File file : filesList) {
+ if (file.isFile() && file.getName().endsWith(".scxml")) {
+ System.out.println("### " + file.getName() + " #####");
+ Interpreter interpreter = Interpreter.fromURI(file.getAbsolutePath());
+ interpreter.setCapabilities(1);
+ interpreter.interpret();
+ }
+ }
+
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/tests/execContent/TestCustomExecContent.java b/embedding/java/src/org/uscxml/tests/execContent/TestCustomExecContent.java
new file mode 100644
index 0000000..dd5e39a
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/execContent/TestCustomExecContent.java
@@ -0,0 +1,81 @@
+package org.uscxml.tests.execContent;
+
+import org.uscxml.Data;
+import org.uscxml.Event;
+import org.uscxml.Factory;
+import org.uscxml.Interpreter;
+import org.uscxml.InterpreterException;
+import org.uscxml.WrappedExecutableContent;
+
+public class TestCustomExecContent extends WrappedExecutableContent {
+
+ static int instanceId = 0;
+ public int id = 0;
+
+ public TestCustomExecContent() {
+ id = instanceId++;
+ }
+
+ @Override
+ public String getLocalName() {
+ return "custom";
+ }
+
+ @Override
+ public String getNamespace() {
+ return "http://www.w3.org/2005/07/scxml";
+ }
+
+
+ @Override
+ public void enterElement(String node) {
+ System.out.println(id + " entering:" + node);
+ }
+
+ @Override
+ public void exitElement(String node) {
+ System.out.println(id + " exiting:" + node);
+ }
+
+ @Override
+ public boolean processChildren() {
+ return false;
+ }
+
+ @Override
+ public WrappedExecutableContent create(Interpreter interpreter) {
+ return new TestCustomExecContent();
+ }
+
+ /**
+ * @param args
+ * @throws InterruptedException
+ * @throws InterpreterException
+ */
+ public static void main(String[] args) throws InterruptedException, InterpreterException {
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib");
+
+ TestCustomExecContent execContent = new TestCustomExecContent();
+ Factory.getInstance().registerExecutableContent(execContent);
+
+ Interpreter interpreter = Interpreter.fromXML(
+ "<scxml>\n" +
+ " <state id=\"s0\">\n" +
+ " <onentry>\n" +
+ " <custom foo=\"bar\">\n" +
+ " <something></something>\n" +
+ " </custom>\n" +
+ " <custom foo=\"bar\">\n" +
+ " <something></something>\n" +
+ " </custom>\n" +
+ " </onentry>\n" +
+ " <transition target=\"exit\" />" +
+ " </state>\n" +
+ " <final id=\"exit\" />" +
+ "</scxml>\n"
+ );
+ interpreter.interpret();
+ Thread.sleep(1000);
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/tests/invoker/TestCustomInvoker.java b/embedding/java/src/org/uscxml/tests/invoker/TestCustomInvoker.java
new file mode 100644
index 0000000..9343c65
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/invoker/TestCustomInvoker.java
@@ -0,0 +1,69 @@
+package org.uscxml.tests.invoker;
+
+import org.uscxml.Data;
+import org.uscxml.DataNative;
+import org.uscxml.Event;
+import org.uscxml.Factory;
+import org.uscxml.Interpreter;
+import org.uscxml.InterpreterException;
+import org.uscxml.InvokeRequest;
+import org.uscxml.StringList;
+import org.uscxml.WrappedInvoker;
+import org.uscxml.SendRequest;
+import org.uscxml.StringSet;
+
+public class TestCustomInvoker extends WrappedInvoker {
+
+ @Override
+ public StringList getNames() {
+ StringList ss = new StringList();
+ ss.add("java");
+ return ss;
+ }
+
+ @Override
+ public DataNative getDataModelVariables() {
+ Data data = new Data();
+ data.array.add(new Data("foo", Data.Type.VERBATIM));
+ return Data.toNative(data);
+ }
+
+ @Override
+ public void send(SendRequest req) {
+ System.out.println("send");
+ }
+
+ @Override
+ public void invoke(InvokeRequest req) {
+ System.out.println("invoke");
+
+ System.out.println(req.getData());
+ System.out.println(req.getXML());
+
+ Event ev = new Event();
+ ev.setName("foo");
+ returnEvent(ev);
+ }
+
+ @Override
+ public WrappedInvoker create(Interpreter interpreter) {
+ return new TestCustomInvoker();
+ }
+
+ /**
+ * @param args
+ * @throws InterpreterException
+ */
+ public static void main(String[] args) throws InterpreterException {
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64_d.jnilib");
+
+ TestCustomInvoker invoker = new TestCustomInvoker();
+ Factory.getInstance().registerInvoker(invoker);
+
+ Interpreter interpreter = Interpreter
+ .fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/samples/uscxml/test-java-invoker.scxml");
+ while (true)
+ interpreter.interpret();
+ }
+
+}
diff --git a/embedding/java/src/org/uscxml/tests/ioprocessor/TestCustomIOProc.java b/embedding/java/src/org/uscxml/tests/ioprocessor/TestCustomIOProc.java
new file mode 100644
index 0000000..37b31a3
--- /dev/null
+++ b/embedding/java/src/org/uscxml/tests/ioprocessor/TestCustomIOProc.java
@@ -0,0 +1,54 @@
+package org.uscxml.tests.ioprocessor;
+
+import org.uscxml.Data;
+import org.uscxml.DataNative;
+import org.uscxml.Factory;
+import org.uscxml.Interpreter;
+import org.uscxml.InterpreterException;
+import org.uscxml.SendRequest;
+import org.uscxml.StringList;
+import org.uscxml.WrappedIOProcessor;
+
+public class TestCustomIOProc extends WrappedIOProcessor {
+
+ @Override
+ public StringList getNames() {
+ StringList ss = new StringList();
+ ss.add("java");
+ return ss;
+ }
+
+ @Override
+ public DataNative getDataModelVariables() {
+ Data data = new Data();
+ data.array.add(new Data("foo", Data.Type.VERBATIM));
+ return Data.toNative(data);
+ }
+
+ @Override
+ public void send(SendRequest req) {
+ System.out.println("send");
+ }
+
+ @Override
+ public WrappedIOProcessor create(Interpreter interpreter) {
+ return new TestCustomIOProc();
+ }
+
+ /**
+ * @param args
+ * @throws InterpreterException
+ */
+ public static void main(String[] args) throws InterpreterException {
+ System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64_d.jnilib");
+
+ TestCustomIOProc ioproc = new TestCustomIOProc();
+ Factory.getInstance().registerIOProcessor(ioproc);
+
+ Interpreter interpreter = Interpreter
+ .fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/samples/uscxml/test-java-invoker.scxml");
+ while (true)
+ interpreter.interpret();
+ }
+
+}