Commit | Line | Data |
---|---|---|
816cbb00 FT |
1 | package dolda.jsvc.next; |
2 | ||
3 | import org.w3c.dom.*; | |
5203590b FT |
4 | import org.w3c.dom.ls.*; |
5 | import javax.xml.validation.*; | |
6 | import java.net.*; | |
7 | import java.io.*; | |
cb67d09c FT |
8 | import dolda.jsvc.*; |
9 | import dolda.jsvc.util.*; | |
816cbb00 FT |
10 | |
11 | public class Html extends DocBuffer { | |
12 | public static final String ns = "http://www.w3.org/1999/xhtml"; | |
5203590b FT |
13 | private static final Schema schema = DomUtil.loadxsd("xhtml1-strict.xsd"); |
14 | ||
816cbb00 FT |
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"); | |
816cbb00 | 23 | Node tit = DomUtil.insertel(head, "title"); |
cb67d09c | 24 | head.appendChild(buf.makecursor("head")); |
816cbb00 FT |
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 | ||
90ff4d14 FT |
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 | ||
816cbb00 FT |
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 | } | |
5203590b FT |
59 | |
60 | public void validate() { | |
c54407f4 FT |
61 | Validator val; |
62 | synchronized(schema) { | |
63 | val = schema.newValidator(); | |
64 | } | |
5203590b FT |
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 | } | |
cb67d09c FT |
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 | } | |
816cbb00 | 106 | } |