The bsvc ShellPage uses them for reference.
import dolda.jsvc.*;
import dolda.jsvc.util.*;
+import dolda.jsvc.next.*;
+import org.w3c.dom.*;
import java.io.*;
import bsh.Interpreter;
-public class ShellPage extends SimpleWriter {
+public class ShellPage implements Responder {
private Console cons = new Console();
private Interpreter ip = new Interpreter(cons);
}
}
- public void respond(Request req, PrintWriter out) {
+ public void respond(Request req) {
MultiMap<String, String> params = req.params();
String cmd = params.get("cmd");
- out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
- out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-US\">");
- out.println("<head>");
- out.println("<title>Shell</title>");
- out.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"css\" />");
- out.println("</head>");
- out.println("<body>");
- out.println("<h1>Shell</h1>");
+ Html buf = Html.xhtml11("Shell");
+ buf.addcss("css", null);
+ buf.insert("body", buf.el("h1", buf.text("Shell")));
+
if((req.method() == "POST") && (cmd != null)) {
String eo, ee;
synchronized(cons) {
try {
ip.set("req", req);
resp = ip.eval(cmd);
- out.println("<pre>");
- out.println(Misc.htmlq((resp == null)?"(null)":(resp.toString())));
- out.println("</pre>");
+ buf.insert("body", buf.el("pre", buf.text((resp == null)?"(null)":(resp.toString()))));
} catch(bsh.EvalError exc) {
- out.println("<h2>Evaluation error</h2>");
- out.println("<pre>");
- out.print(exc.toString());
- out.println("</pre>");
+ buf.insert("body", buf.el("h2", buf.text("Evaluation error")));
+ buf.insert("body", buf.el("pre", buf.text(exc.toString())));
if(exc instanceof bsh.TargetError) {
bsh.TargetError te = (bsh.TargetError)exc;
- out.println("<h3>Target error</h3>");
- out.println("<pre>");
- te.getTarget().printStackTrace(out);
- out.println("</pre>");
+ buf.insert("body", buf.el("h3", buf.text("Target error")));
+ StringWriter sbuf = new StringWriter();
+ te.getTarget().printStackTrace(new PrintWriter(sbuf));
+ buf.insert("body", buf.el("pre", buf.text(sbuf.toString())));
}
}
eo = new String(cons.obuf.toByteArray(), Misc.utf8);
ee = new String(cons.ebuf.toByteArray(), Misc.utf8);
}
if(eo.length() > 0) {
- out.println("<h2>Output</h2>");
- out.println("<pre>");
- out.println(Misc.htmlq(eo));
- out.println("</pre>");
+ buf.insert("body", buf.el("h2", buf.text("Output")));
+ buf.insert("body", buf.el("pre", buf.text(eo)));
}
if(ee.length() > 0) {
- out.println("<h2>Errors</h2>");
- out.println("<pre>");
- out.println(Misc.htmlq(ee));
- out.println("</pre>");
+ buf.insert("body", buf.el("h2", buf.text("Errors")));
+ buf.insert("body", buf.el("pre", buf.text(ee)));
}
}
- out.println("<form action=\"sh\" method=\"post\">");
- out.println("<textarea cols=\"80\" rows=\"5\" name=\"cmd\">");
- if(cmd != null)
- out.print(cmd);
- out.println("</textarea>");
- out.println("<input type=\"submit\" value=\"Evaluate\" />");
- out.println("<input type=\"reset\" value=\"Reset\" />");
- out.println("</form>");
- out.println("</body>");
- out.println("</html>");
+
+ Element form;
+ buf.insert("body", buf.el("form", form = buf.el("p", null), "action=sh", "method=post"));
+ form.appendChild(buf.el("textarea", buf.text(cmd), "cols=80", "rows=5", "name=cmd"));
+ form.appendChild(buf.el("input", null, "type=submit", "value=Evaluate"));
+ form.appendChild(buf.el("input", null, "type=reset", "value=Reset"));
+ try {
+ buf.output(req);
+ } catch(IOException e) {
+ throw(new RuntimeException(e));
+ }
}
}
Node c = cursor(cursor);
if(c == null)
throw(new RuntimeException("No such cursor: `" + cursor + "'"));
- c.getParentNode().insertBefore(doc.importNode(n, true), c);
+ if(n.getOwnerDocument() != doc)
+ n = doc.importNode(n, true);
+ c.getParentNode().insertBefore(n, c);
}
public Element makecursor(String name) {
}
public Text text(String text) {
+ if(text == null)
+ return(null);
return(doc.createTextNode(text));
}
import javax.xml.validation.*;
import java.net.*;
import java.io.*;
+import dolda.jsvc.*;
+import dolda.jsvc.util.*;
public class Html extends DocBuffer {
public static final String ns = "http://www.w3.org/1999/xhtml";
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");
+ head.appendChild(buf.makecursor("head"));
DomUtil.inserttext(tit, title);
Node body = DomUtil.insertel(html, "body");
body.appendChild(buf.makecursor("body"));
throw(new Error(e));
}
}
+
+ private static boolean asxhtml(Request req) {
+ String ah = req.inheaders().get("Accept");
+ AcceptMap ctmap = AcceptMap.parse((ah == null)?"":ah);
+ AcceptMap.Entry ha = ctmap.accepts("text/html");
+ AcceptMap.Entry xa = ctmap.accepts("text/xhtml+xml");
+ if(xa == null)
+ xa = ctmap.accepts("application/xhtml+xml");
+ if((ha == null) && (xa == null))
+ return(false);
+ else if((ha != null) && (xa == null))
+ return(false);
+ else if((ha == null) && (xa != null))
+ return(true);
+ if(xa.q < ha.q)
+ return(false);
+ return(true);
+ }
+
+ public void output(Request req) throws IOException {
+ finalise();
+ validate();
+ XmlWriter w;
+ if(asxhtml(req)) {
+ req.outheaders().put("Content-Type", "application/xhtml+xml");
+ w = new XHtmlWriter(doc);
+ } else {
+ req.outheaders().put("Content-Type", "text/html; charset=utf-8");
+ w = new HtmlWriter(doc);
+ }
+ w.write(req.output());
+ }
}
--- /dev/null
+package dolda.jsvc.next;
+
+import java.io.*;
+import org.w3c.dom.*;
+
+public class HtmlWriter extends XHtmlWriter {
+ public HtmlWriter(Document doc) {
+ super(doc);
+ }
+
+ protected boolean asempty(ColumnWriter out, Element el) {
+ if(!super.asempty(out, el))
+ return(false);
+ String n = el.getTagName();
+ if(n.equals("br") || n.equals("hr") || n.equals("img") ||
+ n.equals("input"))
+ return(true);
+ return(false);
+ }
+
+ protected void attribute(ColumnWriter out, Attr attr, int indent) throws IOException {
+ if(attr.getNamespaceURI() != null)
+ throw(new RuntimeException("HTML does not support non-null-NS attributes (" + attr.getNamespaceURI() + " encountered)"));
+ super.attribute(out, attr, indent);
+ }
+
+ protected void element(ColumnWriter out, Element el, int indent) throws IOException {
+ if(!el.getNamespaceURI().equals(Html.ns))
+ throw(new RuntimeException("HTML does not support non-HTML elements (namespace " + el.getNamespaceURI() + " encountered)"));
+ super.element(out, el, indent);
+ }
+
+ public void write(Writer out) throws IOException {
+ DocumentType dt = doc.getDoctype();
+ if(dt == null)
+ throw(new RuntimeException("Writing HTML requires an HTML document"));
+ if(!dt.getName().equals("html"))
+ throw(new RuntimeException("Writing HTML requires an HTML document, not `" + dt.getName() + "'"));
+ String pubid = dt.getPublicId();
+ if(pubid.equals("-//W3C//DTD XHTML 1.1//EN")) {
+ } else {
+ throw(new RuntimeException("Unimplemented HTML doctype `" + pubid));
+ }
+ super.write(out);
+ }
+}
--- /dev/null
+package dolda.jsvc.next;
+
+import java.io.*;
+import org.w3c.dom.*;
+
+public class XHtmlWriter extends IndentWriter {
+ public XHtmlWriter(Document doc) {
+ super(doc);
+ setnsname(Html.ns, null);
+ }
+
+ protected int indent(ColumnWriter out, Element el) {
+ if(Html.ns.equals(el.getNamespaceURI())) {
+ if(el.getTagName().equals("pre"))
+ return(-1);
+ if(el.getTagName().equals("textarea"))
+ return(-1);
+ }
+ return(super.indent(out, el));
+ }
+}
public class XmlWriter {
private Map<String, String> nsnames = new HashMap<String, String>();
- private Document doc;
+ public final Document doc;
private int nsser = 1;
public XmlWriter(Document doc) {
}
protected void text(ColumnWriter out, String s, int indent) throws IOException {
- out.write(s);
+ out.write(Misc.htmlq(s));
}
protected void text(ColumnWriter out, Text txt, int indent) throws IOException {
}
}
+ protected void doctype(ColumnWriter out, DocumentType dt) throws IOException {
+ out.write(String.format("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n", dt.getName(), dt.getPublicId(), dt.getSystemId()));
+ }
+
public void write(Writer out) throws IOException {
findallnsnames();
ColumnWriter col = new ColumnWriter(out);
DocumentType t = doc.getDoctype();
if(t != null)
- out.write(String.format("<!DOCTYPE %s PUBLIC \"%s\" \"%s\">\n", t.getName(), t.getPublicId(), t.getSystemId()));
+ doctype(col, t);
node(col, doc.getDocumentElement(), 0);
}