WIP: Convenient document creation utilities.
authorFredrik Tolf <fredrik@dolda2000.com>
Mon, 16 Nov 2009 04:24:47 +0000 (05:24 +0100)
committerFredrik Tolf <fredrik@dolda2000.com>
Mon, 16 Nov 2009 04:24:47 +0000 (05:24 +0100)
src/dolda/jsvc/next/DocBuffer.java [new file with mode: 0644]
src/dolda/jsvc/next/DomUtil.java [new file with mode: 0644]
src/dolda/jsvc/next/Html.java [new file with mode: 0644]
src/dolda/jsvc/next/Parser.java

diff --git a/src/dolda/jsvc/next/DocBuffer.java b/src/dolda/jsvc/next/DocBuffer.java
new file mode 100644 (file)
index 0000000..432d817
--- /dev/null
@@ -0,0 +1,73 @@
+package dolda.jsvc.next;
+
+import java.util.*;
+import org.w3c.dom.*;
+
+public class DocBuffer {
+    public final Document doc;
+    private final Map<String, Node> cursors = new HashMap<String, Node>();
+    public static final String ns = "jsvc:next:buffer";
+    
+    public DocBuffer(String ns, String root, String doctype, String pubid, String sysid) {
+       doc = DomUtil.document(ns, root, doctype, pubid, sysid);
+    }
+
+    public DocBuffer(String ns, String root) {
+       this(ns, root, null, null, null);
+    }
+    
+    private Node findcursor(Node c, String name) {
+       if(c instanceof Element) {
+           Element el = (Element)c;
+           if(el.getNamespaceURI().equals(ns) && el.getTagName().equals("cursor") && el.getAttributeNS(ns, "name").equals(name))
+               return(c);
+       }
+       for(Node n = c.getFirstChild(); n != null; n = n.getNextSibling()) {
+           Node r = findcursor(n, name);
+           if(r != null)
+               return(r);
+       }
+       return(null);
+    }
+
+    private Node cursor(String name) {
+       Node n;
+       if((n = cursors.get(name)) != null) {
+           return(n);
+       }
+       if((n = findcursor(doc, name)) == null)
+           return(null);
+       cursors.put(name, n);
+       return(n);
+    }
+    
+    public void insert(String cursor, Node n) {
+       Node c = cursor(cursor);
+       if(c == null)
+           throw(new RuntimeException("No such cursor: `" + cursor + "'"));
+       c.getParentNode().insertBefore(c, doc.importNode(n, true));
+    }
+    
+    public Element makecursor(String name) {
+       Element el = doc.createElementNS(ns, "cursor");
+       Attr a = doc.createAttributeNS(ns, "name");
+       a.setValue(name);
+       el.setAttributeNodeNS(a);
+       return(el);
+    }
+
+    public Element el(String ns, String nm, Node contents, String... attrs) {
+       Element el = doc.createElementNS(ns, nm);
+       if(contents != null)
+           el.appendChild(contents);
+       for(String attr : attrs) {
+           int p = attr.indexOf('=');
+           el.setAttribute(attr.substring(0, p), attr.substring(p + 1));
+       }
+       return(el);
+    }
+    
+    public Text text(String text) {
+       return(doc.createTextNode(text));
+    }
+}
diff --git a/src/dolda/jsvc/next/DomUtil.java b/src/dolda/jsvc/next/DomUtil.java
new file mode 100644 (file)
index 0000000..bedb992
--- /dev/null
@@ -0,0 +1,54 @@
+package dolda.jsvc.next;
+
+import org.w3c.dom.*;
+import org.w3c.dom.bootstrap.*;
+
+public class DomUtil {
+    private static final DOMImplementation domimp;
+    
+    static {
+       DOMImplementationRegistry reg;
+       try {
+           reg = DOMImplementationRegistry.newInstance();
+       } catch(Exception e) {
+           throw(new Error(e));
+       }
+       DOMImplementation di = reg.getDOMImplementation("");
+       if(di == null)
+           throw(new RuntimeException("Could not get a DOM implemenation"));
+       domimp = di;
+    }
+    
+    public static Document document(String ns, String root, String doctype, String pubid, String sysid) {
+       if(doctype == null)
+           return(domimp.createDocument(ns, root, null));
+       else
+           return(domimp.createDocument(ns, root, domimp.createDocumentType(doctype, pubid, sysid)));
+    }
+    
+    public static Document document(String ns, String root) {
+       return(document(ns, root, null, null, null));
+    }
+    
+    public static Element insertel(Node p, String nm) {
+       Document doc;
+       if(p instanceof Document)
+           doc = (Document)p;
+       else
+           doc = p.getOwnerDocument();
+       Element el = doc.createElementNS(p.getNamespaceURI(), nm);
+       p.appendChild(el);
+       return(el);
+    }
+    
+    public static Text inserttext(Node p, String text) {
+       Document doc;
+       if(p instanceof Document)
+           doc = (Document)p;
+       else
+           doc = p.getOwnerDocument();
+       Text t = doc.createTextNode(text);
+       p.appendChild(t);
+       return(t);
+    }
+}
diff --git a/src/dolda/jsvc/next/Html.java b/src/dolda/jsvc/next/Html.java
new file mode 100644 (file)
index 0000000..6d6c24e
--- /dev/null
@@ -0,0 +1,39 @@
+package dolda.jsvc.next;
+
+import org.w3c.dom.*;
+
+public class Html extends DocBuffer {
+    public static final String ns = "http://www.w3.org/1999/xhtml";
+    
+    private Html(String pubid, String sysid) {
+       super(ns, "html", "html", pubid, sysid);
+    }
+
+    public static Html xhtml11(String title) {
+       Html buf = new Html("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
+       Node html = buf.doc.getDocumentElement();
+       Node head = DomUtil.insertel(html, "head");
+       head.appendChild(buf.makecursor("head"));
+       Node tit = DomUtil.insertel(head, "title");
+       DomUtil.inserttext(tit, title);
+       Node body = DomUtil.insertel(html, "body");
+       body.appendChild(buf.makecursor("body"));
+       return(buf);
+    }
+    
+    public Element el(String name, Node contents, String... attrs) {
+       return(el(ns, name, contents, attrs));
+    }
+    
+    public Element csslink(String href, String name) {
+       Element el = el("link", null, "rel=stylesheet", "type=text/css");
+       if(name != null)
+           el.setAttribute("title", name);
+       el.setAttribute("href", href);
+       return(el);
+    }
+    
+    public void addcss(String href, String name) {
+       insert("head", csslink(href, name));
+    }
+}
index dd03710..b896749 100644 (file)
@@ -3,26 +3,10 @@ package dolda.jsvc.next;
 import java.io.*;
 import java.util.*;
 import org.w3c.dom.*;
-import org.w3c.dom.bootstrap.*;
 
 public class Parser {
-    private static final DOMImplementation domimp;
-    
-    static {
-       DOMImplementationRegistry reg;
-       try {
-           reg = DOMImplementationRegistry.newInstance();
-       } catch(Exception e) {
-           throw(new Error(e));
-       }
-       DOMImplementation di = reg.getDOMImplementation("");
-       if(di == null)
-           throw(new RuntimeException("Could not get a DOM implemenation"));
-       domimp = di;
-    }
-
     public class State {
-       public final Document doc = domimp.createDocument(null, "dummy", null);
+       public final Document doc = DomUtil.document(null, "dummy");
        public final PeekReader in;
        
        private State(Reader in) {