DocBuffer.asnode: Convert null properly.
[jsvc.git] / src / dolda / jsvc / next / DocBuffer.java
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;
22             String ns = el.getNamespaceURI();
23             if((ns != null) && ns.equals(DocBuffer.ns) && el.getTagName().equals("cursor") && el.getAttributeNS(null, "name").equals(name))
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 + "'"));
49         if(n.getOwnerDocument() != doc)
50             n = doc.importNode(n, true);
51         c.getParentNode().insertBefore(n, c);
52     }
53     
54     public Element makecursor(String name) {
55         Element el = doc.createElementNS(ns, "cursor");
56         Attr a = doc.createAttributeNS(null, "name");
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) {
74         if(text == null)
75             return(null);
76         return(doc.createTextNode(text));
77     }
78     
79     public Node asnode(Object o) {
80         if(o == null)
81             return(text(""));
82         if(o instanceof Node) {
83             Node n = (Node)o;
84             if(n.getOwnerDocument() != doc)
85                 return(doc.importNode(n, true));
86             return(n);
87         }
88         if(o instanceof String)
89             return(text((String)o));
90         throw(new RuntimeException("Cannot convert a " + o.getClass().getName() + " to a DOM node"));
91     }
92     
93     public void finalise() {
94         Node n = doc;
95         while(true) {
96             Node nx;
97             if(n.getFirstChild() != null) {
98                 nx = n.getFirstChild();
99             } else if(n.getNextSibling() != null) {
100                 nx = n.getNextSibling();
101             } else {
102                 for(nx = n.getParentNode(); nx != null; nx = nx.getParentNode()) {
103                     if(nx.getNextSibling() != null) {
104                         nx = nx.getNextSibling();
105                         break;
106                     }
107                 }
108             }
109             String ns = n.getNamespaceURI();
110             if((ns != null) && ns.equals(DocBuffer.ns))
111                 n.getParentNode().removeChild(n);
112             if(nx == null)
113                 break;
114             else
115                 n = nx;
116         }
117     }
118 }