Added some minor HTML utilities.
[jsvc.git] / src / dolda / jsvc / next / Html.java
1 package dolda.jsvc.next;
2
3 import org.w3c.dom.*;
4 import org.w3c.dom.ls.*;
5 import javax.xml.validation.*;
6 import java.net.*;
7 import java.io.*;
8 import dolda.jsvc.*;
9 import dolda.jsvc.util.*;
10
11 public class Html extends DocBuffer {
12     public static final String ns = "http://www.w3.org/1999/xhtml";
13     private static final Schema schema = DomUtil.loadxsd("xhtml1-strict.xsd");
14
15     private Html(String pubid, String sysid) {
16         super(ns, "html", "html", pubid, sysid);
17     }
18
19     public static Html xhtml11(String title) {
20         Html buf = new Html("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
21         Node html = buf.doc.getDocumentElement();
22         Node head = DomUtil.insertel(html, "head");
23         Node tit = DomUtil.insertel(head, "title");
24         head.appendChild(buf.makecursor("head"));
25         DomUtil.inserttext(tit, title);
26         Node body = DomUtil.insertel(html, "body");
27         body.appendChild(buf.makecursor("body"));
28         return(buf);
29     }
30     
31     public Element el(String name, Node contents, String... attrs) {
32         return(el(ns, name, contents, attrs));
33     }
34     
35     public Element table(Object... headers) {
36         Element tbl = el("table", null);
37         tbl.appendChild(tr(true, headers));
38         return(tbl);
39     }
40     
41     public Element tr(boolean head, Object... cells) {
42         Element tr = el("tr", null);
43         for(Object cell : cells)
44             tr.appendChild(el(head?"th":"td", asnode(cell)));
45         return(tr);
46     }
47     
48     public Element csslink(String href, String name) {
49         Element el = el("link", null, "rel=stylesheet", "type=text/css");
50         if(name != null)
51             el.setAttribute("title", name);
52         el.setAttribute("href", href);
53         return(el);
54     }
55     
56     public void addcss(String href, String name) {
57         insert("head", csslink(href, name));
58     }
59     
60     public void validate() {
61         Validator val;
62         synchronized(schema) {
63             val = schema.newValidator();
64         }
65         try {
66             val.validate(new javax.xml.transform.dom.DOMSource(doc));
67         } catch(org.xml.sax.SAXException e) {
68             throw(new RuntimeException(e));
69         } catch(java.io.IOException e) {
70             /* Should never happen. */
71             throw(new Error(e));
72         }
73     }
74     
75     private static boolean asxhtml(Request req) {
76         String ah = req.inheaders().get("Accept");
77         AcceptMap ctmap = AcceptMap.parse((ah == null)?"":ah);
78         AcceptMap.Entry ha = ctmap.accepts("text/html");
79         AcceptMap.Entry xa = ctmap.accepts("text/xhtml+xml");
80         if(xa == null)
81             xa = ctmap.accepts("application/xhtml+xml");
82         if((ha == null) && (xa == null))
83             return(false);
84         else if((ha != null) && (xa == null))
85             return(false);
86         else if((ha == null) && (xa != null))
87             return(true);
88         if(xa.q < ha.q)
89             return(false);
90         return(true);
91     }
92
93     public void output(Request req) throws IOException {
94         finalise();
95         validate();
96         XmlWriter w;
97         if(asxhtml(req)) {
98             req.outheaders().put("Content-Type", "application/xhtml+xml");
99             w = new XHtmlWriter(doc);
100         } else {
101             req.outheaders().put("Content-Type", "text/html; charset=utf-8");
102             w = new HtmlWriter(doc);
103         }
104         w.write(req.output());
105     }
106 }