Implement the bridge to call Tatoo from java. Very slow at the moment.
[tatoo.git] / src / bindings / java / fxslt / memory / TatooEngine.java
1 package fxslt.memory;
2
3 import javax.xml.parsers.DocumentBuilderFactory;
4
5 import org.w3c.dom.Document;
6 import org.w3c.dom.Node;
7 import org.w3c.dom.NodeList;
8 import org.w3c.dom.NamedNodeMap;
9 import java.util.Vector;
10
11
12 public class TatooEngine {
13   static {
14     System.loadLibrary("tatoo-java");
15   }
16   private static native void unregister(long v);
17
18   public static class CustomBlock<T> {
19     // Stores a pointer to a C++ heap allocated pointer
20     // to an OCaml value. Once this object becomes unreachable on the
21     // Java side, we can de-register the value pointer in the OCaml
22     // runtime
23     // T is a phantom type denoting the type of values on the OCaml side.
24     private long value_ptr;
25     private CustomBlock(long value_ptr)
26     {
27       this.value_ptr = value_ptr;
28     }
29     protected void finalise() {
30       System.err.println("Finalizing a CustomBlock!");
31     unregister (value_ptr);
32     value_ptr = 0;
33     }
34
35   }
36   public static int decorate(Node n, int preorder)
37     {
38       if (n == null) return preorder ;
39
40       n.setUserData("", new Integer (preorder), null);
41       preorder++;
42       NamedNodeMap att = n.getAttributes();
43       if (att != null) {
44         for(int i = 0; i < att.getLength(); i++) {
45           att.item(i).setUserData("", new Integer (preorder), null);
46           preorder++;
47           att.item(i).getFirstChild().setUserData("", new Integer (preorder), null);
48           preorder++;
49         }
50       };
51       for (Node c = n.getFirstChild(); c != null; c = c.getNextSibling())
52         preorder = decorate(c, preorder);
53       return preorder;
54     }
55
56   public static class Tree {}
57   static native CustomBlock<Tree> init_document(Document d, int i);
58   public static CustomBlock<Tree> init_document(Document d)
59     {
60       int i = decorate(d, 0);
61       return init_document(d, i);
62     }
63
64   public static class Automaton {}
65
66   public static native CustomBlock<Automaton> compile(String xpath);
67
68   public static native NodeList evaluate(CustomBlock<Automaton> automaton,
69                                   CustomBlock<Tree> tree,
70                                   NodeList start);
71
72
73   public static void main(String[] args) throws Exception {
74     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
75     dbf.setCoalescing(true);
76     dbf.setNamespaceAware(true);
77     Document doc = dbf.newDocumentBuilder().newDocument();
78
79     MutableNodeList mnl = new MutableNodeList();
80     Node a, b, c, d;
81     a = doc.createElement("a");
82     b = doc.createElement("b");
83     c = doc.createElement("c");
84     d = doc.createElement("d");
85     c.appendChild(d);
86     a.appendChild(b);
87     a.appendChild(c);
88     doc.appendChild(a);
89     CustomBlock<Tree> tree = init_document (doc);
90
91     mnl.add(b);
92     mnl.add(d);
93
94     CustomBlock<Automaton> aut = compile("descendant-or-self::*");
95     System.err.println("After compilation");
96     System.err.println(aut.getClass().getName());
97     System.err.println(tree.getClass().getName());
98     System.err.println(mnl.getClass().getName());
99     NodeList nl = evaluate(aut, tree, mnl);
100     //aut.dispose();
101     System.out.println("NodeList.getLength() = " + nl.getLength());
102     for (int i = 0; i < nl.getLength(); ++i) {
103       System.out.println("NodeList.item(" + i + ").getNodeName() = "
104                          + (nl.item(i) != null ? nl.item(i).getNodeName() : null));
105     }
106     System.out.println(doc.getNodeName());
107   }
108 }