1 package dolda.jsvc.next;
9 public final Document doc = DomUtil.document(null, "dummy");
10 public final PeekReader in;
12 private State(Reader in) {
13 this.in = new PeekReader(in);
17 private static boolean namechar(char c) {
18 return((c == ':') || (c == '_') || (c == '$') || (c == '.') || (c == '-') || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')));
21 protected String entity(String name) {
22 if(name.equals("amp"))
28 if(name.equals("apos"))
30 if(name.equals("quot"))
35 protected Element makenode(Document doc, String name) {
36 return(doc.createElementNS(null, name));
39 protected String name(State s) throws IOException {
40 StringBuilder buf = new StringBuilder();
45 } else if(namechar((char)c)) {
46 buf.append((char)s.in.read());
52 throw(new ParseException("Expected name, got `" + printable(s.in.peek()) + "'"));
53 return(buf.toString());
56 protected String entity(State s) throws IOException {
59 throw(new ParseException("Expected `&' while reading entity, got `" + printable(c) + "'"));
63 throw(new ParseException("Expected `;' while reading entity, got `" + printable(c) + "'"));
67 protected Attr attribute(State s, Element el) throws IOException {
68 Attr a = s.doc.createAttributeNS(null, name(s));
72 throw(new ParseException("Expected `=' while reading attribute, got `" + printable(c) + "'"));
75 if((qt != '"') && (qt != '\''))
76 throw(new ParseException("Expected double or single quote while reading attribute, got `" + printable(qt) + "'"));
77 StringBuilder buf = new StringBuilder();
81 throw(new ParseException("Unexpected end-of-file while reading attribute value"));
86 buf.append(entity(s));
88 buf.append((char)s.in.read());
91 a.setValue(buf.toString());
95 protected Element element(State s) throws IOException {
96 Element n = makenode(s.doc, name(s));
98 int c = s.in.peek(true);
100 throw(new ParseException("Unexpected end-of-file while parsing start tag"));
101 } else if(c == '>') {
104 } else if(c == '/') {
109 throw(new ParseException("Unexpected character `" + printable(c) + "' encountered in end of empty tag"));
111 } else if(namechar((char)c)) {
112 n.setAttributeNodeNS(attribute(s, n));
114 throw(new ParseException("Unexpected character `" + printable(c) + "' encountered in start tag"));
121 } else if(c == '<') {
128 if(!nm.equals(n.getTagName()))
129 throw(new ParseException("Unexpected end tag for `" + nm + "' while parsing `" + n.getTagName() + "'"));
130 if(s.in.peek(true) != '>')
131 throw(new ParseException("Expected `>' while reading end tag, got `" + printable(c) + "'"));
135 n.appendChild(stag(s));
138 n.appendChild(text(s));
144 protected Comment comment(State s) throws IOException {
145 if((s.in.read() != '!') ||
146 (s.in.read() != '-') ||
147 (s.in.read() != '-'))
148 throw(new ParseException("Illegal start of comment"));
149 StringBuilder buf = new StringBuilder();
153 throw(new ParseException("Unexpected end-of-file while parsing comment"));
154 } else if(c == '-') {
156 if(s.in.peek() == '-') {
158 if(s.in.peek() == '>') {
168 buf.append((char)s.in.read());
171 return(s.doc.createComment(buf.toString()));
174 protected Node stag(State s) throws IOException {
175 int c = s.in.peek(true);
177 throw(new ParseException("Unexpected end-of-file while parsing tag type"));
178 } else if(c == '!') {
185 protected Text text(State s) throws IOException {
186 StringBuilder buf = new StringBuilder();
191 } else if(c == '<') {
193 } else if(c == '&') {
194 buf.append(entity(s));
196 buf.append((char)s.in.read());
199 return(s.doc.createTextNode(buf.toString()));
202 public DocumentFragment parse(Reader in) throws IOException {
203 State s = new State(in);
204 DocumentFragment frag = s.doc.createDocumentFragment();
209 } else if(c == '<') {
211 frag.appendChild(stag(s));
213 frag.appendChild(text(s));
218 private static String printable(int c) {
222 return(String.format("\\%03o", (int)c));
223 return(Character.toString((char)c));