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"));
24 private static boolean namechar(char c) {
25 return((c == ':') || (c == '_') || (c == '$') || (c == '.') || (c == '-') || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')));
28 protected String entity(String name) {
29 if(name.equals("amp"))
35 if(name.equals("apos"))
37 if(name.equals("quot"))
42 protected Element makenode(Document doc, String name) {
43 return(doc.createElementNS(null, name));
46 protected Attr makeattr(Document doc, Element el, String name) {
47 return(doc.createAttributeNS(el.getNamespaceURI(), name));
50 public DocumentFragment parse(Reader in) throws IOException {
51 Stack<Node> stack = new Stack<Node>();
52 Document doc = domimp.createDocument(null, "dummy", null);
53 DocumentFragment frag = doc.createDocumentFragment();
55 String st = "content";
57 StringBuilder buf = new StringBuilder();
58 StringBuilder ebuf = new StringBuilder();
67 if(stack.peek() == frag)
70 throw(new ParseException("Unexpected end-of-file while parsing non-root element"));
74 } else if(st == "tag") {
75 if(Character.isWhitespace((char)c)) {
81 } else if(namechar((char)c)) {
87 throw(new ParseException("Unexpected end-of-file while parsing tag"));
89 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in tag name"));
91 } else if(st == "stag") {
92 boolean flush = false;
93 if(namechar((char)c)) {
98 } else if(Character.isWhitespace((char)c)) {
102 throw(new ParseException("Unexpected end-of-file while parsing tag name"));
104 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in tag name"));
107 Element n = makenode(doc, buf.toString());
108 buf = new StringBuilder();
109 stack.peek().appendChild(n);
113 } else if(st == "comment") {
117 } else if((c == '>') && (cdashcnt == 4)) {
118 stack.peek().appendChild(doc.createComment(buf.toString()));
119 buf = new StringBuilder();
122 } else if(cdashcnt >= 2) {
128 throw(new ParseException("Unexpected end-of-file while parsing comment"));
130 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in comment"));
132 } else if(st == "attr") {
133 if(namechar((char)c)) {
135 } else if(c == '>') {
138 } else if(c == '/') {
141 } else if(Character.isWhitespace((char)c)) {
144 throw(new ParseException("Unexpected end-of-file while parsing attributes"));
146 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered inside tag"));
148 } else if(st == "stagend") {
153 } else if(Character.isWhitespace((char)c)) {
156 throw(new ParseException("Unexpected end-of-file at end of empty tag"));
158 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered at and of empty tag"));
160 } else if(st == "aname") {
161 if(namechar((char)c)) {
164 } else if(Character.isWhitespace((char)c)) {
166 } else if(c == '=') {
167 Element el = (Element)stack.peek();
168 Attr attr = makeattr(doc, el, buf.toString());
169 el.setAttributeNodeNS(attr);
170 buf = new StringBuilder();
175 throw(new ParseException("Unexpected end-of-file while parsing attribute name"));
177 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in attribute name"));
179 } else if(st == "avalstart") {
180 if((c == '\'') || (c == '"')) {
184 } else if(Character.isWhitespace((char)c)) {
187 throw(new ParseException("Unexpected end-of-file while parsing attribute value"));
189 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in attribute value"));
191 } else if(st == "aval") {
194 Attr a = (Attr)stack.pop();
195 a.setValue(buf.toString());
196 buf = new StringBuilder();
198 } else if(c == '&') {
202 throw(new ParseException("Unexpected end-of-file while parsing attribute value"));
207 } else if(st == "etag") {
208 if(namechar((char)c)) {
211 } else if(c == '>') {
212 String nm = buf.toString();
213 buf = new StringBuilder();
214 Node n = stack.pop();
215 if(n instanceof DocumentFragment)
216 throw(new ParseException("Unexpected end tag for `" + nm + "' while parsing root content"));
217 Element el = (Element)n;
218 if(!nm.equals(el.getTagName()))
219 throw(new ParseException("Unexpected end tag for `" + nm + "' while parsing `" + el.getTagName() + "'"));
223 throw(new ParseException("Unexpected end-of-file while parsing end tag"));
225 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in end tag"));
227 } else if(st == "text") {
228 boolean flush = false;
232 } else if(c == '<') {
243 Text n = doc.createTextNode(buf.toString());
244 buf = new StringBuilder();
245 stack.peek().appendChild(n);
247 } else if(st == "ent") {
249 String ename = ebuf.toString();
250 ebuf = new StringBuilder();
251 String rep = entity(ename);
253 throw(new ParseException("Unknown entity `" + ename + "' encountered"));
258 throw(new ParseException("Unexpected end-of-file while parsing entity name"));
259 } else if(namechar((char)c)) {
260 ebuf.append((char)c);
263 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in entity name"));
265 } else if(st == "aent") {
267 String ename = ebuf.toString();
268 ebuf = new StringBuilder();
269 String rep = entity(ename);
271 throw(new ParseException("Unknown entity `" + ename + "' encountered"));
276 throw(new ParseException("Unexpected end-of-file while parsing entity name"));
277 } else if(namechar((char)c)) {
278 ebuf.append((char)c);
281 throw(new ParseException("Unexpected character `" + printable((char)c) + "' encountered in entity name"));
284 throw(new Error("BUG: Typoed state " + st));
289 private static String printable(char c) {
291 return(String.format("\\%03o", (int)c));
292 return(Character.toString(c));
295 public static void main(String[] args) throws Exception {
296 Parser p = new Parser();
297 DocumentFragment f = p.parse(new FileReader(args[0]));
298 javax.xml.transform.TransformerFactory fac = javax.xml.transform.TransformerFactory.newInstance();
299 fac.setAttribute("indent-number", 2);
300 javax.xml.transform.Transformer t = fac.newTransformer();
301 t.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes");
302 t.transform(new javax.xml.transform.dom.DOMSource(f), new javax.xml.transform.stream.StreamResult(System.out));
303 System.out.println(t.getClass());