From cf45e4bf71dd2a8b27c50d247c3f09a1e22e1fa9 Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Tue, 13 Aug 2013 19:30:58 +0200 Subject: More work on java datamodel interface --- contrib/java/.classpath | 1 + contrib/java/.project | 5 ++ contrib/java/src/org/uscxml/tests/TestData.java | 23 ++++++ .../java/src/org/uscxml/tests/TestDataModel.java | 11 +-- contrib/java/src/org/uscxml/tests/TestInvoker.java | 9 ++- src/bindings/swig/java/org/uscxml/Data.java | 88 +++++++++++++++++++++ src/bindings/swig/java/uscxml.i | 89 +++++++++++++++++++++- src/uscxml/Factory.h | 2 +- 8 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 contrib/java/src/org/uscxml/tests/TestData.java create mode 100644 src/bindings/swig/java/org/uscxml/Data.java diff --git a/contrib/java/.classpath b/contrib/java/.classpath index 053c69a..96001cb 100644 --- a/contrib/java/.classpath +++ b/contrib/java/.classpath @@ -2,6 +2,7 @@ + diff --git a/contrib/java/.project b/contrib/java/.project index 4c68397..fda3442 100644 --- a/contrib/java/.project +++ b/contrib/java/.project @@ -16,6 +16,11 @@ + bindings + 2 + /Users/sradomski/Documents/TK/Code/uscxml/src/bindings/swig/java + + uscxml 2 /Users/sradomski/Documents/TK/Code/uscxml/build/cli/src/bindings/swig/java diff --git a/contrib/java/src/org/uscxml/tests/TestData.java b/contrib/java/src/org/uscxml/tests/TestData.java new file mode 100644 index 0000000..cb2fc0b --- /dev/null +++ b/contrib/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_d.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/contrib/java/src/org/uscxml/tests/TestDataModel.java b/contrib/java/src/org/uscxml/tests/TestDataModel.java index 0721501..06a56d7 100644 --- a/contrib/java/src/org/uscxml/tests/TestDataModel.java +++ b/contrib/java/src/org/uscxml/tests/TestDataModel.java @@ -1,14 +1,11 @@ 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.SWIGTYPE_p_Arabica__DOM__DocumentT_std__string_t; -import org.uscxml.SWIGTYPE_p_Arabica__DOM__ElementT_std__string_t; -import org.uscxml.SWIGTYPE_p_boost__shared_ptrT_uscxml__DataModelImpl_t; -import org.uscxml.SWIGTYPE_p_uscxml__InterpreterImpl; import org.uscxml.StringSet; @@ -55,14 +52,14 @@ public class TestDataModel extends JavaDataModel { } @Override - public Data getStringAsData(String content) { + 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; + return Data.toNative(data); } @Override @@ -79,7 +76,7 @@ public class TestDataModel extends JavaDataModel { 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 curent iteration and setting the variable in item to the current item + * to the current iteration and setting the variable in item to the current item * from array. */ System.out.println("setForeach " + item + " " + index + " " + iteration); diff --git a/contrib/java/src/org/uscxml/tests/TestInvoker.java b/contrib/java/src/org/uscxml/tests/TestInvoker.java index b41bd43..8f68c6b 100644 --- a/contrib/java/src/org/uscxml/tests/TestInvoker.java +++ b/contrib/java/src/org/uscxml/tests/TestInvoker.java @@ -1,6 +1,7 @@ package org.uscxml.tests; import org.uscxml.Data; +import org.uscxml.DataNative; import org.uscxml.Event; import org.uscxml.Factory; import org.uscxml.Interpreter; @@ -20,10 +21,10 @@ public class TestInvoker extends JavaInvoker { } @Override - public Data getDataModelVariables() { + public DataNative getDataModelVariables() { Data data = new Data(); - data.getArray().add(new Data("foo", Data.Type.VERBATIM)); - return data; + data.array.add(new Data("foo", Data.Type.VERBATIM)); + return Data.toNative(data); } @Override @@ -35,7 +36,7 @@ public class TestInvoker extends JavaInvoker { public void invoke(InvokeRequest req) { System.out.println("invoke"); - System.out.println(Data.toJSON(req.getData())); + System.out.println(req.getData()); System.out.println(req.getXML()); Event ev = new Event(); diff --git a/src/bindings/swig/java/org/uscxml/Data.java b/src/bindings/swig/java/org/uscxml/Data.java new file mode 100644 index 0000000..ce295af --- /dev/null +++ b/src/bindings/swig/java/org/uscxml/Data.java @@ -0,0 +1,88 @@ +package org.uscxml; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class Data { + public Map compound = new HashMap(); + public List array = new LinkedList(); + public String atom; + public Type type = Type.INTERPRETED; + + public enum Type { + VERBATIM, INTERPRETED + } + + public static Data fromJSON(String jsonString) { + return new Data(DataNative.fromJSON(jsonString)); + } + + public Data() { + } + + public Data(String atom, Data.Type type) { + this.atom = atom; + this.type = type; + } + + 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))); + } + } else if (!nativeData.getArray().isEmpty()) { + // data is an array + for (int i = 0; i < nativeData.getArray().size(); i++) { + this.array.add(new Data(nativeData.getArray().get(i))); + } + } else { + // data is a single atom + this.atom = nativeData.getAtom(); + if (nativeData.getType() == DataNative.Type.INTERPRETED) { + this.type = Type.INTERPRETED; + } else { + this.type = Type.VERBATIM; + } + } + } + + @Override + public String toString() { + return toJSON(); + } + + public String toJSON() { + DataNative nativeData = toNative(this); + return DataNative.toJSON(nativeData); + } + + public static DataNative toNative(Data data) { + DataNative nativeData = new DataNative(); + //nativeData.swigCMemOwn = false; + if (data.compound != null && !data.compound.isEmpty()) { + DataMap nativeDataMap = new DataMap(); + for (String key : data.compound.keySet()) { + nativeDataMap.set(key, toNative(data.compound.get(key))); + } + nativeData.setCompound(nativeDataMap); + } else if (data.array != null && !data.array.isEmpty()) { + DataList nativeDataList = new DataList(); + for (Data item : data.array) { + nativeDataList.add(toNative(item)); + } + nativeData.setArray(nativeDataList); + } else { + nativeData.setAtom(data.atom); + if (data.type == Type.INTERPRETED) { + nativeData.setType(DataNative.Type.INTERPRETED); + } else { + nativeData.setType(DataNative.Type.VERBATIM); + } + } + return nativeData; + } + +} diff --git a/src/bindings/swig/java/uscxml.i b/src/bindings/swig/java/uscxml.i index 7f496cd..d469498 100644 --- a/src/bindings/swig/java/uscxml.i +++ b/src/bindings/swig/java/uscxml.i @@ -9,10 +9,12 @@ %include %include +%include "std_string.i" %include %include "stl_set.i" %include "stl_list.i" + %include typedef uscxml::Data Data; @@ -50,10 +52,18 @@ typedef uscxml::SendRequest SendRequest; #include "../../../uscxml/Message.h" #include "../../../uscxml/Factory.h" #include "../../../uscxml/Interpreter.h" + +//#include +//#include +//#include +//#include +//#include + #include "JavaInvoker.h" #include "JavaDataModel.h" using namespace uscxml; +using namespace Arabica::DOM; #include "JavaInvoker.cpp" #include "JavaDataModel.cpp" @@ -64,25 +74,88 @@ using namespace uscxml; %ignore uscxml::SCXMLParser; %ignore uscxml::InterpreterImpl; +%ignore create(); + %ignore uscxml::Interpreter::getDelayQueue(); %ignore uscxml::JavaInvoker::create(InterpreterImpl*); -%ignore uscxml::JavaDataModel::create(InterpreterImpl*); +%ignore uscxml::JavaDataModel::create(InterpreterImpl*); %ignore uscxml::JavaDataModel::init(const Arabica::DOM::Element&, const Arabica::DOM::Document&, const std::string&); %ignore uscxml::JavaDataModel::init(const std::string&, const Data&); %ignore uscxml::JavaDataModel::assign(const Arabica::DOM::Element&, const Arabica::DOM::Document&, const std::string&); %ignore uscxml::JavaDataModel::assign(const std::string&, const Data&); %ignore uscxml::JavaDataModel::eval(const Arabica::DOM::Element&, const std::string&); -%template(DataMap) std::map; +%ignore uscxml::Event::Event(const Arabica::DOM::Node&); +%ignore uscxml::Event::getStrippedDOM; +%ignore uscxml::Event::getFirstDOMElement; +%ignore uscxml::Event::getDOM(); +%ignore uscxml::Event::setDOM(const Arabica::DOM::Document&); +%ignore uscxml::Event::toDocument(); + %template(DataList) std::list; %template(StringSet) std::set; +%rename Data DataNative; +# %typemap(jstype) uscxml::Data "Data" +# %typemap(javaout) uscxml::Data { +# return new Data(new DataNative($jnicall, $owner)); +# } + +# %typemap(javadirectorin) uscxml::Data "new Data($jniinput)" +# %typemap(javadirectorout) uscxml::Data "new Data($jniinput)" %feature("director") uscxml::JavaInvoker; %feature("director") uscxml::JavaDataModel; +// 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); + } +} + +%template(DataMap) std::map; + + //*********************************************** // Parse the header file to generate wrappers //*********************************************** @@ -90,6 +163,18 @@ using namespace uscxml; %include "../../../uscxml/Factory.h" %include "../../../uscxml/Message.h" %include "../../../uscxml/Interpreter.h" + +# %include +# %include +# %include +# %include +# %include + %include "JavaInvoker.h" %include "JavaDataModel.h" +# %template(XMLDocument) Arabica::DOM::Document; +# %template(XMLNode) Arabica::DOM::Node; +# %template(XMLElement) Arabica::DOM::Element; +# %template(XMLAttr) Arabica::DOM::Attr; +# %template(XMLText) Arabica::DOM::Text; diff --git a/src/uscxml/Factory.h b/src/uscxml/Factory.h index 74cb2a4..0432f34 100644 --- a/src/uscxml/Factory.h +++ b/src/uscxml/Factory.h @@ -299,7 +299,7 @@ public: class DataModel { public: DataModel() : _impl() {} - DataModel(boost::shared_ptr const impl) : _impl(impl) { } + DataModel(const boost::shared_ptr impl) : _impl(impl) { } DataModel(const DataModel& other) : _impl(other._impl) { } virtual ~DataModel() {}; -- cgit v0.12