1 package dolda.jsvc.next;
6 import org.w3c.dom.bootstrap.*;
9 private static final DOMImplementation domimp;
12 DOMImplementationRegistry reg;
14 reg = DOMImplementationRegistry.newInstance();
15 } catch(Exception e) {
18 DOMImplementation di = reg.getDOMImplementation("");
20 throw(new RuntimeException("Could not get a DOM implemenation"));
25 public final Document doc = domimp.createDocument(null, "dummy", null);
26 public final PeekReader in;
28 private State(Reader in) {
29 this.in = new PeekReader(in);
33 private static boolean namechar(char c) {
34 return((c == ':') || (c == '_') || (c == '$') || (c == '.') || (c == '-') || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')));
37 protected String entity(String name) {
38 if(name.equals("amp"))
44 if(name.equals("apos"))
46 if(name.equals("quot"))
51 protected Element makenode(Document doc, String name) {
52 return(doc.createElementNS(null, name));
55 protected Attr makeattr(Document doc, Element el, String name, String val) {
56 Attr a = doc.createAttributeNS(el.getNamespaceURI(), name);
61 protected Attr makeattr(Document doc, Element el, String name) {
62 return(doc.createAttributeNS(el.getNamespaceURI(), name));
65 protected String name(State s) throws IOException {
66 StringBuilder buf = new StringBuilder();
71 } else if(namechar((char)c)) {
72 buf.append((char)s.in.read());
78 throw(new ParseException("Expected name, got `" + printable(s.in.peek()) + "'"));
79 return(buf.toString());
82 protected String entity(State s) throws IOException {
85 throw(new ParseException("Expected `&' while reading entity, got `" + printable(c) + "'"));
89 throw(new ParseException("Expected `;' while reading entity, got `" + printable(c) + "'"));
93 protected Attr attribute(State s, Element el) throws IOException {
98 throw(new ParseException("Expected `=' while reading attribute, got `" + printable(c) + "'"));
100 int qt = s.in.read();
101 if((qt != '"') && (qt != '\''))
102 throw(new ParseException("Expected double or single quote while reading attribute, got `" + printable(qt) + "'"));
103 StringBuilder buf = new StringBuilder();
107 throw(new ParseException("Unexpected end-of-file while reading attribute value"));
111 } else if(c == '&') {
112 buf.append(entity(s));
114 buf.append((char)s.in.read());
117 return(makeattr(s.doc, el, nm, buf.toString()));
120 protected Element element(State s) throws IOException {
121 Element n = makenode(s.doc, name(s));
123 int c = s.in.peek(true);
125 throw(new ParseException("Unexpected end-of-file while parsing start tag"));
126 } else if(c == '>') {
129 } else if(c == '/') {
134 throw(new ParseException("Unexpected character `" + printable(c) + "' encountered in end of empty tag"));
136 } else if(namechar((char)c)) {
137 n.setAttributeNodeNS(attribute(s, n));
139 throw(new ParseException("Unexpected character `" + printable(c) + "' encountered in start tag"));
146 } else if(c == '<') {
153 if(!nm.equals(n.getTagName()))
154 throw(new ParseException("Unexpected end tag for `" + nm + "' while parsing `" + n.getTagName() + "'"));
155 if(s.in.peek(true) != '>')
156 throw(new ParseException("Expected `>' while reading end tag, got `" + printable(c) + "'"));
160 n.appendChild(stag(s));
163 n.appendChild(text(s));
169 protected Comment comment(State s) throws IOException {
170 if((s.in.read() != '!') ||
171 (s.in.read() != '-') ||
172 (s.in.read() != '-'))
173 throw(new ParseException("Illegal start of comment"));
174 StringBuilder buf = new StringBuilder();
178 throw(new ParseException("Unexpected end-of-file while parsing comment"));
179 } else if(c == '-') {
181 if(s.in.peek() == '-') {
183 if(s.in.peek() == '>') {
193 buf.append((char)s.in.read());
196 return(s.doc.createComment(buf.toString()));
199 protected Node stag(State s) throws IOException {
200 int c = s.in.peek(true);
202 throw(new ParseException("Unexpected end-of-file while parsing tag type"));
203 } else if(c == '!') {
210 protected Text text(State s) throws IOException {
211 StringBuilder buf = new StringBuilder();
216 } else if(c == '<') {
218 } else if(c == '&') {
219 buf.append(entity(s));
221 buf.append((char)s.in.read());
224 return(s.doc.createTextNode(buf.toString()));
227 public DocumentFragment parse(Reader in) throws IOException {
228 State s = new State(in);
229 DocumentFragment frag = s.doc.createDocumentFragment();
234 } else if(c == '<') {
236 frag.appendChild(stag(s));
238 frag.appendChild(text(s));
243 private static String printable(int c) {
247 return(String.format("\\%03o", (int)c));
248 return(Character.toString((char)c));
251 public static void main(String[] args) throws Exception {
252 Parser p = new Parser();
253 DocumentFragment f = p.parse(new FileReader(args[0]));
254 javax.xml.transform.TransformerFactory fac = javax.xml.transform.TransformerFactory.newInstance();
255 fac.setAttribute("indent-number", 2);
256 javax.xml.transform.Transformer t = fac.newTransformer();
257 t.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
258 t.transform(new javax.xml.transform.dom.DOMSource(f), new javax.xml.transform.stream.StreamResult(System.out));
259 System.out.println(t.getClass());