Fixed potential race condition in Html.validate().
[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 csslink(String href, String name) {
36         Element el = el("link", null, "rel=stylesheet", "type=text/css");
37         if(name != null)
38             el.setAttribute("title", name);
39         el.setAttribute("href", href);
40         return(el);
41     }
42     
43     public void addcss(String href, String name) {
44         insert("head", csslink(href, name));
45     }
46     
47     public void validate() {
48         Validator val;
49         synchronized(schema) {
50             val = schema.newValidator();
51         }
52         try {
53             val.validate(new javax.xml.transform.dom.DOMSource(doc));
54         } catch(org.xml.sax.SAXException e) {
55             throw(new RuntimeException(e));
56         } catch(java.io.IOException e) {
57             /* Should never happen. */
58             throw(new Error(e));
59         }
60     }
61     
62     private static boolean asxhtml(Request req) {
63         String ah = req.inheaders().get("Accept");
64         AcceptMap ctmap = AcceptMap.parse((ah == null)?"":ah);
65         AcceptMap.Entry ha = ctmap.accepts("text/html");
66         AcceptMap.Entry xa = ctmap.accepts("text/xhtml+xml");
67         if(xa == null)
68             xa = ctmap.accepts("application/xhtml+xml");
69         if((ha == null) && (xa == null))
70             return(false);
71         else if((ha != null) && (xa == null))
72             return(false);
73         else if((ha == null) && (xa != null))
74             return(true);
75         if(xa.q < ha.q)
76             return(false);
77         return(true);
78     }
79
80     public void output(Request req) throws IOException {
81         finalise();
82         validate();
83         XmlWriter w;
84         if(asxhtml(req)) {
85             req.outheaders().put("Content-Type", "application/xhtml+xml");
86             w = new XHtmlWriter(doc);
87         } else {
88             req.outheaders().put("Content-Type", "text/html; charset=utf-8");
89             w = new HtmlWriter(doc);
90         }
91         w.write(req.output());
92     }
93 }