Implement the bridge to call Tatoo from java. Very slow at the moment.
[tatoo.git] / src / bindings / java / fxslt / memory / TatooEngine.java
diff --git a/src/bindings/java/fxslt/memory/TatooEngine.java b/src/bindings/java/fxslt/memory/TatooEngine.java
new file mode 100644 (file)
index 0000000..71b2ced
--- /dev/null
@@ -0,0 +1,108 @@
+package fxslt.memory;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.NamedNodeMap;
+import java.util.Vector;
+
+
+public class TatooEngine {
+  static {
+    System.loadLibrary("tatoo-java");
+  }
+  private static native void unregister(long v);
+
+  public static class CustomBlock<T> {
+    // Stores a pointer to a C++ heap allocated pointer
+    // to an OCaml value. Once this object becomes unreachable on the
+    // Java side, we can de-register the value pointer in the OCaml
+    // runtime
+    // T is a phantom type denoting the type of values on the OCaml side.
+    private long value_ptr;
+    private CustomBlock(long value_ptr)
+    {
+      this.value_ptr = value_ptr;
+    }
+    protected void finalise() {
+      System.err.println("Finalizing a CustomBlock!");
+    unregister (value_ptr);
+    value_ptr = 0;
+    }
+
+  }
+  public static int decorate(Node n, int preorder)
+    {
+      if (n == null) return preorder ;
+
+      n.setUserData("", new Integer (preorder), null);
+      preorder++;
+      NamedNodeMap att = n.getAttributes();
+      if (att != null) {
+       for(int i = 0; i < att.getLength(); i++) {
+         att.item(i).setUserData("", new Integer (preorder), null);
+         preorder++;
+         att.item(i).getFirstChild().setUserData("", new Integer (preorder), null);
+         preorder++;
+       }
+      };
+      for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling())
+       preorder = decorate(c, preorder);
+      return preorder;
+    }
+
+  public static class Tree {}
+  static native CustomBlock<Tree> init_document(Document d, int i);
+  public static CustomBlock<Tree> init_document(Document d)
+    {
+      int i = decorate(d, 0);
+      return init_document(d, i);
+    }
+
+  public static class Automaton {}
+
+  public static native CustomBlock<Automaton> compile(String xpath);
+
+  public static native NodeList evaluate(CustomBlock<Automaton> automaton,
+                                 CustomBlock<Tree> tree,
+                                 NodeList start);
+
+
+  public static void main(String[] args) throws Exception {
+    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+    dbf.setCoalescing(true);
+    dbf.setNamespaceAware(true);
+    Document doc = dbf.newDocumentBuilder().newDocument();
+
+    MutableNodeList mnl = new MutableNodeList();
+    Node a, b, c, d;
+    a = doc.createElement("a");
+    b = doc.createElement("b");
+    c = doc.createElement("c");
+    d = doc.createElement("d");
+    c.appendChild(d);
+    a.appendChild(b);
+    a.appendChild(c);
+    doc.appendChild(a);
+    CustomBlock<Tree> tree = init_document (doc);
+
+    mnl.add(b);
+    mnl.add(d);
+
+    CustomBlock<Automaton> aut = compile("descendant-or-self::*");
+    System.err.println("After compilation");
+    System.err.println(aut.getClass().getName());
+    System.err.println(tree.getClass().getName());
+    System.err.println(mnl.getClass().getName());
+    NodeList nl = evaluate(aut, tree, mnl);
+    //aut.dispose();
+    System.out.println("NodeList.getLength() = " + nl.getLength());
+    for (int i = 0; i < nl.getLength(); ++i) {
+      System.out.println("NodeList.item(" + i + ").getNodeName() = "
+                        + (nl.item(i) != null ? nl.item(i).getNodeName() : null));
+    }
+    System.out.println(doc.getNodeName());
+  }
+}