summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2014-05-14 16:52:34 (GMT)
committerStefan Radomski <github@mintwerk.de>2014-05-14 16:52:34 (GMT)
commit8c645e846f8e686f7749cc98f969713289788a54 (patch)
treeb31c1537973792f4ac9216de82c0f041e9e8aeae
parent9e5d8abaec38996734f5f0fc3852fb4edbaa7e72 (diff)
parent49127140ed2ad91bfcf532b3d2265582cb80b0db (diff)
downloaduscxml-8c645e846f8e686f7749cc98f969713289788a54.zip
uscxml-8c645e846f8e686f7749cc98f969713289788a54.tar.gz
uscxml-8c645e846f8e686f7749cc98f969713289788a54.tar.bz2
Merge pull request #31 from sradomski/master
Retain interpreter instance for DataModels in Java (Rhino)
-rw-r--r--contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java137
-rw-r--r--contrib/java/src/org/uscxml/tests/TestData.java2
-rw-r--r--contrib/java/src/org/uscxml/tests/TestDataModel.java162
-rw-r--r--contrib/java/src/org/uscxml/tests/TestW3CECMA.java4
-rw-r--r--src/bindings/swig/java/JavaDataModel.h7
-rw-r--r--src/bindings/swig/java/uscxml.i12
-rw-r--r--src/uscxml/interpreter/InterpreterDraft6.cpp4
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp2
-rw-r--r--test/uscxml/java/test-ecmascript-datamodel.scxml2
9 files changed, 149 insertions, 183 deletions
diff --git a/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java b/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java
index ba4319f..3d77dc5 100644
--- a/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java
+++ b/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java
@@ -1,7 +1,11 @@
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;
@@ -16,6 +20,8 @@ import org.uscxml.StringVector;
public class ECMAScriptDataModel extends JavaDataModel {
+ public static boolean debug = true;
+
private class NullCallable implements Callable {
@Override
public Object call(Context context, Scriptable scope,
@@ -26,6 +32,7 @@ public class ECMAScriptDataModel extends JavaDataModel {
public Context ctx;
public Scriptable scope;
+ public Interpreter interpreter;
public Data getScriptableAsData(Object object) {
Data data = new Data();
@@ -65,6 +72,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
throw new UnsupportedOperationException("Not implemented");
}
+ public static boolean jsIn(String stateName) {
+ return true;
+ }
+
@Override
public JavaDataModel create(Interpreter interpreter) {
/**
@@ -72,22 +83,61 @@ public class ECMAScriptDataModel extends JavaDataModel {
* Be careful to instantiate attributes of instance returned and not
* *this*
*/
+
ECMAScriptDataModel newDM = new ECMAScriptDataModel();
+ newDM.interpreter = interpreter;
newDM.ctx = Context.enter();
- 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()));
- }
-
try {
newDM.scope = newDM.ctx.initStandardObjects();
- newDM.scope.put("_ioprocessors", newDM.scope, new ECMAData(ioProcs));
} 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;
}
@@ -113,16 +163,24 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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);
+ 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
@@ -139,8 +197,9 @@ public class ECMAScriptDataModel extends JavaDataModel {
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) {
@@ -153,6 +212,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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.
@@ -173,6 +236,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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
@@ -191,7 +258,7 @@ public class ECMAScriptDataModel extends JavaDataModel {
"uscxml", 1, null);
}
} else {
- // we ought to throw a error.execution
+ handleException("");
}
} catch (ClassCastException e) {
@@ -201,6 +268,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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.
@@ -211,15 +282,36 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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.
*/
- Object result = ctx.evaluateString(scope, expr, "uscxml", 1, null);
- return Context.toString(result);
+ 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.
@@ -230,6 +322,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@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
@@ -241,6 +337,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@Override
public void init(String dataElem, String location, String content) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " init");
+ }
+
/**
* Called when we pass data elements.
*/
@@ -267,6 +367,10 @@ public class ECMAScriptDataModel extends JavaDataModel {
@Override
public void assign(String assignElem, String location, String content) {
+ if (debug) {
+ System.out.println(interpreter.getName() + " assign");
+ }
+
/**
* Called when we evaluate assign elements
*/
@@ -279,7 +383,14 @@ public class ECMAScriptDataModel extends JavaDataModel {
}
String expr = location + "=" + content;
- ctx.evaluateString(scope, expr, "uscxml", 1, null);
+ 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/contrib/java/src/org/uscxml/tests/TestData.java b/contrib/java/src/org/uscxml/tests/TestData.java
index fc8deda..44f1ce0 100644
--- a/contrib/java/src/org/uscxml/tests/TestData.java
+++ b/contrib/java/src/org/uscxml/tests/TestData.java
@@ -6,7 +6,7 @@ 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_d.jnilib");
+ 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);
diff --git a/contrib/java/src/org/uscxml/tests/TestDataModel.java b/contrib/java/src/org/uscxml/tests/TestDataModel.java
deleted file mode 100644
index e813d66..0000000
--- a/contrib/java/src/org/uscxml/tests/TestDataModel.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package org.uscxml.tests;
-
-import org.uscxml.Data;
-import org.uscxml.DataNative;
-import org.uscxml.Event;
-import org.uscxml.Factory;
-import org.uscxml.Interpreter;
-import org.uscxml.JavaDataModel;
-import org.uscxml.StringSet;
-
-public class TestDataModel extends JavaDataModel {
-
- @Override
- public JavaDataModel create(Interpreter interpreter) {
- /**
- * Called when an SCXML interpreter wants an instance of this datamodel
- */
- System.out.println("create");
- return new TestDataModel();
- }
-
- @Override
- public StringSet getNames() {
- /**
- * Register with the following names for the datamodel attribute at the
- * scxml element. <scxml datamodel="one of these">
- */
- System.out.println("getNames");
- StringSet ss = new StringSet();
- ss.insert("java");
- 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.
- */
- System.out.println("validate " + location + " " + schema);
- return true;
- }
-
- @Override
- public void setEvent(Event event) {
- /**
- * Make the current event available as the variable _event in the
- * datamodel.
- */
- System.out.println("setEvent " + event);
- }
-
- @Override
- public DataNative getStringAsData(String content) {
- /**
- * Evaluate the string as a value expression and transform it into a
- * JSON-like Data structure
- */
- System.out.println("getStringAsData " + content);
- Data data = new Data();
- return Data.toNative(data);
- }
-
- @Override
- public long getLength(String expr) {
- /**
- * Return the length of the expression if it were an array, used by
- * foreach element.
- */
- System.out.println("getLength " + expr);
- return 0;
- }
-
- @Override
- public void setForeach(String item, String array, String index,
- long iteration) {
- /**
- * 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.
- */
- System.out
- .println("setForeach " + item + " " + index + " " + iteration);
- }
-
- @Override
- public void eval(String scriptElem, String expr) {
- /**
- * Evaluate the given expression in the datamodel. This is used foremost
- * with script elements.
- */
- System.out.println("eval " + scriptElem + " " + expr);
- }
-
- @Override
- public String evalAsString(String expr) {
- /**
- * Evaluate the expression as a string e.g. for the log element.
- */
- System.out.println("evalAsString " + expr);
- return "";
- }
-
- @Override
- public boolean evalAsBool(String expr) {
- /**
- * Evaluate the expression as a boolean for cond attributes in if and
- * transition elements.
- */
- System.out.println("evalAsBool " + expr);
- return true;
- }
-
- @Override
- public boolean isDeclared(String expr) {
- /**
- * 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.
- */
- System.out.println("isDeclared " + expr);
- return true;
- }
-
- @Override
- public void init(String dataElem, String location, String content) {
- /**
- * Called when we pass data elements.
- */
- System.out.println("init " + dataElem + " " + location + " " + content);
- }
-
- @Override
- public void assign(String assignElem, String location, String content) {
- /**
- * Called when we evaluate assign elements
- */
- System.out.println("assign " + assignElem + " " + location + " "
- + content);
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- // load JNI library from build directory
- System.load("/Users/sradomski/Documents/TK/Code/uscxml/build/cli/lib/libuscxmlNativeJava64.jnilib");
-
- // register java datamodel at factory
- TestDataModel datamodel = new TestDataModel();
- Factory.getInstance().registerDataModel(datamodel);
-
- // instantiate interpreter with document from file
- Interpreter interpreter = Interpreter
- .fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/uscxml/java/test-java-datamodel.scxml");
-
- // wait until interpreter has finished
- while (true)
- interpreter.interpret();
- }
-
-}
diff --git a/contrib/java/src/org/uscxml/tests/TestW3CECMA.java b/contrib/java/src/org/uscxml/tests/TestW3CECMA.java
index 9cedee0..0949701 100644
--- a/contrib/java/src/org/uscxml/tests/TestW3CECMA.java
+++ b/contrib/java/src/org/uscxml/tests/TestW3CECMA.java
@@ -20,10 +20,10 @@ public class TestW3CECMA {
// while(true) {
// System.out.println("### test235 #####");
-// Interpreter interpreter = Interpreter.fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test235.scxml");
+// 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) {
diff --git a/src/bindings/swig/java/JavaDataModel.h b/src/bindings/swig/java/JavaDataModel.h
index fcfb665..4fe6cbe 100644
--- a/src/bindings/swig/java/JavaDataModel.h
+++ b/src/bindings/swig/java/JavaDataModel.h
@@ -12,12 +12,13 @@ public:
JavaDataModel();
virtual ~JavaDataModel();
- virtual JavaDataModel* create(Interpreter interpreter) {
+ virtual JavaDataModel* create(const Interpreter& interpreter) {
return new JavaDataModel();
}
virtual boost::shared_ptr<DataModelImpl> create(InterpreterImpl* interpreter) {
- return boost::shared_ptr<DataModelImpl>(create(interpreter->shared_from_this()));
+ _interpreter = interpreter->shared_from_this();
+ return boost::shared_ptr<DataModelImpl>(create(_interpreter));
}
virtual std::set<std::string> getNames() {
return std::set<std::string>();
@@ -131,6 +132,8 @@ public:
virtual void assign(const std::string& assignElem, const std::string& location, const std::string& content) {}
virtual void eval(const std::string& scriptElem, const std::string& expr) {}
+private:
+ Interpreter _interpreter;
};
}
diff --git a/src/bindings/swig/java/uscxml.i b/src/bindings/swig/java/uscxml.i
index a88ebf1..5dac9d2 100644
--- a/src/bindings/swig/java/uscxml.i
+++ b/src/bindings/swig/java/uscxml.i
@@ -101,6 +101,7 @@ using namespace Arabica::DOM;
%template(ParamPair) std::pair<std::string, uscxml::Data>;
%template(ParamPairVector) std::vector<std::pair<std::string, uscxml::Data> >;
%template(IOProcMap) std::map<std::string, uscxml::IOProcessor>;
+%template(InvokerMap) std::map<std::string, uscxml::Invoker>;
%rename Data DataNative;
# %typemap(jstype) uscxml::Data "Data"
@@ -140,6 +141,17 @@ using namespace Arabica::DOM;
}
return keys;
}
+
+ std::vector<std::string> getInvokerKeys() {
+ std::vector<std::string> keys;
+ std::map<std::string, Invoker>::const_iterator iter = self->getInvokers().begin();
+ while(iter != self->getInvokers().end()) {
+ keys.push_back(iter->first);
+ iter++;
+ }
+ return keys;
+ }
+
};
%extend uscxml::Data {
diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp
index 31c433c..f80ad24 100644
--- a/src/uscxml/interpreter/InterpreterDraft6.cpp
+++ b/src/uscxml/interpreter/InterpreterDraft6.cpp
@@ -23,6 +23,8 @@
#include "uscxml/UUID.h"
#include "uscxml/DOMUtils.h"
+#define VERBOSE 0
+
namespace uscxml {
using namespace Arabica::XPath;
@@ -185,7 +187,7 @@ void InterpreterDraft6::mainEventLoop() {
// Here we handle eventless transitions and transitions
// triggered by internal events until machine is stable
while(_running && !_stable) {
-#if 0
+#if VERBOSE
std::cout << "Configuration: ";
for (int i = 0; i < _configuration.size(); i++) {
std::cout << ATTR(_configuration[i], "id") << ", ";
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 385ee1c..bddea83 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -712,7 +712,7 @@ void V8DataModel::throwExceptionEvent(const v8::TryCatch& tryCatch) {
std::string sourceLine(*v8::String::AsciiValue(message->GetSourceLine()));
size_t startpos = sourceLine.find_first_not_of(" \t");
- if(std::string::npos != startpos) // removoe leading white space
+ if(std::string::npos != startpos) // remove leading white space
sourceLine = sourceLine.substr(startpos);
exceptionEvent.data.compound["sourceline"] = Data(sourceLine, Data::VERBATIM);
diff --git a/test/uscxml/java/test-ecmascript-datamodel.scxml b/test/uscxml/java/test-ecmascript-datamodel.scxml
index 4ec157c..14e75b3 100644
--- a/test/uscxml/java/test-ecmascript-datamodel.scxml
+++ b/test/uscxml/java/test-ecmascript-datamodel.scxml
@@ -1,4 +1,4 @@
-<scxml datamodel="java" initial="comparison" binding="late">
+<scxml datamodel="ecmascript" initial="comparison" binding="late">
<!-- unimplemented -->
<datamodel>
<data id="year" expr="2008" />