2003/04/24 14:33:28
authordavid <david@xwt.org>
Fri, 30 Jan 2004 06:59:15 +0000 (06:59 +0000)
committerdavid <david@xwt.org>
Fri, 30 Jan 2004 06:59:15 +0000 (06:59 +0000)
darcs-hash:20040130065915-0c9ea-184b936b44f827ad4844c5f288feb1ccd0d8d613.gz

src/org/xwt/Template.java
src/org/xwt/XML.java [deleted file]
src/org/xwt/XMLRPC.java

index 324fea1..ba542fd 100644 (file)
@@ -95,6 +95,9 @@ public class Template {
 
     // Static data/methods ///////////////////////////////////////////////////////////////////
 
+    /** maximum length of a line */
+    private static final int MAX_COLUMN = 150;
+
     /** a template cache so that only one Template object is created for each xwt */
     private static Hashtable cache = new Hashtable(1000);
 
@@ -115,19 +118,19 @@ public class Template {
     }
 
     public static Template buildTemplate(InputStream is, String nodeName) {
+        return buildTemplate(is, nodeName, new TemplateHelper());
+    }
+
+    public static Template buildTemplate(InputStream is, String nodeName, TemplateHelper t) {
         try {
-            return new Template(is, nodeName);
-        } catch (XML.SAXParseException e) {
-            if (Log.on) Log.log(Template.class, "error parsing template at " + nodeName + ":" + e.getLineNumber() + "," + e.getColumnNumber());
-            if (Log.on) Log.log(Template.class, e);
-            return null;
-        } catch (XML.SAXException e) {
+            return new Template(is, nodeName, t);
+        } catch (XML.SchemaException e) {
             if (Log.on) Log.log(Template.class, "error parsing template " + nodeName);
-            if (Log.on) Log.log(Template.class, e);
+            if (Log.on) Log.log(Template.class, e.getMessage());
             return null;
-        } catch (TemplateException te) {
-            if (Log.on) Log.log(Template.class, "error parsing template " + nodeName);
-            if (Log.on) Log.log(Template.class, te);
+        } catch (XML.XMLException e) {
+            if (Log.on) Log.log(Template.class, "error parsing template at " + nodeName + ":" + e.getLine() + "," + e.getCol());
+            if (Log.on) Log.log(Template.class, e.getMessage());
             return null;
         } catch (IOException e) {
             if (Log.on) Log.log(Template.class, "IOException while parsing template " + nodeName + " -- this should never happen");
@@ -143,9 +146,9 @@ public class Template {
         this.nodeName = nodeName;
         cache.put(nodeName, this);
     }
-    private Template(InputStream is, String nodeName) throws XML.SAXException, IOException {
+    private Template(InputStream is, String nodeName, TemplateHelper th) throws XML.XMLException, IOException {
         this(nodeName);
-        new TemplateHelper().parseit(is, this);
+        th.parseit(is, this);
     }
 
     /** calculates, caches, and returns an integer approximation of how long it will take to apply this template, including pre/post and children */
@@ -410,16 +413,27 @@ public class Template {
     // XML Parsing /////////////////////////////////////////////////////////////////
 
     /** handles XML parsing; builds a Template tree as it goes */
-    private static class TemplateHelper extends XML {
+    static final class TemplateHelper extends XML {
 
-        TemplateHelper() {
-            for(int i=0; i<defaultImportList.length; i++) importlist.addElement(defaultImportList[i]);
-        }
+        TemplateHelper() { }
 
         /** parse an XML input stream, building a Template tree off of <tt>root</tt> */
-        void parseit(InputStream is, Template root) throws XML.SAXException, IOException {
+        void parseit(InputStream is, Template root) throws XML.XMLException, IOException {
+            rootNodeHasBeenEncountered = false;
+            templateNodeHasBeenEncountered = false;
+            staticNodeHasBeenEncountered = false;
+            templateNodeHasBeenFinished = false;
+            nameOfHeaderNodeBeingProcessed = null;
+
+            nodeStack.setSize(0);
+            importlist.setSize(0);
+            preapply.setSize(0);
+            postapply.setSize(0);
+
+            importlist.fromArray(defaultImportList);
+
             t = root;
-            parse(new TabAndMaxColumnEnforcingReader(new InputStreamReader(is), root.nodeName)); 
+            parse(new InputStreamReader(is)); 
         }
 
         /** parsing state: true iff we have already encountered the <xwt> open-tag */
@@ -453,79 +467,78 @@ public class Template {
         /** the template we're currently working on */
         Template t = null;
 
-        public void startElement(String name, String[] keys, Object[] vals, int line, int col) throws XML.SAXException {
-
+        public void startElement(XML.Element c) throws XML.SchemaException {
             if (templateNodeHasBeenFinished) {
-                throw new XML.SAXException("no elements may appear after the <template> node");
+                throw new XML.SchemaException("no elements may appear after the <template> node");
 
             } else if (!rootNodeHasBeenEncountered) {
-                if (!"xwt".equals(name)) throw new XML.SAXException("root element was not <xwt>");
-                if (keys.length != 0) throw new XML.SAXException("root element must not have attributes");
+                if (!"xwt".equals(c.localName)) throw new XML.SchemaException("root element was not <xwt>");
+                if (c.len != 0) throw new XML.SchemaException("root element must not have attributes");
                 rootNodeHasBeenEncountered = true;
                 return;
         
             } else if (!templateNodeHasBeenEncountered) {
-                if (nameOfHeaderNodeBeingProcessed != null) throw new XML.SAXException("can't nest header nodes");
-                nameOfHeaderNodeBeingProcessed = name;
+                if (nameOfHeaderNodeBeingProcessed != null) throw new XML.SchemaException("can't nest header nodes");
+                nameOfHeaderNodeBeingProcessed = c.localName;
 
-                if (name.equals("import")) {
-                    if (keys.length != 1 || !keys[0].equals("name"))
-                        throw new XML.SAXException("<import> node must have exactly one attribute, which must be called 'name'");
-                    String importpackage = vals[0].toString();
+                if (c.localName.equals("import")) {
+                    if (c.len != 1 || !c.keys[0].equals("name"))
+                        throw new XML.SchemaException("<import> node must have exactly one attribute, which must be called 'name'");
+                    String importpackage = c.vals[0].toString();
                     if (importpackage.endsWith(".*")) importpackage = importpackage.substring(0, importpackage.length() - 2);
                     importlist.addElement(importpackage);
                     return;
 
-                } else if (name.equals("redirect")) {
-                    if (keys.length != 1 || !keys[0].equals("target"))
-                        throw new XML.SAXException("<redirect> node must have exactly one attribute, which must be called 'target'");
+                } else if (c.localName.equals("redirect")) {
+                    if (c.len != 1 || !c.keys[0].equals("target"))
+                        throw new XML.SchemaException("<redirect> node must have exactly one attribute, which must be called 'target'");
                     if (t.redirect != null)
-                        throw new XML.SAXException("the <redirect> header element may not appear more than once");
-                    t.redirect = vals[0].toString();
+                        throw new XML.SchemaException("the <redirect> header element may not appear more than once");
+                    t.redirect = c.vals[0].toString();
                     return;
 
-                } else if (name.equals("preapply")) {
-                    if (keys.length != 1 || !keys[0].equals("name"))
-                        throw new XML.SAXException("<preapply> node must have exactly one attribute, which must be called 'name'");
-                    preapply.addElement(vals[0]);
+                } else if (c.localName.equals("preapply")) {
+                    if (c.len != 1 || !c.keys[0].equals("name"))
+                        throw new XML.SchemaException("<preapply> node must have exactly one attribute, which must be called 'name'");
+                    preapply.addElement(c.vals[0]);
                     return;
 
-                } else if (name.equals("postapply")) {
-                    if (keys.length != 1 || !keys[0].equals("name"))
-                        throw new XML.SAXException("<postapply> node must have exactly one attribute, which must be called 'name'");
-                    postapply.addElement(vals[0]);
+                } else if (c.localName.equals("postapply")) {
+                    if (c.len != 1 || !c.keys[0].equals("name"))
+                        throw new XML.SchemaException("<postapply> node must have exactly one attribute, which must be called 'name'");
+                    postapply.addElement(c.vals[0]);
                     return;
 
-                } else if (name.equals("static")) {
+                } else if (c.localName.equals("static")) {
                     if (staticNodeHasBeenEncountered)
-                        throw new XML.SAXException("the <static> header node may not appear more than once");
-                    if (keys.length > 0)
-                        throw new XML.SAXException("the <static> node may not have attributes");
+                        throw new XML.SchemaException("the <static> header node may not appear more than once");
+                    if (c.len > 0)
+                        throw new XML.SchemaException("the <static> node may not have attributes");
                     staticNodeHasBeenEncountered = true;
                     return;
 
-                } else if (name.equals("preserve")) {
-                    if (keys.length != 1 || !keys[0].equals("attributes"))
-                        throw new XML.SAXException("<preserve> node must have exactly one attribute, which must be called 'attributes'");
+                } else if (c.localName.equals("preserve")) {
+                    if (c.len != 1 || !c.keys[0].equals("attributes"))
+                        throw new XML.SchemaException("<preserve> node must have exactly one attribute, which must be called 'attributes'");
                     if (t.preserve != null)
-                        throw new XML.SAXException("<preserve> header element may not appear more than once");
+                        throw new XML.SchemaException("<preserve> header element may not appear more than once");
 
-                    StringTokenizer tok = new StringTokenizer(vals[0].toString(), ",", false);
+                    StringTokenizer tok = new StringTokenizer(c.vals[0].toString(), ",", false);
                     t.preserve = new String[tok.countTokens()];
                     for(int i=0; i<t.preserve.length; i++) t.preserve[i] = tok.nextToken();
                     return;
 
-                } else if (name.equals("template")) {
+                } else if (c.localName.equals("template")) {
                     // finalize importlist/preapply/postapply, since they can't change from here on
-                    t.startLine = line;
+                    t.startLine = getLine();
                     importlist.toArray(t.importlist = new String[importlist.size()]);
                     if (preapply.size() > 0) preapply.copyInto(t.preapply = new String[preapply.size()]);
                     if (postapply.size() > 0) postapply.copyInto(t.postapply = new String[postapply.size()]);
-                    importlist = preapply = postapply = null;
+                    importlist.setSize(0); preapply.setSize(0); postapply.setSize(0);
                     templateNodeHasBeenEncountered = true;
 
                 } else {
-                    throw new XML.SAXException("unrecognized header node \"" + name + "\"");
+                    throw new XML.SchemaException("unrecognized header node \"" + c.localName + "\"");
 
                 }
 
@@ -537,29 +550,31 @@ public class Template {
                 // instantiate a new node, and set its nodeName/importlist/preapply
                 Template t2 = new Template(t.nodeName + "." + t.childvect.size());
                 t2.importlist = t.importlist;
-                t2.startLine = line;
-                if (!name.equals("box")) t2.preapply = new String[] { name };
+                t2.startLine = getLine();
+                if (!c.localName.equals("box")) t2.preapply = new String[] { c.localName };
 
                 // make the new node the current node
                 t = t2;
 
             }
 
-            t.keys = keys;
-            t.vals = vals;
-
+            // TODO: Sort contents straight from one array to another
+            t.keys = new String[c.len];
+            t.vals = new Object[c.len];
+            System.arraycopy(c.keys, 0, t.keys, 0, c.len);
+            System.arraycopy(c.vals, 0, t.vals, 0, c.len);
             quickSortAttributes(0, t.keys.length - 1);
 
             for(int i=0; i<t.keys.length; i++) {
                 if (t.keys[i].equals("id")) {
-                    t.id = vals[i].toString().intern();
+                    t.id = t.vals[i].toString().intern();
                     t.keys[i] = null;
                     continue;
                 }
 
                 t.keys[i] = t.keys[i].intern();
 
-                String valString = vals[i].toString();
+                String valString = t.vals[i].toString();
                 
                 if (valString.equals("true")) t.vals[i] = Boolean.TRUE;
                 else if (valString.equals("false")) t.vals[i] = Boolean.FALSE;
@@ -575,8 +590,8 @@ public class Template {
                             hasNonNumeral = true;
                             break;
                         }
-                    if (valString.length() > 0 && !hasNonNumeral) vals[i] = new Double(valString);
-                    else vals[i] = valString.intern();
+                    if (valString.length() > 0 && !hasNonNumeral) t.vals[i] = new Double(valString);
+                    else t.vals[i] = valString.intern();
                 }
 
                 // bump thisbox to the front of the pack
@@ -607,7 +622,7 @@ public class Template {
             o = t.vals[right]; t.vals[right] = t.vals[i]; t.vals[i] = o;
             return i;
         }
-        
+
         /** simple quicksort, from http://sourceforge.net/snippet/detail.php?type=snippet&id=100240 */
         private void quickSortAttributes(int left, int right) {
             if (left >= right) return;
@@ -615,61 +630,17 @@ public class Template {
             quickSortAttributes(left, p - 1);
             quickSortAttributes(p + 1, right);
         }
-        
-        public void endElement(String name, int line, int col) throws XML.SAXException {
-
-            boolean hasNonWhitespace = false;
-
-            int len = t == null || t.content == null ? 0 : t.content.length();
-            for(int i=0; t.content != null && i<len; i++)
-                
-                // ignore double-slash comment blocks
-                if (t.content.charAt(i) == '/' && t.content.charAt(i + 1) == '/') {
-                    while(t.content.charAt(i) != '\n' && i<len) i++;
-                    i--;
-
-                // ignore /* .. */ comment blocks
-                } else if (i<len - 1 && t.content.charAt(i) == '/' && t.content.charAt(i + 1) == '*') {
-                    i += 2;
-                    while(i<len - 1 && !(t.content.charAt(i) == '*' && t.content.charAt(i + 1) == '/')) i++;
-                    if (i<len - 1 && t.content.charAt(i) == '*' && t.content.charAt(i + 1) == '/') i += 2;
-                    i--;
-
-                // check for named functions
-                } else if (i + 8 <= len && t.content.charAt(i) == 'f' && t.content.charAt(i+1) == 'u' &&
-                           t.content.charAt(i+2) == 'n' && t.content.charAt(i+3) == 'c' && t.content.charAt(i+4) == 't' &&
-                           t.content.charAt(i+5) == 'i' && t.content.charAt(i+6) == 'o' && t.content.charAt(i+7) == 'n') {
-                    int j = i + 8;
-                    while(j<len && Character.isWhitespace(t.content.charAt(j))) j++;
-                    if (j<len && t.content.charAt(j) != '(')
-                        throw new XML.SAXException("named functions are not permitted in XWT -- instead of \"function foo() { ... }\"," +
-                                        " use \"foo = function() { ... }\"");
-
-                // replace " and " with " && "
-                } else if (i + 5 < len && Character.isWhitespace(t.content.charAt(i)) &&
-                           t.content.charAt(i+1) == 'a' && t.content.charAt(i+2) == 'n' && t.content.charAt(i+3) == 'd' &&
-                           Character.isWhitespace(t.content.charAt(i + 4))) {
-                    t.content.setCharAt(i+1, '&');
-                    t.content.setCharAt(i+2, '&');
-                    t.content.setCharAt(i+3, ' ');
-                    hasNonWhitespace = true;
-
-                // generic check for nonwhitespace
-                } else if (!Character.isWhitespace(t.content.charAt(i))) {
-                    hasNonWhitespace = true;
 
-                }
-            
+        public void endElement(XML.Element c) throws XML.SchemaException {
             if (rootNodeHasBeenEncountered && !templateNodeHasBeenEncountered) {
-                if ("static".equals(nameOfHeaderNodeBeingProcessed) && hasNonWhitespace) t.staticscript = genscript(true);
+                if ("static".equals(nameOfHeaderNodeBeingProcessed) && t.content != null) t.staticscript = genscript(true);
                 nameOfHeaderNodeBeingProcessed = null;
 
             } else if (templateNodeHasBeenEncountered && !templateNodeHasBeenFinished) {
-
                 // turn our childvect into a Template[]
                 t.childvect.copyInto(t.children = new Template[t.childvect.size()]);
                 t.childvect = null;
-                if (hasNonWhitespace) t.script = genscript(false);
+                if (t.content != null) t.script = genscript(false);
                 
                 if (nodeStack.size() == 0) {
                     // </template>
@@ -700,8 +671,7 @@ public class Template {
                 if (Log.on) Log.log(this, "  ERROR: " + ee.getMessage());
                 thisscript = null;
             } catch (IOException ioe) {
-                if (Log.on) Log.log(this, "IOException while compiling script; this should never happen");
-                if (Log.on) Log.log(this, ioe);
+                if (Log.on) Log.log(this, "  ERROR: " + ioe.getMessage());
                 thisscript = null;
             }
 
@@ -711,74 +681,31 @@ public class Template {
             return thisscript;
         }
 
-        public void content(char[] ch, int start, int length, int line, int col) throws XML.SAXException {
-            if ("static".equals(nameOfHeaderNodeBeingProcessed) || templateNodeHasBeenEncountered) {
-                int contentlines = 0;
-                for(int i=start; i<start + length; i++) if (ch[i] == '\n') contentlines++;
-                line -= contentlines;
+        public void characters(char[] ch, int start, int length) throws XML.SchemaException {
+            // invoke the max-column-length and no-tab crusade
+            if (getCol() + length > MAX_COLUMN) throw new XML.SchemaException(
+                t.nodeName+ ":" + getLine() + ": lines longer than " + MAX_COLUMN + " characters not allowed");
+
+            for (int i=0; length >i; i++) if (ch[start+i] == '\t') throw new XML.SchemaException(
+                t.nodeName+ ":" + getLine() + "," + getCol() + ": tabs are not allowed in XWT files");
 
+            if ("static".equals(nameOfHeaderNodeBeingProcessed) || templateNodeHasBeenEncountered) {
                 if (t.content == null) {
-                    t.content_start = line;
+                    t.content_start = getLine();
                     t.content_lines = 0;
                     t.content = new StringBuffer();
                 }
 
-                for(int i=t.content_start + t.content_lines; i<line; i++) {
-                    t.content.append('\n');
-                    t.content_lines++;
-                }
-
                 t.content.append(ch, start, length);
-                t.content_lines += contentlines;
+                t.content_lines++;
 
             } else if (nameOfHeaderNodeBeingProcessed != null) {
-                throw new XML.SAXException("header node <" + nameOfHeaderNodeBeingProcessed + "> cannot have text content");
-
+                throw new XML.SchemaException("header node <" + nameOfHeaderNodeBeingProcessed + "> cannot have text content");
             }
-
         }
 
-    }
-
-    /** a filtering reader that watches for tabs and long lines */
-    private static class TabAndMaxColumnEnforcingReader extends FilterReader {
-        private int MAX_COLUMN = 150;
-        private int column = 0;
-        private int line = 1;
-        private boolean lastCharWasCR = false;
-        private String filename;
-        public TabAndMaxColumnEnforcingReader(Reader r, String filename) { super(r); this.filename = filename; }
-        public int read() {
-            if (Log.on) Log.log(this, this.getClass().getName() + ".read() not supported, this should never happen");
-            return -1;
+        public void whitespace(char[] ch, int start, int length) throws XML.SchemaException {
         }
-        public long skip(long numskip) {
-            if (Log.on) Log.log(this, this.getClass().getName() + ".skip() not supported; this should never happen");
-            return numskip;
-        }
-        public int read(char[] buf, int off, int len) throws IOException {
-            int ret = super.read(buf, off, len);
-            for(int i=off; i<off + ret; i++)
-                if (buf[i] == '\t') {
-                    throw new TemplateException(filename + ":" + line + "," + column + ": tabs are not allowed in XWT files");
-                } else if (buf[i] == '\r') {
-                    column = 0;
-                    line++;
-                    lastCharWasCR = true;
-                } else if (buf[i] == '\n') {
-                    column = 0;
-                    if (!lastCharWasCR) line++;
-                } else if (++column > MAX_COLUMN) {
-                    throw new TemplateException(filename + ":" + line + ": lines longer than " + MAX_COLUMN + " characters not allowed");
-                } else {
-                    lastCharWasCR = false;
-                }
-            return ret;
-        }
-    }
-
-    private static class TemplateException extends IOException {
-        TemplateException(String s) { super(s); }
     }
 
 }
diff --git a/src/org/xwt/XML.java b/src/org/xwt/XML.java
deleted file mode 100644 (file)
index afd2c3a..0000000
+++ /dev/null
@@ -1,971 +0,0 @@
-package org.xwt;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-/** an event-driven XML parser, derived from MinML (http://www.wilson.co.uk/xml/minml.htm) */
-public abstract class XML {
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////
-    // The following code was copied from the w3c's org.xml.sax.* classes
-    /////////////////////////////////////////////////////////////////////////////////////////////
-    
-    protected static interface AttributeList {
-        public abstract int getLength ();
-        public abstract String getName (int i);
-        public abstract String getType (int i);
-        public abstract String getValue (int i);
-        public abstract String getType (String name);
-        public abstract String getValue (String name);
-    }
-    
-    protected static interface DTDHandler {
-        public abstract void notationDecl (String name, String publicId, String systemId) throws SAXException;
-        public abstract void unparsedEntityDecl (String name, String publicId, String systemId, String notationName) throws SAXException;
-    }
-    
-    protected static interface EntityResolver {
-        public abstract InputSource resolveEntity (String publicId, String systemId) throws SAXException, IOException;
-    }
-    
-    protected static interface ErrorHandler {
-        public abstract void warning (SAXParseException exception) throws SAXException;
-        public abstract void error (SAXParseException exception) throws SAXException;
-        public abstract void fatalError (SAXParseException exception) throws SAXException;
-    }
-    
-    private static class InputSource {
-        public InputSource () { }
-        public InputSource (String systemId) { setSystemId(systemId); }
-        public InputSource (InputStream byteStream) { setByteStream(byteStream); }
-        public InputSource (Reader characterStream) { setCharacterStream(characterStream); }
-        public void setPublicId (String publicId) { this.publicId = publicId; }
-        public String getPublicId () { return publicId; }
-        public void setSystemId (String systemId) { this.systemId = systemId; }
-        public String getSystemId() { return systemId; }
-        public void setByteStream (InputStream byteStream) { this.byteStream = byteStream; }
-        public InputStream getByteStream() { return byteStream; }
-        public void setEncoding (String encoding) { this.encoding = encoding; }
-        public String getEncoding() { return encoding; }
-        public void setCharacterStream (Reader characterStream) { this.characterStream = characterStream; }
-        public Reader getCharacterStream () { return characterStream; }
-        private String publicId;
-        private String systemId;
-        private InputStream byteStream;
-        private String encoding;
-        private Reader characterStream;
-    }
-    
-    protected static interface Locator {
-        public abstract String getPublicId ();
-        public abstract String getSystemId ();
-        public abstract int getLineNumber ();
-        public abstract int getColumnNumber ();
-    }
-    
-    protected static interface Parser {
-        public abstract void setLocale (Locale locale) throws SAXException;
-        public abstract void setEntityResolver (EntityResolver resolver);
-        public abstract void setDTDHandler (DTDHandler handler);
-        public abstract void setDocumentHandler (DocumentHandler handler);
-        public abstract void setErrorHandler (ErrorHandler handler);
-        public abstract void parse (InputSource source) throws SAXException, IOException;
-        public abstract void parse (String systemId) throws SAXException, IOException;
-    }
-    
-    public static class SAXException extends Exception {
-        public SAXException (String message) {
-            super();
-            this.message = message;
-            this.exception = null;
-        }
-        
-        public SAXException (Exception e) {
-            super();
-            this.message = null;
-            this.exception = e;
-        }
-        
-        public SAXException (String message, Exception e) {
-            super();
-            this.message = message;
-            this.exception = e;
-        }
-        
-        public String getMessage () {
-            if (message == null && exception != null) {
-                return exception.getMessage();
-            } else {
-                return this.message;
-            }
-        }
-        
-        public Exception getException () { return exception; }
-        public String toString () { return getMessage(); }
-        private String message;
-        private Exception exception;
-    }
-    
-    static class SAXParseException extends SAXException {
-        public SAXParseException (String message, Locator locator) {
-            super(message);
-            this.publicId = locator.getPublicId();
-            this.systemId = locator.getSystemId();
-            this.lineNumber = locator.getLineNumber();
-            this.columnNumber = locator.getColumnNumber();
-        }
-        public SAXParseException (String message, Locator locator, Exception e) {
-            super(message, e);
-            this.publicId = locator.getPublicId();
-            this.systemId = locator.getSystemId();
-            this.lineNumber = locator.getLineNumber();
-            this.columnNumber = locator.getColumnNumber();
-        }
-        public SAXParseException (String message, String publicId, String systemId, int lineNumber, int columnNumber) {
-            super(message);
-            this.publicId = publicId;
-            this.systemId = systemId;
-            this.lineNumber = lineNumber;
-            this.columnNumber = columnNumber;
-        }
-        public SAXParseException (String message, String publicId, String systemId, int lineNumber, int columnNumber, Exception e) {
-            super(message, e);
-            this.publicId = publicId;
-            this.systemId = systemId;
-            this.lineNumber = lineNumber;
-            this.columnNumber = columnNumber;
-        }
-        public String getPublicId() { return this.publicId; }
-        public String getSystemId() { return this.systemId; }
-        public int getLineNumber () { return this.lineNumber; }
-        public int getColumnNumber () { return this.columnNumber; }
-        private String publicId;
-        private String systemId;
-        private int lineNumber;
-        private int columnNumber;
-    }
-    
-    protected static interface DocumentHandler {
-        public abstract void setDocumentLocator (Locator locator);
-        public abstract void startDocument() throws SAXException;
-        public abstract void endDocument() throws SAXException;
-        public abstract void startElement(String name, AttributeList atts) throws SAXException;
-        public abstract void endElement(String name) throws SAXException;
-        public abstract void characters(char ch[], int start, int length) throws SAXException;
-        public abstract void ignorableWhitespace(char ch[], int start, int length) throws SAXException;
-        public abstract void processingInstruction (String target, String data) throws SAXException;
-        Writer startDocument(final Writer writer) throws SAXException;
-        Writer startElement(final String name, final AttributeList attributes, final Writer writer) throws SAXException;
-    }
-    
-    
-    
-    /////////////////////////////////////////////////////////////////////////////////////////////
-    // Everything from here down is copied verbatim from the MinML 1.7
-    // distribution, except for these modifications:
-    //   - some classes have been changed from 'public' to 'private static'
-    //   - extraneous import and package declarations have been removed
-    //   - the advertising clause of the copyright notice has been removed
-    //     as approved by John Wilson in an email to Adam Megacz.
-    /////////////////////////////////////////////////////////////////////////////////////////////
-    
-    // Copyright (c) 2000, 2001, 2002 The Wilson Partnership.
-    // All Rights Reserved.
-    // @(#)MinML.java, 1.8(provisional), 2nd March 2002
-    // Author: John Wilson - tug@wilson.co.uk
-    
-    /*
-      Copyright (c) 2000, 2001 John Wilson (tug@wilson.co.uk).
-      All rights reserved.
-      Redistribution and use in source and binary forms,
-      with or without modification, are permitted provided
-      that the following conditions are met:
-      
-      Redistributions of source code must retain the above
-      copyright notice, this list of conditions and the
-      following disclaimer.
-      
-      Redistributions in binary form must reproduce the
-      above copyright notice, this list of conditions and
-      the following disclaimer in the documentation and/or
-      other materials provided with the distribution.
-      
-      THIS SOFTWARE IS PROVIDED BY JOHN WILSON ``AS IS'' AND ANY
-      EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-      PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JOHN WILSON
-      BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-      EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-      TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-      ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-      LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-      IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-      OF THE POSSIBILITY OF SUCH DAMAGE
-    */
-    
-    private static class MinML implements Parser, Locator, DocumentHandler, ErrorHandler {
-        public static final int endStartName = 0;
-        public static final int emitStartElement = 1;
-        public static final int emitEndElement = 2;
-        public static final int possiblyEmitCharacters = 3;
-        public static final int emitCharacters = 4;
-        public static final int emitCharactersSave = 5;
-        public static final int saveAttributeName = 6;
-        public static final int saveAttributeValue = 7;
-        public static final int startComment = 8;
-        public static final int endComment = 9;
-        public static final int incLevel = 10;
-        public static final int decLevel = 11;
-        public static final int startCDATA = 12;
-        public static final int endCDATA = 13;
-        public static final int processCharRef = 14;
-        public static final int writeCdata = 15;
-        public static final int exitParser = 16;
-        public static final int parseError = 17;
-        public static final int discardAndChange = 18;
-        public static final int discardSaveAndChange = 19;
-        public static final int saveAndChange = 20;
-        public static final int change = 21;
-        public static final int writeAsWS = 22;
-        
-        public static final int inSkipping = 0;
-        public static final int inSTag = 1;
-        public static final int inPossiblyAttribute = 2;
-        public static final int inNextAttribute = 3;
-        public static final int inAttribute = 4;
-        public static final int inAttribute1 = 5;
-        public static final int inAttributeValue = 6;
-        public static final int inAttributeQuoteValue = 7;
-        public static final int inAttributeQuotesValue = 8;
-        public static final int inETag = 9;
-        public static final int inETag1 = 10;
-        public static final int inMTTag = 11;
-        public static final int inTag = 12;
-        public static final int inTag1 = 13;
-        public static final int inPI = 14;
-        public static final int inPI1 = 15;
-        public static final int inPossiblySkipping = 16;
-        public static final int inCharData = 17;
-        public static final int inCDATA = 18;
-        public static final int inCDATA1 = 19;
-        public static final int inComment =20;
-        public static final int inDTD = 21;
-        
-        public MinML(final int initialBufferSize, final int bufferIncrement) {
-            this.initialBufferSize = initialBufferSize;
-            this.bufferIncrement = bufferIncrement;
-        }
-        
-        public MinML() {
-            this(256, 128);
-        }
-        
-        public void parse(final Reader in) throws SAXException, IOException {
-            final Vector attributeNames = new Vector();
-            final Vector attributeValues = new Vector();
-            
-            final AttributeList attrs = new AttributeList() {
-                    public int getLength() {
-                        return attributeNames.size();
-                    }
-                    
-                    public String getName(final int i) {
-                        return (String)attributeNames.elementAt(i);
-                    }
-                    
-                    public String getType(final int i) {
-                        return "CDATA";
-                    }
-                    
-                    public String getValue(final int i) {
-                        return (String)attributeValues.elementAt(i);
-                    }
-                    
-                    public String getType(final String name) {
-                        return "CDATA";
-                    }
-                    
-                    public String getValue(final String name) {
-                        final int index = attributeNames.indexOf(name);
-                        
-                        return (index == -1) ? null : (String)attributeValues.elementAt(index);
-                    }
-                };
-            
-            final MinMLBuffer buffer = new MinMLBuffer(in);
-            int currentChar = 0, charCount = 0;
-            int level = 0;
-            int mixedContentLevel = -1;
-            String elementName = null;
-            String state = operands[inSkipping];
-            
-            this.lineNumber = 1;
-            this.columnNumber = 0;
-            
-            try {
-                while(true) {
-                    charCount++;
-                    
-                    //
-                    // this is to try and make the loop a bit faster
-                    // currentChar = buffer.read(); is simpler but is a bit slower.
-                    //
-                    currentChar = (buffer.nextIn == buffer.lastIn) ? buffer.read() : buffer.chars[buffer.nextIn++];
-                    
-                    final int transition;
-                    
-                    if (currentChar > ']') {
-                        transition = state.charAt(14);
-                    } else {
-                        final int charClass = charClasses[currentChar + 1];
-                        
-                        if (charClass == -1) fatalError("Document contains illegal control character with value " + currentChar, this.lineNumber, this.columnNumber);
-                        
-                        if (charClass == 12) {
-                            if (currentChar == '\r') {
-                                currentChar = '\n';
-                                charCount = -1;
-                            }
-                            
-                            if (currentChar == '\n') {
-                                if (charCount == 0) continue;  // preceeded by '\r' so ignore
-                                
-                                if (charCount != -1) charCount = 0;
-                                
-                                this.lineNumber++;
-                                this.columnNumber = 0;
-                            }
-                        }
-                        
-                        transition = state.charAt(charClass);
-                    }
-                    
-                    this.columnNumber++;
-                    
-                    final String operand = operands[transition >>> 8];
-                    
-                    switch (transition & 0XFF) {
-                    case endStartName:
-                        // end of start element name
-                        elementName = buffer.getString();
-                        if (currentChar != '>' && currentChar != '/') break;  // change state to operand
-                        // drop through to emit start element (we have no attributes)
-                        
-                    case emitStartElement:
-                        // emit start element
-                        
-                        final Writer newWriter = this.extDocumentHandler.startElement(elementName, attrs,
-                                                                                      (this.tags.empty()) ?
-                                                                                      this.extDocumentHandler.startDocument(buffer)
-                                                                                      :
-                                                                                      buffer.getWriter());
-                        
-                        buffer.pushWriter(newWriter);
-                        this.tags.push(elementName);
-                        
-                        attributeValues.removeAllElements();
-                        attributeNames.removeAllElements();
-                        
-                        if (mixedContentLevel != -1) mixedContentLevel++;
-                        
-                        if (currentChar != '/') break;  // change state to operand
-                        
-                        // <element/> drop through
-                        
-                    case emitEndElement:
-                        // emit end element
-                        
-                        try {
-                            final String begin = (String)this.tags.pop();
-                            
-                            buffer.popWriter();
-                            elementName = buffer.getString();
-                            
-                            if (currentChar != '/' && !elementName.equals(begin)) {
-                                fatalError("end tag </" + elementName + "> does not match begin tag <" + begin + ">",
-                                           this.lineNumber, this.columnNumber);
-                            } else {
-                                this.documentHandler.endElement(begin);
-                                
-                                if (this.tags.empty()) {
-                                    this.documentHandler.endDocument();
-                                    return;
-                                }
-                            }
-                        }
-                        catch (final EmptyStackException e) {
-                            fatalError("end tag at begining of document", this.lineNumber, this.columnNumber);
-                        }
-                        
-                        if (mixedContentLevel != -1) --mixedContentLevel;
-                        
-                        break;  // change state to operand
-                        
-                    case emitCharacters:
-                        // emit characters
-                        
-                        buffer.flush();
-                        break;  // change state to operand
-                        
-                    case emitCharactersSave:
-                        // emit characters and save current character
-                        
-                        if (mixedContentLevel == -1) mixedContentLevel = 0;
-                        
-                        buffer.flush();
-                        
-                        buffer.saveChar((char)currentChar);
-                        
-                        break;  // change state to operand
-                        
-                    case possiblyEmitCharacters:
-                        // write any skipped whitespace if in mixed content
-                        
-                        if (mixedContentLevel != -1) buffer.flush();
-                        break;  // change state to operand
-                        
-                    case saveAttributeName:
-                        // save attribute name
-                        
-                        attributeNames.addElement(buffer.getString());
-                        break;  // change state to operand
-                        
-                    case saveAttributeValue:
-                        // save attribute value
-                        
-                        attributeValues.addElement(buffer.getString());
-                        break;  // change state to operand
-                        
-                    case startComment:
-                        // change state if we have found "<!--"
-                        
-                        if (buffer.read() != '-') continue; // not "<!--"
-
-                        state = operands[inComment];
-                        continue;  // change state to operand
-
-                    case endComment:
-                        // change state if we find "-->"
-                        
-                        if ((currentChar = buffer.read()) == '-') {
-                            // deal with the case where we might have "------->"
-                            while ((currentChar = buffer.read()) == '-');
-                            
-                            if (currentChar == '>') {
-                                state = operands[inCharData];
-                            }
-                        }
-                        
-                        continue;   // not end of comment, don't change state
-                        
-                    case incLevel:
-                        
-                        level++;
-                        
-                        break;
-                        
-                    case decLevel:
-                        
-                        if (level == 0) break; // outer level <> change state
-                        
-                        level--;
-                        
-                        continue; // in nested <>, don't change state
-                        
-                    case startCDATA:
-                        // change state if we have found "<![CDATA["
-                        
-                        if (buffer.read() != 'C') continue;   // don't change state
-                        if (buffer.read() != 'D') continue;   // don't change state
-                        if (buffer.read() != 'A') continue;   // don't change state
-                        if (buffer.read() != 'T') continue;   // don't change state
-                        if (buffer.read() != 'A') continue;   // don't change state
-                        if (buffer.read() != '[') continue;   // don't change state
-                        break;  // change state to operand
-                        
-                    case endCDATA:
-                        // change state if we find "]]>"
-                        
-                        if ((currentChar = buffer.read()) == ']') {
-                            // deal with the case where we might have "]]]]]]]>"
-                            while ((currentChar = buffer.read()) == ']') buffer.write(']');
-                            
-                            if (currentChar == '>') break;  // end of CDATA section, change state to operand
-                            
-                            buffer.write(']');
-                        }
-                        
-                        buffer.write(']');
-                        buffer.write(currentChar);
-                        continue;   // not end of CDATA section, don't change state
-                        
-                    case processCharRef:
-                        // process character entity
-                        
-                        int crefState = 0;
-                        
-                        currentChar = buffer.read();
-                        
-                        while (true) {
-                            if ("#amp;&pos;'quot;\"gt;>lt;<".charAt(crefState) == currentChar) {
-                                crefState++;
-                                
-                                if (currentChar == ';') {
-                                    buffer.write("#amp;&pos;'quot;\"gt;>lt;<".charAt(crefState));
-                                    break;
-                                    
-                                } else if (currentChar == '#') {
-                                    final int radix;
-                                    
-                                    currentChar = buffer.read();
-                                    
-                                    if (currentChar == 'x') {
-                                        radix = 16;
-                                        currentChar = buffer.read();
-                                    } else {
-                                        radix = 10;
-                                    }
-                                    
-                                    int charRef = Character.digit((char)currentChar, radix);
-                                    
-                                    while (true) {
-                                        currentChar = buffer.read();
-                                        
-                                        final int digit = Character.digit((char)currentChar, radix);
-                                        
-                                        if (digit == -1) break;
-                                        
-                                        charRef = (char)((charRef * radix) + digit);
-                                    }
-                                    
-                                    if (currentChar == ';' && charRef != -1) {
-                                        buffer.write(charRef);
-                                        break;
-                                    }
-                                    
-                                    fatalError("invalid Character Entitiy", this.lineNumber, this.columnNumber);
-                                } else {
-                                    currentChar = buffer.read();
-                                }
-                            } else {
-                                crefState = ("\u0001\u000b\u0006\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff\u00ff" +
-                                             //                               #     a     m     p     ;     &     p     o     s     ;     '
-                                             //                               0     1     2     3     4     5     6     7     8     9     a
-                                             "\u0011\u00ff\u00ff\u00ff\u00ff\u00ff\u0015\u00ff\u00ff\u00ff" +
-                                             //                               q     u     o     t     ;     "     g     t     ;     >
-                                             //                               b     b     d     e     f     10    11    12    13    14
-                                             "\u00ff\u00ff\u00ff").charAt(crefState);
-                                //                               l     t     ;
-                                //                               15    16    17
-                                
-                                if (crefState == 255) fatalError("invalid Character Entitiy", this.lineNumber, this.columnNumber);
-                            }
-                        }
-                        
-                        break;
-                        
-                    case parseError:
-                        // report fatal error
-                        
-                        fatalError(operand, this.lineNumber, this.columnNumber);
-                        // drop through to exit parser
-                        
-                    case exitParser:
-                        // exit parser
-                        
-                        return;
-                        
-                    case writeCdata:
-                        // write character data
-                        // this will also write any skipped whitespace
-                        
-                        buffer.write(currentChar);
-                        break;  // change state to operand
-                        
-                    case writeAsWS:
-                        buffer.write((currentChar == '\n' ? currentChar : (char)32));
-                        break;
-
-                    case discardAndChange:
-                        // throw saved characters away and change state
-                        
-                        buffer.reset();
-                        break;  // change state to operand
-                        
-                    case discardSaveAndChange:
-                        // throw saved characters away, save character and change state
-                        
-                        buffer.reset();
-                        // drop through to save character and change state
-                        
-                    case saveAndChange:
-                        // save character and change state
-                        
-                        buffer.saveChar((char)currentChar);
-                        break;  // change state to operand
-                        
-                    case change:
-                        // change state to operand
-                        
-                        break;  // change state to operand
-                    }
-                    
-                    state = operand;
-                }
-            }
-            catch (final IOException e) {
-                this.errorHandler.fatalError(new SAXParseException(e.toString(), null, null, this.lineNumber, this.columnNumber, e));
-            }
-            finally {
-                this.errorHandler = this;
-                this.documentHandler = this.extDocumentHandler = this;
-                this.tags.removeAllElements();
-            }
-        }
-        
-        public void parse(final InputSource source) throws SAXException, IOException {
-            if (source.getCharacterStream() != null)
-                parse(source.getCharacterStream());
-            else if (source.getByteStream() != null)
-                parse(new InputStreamReader(source.getByteStream()));
-            else
-                parse(new InputStreamReader(new URL(source.getSystemId()).openStream()));
-        }
-        
-        public void parse(final String systemId) throws SAXException, IOException {
-            parse(new InputSource(systemId));
-        }
-        
-        public void setLocale(final Locale locale) throws SAXException {
-            throw new SAXException("Not supported");
-        }
-        
-        public void setEntityResolver(final EntityResolver resolver) {
-            // not supported
-        }
-        
-        public void setDTDHandler(final DTDHandler handler) {
-            // not supported
-        }
-        
-        public void setDocumentHandler(final DocumentHandler handler) {
-            this.documentHandler = (handler == null) ? this : handler;
-            if (handler != null) handler.setDocumentLocator(this);
-            this.extDocumentHandler = this;
-        }
-
-        public void setErrorHandler(final ErrorHandler handler) {
-            this.errorHandler = (handler == null) ? this : handler;
-        }
-        
-        public void setDocumentLocator(final Locator locator) {
-        }
-        
-        public void startDocument() throws SAXException {
-        }
-        
-        public Writer startDocument(final Writer writer) throws SAXException {
-            this.documentHandler.startDocument();
-            return writer;
-        }
-        
-        public void endDocument() throws SAXException {
-        }
-        
-        public void startElement(final String name, final AttributeList attributes) throws SAXException {
-        }
-        
-        public Writer startElement(final String name, final AttributeList attributes, final Writer writer)
-            throws SAXException
-        {
-            this.documentHandler.startElement(name, attributes);
-            return writer;
-        }
-        
-        public void endElement(final String name) throws SAXException {
-        }
-        
-        public void characters(final char ch[], final int start, final int length) throws SAXException {
-        }
-        
-        public void ignorableWhitespace(final char ch[], final int start, final int length) throws SAXException {
-        }
-        
-        public void processingInstruction(final String target, final String data) throws SAXException {
-        }
-        
-        public void warning(final SAXParseException e) throws SAXException {
-        }
-        
-        public void error(final SAXParseException e) throws SAXException {
-        }
-        
-        public void fatalError(final SAXParseException e) throws SAXException {
-            throw e;
-        }
-        
-        public String getPublicId() {
-            return "";
-        }
-        
-        
-        public String getSystemId() {
-            return "";
-        }
-        
-        public int getLineNumber () {
-            return this.lineNumber;
-        }
-        
-        public int getColumnNumber () {
-            return this.columnNumber;
-        }
-        
-        private void fatalError(final String msg, final int lineNumber, final int columnNumber) throws SAXException {
-            this.errorHandler.fatalError(new SAXParseException(msg, null, null, lineNumber, columnNumber));
-        }
-        
-        private class MinMLBuffer extends Writer {
-            public MinMLBuffer(final Reader in) {
-                this.in = in;
-            }
-            
-            public void close() throws IOException {
-                flush();
-            }
-            
-            public void flush() throws IOException {
-                try {
-                    _flush();
-                    if (writer != this) writer.flush();
-                }
-                finally {
-                    flushed = true;
-                }
-            }
-            
-            public void write(final int c) throws IOException {
-                written = true;
-                chars[count++] = (char)c;
-            }
-            
-            public void write(final char[] cbuf, final int off, final int len) throws IOException {
-                written = true;
-                System.arraycopy(cbuf, off, chars, count, len);
-                count += len;
-            }
-            
-            public void saveChar(final char c) {
-                written = false;
-                chars[count++] = c;
-            }
-            
-            public void pushWriter(final Writer writer) {
-                MinML.this.tags.push(this.writer);
-                
-                this.writer = (writer == null) ? this : writer;
-                
-                flushed = written = false;
-            }
-            
-            public Writer getWriter() {
-                return writer;
-            }
-            
-            public void popWriter() throws IOException {
-                try {
-                    if (!flushed && writer != this) writer.flush();
-                }
-                finally {
-                    writer = (Writer)MinML.this.tags.pop();
-                    flushed = written = false;
-                }
-            }
-            
-            public String getString() {
-                final String result = new String(chars, 0, count);
-                
-                count = 0;
-                return result;
-            }
-            
-            public void reset() {
-                count = 0;
-            }
-            
-            public int read() throws IOException {
-                if (nextIn == lastIn) {
-                    if (count != 0) {
-                        if (written) {
-                            _flush();
-                        } else if (count >= (chars.length - MinML.this.bufferIncrement)) {
-                            final char[] newChars = new char[chars.length + MinML.this.bufferIncrement];
-                            
-                            System.arraycopy(chars, 0, newChars, 0, count);
-                            chars = newChars;
-                        }
-                    }
-                    
-                    final int numRead = in.read(chars, count, chars.length - count);
-                    
-                    if (numRead == -1) return -1;
-                    
-                    nextIn = count;
-                    lastIn = count + numRead;
-                }
-                
-                return chars[nextIn++];
-            }
-            
-            private void _flush() throws IOException {
-                if (count != 0) {
-                    try {
-                        if (writer == this) {
-                            try {
-                                MinML.this.documentHandler.characters(chars, 0, count);
-                            }
-                            catch (final SAXException e) {
-                                throw new IOException(e.toString());
-                            }
-                        } else {
-                            writer.write(chars, 0, count);
-                        }
-                    }
-                    finally {
-                        count = 0;
-                    }
-                }
-            }
-            
-            private int nextIn = 0, lastIn = 0;
-            private char[] chars = new char[MinML.this.initialBufferSize];
-            private final Reader in;
-            private int count = 0;
-            private Writer writer = this;
-            private boolean flushed = false;
-            private boolean written = false;
-        }
-        
-        private DocumentHandler extDocumentHandler = this;
-        private DocumentHandler documentHandler = this;
-        private ErrorHandler errorHandler = this;
-        private final Stack tags = new Stack();
-        private int lineNumber = 1;
-        private int columnNumber = 0;
-        private final int initialBufferSize;
-        private final int bufferIncrement;
-        
-        private static final byte[] charClasses = {
-            //  EOF
-            13,
-            //                                      \t  \n          \r
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 12, -1, -1, 12, -1, -1,
-            //
-            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-            //  SP   !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /
-            12,  8,  7, 14, 14, 14,  3,  6, 14, 14, 14, 14, 14, 11, 14,  2,
-            //   0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  0,  5,  1,  4,
-            //
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-            //                                               [   \   ]
-            14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  9, 14, 10
-        };
-        
-        private static final String[] operands = {
-            "\u0d15\u1611\u1611\u1611\u1611\u1611\u1611\u1611\u1611\u1611\u1611\u1611\u0015\u0010\u1611",
-            "\u1711\u1000\u0b00\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u0114\u0200\u1811\u0114",
-            "\u1711\u1001\u0b01\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u0215\u1811\u0414",
-            "\u1711\u1001\u0b01\u1711\u1911\u1911\u1911\u1911\u1911\u1911\u1911\u1911\u0315\u1811\u0414",
-            "\u1911\u1911\u1911\u1911\u1911\u0606\u1911\u1911\u1911\u1911\u1911\u0414\u0515\u1811\u0414",
-            "\u1911\u1911\u1911\u1911\u1911\u0606\u1911\u1911\u1911\u1911\u1911\u1911\u0515\u1811\u1911",
-            "\u1a11\u1a11\u1a11\u1a11\u1a11\u1a11\u0715\u0815\u1a11\u1a11\u1a11\u1a11\u0615\u1811\u1a11",
-            "\u0714\u0714\u0714\u070e\u0714\u0714\u0307\u0714\u0714\u0714\u0714\u0714\u0714\u1811\u0714",
-            "\u0814\u0814\u0814\u080e\u0814\u0814\u0814\u0307\u0814\u0814\u0814\u0814\u0814\u1811\u0814",
-            "\u1711\u1002\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u0914\u0915\u1811\u0914",
-            "\u1b11\u1b11\u0904\u1b11\u1b11\u1b11\u1b11\u1b11\u1215\u1b11\u1b11\u1b11\u1b11\u1811\u0105",
-            "\u1711\u1012\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1711\u1811\u1711",
-            "\u1711\u1c11\u0912\u1711\u0e12\u1711\u1711\u1711\u1212\u1711\u1711\u1711\u1711\u1811\u0113",
-            "\u1711\u1c11\u0912\u1711\u0e12\u1711\u1711\u1711\u1212\u1711\u1711\u1711\u1711\u1811\u0113",
-            "\u0e15\u0e15\u0e15\u0e15\u0f15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u1811\u0e15",
-            "\u0e15\u0015\u0e15\u0e15\u0f15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u0e15\u1811\u0e15",
-            "\u0c03\u110f\u110f\u110e\u110f\u110f\u110f\u110f\u110f\u110f\u110f\u110f\u1014\u1811\u110f",
-            "\u0a15\u110f\u110f\u110e\u110f\u110f\u110f\u110f\u110f\u110f\u110f\u110f\u110f\u1811\u110f",
-            "\u1d11\u1d11\u1d11\u1d11\u1d11\u1d11\u1d11\u1d11\u1d11\u130c\u1d11\u1408\u1d11\u1811\u1515",
-            "\u130f\u130f\u130f\u130f\u130f\u130f\u130f\u130f\u130f\u130f\u110d\u130f\u130f\u1811\u130f",
-            "\u1416\u1416\u1416\u1416\u1416\u1416\u1416\u1416\u1416\u1416\u1416\u0009\u1416\u1811\u1416",
-//            "\u1415\u1415\u1415\u1415\u1415\u1415\u1415\u1415\u1415\u1415\u1415\u0009\u1415\u1811\u1415",
-            "\u150a\u000b\u1515\u1515\u1515\u1515\u1515\u1515\u1515\u1515\u1515\u1515\u1515\u1811\u1515",
-            "expected Element",
-            "unexpected character in tag",
-            "unexpected end of file found",
-            "attribute name not followed by '='",
-            "invalid attribute value",
-            "expecting end tag",
-            "empty tag",
-            "unexpected character after <!"
-        };
-    }
-    ///////////////////////////////////////////////////////////////////////////////
-
-    private class XMLHelper implements DocumentHandler {
-        private MinML minml = new MinML();
-        XMLHelper() { }
-        public void parse(Reader r) throws IOException, XML.SAXException {
-            minml.setDocumentHandler(this);
-            minml.parse(new InputSource(r));
-        }
-        
-        public void startDocument() throws SAXException { }
-        public void endDocument() throws SAXException { }
-        public void processingInstruction (String target, String data) throws SAXException { }
-        public Writer startDocument(final Writer writer) throws SAXException { return null; }
-        public Writer startElement(final String name, final AttributeList attributes, final Writer writer) throws SAXException { return null; }
-
-        public void setDocumentLocator (Locator locator) {
-            this.locator = locator;
-        }
-
-        private Locator locator = null;
-
-        public void startElement(String name, AttributeList atts) throws SAXException {
-            String[] keys = new String[atts.getLength()];
-            Object[] vals = new Object[atts.getLength()];
-            for (int i=0; i <atts.getLength(); i++) {
-                keys[i] = atts.getName(i);
-                vals[i] = atts.getValue(i).toString();
-            }
-            XML.this.startElement(name, keys, vals,
-                                  locator == null ? 0 : locator.getLineNumber(), locator == null ? 0 : locator.getColumnNumber());
-        }
-
-        public void endElement(String name) throws SAXException {
-            XML.this.endElement(name, locator == null ? 0 : locator.getLineNumber(), locator == null ? 0 : locator.getColumnNumber());
-        }
-
-        public void characters(char ch[], int start, int length) throws SAXException {
-            XML.this.content(ch, start, length, locator == null ? 0 : locator.getLineNumber(), locator == null ? 0 : locator.getColumnNumber());
-        }
-        public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
-            XML.this.content(ch, start, length, locator == null ? 0 : locator.getLineNumber(), locator == null ? 0 : locator.getColumnNumber());
-        }
-    }
-
-    public XML() { }
-    public void parse(Reader r) throws IOException, XML.SAXException {
-        XMLHelper helper = new XMLHelper();
-        helper.parse(r);
-        helper = null;
-    }
-
-    /** indicates the start of an element with name <tt>name</tt>, and attributes <tt>attributes</tt>, starting on line <tt>line</tt> */
-    public abstract void startElement(String name, String[] keys, Object[] vals, int line, int col) throws SAXException;
-
-    /** indicates the end of an element with name <tt>name</tt>, starting on line <tt>line</tt> */
-    public abstract void endElement(String name, int line, int col) throws SAXException;
-
-    /** indicates a chunk of CDATA content, starting on line <tt>line</tt> */
-    public abstract void content(char[] content, int start, int length, int line, int col) throws SAXException; 
-}
index 2bbebb9..ebea2a6 100644 (file)
@@ -76,38 +76,38 @@ class XMLRPC extends XML implements Function {
 
     // Methods to Recieve and parse XML-RPC Response ////////////////////////////////////////////////////
 
-    public void startElement(String name, String[] keys, Object[] vals, int line, int col) {
+    public void startElement(XML.Element c) {
         content.reset();
-        if (name.equals("fault")) fault = true;
-        else if (name.equals("struct")) objects.setElementAt(new JSObject(false), objects.size() - 1);
-        else if (name.equals("array")) objects.setElementAt(null, objects.size() - 1);
-        else if (name.equals("value")) objects.addElement("");
+        if (c.localName.equals("fault")) fault = true;
+        else if (c.localName.equals("struct")) objects.setElementAt(new JSObject(false), objects.size() - 1);
+        else if (c.localName.equals("array")) objects.setElementAt(null, objects.size() - 1);
+        else if (c.localName.equals("value")) objects.addElement("");
     }
 
-    public void endElement(String name, int line, int col) {
+    public void endElement(XML.Element c) {
 
-        if (name.equals("int") || name.equals("i4"))
+        if (c.localName.equals("int") || c.localName.equals("i4"))
             objects.setElementAt(new Integer(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
 
-        else if (name.equals("boolean"))
+        else if (c.localName.equals("boolean"))
             objects.setElementAt(content.getBuf()[0] == '1' ? Boolean.TRUE : Boolean.FALSE, objects.size() - 1);
 
-        else if (name.equals("string"))
+        else if (c.localName.equals("string"))
             objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
 
-        else if (name.equals("double"))
+        else if (c.localName.equals("double"))
             objects.setElementAt(new Double(new String(content.getBuf(), 0, content.size())), objects.size() - 1);
 
-        else if (name.equals("base64"))
+        else if (c.localName.equals("base64"))
             objects.setElementAt(new ByteStream(Base64.decode(new String(content.getBuf(), 0, content.size()))), objects.size() - 1);
 
-        else if (name.equals("name"))
+        else if (c.localName.equals("name"))
             objects.addElement(new String(content.getBuf(), 0, content.size()));
 
-        else if (name.equals("value") && "".equals(objects.lastElement()))
+        else if (c.localName.equals("value") && "".equals(objects.lastElement()))
             objects.setElementAt(new String(content.getBuf(), 0, content.size()), objects.size() - 1);
 
-        else if (name.equals("dateTime.iso8601")) {
+        else if (c.localName.equals("dateTime.iso8601")) {
             String s = new String(content.getBuf(), 0, content.size());
 
             // strip whitespace
@@ -133,14 +133,14 @@ class XMLRPC extends XML implements Function {
                 if (Log.on) Log.log(this, e);
             }
 
-        } else if (name.equals("member")) {
+        } else if (c.localName.equals("member")) {
             Object memberValue = objects.elementAt(objects.size() - 1);
             String memberName = (String)objects.elementAt(objects.size() - 2);
             Scriptable struct = (Scriptable)objects.elementAt(objects.size() - 3);
             struct.put(memberName, struct, memberValue);
             objects.setSize(objects.size() - 2);
 
-        } else if (name.equals("data")) {
+        } else if (c.localName.equals("data")) {
             int i;
             for(i=objects.size() - 1; objects.elementAt(i) != null; i--);
             Object[] arr = new Object[objects.size() - i - 1];
@@ -153,7 +153,7 @@ class XMLRPC extends XML implements Function {
         content.reset();
     }
 
-    public void content(char[] ch, int start, int length, int line, int col) {
+    public void characters(char[] ch, int start, int length) {
         try { content.write(ch, start, length); }
         catch (Exception e) { 
             if (Log.on) Log.log(this, "Exception in XMLRPC.content() -- this should never happen");
@@ -161,6 +161,7 @@ class XMLRPC extends XML implements Function {
         }
     }
 
+    public void whitespace(char[] ch, int start, int length) {}
 
     // Methods to make outbound XML-RPC request ///////////////////////////////////////////////////
 
@@ -344,7 +345,7 @@ class XMLRPC extends XML implements Function {
         // parse XML reply
         try {
             parse(br);
-        } catch (XML.SAXException e) {
+        } catch (XML.XMLException e) {
             if (Log.on) Log.log(this, "reply from server was not well-formed XML: " + e);
             throw new JavaScriptException("reply from server was not well-formed XML: " + e);
         }
@@ -388,6 +389,8 @@ class XMLRPC extends XML implements Function {
     }
 
     public XMLRPC(String url, String methodname, HTTP http) {
+        super(BUFFER_SIZE);
+
         this.http = http;
         this.url = url;
         this.methodname = methodname;