From cc580e3c27c45f56193e3add35a8cc00dcd19b31 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Wed, 14 May 2014 14:07:05 +0200 Subject: Fixed some bugs with java bindings --- .../datamodel/ecmascript/ECMAScriptDataModel.java | 31 ++++------ contrib/java/src/org/uscxml/tests/TestW3CECMA.java | 13 ++-- src/bindings/swig/java/org/uscxml/Data.java | 5 +- src/bindings/swig/java/uscxml.i | 69 ++++++++-------------- src/uscxml/Interpreter.cpp | 13 +++- src/uscxml/Interpreter.h | 39 ++++++------ src/uscxml/interpreter/InterpreterDraft6.cpp | 9 +++ .../datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp | 3 + .../ecmascript/JavaScriptCore/JSCDataModel.cpp | 2 +- .../plugins/datamodel/xpath/XPathDataModel.cpp | 2 +- src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp | 3 + test/CMakeLists.txt | 14 ++--- test/src/test-arabica-namespaces.cpp | 6 +- test/src/test-stress.cpp | 8 +++ 14 files changed, 114 insertions(+), 103 deletions(-) diff --git a/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java b/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java index e3f4f2c..ba4319f 100644 --- a/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java +++ b/contrib/java/src/org/uscxml/datamodel/ecmascript/ECMAScriptDataModel.java @@ -3,7 +3,6 @@ package org.uscxml.datamodel.ecmascript; import org.mozilla.javascript.Callable; import org.mozilla.javascript.Context; import org.mozilla.javascript.NativeJSON; -import org.mozilla.javascript.NativeJavaObject; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.Undefined; @@ -13,6 +12,7 @@ import org.uscxml.Event; import org.uscxml.Interpreter; import org.uscxml.JavaDataModel; import org.uscxml.StringSet; +import org.uscxml.StringVector; public class ECMAScriptDataModel extends JavaDataModel { @@ -34,7 +34,6 @@ public class ECMAScriptDataModel extends JavaDataModel { try { s = (Scriptable) object; String className = s.getClassName(); // ECMA class name -// System.out.println("Scriptable: " + className); if (className.toLowerCase().equals("object")) { ScriptableObject obj = (ScriptableObject) Context.toObject(s, scope); @@ -63,7 +62,6 @@ public class ECMAScriptDataModel extends JavaDataModel { } public ScriptableObject getDataAsScriptable(Data data) { - // TODO! throw new UnsupportedOperationException("Not implemented"); } @@ -75,12 +73,17 @@ public class ECMAScriptDataModel extends JavaDataModel { * *this* */ ECMAScriptDataModel newDM = new ECMAScriptDataModel(); - 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(); -// ScriptableObject.defineClass(newDM.scope, ECMAEvent.class); -// ScriptableObject.defineClass(newDM.scope, ECMAEventScriptable.class); + newDM.scope.put("_ioprocessors", newDM.scope, new ECMAData(ioProcs)); } catch (Exception e) { System.err.println(e); } @@ -114,21 +117,7 @@ public class ECMAScriptDataModel extends JavaDataModel { * Make the current event available as the variable _event in the * datamodel. */ - - Data data = new Data(event.getData()); - -// Object[] args = { event }; -// Scriptable ecmaEvent = ctx.newObject(scope, "Event", args); - -// ECMAEvent ecmaEvent = new ECMAEvent(event); -// NativeJavaObject njo = new NativeJavaObject(scope, ecmaEvent, ECMAEvent.class, true); - - ECMAEvent ecmaEvent = new ECMAEvent(event); - -// for (Object key : ecmaEvent.getIds()) { -// System.out.println(key); -// } - + ECMAEvent ecmaEvent = new ECMAEvent(event); scope.put("_event", scope, ecmaEvent); } diff --git a/contrib/java/src/org/uscxml/tests/TestW3CECMA.java b/contrib/java/src/org/uscxml/tests/TestW3CECMA.java index 4c77a11..9cedee0 100644 --- a/contrib/java/src/org/uscxml/tests/TestW3CECMA.java +++ b/contrib/java/src/org/uscxml/tests/TestW3CECMA.java @@ -2,8 +2,10 @@ package org.uscxml.tests; import java.io.File; +import org.uscxml.Capabilities; import org.uscxml.Factory; import org.uscxml.Interpreter; +import org.uscxml.InterpreterOptions; import org.uscxml.datamodel.ecmascript.ECMAScriptDataModel; public class TestW3CECMA { @@ -16,16 +18,19 @@ public class TestW3CECMA { ECMAScriptDataModel datamodel = new ECMAScriptDataModel(); Factory.getInstance().registerDataModel(datamodel); -// Interpreter interpreter = Interpreter.fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test176.scxml"); -// interpreter.interpret(); -// System.exit(0); - +// while(true) { +// System.out.println("### test235 #####"); +// Interpreter interpreter = Interpreter.fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test235.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/src/bindings/swig/java/org/uscxml/Data.java b/src/bindings/swig/java/org/uscxml/Data.java index f3f21f3..fdd7448 100644 --- a/src/bindings/swig/java/org/uscxml/Data.java +++ b/src/bindings/swig/java/org/uscxml/Data.java @@ -30,8 +30,9 @@ public class Data { public Data(DataNative nativeData) { if (!nativeData.getCompound().empty()) { // data is a key value compound - for(String key : nativeData.getCompound()) { - this.compound.put(key, new Data(nativeData.getCompound().get(key))); + StringVector keys = nativeData.getCompundKeys(); + for(int i = 0; i < keys.size(); i++) { + this.compound.put(keys.get(i), new Data(nativeData.getCompound().get(keys.get(i)))); } } else if (!nativeData.getArray().isEmpty()) { // data is an array diff --git a/src/bindings/swig/java/uscxml.i b/src/bindings/swig/java/uscxml.i index ab46783..a88ebf1 100644 --- a/src/bindings/swig/java/uscxml.i +++ b/src/bindings/swig/java/uscxml.i @@ -95,9 +95,12 @@ using namespace Arabica::DOM; %ignore uscxml::Event::toDocument(); %template(DataList) std::list; +%template(DataMap) std::map; %template(StringSet) std::set; +%template(StringVector) std::vector; %template(ParamPair) std::pair; %template(ParamPairVector) std::vector >; +%template(IOProcMap) std::map; %rename Data DataNative; # %typemap(jstype) uscxml::Data "Data" @@ -127,52 +130,30 @@ using namespace Arabica::DOM; } }; +%extend uscxml::Interpreter { + std::vector getIOProcessorKeys() { + std::vector keys; + std::map::const_iterator iter = self->getIOProcessors().begin(); + while(iter != self->getIOProcessors().end()) { + keys.push_back(iter->first); + iter++; + } + return keys; + } +}; -// Provide an iterable interface for maps -// http://stackoverflow.com/questions/9465856/no-iterator-for-java-when-using-swig-with-cs-stdmap - -%typemap(javainterfaces) MapKeyIterator "java.util.Iterator" -%typemap(javacode) MapKeyIterator %{ - public void remove() throws UnsupportedOperationException { - throw new UnsupportedOperationException(); - } - - public String next() throws java.util.NoSuchElementException { - if (!hasNext()) { - throw new java.util.NoSuchElementException(); - } - return nextImpl(); - } -%} - -%javamethodmodifiers MapKeyIterator::nextImpl "private"; -%inline %{ - struct MapKeyIterator { - typedef std::map map_t; - MapKeyIterator(const map_t& m) : it(m.begin()), map(m) {} - bool hasNext() const { - return it != map.end(); - } - - const std::string nextImpl() { - const std::pair& ret = *it++; - return ret.first; - } - private: - map_t::const_iterator it; - const map_t& map; - }; -%} -%typemap(javainterfaces) std::map "Iterable" - -%newobject std::map::iterator() const; -%extend std::map { - MapKeyIterator *iterator() const { - return new MapKeyIterator(*$self); - } -} +%extend uscxml::Data { + std::vector getCompundKeys() { + std::vector keys; + std::map::const_iterator iter = self->compound.begin(); + while(iter != self->compound.end()) { + keys.push_back(iter->first); + iter++; + } + return keys; + } +}; -%template(DataMap) std::map; //*********************************************** diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index b7de262..75d44c1 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -240,6 +240,8 @@ DONE_PARSING_CMD: void NameSpaceInfo::init(const std::map& namespaceInfo) { nsInfo = namespaceInfo; nsURL = ""; + if (nsContext) + delete nsContext; nsContext = new Arabica::XPath::StandardNamespaceContext(); std::map::const_iterator nsIter = namespaceInfo.begin(); @@ -462,7 +464,12 @@ void InterpreterImpl::setName(const std::string& name) { } InterpreterImpl::~InterpreterImpl() { - _running = false; + { + // make sure we are done with setting up with early abort + tthread::lock_guard lock(_mutex); + _running = false; + } +// std::cout << "stopped " << this << std::endl; // tthread::lock_guard lock(_mutex); if (_thread) { if (_thread->get_id() != tthread::this_thread::get_id()) { @@ -554,8 +561,8 @@ void InterpreterImpl::init() { _scxml = (Arabica::DOM::Element)scxmls.item(0); // setup xpath and check that it works - if (_nsInfo.nsContext != NULL) - _xpath.setNamespaceContext(*_nsInfo.nsContext); + if (_nsInfo.getNSContext() != NULL) + _xpath.setNamespaceContext(*_nsInfo.getNSContext()); if (_name.length() == 0) _name = (HAS_ATTR(_scxml, "name") ? ATTR(_scxml, "name") : UUID::getUUID()); diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index a18bc28..6a11c46 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -98,6 +98,18 @@ enum Capabilities { class USCXML_API InterpreterOptions { public: + InterpreterOptions() : + withDebugger(false), + verbose(false), + withHTTP(true), + withHTTPS(true), + withWS(true), + logLevel(0), + httpPort(0), + httpsPort(0), + wsPort(0) + {} + bool withDebugger; bool verbose; bool withHTTP; @@ -124,31 +136,19 @@ public: static InterpreterOptions fromCmdLine(int argc, char** argv); unsigned int getCapabilities(); -protected: - InterpreterOptions() : - withDebugger(false), - verbose(false), - withHTTP(true), - withHTTPS(true), - withWS(true), - logLevel(0), - httpPort(0), - httpsPort(0), - wsPort(0) - {} }; class NameSpaceInfo { public: - NameSpaceInfo() { + NameSpaceInfo() : nsContext(NULL) { init(std::map()); } - NameSpaceInfo(const std::map& nsInfo) { + NameSpaceInfo(const std::map& nsInfo) : nsContext(NULL) { init(nsInfo); } - NameSpaceInfo(const NameSpaceInfo& other) { + NameSpaceInfo(const NameSpaceInfo& other) : nsContext(NULL) { init(other.nsInfo); } @@ -172,14 +172,19 @@ public: attribute.setPrefix(nsToPrefix[nsURL]); } + const Arabica::XPath::StandardNamespaceContext* getNSContext() { + return nsContext; + } + std::string nsURL; // ough to be "http://www.w3.org/2005/07/scxml" but maybe empty std::string xpathPrefix; // prefix mapped for xpath, "scxml" is _xmlNSPrefix is empty but _nsURL set std::string xmlNSPrefix; // the actual prefix for elements in the xml file - Arabica::XPath::StandardNamespaceContext* nsContext; std::map nsToPrefix; // prefixes for a given namespace std::map nsInfo; // all xmlns mappings private: + Arabica::XPath::StandardNamespaceContext* nsContext; + void init(const std::map& nsInfo); }; @@ -267,7 +272,7 @@ public: void setNameSpaceInfo(const NameSpaceInfo& nsInfo) { _nsInfo = nsInfo; - _xpath.setNamespaceContext(*_nsInfo.nsContext); + _xpath.setNamespaceContext(*_nsInfo.getNSContext()); } NameSpaceInfo getNameSpaceInfo() const { return _nsInfo; diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 721aea0..31c433c 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -69,6 +69,10 @@ void InterpreterDraft6::interpret() { } _running = true; +#if VERBOSE + std::cout << "running " << this << std::endl; +#endif + _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); // @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding @@ -270,6 +274,11 @@ void InterpreterDraft6::mainEventLoop() { _currEvent = _externalQueue.pop(); #if VERBOSE std::cout << "Received externalEvent event " << _currEvent.name << std::endl; + if (_running && _currEvent.name == "unblock.and.die") { + std::cout << "Still running " << this << std::endl; + } else { + std::cout << "Aborting " << this << std::endl; + } #endif _currEvent.eventType = Event::EXTERNAL; // make sure it is set to external if (!_running) diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp index 40bd464..402152d 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDOM.cpp @@ -29,10 +29,13 @@ JSCDOM::JSCDOM() { } JSCDOM::~JSCDOM() { + if (nsInfo) + delete(nsInfo); if (xpath) delete(xpath); if (storage) delete(storage); + } } diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 2e8e6d2..3130d42 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -125,7 +125,7 @@ boost::shared_ptr JSCDataModel::create(InterpreterImpl* interpret dm->_dom = new JSCDOM(); dm->_dom->xpath = new XPath(); - dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().nsContext); + dm->_dom->xpath->setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext()); dm->_dom->storage = new Storage(URL::getResourceDir() + PATH_SEPERATOR + interpreter->getName() + ".storage"); dm->_dom->nsInfo = new NameSpaceInfo(interpreter->getNameSpaceInfo()); diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index c3e82df..bf32bf9 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -54,7 +54,7 @@ boost::shared_ptr XPathDataModel::create(InterpreterImpl* interpr // dm->_xpath->setNamespaceContext(interpreter->getNSContext()); dm->_funcResolver.setInterpreter(interpreter); - dm->_xpath.setNamespaceContext(*interpreter->getNameSpaceInfo().nsContext); + dm->_xpath.setNamespaceContext(*interpreter->getNameSpaceInfo().getNSContext()); dm->_xpath.setFunctionResolver(dm->_funcResolver); dm->_xpath.setVariableResolver(dm->_varResolver); diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp index 37ec669..d89d8ac 100644 --- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp @@ -41,6 +41,9 @@ USCXMLInvoker::USCXMLInvoker() : _cancelled(false) { USCXMLInvoker::~USCXMLInvoker() { _cancelled = true; + Event event; + event.name = "unblock.and.die"; + _invokedInterpreter.receive(event); }; boost::shared_ptr USCXMLInvoker::create(InterpreterImpl* interpreter) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 24d05ab..18dfc03 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -78,14 +78,14 @@ if (NOT WIN32) add_test(test-arabica-xpath ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-arabica-parsing) set_target_properties(test-arabica-parsing PROPERTIES FOLDER "Tests") - # add_executable(test-stress src/test-stress.cpp) - # if (BUILD_AS_PLUGINS) - # target_link_libraries(test-stress uscxml invoker_dirmon) - # else() - # target_link_libraries(test-stress uscxml) - # endif() + add_executable(test-stress src/test-stress.cpp) + if (BUILD_AS_PLUGINS) + target_link_libraries(test-stress uscxml invoker_dirmon) + else() + target_link_libraries(test-stress uscxml) + endif() # add_test(test-stress ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test-stress ${CMAKE_SOURCE_DIR}/test/w3c) - # set_target_properties(test-stress PROPERTIES FOLDER "Tests") + set_target_properties(test-stress PROPERTIES FOLDER "Tests") # if (LIBPURPLE_FOUND) # add_executable(test-instant-messaging src/test-instant-messaging.cpp) diff --git a/test/src/test-arabica-namespaces.cpp b/test/src/test-arabica-namespaces.cpp index baebeee..ae529c9 100644 --- a/test/src/test-arabica-namespaces.cpp +++ b/test/src/test-arabica-namespaces.cpp @@ -93,7 +93,7 @@ static void validateRootFoo(std::pair, NameSpaceInfo>& par Document document = parsed.first; Node root = document.getDocumentElement(); - _xpath.setNamespaceContext(*nsInfo.nsContext); + _xpath.setNamespaceContext(*nsInfo.getNSContext()); assert(TAGNAME(root) == nsInfo.xmlNSPrefix + "root"); assert(LOCALNAME(root) == "root"); @@ -117,7 +117,7 @@ static void validateRootFooBar(std::pair, NameSpaceInfo>& Document document = parsed.first; Node root = document.getDocumentElement(); - _xpath.setNamespaceContext(*nsInfo.nsContext); + _xpath.setNamespaceContext(*nsInfo.getNSContext()); NodeSet barsFiltered = Interpreter::filterChildElements(nsInfo.xmlNSPrefix + "bar", root); assert(barsFiltered.size() == 3); @@ -139,7 +139,7 @@ static void validateRootFooBarBaz(std::pair, NameSpaceInfo Document document = parsed.first; Node root = document.getDocumentElement(); - _xpath.setNamespaceContext(*nsInfo.nsContext); + _xpath.setNamespaceContext(*nsInfo.getNSContext()); assert(TAGNAME(root) == nsInfo.xmlNSPrefix + "root"); assert(LOCALNAME(root) == "root"); diff --git a/test/src/test-stress.cpp b/test/src/test-stress.cpp index 996e0ee..fd36b0a 100644 --- a/test/src/test-stress.cpp +++ b/test/src/test-stress.cpp @@ -144,6 +144,13 @@ int main(int argc, char** argv) { } } +#if 1 + while(true) { + Interpreter interpreter = Interpreter::fromURI("/Users/sradomski/Documents/TK/Code/uscxml/test/w3c/ecma/test235.scxml"); + interpreter.interpret(); + } +#else + DirectoryWatch* watcher = new DirectoryWatch(argv[optind], true); watcher->updateEntries(true); std::map entries = watcher->getAllEntries(); @@ -180,5 +187,6 @@ int main(int argc, char** argv) { } delete watcher; +#endif return EXIT_SUCCESS; } \ No newline at end of file -- cgit v0.12