Commit | Line | Data |
---|---|---|
816cbb00 FT |
1 | package dolda.jsvc.next; |
2 | ||
3 | import java.util.*; | |
4 | import org.w3c.dom.*; | |
5 | ||
6 | public class DocBuffer { | |
7 | public final Document doc; | |
8 | private final Map<String, Node> cursors = new HashMap<String, Node>(); | |
9 | public static final String ns = "jsvc:next:buffer"; | |
10 | ||
11 | public DocBuffer(String ns, String root, String doctype, String pubid, String sysid) { | |
12 | doc = DomUtil.document(ns, root, doctype, pubid, sysid); | |
13 | } | |
14 | ||
15 | public DocBuffer(String ns, String root) { | |
16 | this(ns, root, null, null, null); | |
17 | } | |
18 | ||
19 | private Node findcursor(Node c, String name) { | |
20 | if(c instanceof Element) { | |
21 | Element el = (Element)c; | |
6e40b32e FT |
22 | String ns = el.getNamespaceURI(); |
23 | if((ns != null) && ns.equals(DocBuffer.ns) && el.getTagName().equals("cursor") && el.getAttributeNS(null, "name").equals(name)) | |
816cbb00 FT |
24 | return(c); |
25 | } | |
26 | for(Node n = c.getFirstChild(); n != null; n = n.getNextSibling()) { | |
27 | Node r = findcursor(n, name); | |
28 | if(r != null) | |
29 | return(r); | |
30 | } | |
31 | return(null); | |
32 | } | |
33 | ||
34 | private Node cursor(String name) { | |
35 | Node n; | |
36 | if((n = cursors.get(name)) != null) { | |
37 | return(n); | |
38 | } | |
39 | if((n = findcursor(doc, name)) == null) | |
40 | return(null); | |
41 | cursors.put(name, n); | |
42 | return(n); | |
43 | } | |
44 | ||
45 | public void insert(String cursor, Node n) { | |
46 | Node c = cursor(cursor); | |
47 | if(c == null) | |
48 | throw(new RuntimeException("No such cursor: `" + cursor + "'")); | |
cb67d09c FT |
49 | if(n.getOwnerDocument() != doc) |
50 | n = doc.importNode(n, true); | |
51 | c.getParentNode().insertBefore(n, c); | |
816cbb00 FT |
52 | } |
53 | ||
54 | public Element makecursor(String name) { | |
55 | Element el = doc.createElementNS(ns, "cursor"); | |
6e40b32e | 56 | Attr a = doc.createAttributeNS(null, "name"); |
816cbb00 FT |
57 | a.setValue(name); |
58 | el.setAttributeNodeNS(a); | |
59 | return(el); | |
60 | } | |
61 | ||
62 | public Element el(String ns, String nm, Node contents, String... attrs) { | |
63 | Element el = doc.createElementNS(ns, nm); | |
64 | if(contents != null) | |
65 | el.appendChild(contents); | |
66 | for(String attr : attrs) { | |
67 | int p = attr.indexOf('='); | |
68 | el.setAttribute(attr.substring(0, p), attr.substring(p + 1)); | |
69 | } | |
70 | return(el); | |
71 | } | |
72 | ||
73 | public Text text(String text) { | |
cb67d09c FT |
74 | if(text == null) |
75 | return(null); | |
816cbb00 FT |
76 | return(doc.createTextNode(text)); |
77 | } | |
6e40b32e | 78 | |
90ff4d14 FT |
79 | public Node asnode(Object o) { |
80 | if(o instanceof Node) { | |
81 | Node n = (Node)o; | |
82 | if(n.getOwnerDocument() != doc) | |
83 | return(doc.importNode(n, true)); | |
84 | return(n); | |
85 | } | |
86 | if(o instanceof String) | |
87 | return(text((String)o)); | |
88 | throw(new RuntimeException("Cannot convert a " + o.getClass().getName() + " to a DOM node")); | |
89 | } | |
90 | ||
6e40b32e FT |
91 | public void finalise() { |
92 | Node n = doc; | |
93 | while(true) { | |
94 | Node nx; | |
95 | if(n.getFirstChild() != null) { | |
96 | nx = n.getFirstChild(); | |
97 | } else if(n.getNextSibling() != null) { | |
98 | nx = n.getNextSibling(); | |
99 | } else { | |
100 | for(nx = n.getParentNode(); nx != null; nx = nx.getParentNode()) { | |
101 | if(nx.getNextSibling() != null) { | |
102 | nx = nx.getNextSibling(); | |
103 | break; | |
104 | } | |
105 | } | |
106 | } | |
107 | String ns = n.getNamespaceURI(); | |
108 | if((ns != null) && ns.equals(DocBuffer.ns)) | |
109 | n.getParentNode().removeChild(n); | |
110 | if(nx == null) | |
111 | break; | |
112 | else | |
113 | n = nx; | |
114 | } | |
115 | } | |
816cbb00 | 116 | } |