home *** CD-ROM | disk | FTP | other *** search
/ Online Today 2000 January / Onto0100.iso / pc / JAVA / MSJAVX86.EXE / xmldso.cab / XML4IE3.cab / com / ms / xml / parser / Parser.class (.txt) < prev    next >
Encoding:
Java Class File  |  1997-10-10  |  29.1 KB  |  1,932 lines

  1. package com.ms.xml.parser;
  2.  
  3. import com.ms.xml.om.Element;
  4. import com.ms.xml.om.ElementFactory;
  5. import com.ms.xml.util.EnumWrapper;
  6. import com.ms.xml.util.Name;
  7. import com.ms.xml.util.QualifiedName;
  8. import com.ms.xml.util.XMLInputStream;
  9. import com.ms.xml.util.XMLOutputStream;
  10. import java.io.BufferedInputStream;
  11. import java.io.IOException;
  12. import java.io.InputStream;
  13. import java.io.OutputStream;
  14. import java.io.PrintStream;
  15. import java.net.URL;
  16. import java.util.Enumeration;
  17. import java.util.Hashtable;
  18. import java.util.Stack;
  19. import java.util.Vector;
  20.  
  21. public class Parser {
  22.    static final int TAGSTART = 60;
  23.    static final int TAGEND = 62;
  24.    static final int SLASH = 47;
  25.    // $FF: renamed from: EQ int
  26.    static final int field_0 = 61;
  27.    static final int LPAREN = 40;
  28.    static final int RPAREN = 41;
  29.    static final int BANG = 33;
  30.    static final int QMARK = 63;
  31.    static final int DASH = 45;
  32.    static final int PERCENT = 37;
  33.    static final int AMP = 38;
  34.    static final int LEFTSQB = 91;
  35.    static final int RIGHTSQB = 93;
  36.    static final int QUOTE = 39;
  37.    // $FF: renamed from: OR int
  38.    static final int field_1 = 124;
  39.    static final int ASTERISK = 42;
  40.    static final int PLUS = 43;
  41.    static final int HASH = 35;
  42.    static final int COMMA = 44;
  43.    static final int INVALIDTOKEN = 0;
  44.    static final int EOF = -1;
  45.    static final int WHITESPACE = -2;
  46.    static final int WORDCHAR = -3;
  47.    static final int NAME = -4;
  48.    static final int TEXT = -5;
  49.    static final int PITAGSTART = -6;
  50.    static final int PITAGEND = -7;
  51.    static final int DECLTAGSTART = -8;
  52.    static final int CLOSETAGSTART = -9;
  53.    static final int EMPTYTAGEND = -10;
  54.    static final int COMMENT = -11;
  55.    static final int DOCTYPE = -12;
  56.    static final int SYSTEM = -13;
  57.    static final int CDATATAGSTART = -14;
  58.    static final int ELEMENT = -15;
  59.    static final int EMPTY = -16;
  60.    static final int ANY = -17;
  61.    static final int PCDATA = -18;
  62.    static final int ATTLIST = -19;
  63.    static final int CDATA = -20;
  64.    // $FF: renamed from: ID int
  65.    static final int field_2 = -21;
  66.    static final int IDREF = -22;
  67.    static final int IDREFS = -23;
  68.    static final int ENTITY = -24;
  69.    static final int ENTITIES = -25;
  70.    static final int NMTOKEN = -26;
  71.    static final int NMTOKENS = -27;
  72.    static final int NOTATION = -28;
  73.    static final int ENUMERATION = -29;
  74.    static final int FIXED = -30;
  75.    static final int REQUIRED = -31;
  76.    static final int IMPLIED = -32;
  77.    static final int NDATA = -33;
  78.    static final int INCLUDE = -34;
  79.    static final int INCLUDETAGSTART = -35;
  80.    static final int IGNORE = -36;
  81.    static final int IGNORETAGSTART = -37;
  82.    static final int NAMESPACE = -38;
  83.    static final int PUBLIC = -100;
  84.    ElementFactory factory;
  85.    DTD dtd;
  86.    Element root;
  87.    Stack contexts = new Stack();
  88.    Context current;
  89.    EntityReader reader;
  90.    XMLInputStream xmlIn;
  91.    boolean inTag;
  92.    int lookahead;
  93.    char quote;
  94.    char[] chars = new char[8192];
  95.    int charAt;
  96.    char[] buf = new char[8192];
  97.    int bufAt;
  98.    int nameappend;
  99.    static Hashtable tokens;
  100.    int token;
  101.    int keyword;
  102.    int nouppercase;
  103.    int substitution;
  104.    int breakText;
  105.    int nametoken;
  106.    int simplename;
  107.    int inEntityRef;
  108.    boolean expandNamedEntities;
  109.    static boolean jdk11;
  110.    Name name;
  111.    String text;
  112.    URL url;
  113.    Name docType;
  114.    boolean internalSubset;
  115.    static ElementDecl XMLDecl;
  116.    static int RMD_ALL;
  117.    static int RMD_NONE = 1;
  118.    static int RMD_INTERNAL = 2;
  119.    int rmd;
  120.    static int[] chartype = new int[256];
  121.    static char[] charupper = new char[256];
  122.    static final int FWHITESPACE = 1;
  123.    static final int FDIGIT = 2;
  124.    static final int FLETTER = 4;
  125.    static final int FMISCNAME = 8;
  126.    static final int FSTARTNAME = 16;
  127.    static Name nameComment = Name.create("--");
  128.    static Name nameCDATA = Name.create("[CDATA[");
  129.    static Name namePCDATA = Name.create("PCDATA");
  130.    static Name nameINCLUDE = Name.create("[INCLUDE[");
  131.    static Name nameIGNORE = Name.create("[IGNORE[");
  132.    static Name nameVERSION = Name.create("VERSION");
  133.    static Name nameENCODING = Name.create("ENCODING");
  134.    static Name nameDOCTYPE = Name.create("DOCTYPE");
  135.    static Name nameXML = Name.create("XML");
  136.    static Name nameRMD = Name.create("RMD");
  137.    static Name nameNONE = Name.create("NONE");
  138.    static Name nameINTERNAL = Name.create("INTERNAL");
  139.    static Name nameALL = Name.create("ALL");
  140.    static Name nameURL = Name.create("URL");
  141.    static Name namePUBLICID = Name.create("PUBLICID");
  142.    static Name nameNAME = Name.create("NAME");
  143.    static Name nameXMLSpace = Name.create("XML-SPACE");
  144.    static Name nameXMLAS = QualifiedName.create(Name.create("AS"), Name.create("XML"));
  145.    static Name nameXMLHREF = QualifiedName.create(Name.create("HREF"), Name.create("XML"));
  146.    static Name nameXMLNameSpace = QualifiedName.create(Name.create("NAMESPACE"), Name.create("XML"));
  147.  
  148.    static final boolean isWhiteSpaceChar(char var0) {
  149.       if (var0 < 256) {
  150.          return (chartype[var0] & 1) != 0;
  151.       } else if (jdk11) {
  152.          return Character.isWhitespace(var0);
  153.       } else {
  154.          return Character.isSpace(var0) || var0 == '\r';
  155.       }
  156.    }
  157.  
  158.    static final boolean isNameSpaceSeparatorChar(char var0) {
  159.       return var0 == ':';
  160.    }
  161.  
  162.    final String scanUrl() throws ParseException {
  163.       this.parseToken(39, "Url");
  164.       this.scanString(this.quote, 65535, 65535, 65535);
  165.       return this.text;
  166.    }
  167.  
  168.    public final void parse(URL var1, ElementFactory var2, DTD var3, Element var4) throws ParseException {
  169.       this.dtd = var3;
  170.       this.root = var4;
  171.       this.setURL(var1);
  172.       this.setFactory(var2);
  173.       this.parseDocument();
  174.    }
  175.  
  176.    public final void parse(InputStream var1, ElementFactory var2, DTD var3, Element var4) throws ParseException {
  177.       this.dtd = var3;
  178.       this.url = null;
  179.       this.root = var4;
  180.       this.setInputStream(var1);
  181.       this.setFactory(var2);
  182.       this.parseDocument();
  183.    }
  184.  
  185.    final ElementDecl createElementDecl(Vector var1) throws ParseException {
  186.       if (this.token != -4) {
  187.          this.error("Expected " + this.tokenString(-4) + " instead of " + this.tokenString(this.token));
  188.       }
  189.  
  190.       if (this.dtd.findElementDecl(this.name) != null) {
  191.          this.error("Element '" + this.name + "' already declared.");
  192.       }
  193.  
  194.       ElementDecl var2 = new ElementDecl(this.name);
  195.       this.dtd.addElementDecl(var2);
  196.       var1.addElement(var2);
  197.       return var2;
  198.    }
  199.  
  200.    final void parseAttributes(Element var1) throws ParseException {
  201.       Hashtable var2 = new Hashtable();
  202.  
  203.       while(this.nextToken() == -4) {
  204.          Name var3 = this.name;
  205.          if (var2.contains(this.name)) {
  206.             this.error("An attribute cannot appear more than once in the same start tag");
  207.          }
  208.  
  209.          var2.put(this.name, this.name);
  210.          this.parseToken(61, "=");
  211.          if (this.current.ed != null) {
  212.             this.current.ed.parseAttribute(var1, this.name, this);
  213.          } else {
  214.             this.parseToken(39, "string");
  215.             this.scanString(this.quote, 38, 38, 60);
  216.             var1.setAttribute(var3, this.text);
  217.          }
  218.  
  219.          if (this.isXMLSpaceAtt(var3)) {
  220.             Object var4 = var1.getAttribute(var3);
  221.             if (var4 != null) {
  222.                String var5 = null;
  223.                if (var4 instanceof String) {
  224.                   var5 = (String)var4;
  225.                } else if (var4 instanceof QualifiedName) {
  226.                   var5 = ((QualifiedName)var4).getName().toString();
  227.                } else if (var4 instanceof Name) {
  228.                   var5 = var4.toString();
  229.                }
  230.  
  231.                if (var5 != null && var5.equalsIgnoreCase("preserve")) {
  232.                   this.current.preserveWS = true;
  233.                } else if (var5 != null && var5.equalsIgnoreCase("default")) {
  234.                   this.current.preserveWS = false;
  235.                } else {
  236.                   this.error("Invalid value '" + var5 + "' for XML-SPACE attribute.");
  237.                }
  238.             }
  239.          }
  240.       }
  241.  
  242.       if (this.current.ed != null) {
  243.          this.current.ed.checkAttributes(var1, this);
  244.       }
  245.  
  246.    }
  247.  
  248.    final Element parseNameSpaceDecl(boolean var1, boolean var2) throws ParseException {
  249.       Element var3 = this.factory.createElement(10, this.name);
  250.       this.current.e.addChild(var3, (Element)null);
  251.       this.push(var3);
  252.       this.parseAttributes(var3);
  253.       this.pop();
  254.       if (var2 && this.token != -7) {
  255.          this.error("Expected PI tag end '?>' instead of " + this.tokenString(this.token));
  256.       } else if (!var2 && this.token != -10) {
  257.          this.error("Expected " + this.tokenString(-10) + " instead of " + this.tokenString(this.token));
  258.       }
  259.  
  260.       Object var4 = var3.getAttribute(nameXMLAS);
  261.       Object var5 = var3.getAttribute(nameXMLHREF);
  262.       if (var4 == null || var5 == null) {
  263.          this.error("Missing attribute 'AS' or 'HREF'");
  264.       }
  265.  
  266.       Name var6 = Name.create(var4.toString().toUpperCase());
  267.       Name var7 = Name.create(var5.toString().toUpperCase());
  268.       if (DTD.isReservedNameSpace(var6)) {
  269.          this.error(var6.toString() + " is a reserved name space.");
  270.       }
  271.  
  272.       this.addNameSpace(var6, var7, var1);
  273.       if (this.rmd == RMD_ALL) {
  274.          try {
  275.             if (this.dtd.findLoadedNameSpace(var7) == null) {
  276.                this.dtd.addLoadedNameSpace(var7);
  277.                this.loadExternalDTD(var7.toString(), var7);
  278.             }
  279.          } catch (IOException var8) {
  280.             this.error("Couldn't find name space '" + var7.toString() + "'");
  281.          }
  282.       }
  283.  
  284.       return var3;
  285.    }
  286.  
  287.    final void parseDocument() throws ParseException {
  288.       this.expandNamedEntities = true;
  289.       this.rmd = RMD_NONE;
  290.       this.internalSubset = false;
  291.       this.current = new Context(this.root, false, (Name)null, (Hashtable)null);
  292.       this.parseProlog();
  293.       this.parseRootElement();
  294.       if (this.lookahead != -1) {
  295.          this.nextToken();
  296.          this.tryMisc();
  297.          if (this.lookahead != -1) {
  298.             this.error("Expected comments, PI, or EOF instead of " + this.tokenString(this.token));
  299.          }
  300.       }
  301.  
  302.       this.dtd.checkIDs();
  303.    }
  304.  
  305.    private final boolean isXMLSpaceAtt(Name var1) {
  306.       if (var1 == nameXMLSpace) {
  307.          return true;
  308.       } else if (var1 instanceof QualifiedName) {
  309.          return ((QualifiedName)var1).getName() == nameXMLSpace;
  310.       } else {
  311.          return false;
  312.       }
  313.    }
  314.  
  315.    private final void setInputStream(InputStream var1) throws ParseException {
  316.       this.xmlIn = new XMLInputStream(var1);
  317.       this.reader = new EntityReader(this.xmlIn, 1, 1, (EntityReader)null, this);
  318.       this.advance();
  319.    }
  320.  
  321.    public final void report(ParseException var1, OutputStream var2) {
  322.       PrintStream var3 = new PrintStream(var2);
  323.       String var4 = null;
  324.       if (var1.owner instanceof Parser) {
  325.          URL var5 = ((Parser)var1.owner).url;
  326.          if (var5 != null) {
  327.             var4 = var5.toString();
  328.          }
  329.       } else if (var1.owner instanceof Entity) {
  330.          var4 = "Parsing <" + ((Entity)var1.owner).name + ">";
  331.       } else {
  332.          var4 = "Parsing";
  333.       }
  334.  
  335.       var3.println("Error: " + var4 + "(" + var1.line + "," + var1.column + ")");
  336.       var3.print("Context: ");
  337.       Enumeration var6 = this.contexts.elements();
  338.  
  339.       while(var6.hasMoreElements()) {
  340.          var3.print(" - <" + ((Context)var6.nextElement()).e.getTagName() + ">");
  341.       }
  342.  
  343.       var3.print(" - <");
  344.       if (this.current != null) {
  345.          var3.print(this.current.e.getTagName());
  346.       }
  347.  
  348.       var3.print(">");
  349.       var3.println("");
  350.       ((Throwable)var1).printStackTrace(var3);
  351.    }
  352.  
  353.    final int parseNames(Vector var1, int var2, StringBuffer var3) throws ParseException {
  354.       int var4 = 0;
  355.       this.bufAt = 0;
  356.       if (var3 != null) {
  357.          ++this.nameappend;
  358.       }
  359.  
  360.       while(this.nextToken() == -4) {
  361.          if (var4 > 0) {
  362.             this.buf[this.bufAt++] = ' ';
  363.          }
  364.  
  365.          var1.addElement(this.name);
  366.          ++var4;
  367.          if (var2 != 0 && this.nextToken() != 124) {
  368.             break;
  369.          }
  370.       }
  371.  
  372.       if (var3 != null) {
  373.          var3.append(this.buf, 0, this.bufAt);
  374.          this.nameappend += -1;
  375.       }
  376.  
  377.       return var4;
  378.    }
  379.  
  380.    final void advance() throws ParseException {
  381.       for(this.lookahead = this.reader.read(); this.lookahead == -1 && this.reader.owner != this; this.lookahead = this.reader.read()) {
  382.          if (((Entity)this.reader.owner).url != null && this.charAt != 0) {
  383.             this.text = new String(this.chars, 0, this.charAt);
  384.             this.addPCDATA(this.text);
  385.          }
  386.  
  387.          this.reader = this.reader.prev;
  388.          this.pop();
  389.          if (!this.inTag) {
  390.             this.charAt = 0;
  391.          }
  392.       }
  393.  
  394.    }
  395.  
  396.    private void addNameSpace(Name var1, Name var2, boolean var3) throws ParseException {
  397.       if (var1 instanceof QualifiedName) {
  398.          if (((QualifiedName)var1).getNameSpace() != this.current.defaultNameSpace) {
  399.             this.error("Name space syntax error.");
  400.          }
  401.  
  402.          var1 = ((QualifiedName)var1).getName();
  403.       }
  404.  
  405.       if (DTD.isReservedNameSpace(var1)) {
  406.          this.error(var1.toString() + " is a reserved name space.");
  407.       }
  408.  
  409.       if (var3) {
  410.          Name var4 = this.dtd.findShortNameSpace(var2);
  411.          if (var4 == null) {
  412.             var4 = this.dtd.findLongNameSpace(var1);
  413.             if (var4 != null) {
  414.                this.error("Short reference '" + var1.toString() + "' is used by name space '" + var4.toString() + "'");
  415.             }
  416.  
  417.             this.dtd.addNameSpace(var1, var2);
  418.             return;
  419.          }
  420.  
  421.          if (var4 != var1) {
  422.             this.error("Cannot give two short references '" + var4.toString() + "' and '" + var1.toString() + "' to the same name space: '" + var2.toString() + "'");
  423.             return;
  424.          }
  425.       } else {
  426.          this.current.addNameSpace(var1, var2);
  427.       }
  428.  
  429.    }
  430.  
  431.    final boolean match(String var1) throws ParseException {
  432.       int var2 = 0;
  433.       int var3 = var1.length();
  434.  
  435.       while(var3 > 0 && this.lookahead == var1.charAt(var2++)) {
  436.          --var3;
  437.          this.advance();
  438.       }
  439.  
  440.       return var3 == 0;
  441.    }
  442.  
  443.    public final XMLOutputStream createOutputStream(OutputStream var1) {
  444.       return this.xmlIn != null ? this.xmlIn.createOutputStream(var1) : null;
  445.    }
  446.  
  447.    final Element addPCDATA(String var1) throws ParseException {
  448.       if (var1.length() > 0) {
  449.          Element var2 = this.factory.createElement(1, (Name)null);
  450.          var2.setText(var1);
  451.          if (this.current.ed != null) {
  452.             this.current.ed.checkContent(this.current, var2, this);
  453.          }
  454.  
  455.          this.current.e.addChild(var2, (Element)null);
  456.          return var2;
  457.       } else {
  458.          return null;
  459.       }
  460.    }
  461.  
  462.    final Element finishPI() throws ParseException {
  463.       Element var1 = this.factory.createElement(5, this.name);
  464.       this.current.e.addChild(var1, (Element)null);
  465.       this.charAt = 0;
  466.       boolean var2 = false;
  467.  
  468.       while(this.lookahead != -1) {
  469.          this.chars[this.charAt++] = (char)this.lookahead;
  470.          if (this.lookahead == 63) {
  471.             this.advance();
  472.             if (this.lookahead == 62) {
  473.                this.charAt += -1;
  474.                var2 = true;
  475.             }
  476.          } else {
  477.             this.advance();
  478.          }
  479.  
  480.          if (this.charAt == this.chars.length || var2) {
  481.             Element var3 = this.factory.createElement(6, (Name)null);
  482.             var1.addChild(var3, (Element)null);
  483.             var3.setText(new String(this.chars, 0, this.charAt));
  484.             this.charAt = 0;
  485.             if (var2) {
  486.                break;
  487.             }
  488.          }
  489.       }
  490.  
  491.       this.parseToken(62, "PI end");
  492.       return var1;
  493.    }
  494.  
  495.    public Parser() {
  496.       String var1 = System.getProperty("java.version");
  497.       jdk11 = var1.equals("1.1");
  498.    }
  499.  
  500.    static final boolean isNameChar(char var0) {
  501.       if (var0 < 256) {
  502.          return (chartype[var0] & 14) != 0;
  503.       } else {
  504.          return Character.isLetter(var0) || Character.isDigit(var0) || var0 == '-' || var0 == '_' || var0 == '.';
  505.       }
  506.    }
  507.  
  508.    final char toUpperCase(char var1) {
  509.       if (this.nouppercase != 0) {
  510.          return var1;
  511.       } else {
  512.          return var1 < 256 ? charupper[var1] : Character.toUpperCase(var1);
  513.       }
  514.    }
  515.  
  516.    final void parseXMLDecl() throws ParseException {
  517.       if (this.token == -6) {
  518.          this.parseToken(-4, "XML");
  519.          if (this.name != nameXML) {
  520.             if (this.name == nameXMLNameSpace) {
  521.                this.parseNameSpaceDecl(true, true);
  522.             } else {
  523.                this.finishPI();
  524.             }
  525.  
  526.             this.nextToken();
  527.             return;
  528.          }
  529.  
  530.          this.rmd = RMD_ALL;
  531.          Element var1 = this.factory.createElement(5, this.name);
  532.          this.current.e.addChild(var1, (Element)null);
  533.          this.push(var1);
  534.          ElementDecl var2 = this.current.ed;
  535.          this.current.ed = XMLDecl;
  536.          this.nextToken();
  537.          if (this.token != -4) {
  538.             this.error("Expected " + nameVERSION + " tag instead of " + this.tokenString(this.token));
  539.          } else if (this.name != nameVERSION) {
  540.             this.error("Expected " + nameVERSION + " tag instead of " + this.name.toString());
  541.          }
  542.  
  543.          this.parseToken(61, "=");
  544.          this.parseToken(39, "string");
  545.          this.scanString(this.quote, 65535, 65535, 65535);
  546.          if (!this.text.equals("1.0")) {
  547.             this.error("Expected version 1.0 instead of " + this.text);
  548.          }
  549.  
  550.          var1.setAttribute(nameVERSION, this.text);
  551.          this.nextToken();
  552.          String var3 = null;
  553.          if (this.token == -4 && this.name == nameENCODING) {
  554.             this.parseToken(61, "=");
  555.             this.parseToken(39, "string");
  556.             this.scanString(this.quote, 65535, 65535, 65535);
  557.             var1.setAttribute(nameENCODING, this.text);
  558.             var3 = this.text;
  559.             this.nextToken();
  560.          }
  561.  
  562.          if (this.token == -4 && this.name == nameRMD) {
  563.             this.parseToken(61, "=");
  564.             this.parseToken(39, "string");
  565.             this.scanString(this.quote, 65535, 65535, 65535);
  566.             Name var4 = Name.create(this.text.toUpperCase());
  567.             if (var4 == nameNONE) {
  568.                this.rmd = RMD_NONE;
  569.             } else if (var4 == nameINTERNAL) {
  570.                this.rmd = RMD_INTERNAL;
  571.             } else if (var4 == nameALL) {
  572.                this.rmd = RMD_ALL;
  573.             } else {
  574.                this.error("Expected NONE, INTERNAL, or ALL instead of " + var4);
  575.             }
  576.  
  577.             var1.setAttribute(nameRMD, var4.toString());
  578.             this.nextToken();
  579.          }
  580.  
  581.          if (var3 != null) {
  582.             try {
  583.                this.xmlIn.setEncoding(var3);
  584.             } catch (IOException var5) {
  585.                this.error("Unsupported XML encoding: \"" + var3 + "\"");
  586.             }
  587.          }
  588.  
  589.          if (this.token != -7) {
  590.             this.error("Expected " + this.tokenString(-7) + " instead of " + this.tokenString(this.token));
  591.          }
  592.  
  593.          this.current.ed = var2;
  594.          this.nextToken();
  595.          this.pop();
  596.       }
  597.  
  598.    }
  599.  
  600.    final void parseProlog() throws ParseException {
  601.       if (this.lookahead != -1) {
  602.          this.nextToken();
  603.          this.parseXMLDecl();
  604.       }
  605.  
  606.       this.tryMisc();
  607.       this.tryDocTypeDecl();
  608.       this.tryMisc();
  609.    }
  610.  
  611.    final ElementDecl findElementDecl(Vector var1) throws ParseException {
  612.       if (this.token != -4) {
  613.          this.error("Expected " + this.tokenString(-4) + " instead of " + this.tokenString(this.token));
  614.       }
  615.  
  616.       ElementDecl var2 = this.dtd.findElementDecl(this.name);
  617.       if (var2 == null) {
  618.          this.error("Missing Element declaration '" + this.name + "'");
  619.       }
  620.  
  621.       var1.addElement(var2);
  622.       return var2;
  623.    }
  624.  
  625.    final void parseAttListDecl() throws ParseException {
  626.       Vector var1 = new Vector();
  627.       this.nextToken();
  628.       ElementDecl var2 = this.findElementDecl(var1);
  629.       this.push(var2);
  630.       var2.parseAttList(this);
  631.       this.checkToken(62, ">");
  632.       this.pop();
  633.    }
  634.  
  635.    final void scanCharRef() throws ParseException {
  636.       int var1 = 0;
  637.       if (this.lookahead == 35) {
  638.          this.advance();
  639.          if (this.lookahead != 120 && this.lookahead != 88) {
  640.             while(this.lookahead >= 48 && this.lookahead <= 57) {
  641.                var1 = var1 * 10 + this.lookahead - 48;
  642.                this.advance();
  643.             }
  644.          } else {
  645.             this.advance();
  646.             int var2 = 0;
  647.  
  648.             do {
  649.                if (this.lookahead >= 48 && this.lookahead <= 57) {
  650.                   var1 = var1 * 16 + this.lookahead - 48;
  651.                } else if (this.lookahead >= 97 && this.lookahead <= 102) {
  652.                   var1 = var1 * 16 + this.lookahead - 97 + 10;
  653.                } else if (this.lookahead >= 65 && this.lookahead <= 70) {
  654.                   var1 = var1 * 16 + this.lookahead - 65 + 10;
  655.                } else {
  656.                   this.error("Bad character reference syntax.  Expecting &#xx;");
  657.                }
  658.  
  659.                this.advance();
  660.                ++var2;
  661.             } while(var2 < 4);
  662.          }
  663.       }
  664.  
  665.       if (this.lookahead != 59) {
  666.          this.error("Bad character reference syntax. Expecting &#xx;");
  667.       } else {
  668.          this.chars[this.charAt++] = (char)var1;
  669.       }
  670.  
  671.       this.advance();
  672.    }
  673.  
  674.    final void parseCDATA() throws ParseException {
  675.       this.charAt = 0;
  676.       boolean var1 = false;
  677.  
  678.       while(this.lookahead != -1) {
  679.          this.chars[this.charAt++] = (char)this.lookahead;
  680.          if (this.lookahead == 93) {
  681.             this.advance();
  682.             if (this.lookahead == 93) {
  683.                this.advance();
  684.                if (this.lookahead == 62) {
  685.                   this.charAt += -1;
  686.                   var1 = true;
  687.                } else {
  688.                   this.reader.push((char)this.lookahead);
  689.                   this.reader.push((char)this.lookahead);
  690.                   this.lookahead = 93;
  691.                }
  692.             }
  693.          } else {
  694.             this.advance();
  695.          }
  696.  
  697.          if (this.charAt == this.chars.length || var1) {
  698.             Element var2 = this.factory.createElement(6, nameCDATA);
  699.             this.current.e.addChild(var2, (Element)null);
  700.             var2.setText(new String(this.chars, 0, this.charAt));
  701.             this.charAt = 0;
  702.             if (var1) {
  703.                break;
  704.             }
  705.          }
  706.       }
  707.  
  708.       this.parseToken(62, "CDATA end");
  709.    }
  710.  
  711.    private final void setFactory(ElementFactory var1) {
  712.       this.factory = var1;
  713.    }
  714.  
  715.    final void scanText(int var1, int var2, boolean var3) throws ParseException {
  716.       this.charAt = 0;
  717.       boolean var4 = false;
  718.  
  719.       while(this.lookahead != -1 && this.lookahead != 60 && this.lookahead != this.breakText && this.charAt < this.chars.length) {
  720.          if (this.lookahead == var2) {
  721.             if (var4) {
  722.                this.chars[this.charAt++] = ' ';
  723.                var4 = false;
  724.             }
  725.  
  726.             this.advance();
  727.             if (this.lookahead == 35) {
  728.                this.scanCharRef();
  729.             } else if (isNameChar((char)this.lookahead)) {
  730.                this.scanEntityRef(false);
  731.             } else {
  732.                this.chars[this.charAt++] = (char)var2;
  733.             }
  734.          } else if (this.lookahead == var1) {
  735.             if (var4) {
  736.                this.chars[this.charAt++] = ' ';
  737.                var4 = false;
  738.             }
  739.  
  740.             this.advance();
  741.             if (isNameChar((char)this.lookahead)) {
  742.                this.scanEntityRef(var1 == 37);
  743.             } else {
  744.                this.chars[this.charAt++] = (char)var2;
  745.             }
  746.          } else {
  747.             if (var3 && isWhiteSpaceChar((char)this.lookahead)) {
  748.                var4 = true;
  749.             } else {
  750.                if (var4) {
  751.                   this.chars[this.charAt++] = ' ';
  752.                   var4 = false;
  753.                }
  754.  
  755.                this.chars[this.charAt++] = (char)this.lookahead;
  756.             }
  757.  
  758.             this.advance();
  759.          }
  760.       }
  761.  
  762.       this.text = new String(this.chars, 0, this.charAt);
  763.       this.token = -5;
  764.    }
  765.  
  766.    final void pop() {
  767.       this.current = (Context)this.contexts.pop();
  768.    }
  769.  
  770.    final void tryMisc() throws ParseException {
  771.       while(true) {
  772.          switch (this.token) {
  773.             case -11:
  774.                this.parseComment();
  775.                break;
  776.             case -10:
  777.             case -9:
  778.             case -8:
  779.             case -7:
  780.             default:
  781.                return;
  782.             case -6:
  783.                this.parsePI(true);
  784.          }
  785.  
  786.          if (this.lookahead == -1) {
  787.             this.token = -1;
  788.             return;
  789.          }
  790.  
  791.          this.nextToken();
  792.       }
  793.    }
  794.  
  795.    final int nextToken() throws ParseException {
  796.       if (this.inTag || !this.current.preserveWS) {
  797.          while(isWhiteSpaceChar((char)this.lookahead)) {
  798.             this.advance();
  799.          }
  800.       }
  801.  
  802.       if (this.inTag) {
  803.          switch (this.lookahead) {
  804.             case -1:
  805.                this.token = -1;
  806.                break;
  807.             case 34:
  808.             case 39:
  809.                this.quote = (char)this.lookahead;
  810.                this.token = 39;
  811.                this.advance();
  812.                break;
  813.             case 35:
  814.             case 40:
  815.             case 41:
  816.             case 42:
  817.             case 43:
  818.             case 44:
  819.             case 61:
  820.             case 91:
  821.             case 93:
  822.             case 124:
  823.                this.token = this.lookahead;
  824.                this.advance();
  825.                break;
  826.             case 37:
  827.                this.advance();
  828.                if (this.substitution > 0 && isNameChar((char)this.lookahead)) {
  829.                   this.scanEntityRef(true);
  830.                   return this.nextToken();
  831.                }
  832.  
  833.                this.token = 37;
  834.                break;
  835.             case 47:
  836.                this.advance();
  837.                if (this.lookahead == 62) {
  838.                   this.token = -10;
  839.                   this.inTag = false;
  840.                   this.advance();
  841.                }
  842.                break;
  843.             case 62:
  844.                this.token = 62;
  845.                this.inTag = false;
  846.                this.advance();
  847.                break;
  848.             case 63:
  849.                this.advance();
  850.                if (this.current.e.getType() == 9) {
  851.                   this.token = 63;
  852.                } else if (this.lookahead == 62) {
  853.                   this.token = -7;
  854.                   this.inTag = false;
  855.                   this.advance();
  856.                } else {
  857.                   this.token = 63;
  858.                }
  859.                break;
  860.             default:
  861.                if (!isNameChar((char)this.lookahead) && !isNameSpaceSeparatorChar((char)this.lookahead)) {
  862.                   this.error("Unexpected token '" + (char)this.lookahead + "' inside tag <" + this.current.e.getTagName() + ">");
  863.                } else {
  864.                   this.scanName("name");
  865.                   if (this.keyword > 0) {
  866.                      if (this.name instanceof QualifiedName) {
  867.                         this.token = this.lookup(((QualifiedName)this.name).getName());
  868.                      } else {
  869.                         this.token = this.lookup(this.name);
  870.                      }
  871.                   }
  872.                }
  873.          }
  874.       } else {
  875.          switch (this.lookahead) {
  876.             case -1:
  877.                this.token = -1;
  878.                break;
  879.             case 60:
  880.                this.inTag = true;
  881.                this.advance();
  882.                switch (this.lookahead) {
  883.                   case 33:
  884.                      this.token = -8;
  885.                      this.advance();
  886.                      if (this.lookahead == 45) {
  887.                         this.advance();
  888.                         if (this.lookahead == 45) {
  889.                            this.token = -11;
  890.                            this.advance();
  891.                         } else {
  892.                            this.error("Bad comment start syntax.  Expected '<!--'");
  893.                         }
  894.  
  895.                         return this.token;
  896.                      } else {
  897.                         if (this.lookahead == 91) {
  898.                            if (this.match(nameCDATA.toString())) {
  899.                               this.token = -14;
  900.                            } else {
  901.                               this.error("Bad start tag: <![");
  902.                            }
  903.  
  904.                            return this.token;
  905.                         }
  906.  
  907.                         return this.token;
  908.                      }
  909.                   case 47:
  910.                      this.token = -9;
  911.                      this.advance();
  912.                      return this.token;
  913.                   case 63:
  914.                      this.token = -6;
  915.                      this.advance();
  916.                      return this.token;
  917.                   default:
  918.                      this.token = 60;
  919.                      return this.token;
  920.                }
  921.             case 93:
  922.                if (this.breakText == this.lookahead) {
  923.                   this.token = 93;
  924.                   this.advance();
  925.                   break;
  926.                }
  927.             default:
  928.                this.token = -5;
  929.          }
  930.       }
  931.  
  932.       return this.token;
  933.    }
  934.  
  935.    final void parseInternalSubset() throws ParseException {
  936.       ++this.substitution;
  937.  
  938.       while(true) {
  939.          switch (this.nextToken()) {
  940.             case -37:
  941.             case -35:
  942.                this.error("Conditional sections are not processed !");
  943.                break;
  944.             case -11:
  945.                this.parseComment();
  946.                break;
  947.             case -8:
  948.                this.parseKeyword(0, "ENTITY|...");
  949.                switch (this.token) {
  950.                   case -28:
  951.                      this.parseNotation();
  952.                      continue;
  953.                   case -24:
  954.                      this.parseEntityDecl();
  955.                      continue;
  956.                   case -19:
  957.                      this.parseAttListDecl();
  958.                      continue;
  959.                   case -15:
  960.                      this.parseElementDecl();
  961.                      continue;
  962.                   default:
  963.                      this.error("Unknown DTD keyword " + this.name);
  964.                      continue;
  965.                }
  966.             case -6:
  967.                this.parsePI(true);
  968.                break;
  969.             case -5:
  970.                if (this.lookahead != 37) {
  971.                   this.substitution += -1;
  972.                   return;
  973.                }
  974.  
  975.                this.advance();
  976.                this.scanEntityRef(true);
  977.                break;
  978.             default:
  979.                this.substitution += -1;
  980.                return;
  981.          }
  982.       }
  983.    }
  984.  
  985.    final String tokenString(int var1) {
  986.       return this.tokenString(var1, (String)null);
  987.    }
  988.  
  989.    final String tokenString(int var1, String var2) {
  990.       switch (var1) {
  991.          case -100:
  992.             return "PUBLIC";
  993.          case -38:
  994.             return "NAMESPACE";
  995.          case -37:
  996.             return "IGNORETAGSTART";
  997.          case -36:
  998.             return "IGNORE";
  999.          case -35:
  1000.             return "INCLUDETAGSTART";
  1001.          case -34:
  1002.             return "INCLUDE";
  1003.          case -33:
  1004.             return "NDATA";
  1005.          case -32:
  1006.             return "IMPLIED";
  1007.          case -31:
  1008.             return "REQUIRED";
  1009.          case -30:
  1010.             return "FIXED";
  1011.          case -29:
  1012.             return "ENUMERATION";
  1013.          case -28:
  1014.             return "NOTATION";
  1015.          case -27:
  1016.             return "NMTOKENS";
  1017.          case -26:
  1018.             return "NMTOKEN";
  1019.          case -25:
  1020.             return "ENTITIES";
  1021.          case -24:
  1022.             return "ENTITY";
  1023.          case -23:
  1024.             return "IDREFS";
  1025.          case -22:
  1026.             return "IDREF";
  1027.          case -21:
  1028.             return "ID";
  1029.          case -20:
  1030.             return "CDATA";
  1031.          case -19:
  1032.             return "ATTLIST";
  1033.          case -18:
  1034.             return "PCDATA";
  1035.          case -17:
  1036.             return "ANY";
  1037.          case -16:
  1038.             return "EMPTY";
  1039.          case -15:
  1040.             return "ELEMENT";
  1041.          case -14:
  1042.             return "<![CDATA";
  1043.          case -13:
  1044.             return "SYSTEM";
  1045.          case -12:
  1046.             return "DOCTYPE";
  1047.          case -11:
  1048.             return "<!--";
  1049.          case -10:
  1050.             return "/>";
  1051.          case -9:
  1052.             return "</";
  1053.          case -8:
  1054.             return "<!";
  1055.          case -7:
  1056.             return "?>";
  1057.          case -6:
  1058.             return "<?";
  1059.          case -5:
  1060.             return "TEXT '" + this.text + "'";
  1061.          case -4:
  1062.             if (var2 != null) {
  1063.                return var2;
  1064.             }
  1065.  
  1066.             return "NAME '" + this.name + "'";
  1067.          case -3:
  1068.             return "word character";
  1069.          case -2:
  1070.             return "whitespace";
  1071.          case -1:
  1072.             return "EOF";
  1073.          case 0:
  1074.             return "invalidtoken";
  1075.          case 33:
  1076.             return "!";
  1077.          case 35:
  1078.             return "#";
  1079.          case 37:
  1080.             return "percent(%)";
  1081.          case 38:
  1082.             return "&";
  1083.          case 39:
  1084.             return "quote(' or \")";
  1085.          case 40:
  1086.             return "(";
  1087.          case 41:
  1088.             return ")";
  1089.          case 42:
  1090.             return "*";
  1091.          case 43:
  1092.             return "+";
  1093.          case 44:
  1094.             return ",";
  1095.          case 45:
  1096.             return "-";
  1097.          case 47:
  1098.             return "/";
  1099.          case 60:
  1100.             return "start tag(<)";
  1101.          case 61:
  1102.             return "=";
  1103.          case 62:
  1104.             return "tag end(>)";
  1105.          case 63:
  1106.             return "question mark(?)";
  1107.          case 91:
  1108.             return "[";
  1109.          case 93:
  1110.             return "]";
  1111.          case 124:
  1112.             return "|";
  1113.          default:
  1114.             return var2;
  1115.       }
  1116.    }
  1117.  
  1118.    final void loadExternalDTD(String var1, Name var2) throws ParseException {
  1119.       try {
  1120.          URL var3 = new URL(this.url, var1);
  1121.          Parser var4 = new Parser();
  1122.          var4.dtd = this.dtd;
  1123.          var4.setURL(var3);
  1124.          var4.setFactory(this.factory);
  1125.          Element var5 = this.factory.createElement(0, QualifiedName.create(nameDOCTYPE, nameXML));
  1126.          var4.current = new Context(var5, false, var2, this.current.spaceTable);
  1127.          var4.parseInternalSubset();
  1128.       } catch (IOException var6) {
  1129.          this.error("Couldn't find external DTD '" + var1 + "'");
  1130.       }
  1131.    }
  1132.  
  1133.    final Element parseComment() throws ParseException {
  1134.       Element var1 = this.factory.createElement(2, nameComment);
  1135.       this.current.e.addChild(var1, (Element)null);
  1136.       this.charAt = 0;
  1137.       boolean var2 = false;
  1138.  
  1139.       while(this.lookahead != -1) {
  1140.          this.chars[this.charAt++] = (char)this.lookahead;
  1141.          if (this.lookahead == 45) {
  1142.             this.advance();
  1143.             if (this.lookahead == 45) {
  1144.                this.advance();
  1145.                if (this.lookahead == 62) {
  1146.                   this.charAt += -1;
  1147.                   var2 = true;
  1148.                } else {
  1149.                   this.reader.push((char)this.lookahead);
  1150.                   this.lookahead = 45;
  1151.                }
  1152.             }
  1153.          } else {
  1154.             this.advance();
  1155.          }
  1156.  
  1157.          if (this.charAt == this.chars.length || var2) {
  1158.             Element var3 = this.factory.createElement(6, (Name)null);
  1159.             var1.addChild(var3, (Element)null);
  1160.             var3.setText(new String(this.chars, 0, this.charAt));
  1161.             this.charAt = 0;
  1162.             if (var2) {
  1163.                break;
  1164.             }
  1165.          }
  1166.       }
  1167.  
  1168.       this.parseToken(62, "comment end");
  1169.       return var1;
  1170.    }
  1171.  
  1172.    final void parseKeyword(int var1, String var2) throws ParseException {
  1173.       ++this.keyword;
  1174.       if (var1 == 0) {
  1175.          this.nextToken();
  1176.       } else {
  1177.          this.parseToken(var1, var2);
  1178.       }
  1179.  
  1180.       this.keyword += -1;
  1181.    }
  1182.  
  1183.    private void reportMismatch(int var1) throws ParseException {
  1184.       String var2 = null;
  1185.       if (this.current.ed == null) {
  1186.          this.error("Content mismatch. Stoped at state " + var1);
  1187.       }
  1188.  
  1189.       Vector var3 = this.current.ed.expectedElements(var1);
  1190.       int var4 = 0;
  1191.       Enumeration var5 = var3.elements();
  1192.  
  1193.       while(var5.hasMoreElements()) {
  1194.          ++var4;
  1195.          if (var2 == null) {
  1196.             var2 = new String("'" + ((Name)var5.nextElement()).toString() + "'");
  1197.          } else if (var4 > 1 && var4 == var3.size()) {
  1198.             var2 = new String(var2 + ", or '" + ((Name)var5.nextElement()).toString() + "'");
  1199.          } else {
  1200.             var2 = new String(var2 + ", '" + ((Name)var5.nextElement()).toString() + "'");
  1201.          }
  1202.       }
  1203.  
  1204.       this.error("Content mismatch. Expected " + var2);
  1205.    }
  1206.  
  1207.    final int scanSimpleName(int var1, String var2) throws ParseException {
  1208.       boolean var3;
  1209.       if (this.lookahead < 256) {
  1210.          var3 = (chartype[this.lookahead] & 20) != 0;
  1211.       } else {
  1212.          var3 = Character.isLetter((char)this.lookahead) || this.lookahead == 95;
  1213.       }
  1214.  
  1215.       if (!var3 && (this.nametoken <= 0 || !Character.isDigit((char)this.lookahead))) {
  1216.          this.error("Expecting " + var2 + " instead of '" + (char)this.lookahead + "'");
  1217.       }
  1218.  
  1219.       this.buf[var1++] = this.toUpperCase((char)this.lookahead);
  1220.       this.advance();
  1221.  
  1222.       while(isNameChar((char)this.lookahead)) {
  1223.          this.buf[var1++] = this.toUpperCase((char)this.lookahead);
  1224.          this.advance();
  1225.       }
  1226.  
  1227.       return var1;
  1228.    }
  1229.  
  1230.    final void parseEntityDecl() throws ParseException {
  1231.       boolean var1 = false;
  1232.       ++this.nouppercase;
  1233.       if (this.nextToken() == 37) {
  1234.          var1 = true;
  1235.          this.parseToken(-4, "Entity name");
  1236.       } else if (this.token != -4) {
  1237.          this.error("Expected entity name instead of " + this.tokenString(this.token));
  1238.       }
  1239.  
  1240.       this.nouppercase += -1;
  1241.       Entity var2 = this.dtd.findEntity(this.name);
  1242.       if (var2 != null) {
  1243.          System.err.println("Warning: Entity <" + this.name + "> already defined, using the first definition.");
  1244.       } else {
  1245.          var2 = new Entity(this.name, var1);
  1246.          this.dtd.addEntity(var2);
  1247.          if (this.internalSubset) {
  1248.             this.current.e.addChild(var2, (Element)null);
  1249.          }
  1250.       }
  1251.  
  1252.       this.push(var2);
  1253.       this.parseKeyword(0, "String or SYSTEM");
  1254.       if (this.token == -100) {
  1255.          this.parseKeyword(0, "String");
  1256.          if (this.token == 39) {
  1257.             this.expandNamedEntities = false;
  1258.             this.scanString(this.quote, 65535, 65535, 65535);
  1259.             this.expandNamedEntities = true;
  1260.             var2.pubid = this.text;
  1261.             this.token = -13;
  1262.          } else {
  1263.             this.error("Expected " + this.tokenString(39) + " instead of " + this.tokenString(this.token));
  1264.          }
  1265.       }
  1266.  
  1267.       switch (this.token) {
  1268.          case -13:
  1269.             var2.setURL(this.scanUrl());
  1270.             this.parseKeyword(0, "ndata");
  1271.             if (this.token == -33) {
  1272.                this.parseToken(-4, "ndata name");
  1273.                Notation var5 = this.dtd.findNotation(this.name);
  1274.                if (var5 == null) {
  1275.                   this.error("Notation: " + this.name + " has not been declared yet");
  1276.                }
  1277.  
  1278.                var2.setNDATA(this.name);
  1279.                this.nextToken();
  1280.             }
  1281.             break;
  1282.          case 39:
  1283.             int var3 = this.reader.line;
  1284.             int var4 = this.reader.column;
  1285.             this.expandNamedEntities = false;
  1286.             this.scanString(this.quote, 37, 38, 65535);
  1287.             this.expandNamedEntities = true;
  1288.             var2.setText(this.text);
  1289.             var2.setPosition(var3, var4);
  1290.             this.nextToken();
  1291.             break;
  1292.          default:
  1293.             this.error("Expected " + this.tokenString(39) + " or " + this.tokenString(-13) + " instead of " + this.tokenString(this.token));
  1294.       }
  1295.  
  1296.       this.checkToken(62, ">");
  1297.       this.pop();
  1298.    }
  1299.  
  1300.    final void push(Element var1) {
  1301.       this.contexts.push(this.current);
  1302.       this.current = new Context(var1, this.current.preserveWS, this.current.nameSpace, this.current.spaceTable);
  1303.    }
  1304.  
  1305.    final void checkToken(int var1, String var2) throws ParseException {
  1306.       if (this.token != var1) {
  1307.          this.error("Expected " + this.tokenString(var1, var2) + " instead of " + this.tokenString(this.token));
  1308.       }
  1309.  
  1310.    }
  1311.  
  1312.    final void scanString(int var1, int var2, int var3, int var4) throws ParseException {
  1313.       this.charAt = 0;
  1314.  
  1315.       while(this.lookahead != -1 && this.lookahead != var1) {
  1316.          if (this.lookahead == var4) {
  1317.             this.error("Illegal character in string " + (char)this.lookahead);
  1318.          } else if (this.lookahead == var3) {
  1319.             this.advance();
  1320.             if (this.lookahead == 35) {
  1321.                this.scanCharRef();
  1322.             } else if (isNameChar((char)this.lookahead)) {
  1323.                if (this.expandNamedEntities) {
  1324.                   this.scanEntityRef(false);
  1325.                } else {
  1326.                   this.chars[this.charAt++] = (char)var3;
  1327.                }
  1328.             } else {
  1329.                this.chars[this.charAt++] = (char)this.lookahead;
  1330.             }
  1331.          } else if (this.lookahead == var2) {
  1332.             this.advance();
  1333.             if (isNameChar((char)this.lookahead)) {
  1334.                if (this.expandNamedEntities) {
  1335.                   this.scanEntityRef(var2 == 37);
  1336.                } else {
  1337.                   this.chars[this.charAt++] = (char)var2;
  1338.                }
  1339.             } else {
  1340.                this.chars[this.charAt++] = (char)this.lookahead;
  1341.             }
  1342.          } else {
  1343.             this.chars[this.charAt++] = (char)this.lookahead;
  1344.             this.advance();
  1345.          }
  1346.       }
  1347.  
  1348.       if (this.lookahead == var1) {
  1349.          this.advance();
  1350.       } else {
  1351.          this.error("Unterminated string");
  1352.       }
  1353.  
  1354.       this.text = new String(this.chars, 0, this.charAt);
  1355.    }
  1356.  
  1357.    static {
  1358.       XMLDecl = new ElementDecl(nameXML);
  1359.       XMLDecl.addAttDef(new AttDef(nameVERSION, 0, "1.0", 3));
  1360.       XMLDecl.addAttDef(new AttDef(nameENCODING, 0, "UTF-8", 2));
  1361.       Vector var0 = new Vector(3);
  1362.       var0.addElement(nameNONE);
  1363.       var0.addElement(nameINTERNAL);
  1364.       var0.addElement(nameALL);
  1365.       XMLDecl.addAttDef(new AttDef(nameRMD, 9, (Name)var0.elementAt(0), 2, var0));
  1366.       tokens = new Hashtable();
  1367.       tokens.put(Name.create("DOCTYPE"), new Integer(-12));
  1368.       tokens.put(Name.create("SYSTEM"), new Integer(-13));
  1369.       tokens.put(Name.create("PUBLIC"), new Integer(-100));
  1370.       tokens.put(Name.create("ENTITY"), new Integer(-24));
  1371.       tokens.put(Name.create("ELEMENT"), new Integer(-15));
  1372.       tokens.put(Name.create("EMPTY"), new Integer(-16));
  1373.       tokens.put(Name.create("ANY"), new Integer(-17));
  1374.       tokens.put(Name.create("PCDATA"), new Integer(-18));
  1375.       tokens.put(Name.create("ATTLIST"), new Integer(-19));
  1376.       tokens.put(Name.create("CDATA"), new Integer(-20));
  1377.       tokens.put(Name.create("ID"), new Integer(-21));
  1378.       tokens.put(Name.create("IDREF"), new Integer(-22));
  1379.       tokens.put(Name.create("IDREFS"), new Integer(-23));
  1380.       tokens.put(Name.create("ENTITY"), new Integer(-24));
  1381.       tokens.put(Name.create("ENTITIES"), new Integer(-25));
  1382.       tokens.put(Name.create("NMTOKEN"), new Integer(-26));
  1383.       tokens.put(Name.create("NMTOKENS"), new Integer(-27));
  1384.       tokens.put(Name.create("FIXED"), new Integer(-30));
  1385.       tokens.put(Name.create("REQUIRED"), new Integer(-31));
  1386.       tokens.put(Name.create("IMPLIED"), new Integer(-32));
  1387.       tokens.put(Name.create("NDATA"), new Integer(-33));
  1388.       tokens.put(Name.create("NOTATION"), new Integer(-28));
  1389.       tokens.put(Name.create("INCLUDE"), new Integer(-34));
  1390.       tokens.put(Name.create("IGNORE"), new Integer(-36));
  1391.       tokens.put(QualifiedName.create(Name.create("NAMESPACE"), Name.create("XML")), new Integer(-38));
  1392.       int var1 = 0;
  1393.  
  1394.       do {
  1395.          char var2 = (char)var1;
  1396.          chartype[var1] = 0;
  1397.          if (jdk11 && Character.isWhitespace(var2) || Character.isSpace(var2) || var2 == '\r') {
  1398.             chartype[var1] = 1;
  1399.          }
  1400.  
  1401.          if (Character.isLetter(var2)) {
  1402.             int[] var10000 = chartype;
  1403.             var10000[var1] |= 4;
  1404.          }
  1405.  
  1406.          if (Character.isDigit(var2)) {
  1407.             int[] var3 = chartype;
  1408.             var3[var1] |= 2;
  1409.          }
  1410.  
  1411.          charupper[var1] = Character.toUpperCase(var2);
  1412.          ++var1;
  1413.       } while(var1 < 256);
  1414.  
  1415.       int[] var4 = chartype;
  1416.       var4[46] |= 8;
  1417.       var4 = chartype;
  1418.       var4[45] |= 8;
  1419.       var4 = chartype;
  1420.       var4[95] |= 24;
  1421.       var4 = chartype;
  1422.       var4[183] |= 8;
  1423.    }
  1424.  
  1425.    final void scanEntityRef(boolean var1) throws ParseException {
  1426.       ++this.nouppercase;
  1427.       ++this.inEntityRef;
  1428.       this.scanName("entity ref");
  1429.       this.inEntityRef += -1;
  1430.       this.nouppercase += -1;
  1431.       if (this.lookahead != 59) {
  1432.          this.error("Entity reference syntax error " + this.name);
  1433.       }
  1434.  
  1435.       Entity var2 = this.dtd.findEntity(this.name);
  1436.       if (var2 == null) {
  1437.          this.error("Missing entity '" + this.name + "' or RMD should not be 'NONE'.");
  1438.       }
  1439.  
  1440.       if (var1 != var2.par) {
  1441.          if (var1) {
  1442.             this.error("Entity '" + this.name + "' is not a parameter entity.");
  1443.          } else {
  1444.             this.error("Entity '" + this.name + "' is a parameter entity.");
  1445.          }
  1446.       }
  1447.  
  1448.       if (var1) {
  1449.          if (!this.inTag) {
  1450.             Element var3 = this.factory.createElement(11, this.name);
  1451.             this.current.e.addChild(var3, (Element)null);
  1452.          }
  1453.  
  1454.          if (var2.getURL() == null) {
  1455.             this.push(var2);
  1456.             this.reader = var2.getReader(this.reader);
  1457.          } else {
  1458.             if (var2.ndata != null) {
  1459.                this.error("Binary parameter entity " + this.name.toString() + "cannot be used in DTD");
  1460.             }
  1461.  
  1462.             if (this.rmd == RMD_ALL) {
  1463.                this.loadExternalDTD(var2.getURL(), this.current.defaultNameSpace);
  1464.             }
  1465.          }
  1466.       } else if (var2.getLength() == -1) {
  1467.          this.lookahead = this.chars[this.charAt++] = var2.getChar(0);
  1468.       } else {
  1469.          if (!this.inTag) {
  1470.             this.text = new String(this.chars, 0, this.charAt);
  1471.             this.addPCDATA(this.text);
  1472.             this.charAt = 0;
  1473.             Element var5 = this.factory.createElement(11, this.name);
  1474.             this.current.e.addChild(var5, (Element)null);
  1475.          }
  1476.  
  1477.          if (!var2.parsed) {
  1478.             if (var2.getURL() == null) {
  1479.                var2.parsed = true;
  1480.                this.push(var2);
  1481.                this.reader = var2.getReader(this.reader);
  1482.             } else if (var2.ndata == null && this.rmd == RMD_ALL) {
  1483.                var2.parsed = true;
  1484.                this.push(var2);
  1485.  
  1486.                try {
  1487.                   URL var6 = new URL(this.url, var2.getURL());
  1488.                   this.reader = new EntityReader(var6.openStream(), this.reader.line, this.reader.column, this.reader, var2);
  1489.                } catch (Exception var4) {
  1490.                   this.error("Cannot load external text entity: " + this.name.toString());
  1491.                }
  1492.             }
  1493.          }
  1494.       }
  1495.  
  1496.       this.advance();
  1497.    }
  1498.  
  1499.    final Element parsePI(boolean var1) throws ParseException {
  1500.       this.scanName("PI name");
  1501.       if (this.name == nameXML) {
  1502.          this.error("An XML declaration can only appear in the beginning of the document.");
  1503.       } else if (this.name == nameXMLNameSpace) {
  1504.          return this.parseNameSpaceDecl(var1, true);
  1505.       }
  1506.  
  1507.       return this.finishPI();
  1508.    }
  1509.  
  1510.    final Element parseText(int var1, int var2) throws ParseException {
  1511.       this.scanText(var1, var2, !this.current.preserveWS);
  1512.       return this.addPCDATA(this.text);
  1513.    }
  1514.  
  1515.    final void tryDocTypeDecl() throws ParseException {
  1516.       if (this.token == -8) {
  1517.          this.parseKeyword(-12, "Doctype");
  1518.          Element var1 = this.factory.createElement(4, nameDOCTYPE);
  1519.          this.current.e.addChild(var1, (Element)null);
  1520.          this.parseToken(-4, "Doctype name");
  1521.          this.docType = this.name;
  1522.          var1.setAttribute(nameNAME, this.docType.toString());
  1523.          this.parseKeyword(0, "ExternalID");
  1524.          switch (this.token) {
  1525.             case -100:
  1526.                this.parseKeyword(0, "String");
  1527.                if (this.token == 39) {
  1528.                   this.expandNamedEntities = false;
  1529.                   this.scanString(this.quote, 65535, 65535, 65535);
  1530.                   this.expandNamedEntities = true;
  1531.                   var1.setAttribute(namePUBLICID, this.text);
  1532.                } else {
  1533.                   this.error("Expected " + this.tokenString(39) + " instead of " + this.tokenString(this.token));
  1534.                }
  1535.  
  1536.                var1.setAttribute(nameURL, this.scanUrl());
  1537.                this.nextToken();
  1538.                break;
  1539.             case -13:
  1540.                var1.setAttribute(nameURL, this.scanUrl());
  1541.                this.nextToken();
  1542.          }
  1543.  
  1544.          if (this.token == 91) {
  1545.             this.inTag = false;
  1546.             this.breakText = 93;
  1547.             this.internalSubset = true;
  1548.             this.push(var1);
  1549.             this.parseInternalSubset();
  1550.             if (this.token != 93) {
  1551.                this.error("Expected " + this.tokenString(93));
  1552.             }
  1553.  
  1554.             if (this.rmd == RMD_NONE) {
  1555.                this.dtd.clear();
  1556.             }
  1557.  
  1558.             this.inTag = true;
  1559.             this.internalSubset = false;
  1560.             this.breakText = 0;
  1561.             this.pop();
  1562.             this.nextToken();
  1563.          }
  1564.  
  1565.          Object var2 = var1.getAttribute(nameURL);
  1566.          if (var2 != null && this.rmd == RMD_ALL) {
  1567.             this.loadExternalDTD(var2.toString(), (Name)null);
  1568.          }
  1569.  
  1570.          if (this.token != 62) {
  1571.             this.error("Expected " + this.tokenString(62) + " instead of " + this.tokenString(this.token));
  1572.          }
  1573.  
  1574.          if (this.lookahead != -1) {
  1575.             this.nextToken();
  1576.          }
  1577.       }
  1578.  
  1579.    }
  1580.  
  1581.    final void parseElementDecl() throws ParseException {
  1582.       Vector var1 = new Vector();
  1583.       this.nextToken();
  1584.       ElementDecl var2 = this.createElementDecl(var1);
  1585.       if (this.internalSubset) {
  1586.          this.current.e.addChild(var2, (Element)null);
  1587.       }
  1588.  
  1589.       this.push(var2);
  1590.       var2.parseModel(this);
  1591.       this.checkToken(62, ">");
  1592.       this.pop();
  1593.    }
  1594.  
  1595.    final void parseNotation() throws ParseException {
  1596.       this.parseToken(-4, "Notation name");
  1597.       Notation var1 = this.dtd.findNotation(this.name);
  1598.       if (var1 != null) {
  1599.          this.error("Notation already declared " + this.name);
  1600.       }
  1601.  
  1602.       var1 = new Notation(this.name);
  1603.       this.dtd.addNotation(var1);
  1604.       if (this.internalSubset) {
  1605.          this.current.e.addChild(var1, (Element)null);
  1606.       }
  1607.  
  1608.       this.push(var1);
  1609.       this.parseKeyword(0, "SYSTEM or PUBLIC");
  1610.       if (this.token != -13 && this.token != -100) {
  1611.          this.error("Expected " + this.tokenString(-13) + " or " + this.tokenString(-100) + " instead of " + this.tokenString(this.token));
  1612.       }
  1613.  
  1614.       var1.type = this.token;
  1615.       if (var1.type == -100) {
  1616.          this.parseKeyword(0, "String");
  1617.          if (this.token == 39) {
  1618.             this.expandNamedEntities = false;
  1619.             this.scanString(this.quote, 65535, 65535, 65535);
  1620.             this.expandNamedEntities = true;
  1621.             var1.pubid = this.text;
  1622.          } else {
  1623.             this.error("Expected " + this.tokenString(39) + " instead of " + this.tokenString(this.token));
  1624.          }
  1625.       }
  1626.  
  1627.       var1.setURL(this.scanUrl());
  1628.       this.parseToken(62, ">");
  1629.       this.pop();
  1630.    }
  1631.  
  1632.    private final void setURL(URL var1) throws ParseException {
  1633.       this.url = var1;
  1634.  
  1635.       InputStream var2;
  1636.       try {
  1637.          var2 = var1.openStream();
  1638.       } catch (IOException var5) {
  1639.          throw new ParseException("Error opening input stream for \"" + this.url.toString() + "\": " + ((Throwable)var5).toString());
  1640.       }
  1641.  
  1642.       this.setInputStream(new BufferedInputStream(var2));
  1643.    }
  1644.  
  1645.    final int lookup(Name var1) {
  1646.       Object var2 = tokens.get(var1);
  1647.       if (var2 != null) {
  1648.          this.token = (Integer)var2;
  1649.       } else {
  1650.          this.token = -4;
  1651.       }
  1652.  
  1653.       return this.token;
  1654.    }
  1655.  
  1656.    final void parseToken(int var1, String var2) throws ParseException {
  1657.       if (this.nextToken() != var1) {
  1658.          this.error("Expected " + this.tokenString(var1, var2) + " instead of " + this.tokenString(this.token));
  1659.       }
  1660.  
  1661.    }
  1662.  
  1663.    final void parseElement() throws ParseException {
  1664.       boolean var1 = false;
  1665.  
  1666.       while(true) {
  1667.          if (var1 && this.token != -9) {
  1668.             this.error("Expected " + this.tokenString(-9) + " instead of " + this.tokenString(this.token));
  1669.          }
  1670.  
  1671.          var1 = false;
  1672.          switch (this.token) {
  1673.             case -14:
  1674.                this.parseCDATA();
  1675.                break;
  1676.             case -11:
  1677.                this.parseComment();
  1678.                break;
  1679.             case -9:
  1680.                if (!this.current.matched) {
  1681.                   this.reportMismatch(this.current.state);
  1682.                }
  1683.  
  1684.                if (this.lookahead != 62) {
  1685.                   if (this.lookahead == 47) {
  1686.                      this.advance();
  1687.                   } else {
  1688.                      this.scanName("element close tag");
  1689.                      if (this.name != this.current.e.getTagName()) {
  1690.                         this.error("Close tag " + this.name + " does not match start tag " + this.current.e.getTagName());
  1691.                      }
  1692.                   }
  1693.                }
  1694.  
  1695.                this.parseToken(62, ">");
  1696.                this.factory.parsed(this.current.e);
  1697.                this.pop();
  1698.                break;
  1699.             case -6:
  1700.                this.parsePI(false);
  1701.                break;
  1702.             case -5:
  1703.                this.parseText(38, 38);
  1704.                break;
  1705.             case -1:
  1706.                if (this.contexts.size() == 1) {
  1707.                   this.error("Expected the end of root element instead of end of file.");
  1708.                   break;
  1709.                }
  1710.             default:
  1711.                this.error("Bad token in element content: " + this.tokenString(this.token));
  1712.                break;
  1713.             case 60:
  1714.                this.scanName("element tag");
  1715.                if (this.lookup(this.name) == -38) {
  1716.                   this.parseNameSpaceDecl(false, false);
  1717.                } else {
  1718.                   ElementDecl var2 = this.dtd.findElementDecl(this.name);
  1719.                   Element var3 = this.factory.createElement(0, this.name);
  1720.                   if (this.current.ed != null) {
  1721.                      this.current.ed.checkContent(this.current, var3, this);
  1722.                   }
  1723.  
  1724.                   this.current.e.addChild(var3, (Element)null);
  1725.                   this.push(var3);
  1726.                   if (var2 != null) {
  1727.                      if (var2.getContent().type == 1) {
  1728.                         var1 = true;
  1729.                      }
  1730.  
  1731.                      var2.initContent(this.current, this);
  1732.                   } else {
  1733.                      this.current.matched = true;
  1734.                   }
  1735.  
  1736.                   this.parseAttributes(var3);
  1737.                   if (this.token == -10) {
  1738.                      if (var2 != null && !var2.acceptEmpty()) {
  1739.                         this.reportMismatch(0);
  1740.                      }
  1741.  
  1742.                      this.factory.parsed(this.current.e);
  1743.                      this.pop();
  1744.                      var1 = false;
  1745.                   } else if (this.token != 62) {
  1746.                      this.error("Expected " + this.tokenString(62) + " instead of " + this.tokenString(this.token));
  1747.                   } else if (this.lookahead != 60 && var1) {
  1748.                      this.error("Expected " + this.tokenString(62) + " instead of '" + (char)this.lookahead + "'");
  1749.                   }
  1750.                }
  1751.          }
  1752.  
  1753.          if (this.contexts.size() == 0) {
  1754.             return;
  1755.          }
  1756.  
  1757.          this.nextToken();
  1758.       }
  1759.    }
  1760.  
  1761.    final void parseRootElement() throws ParseException {
  1762.       if (this.token != 60) {
  1763.          this.error("Start of root element expected instead of " + this.tokenString(this.token));
  1764.       }
  1765.  
  1766.       this.scanName("element tag");
  1767.       if (this.docType != null) {
  1768.          Name var1 = this.name;
  1769.          if (this.name instanceof QualifiedName) {
  1770.             var1 = ((QualifiedName)this.name).getName();
  1771.          }
  1772.  
  1773.          if (var1 != this.docType) {
  1774.             this.error("Root element name must match the DOCTYPE name");
  1775.          }
  1776.       }
  1777.  
  1778.       if (this.lookup(this.name) == -38) {
  1779.          this.parseNameSpaceDecl(false, false);
  1780.       } else {
  1781.          ElementDecl var4 = this.dtd.findElementDecl(this.name);
  1782.          Element var2 = this.factory.createElement(0, this.name);
  1783.          this.current.e.addChild(var2, (Element)null);
  1784.          this.push(var2);
  1785.          boolean var3 = false;
  1786.          if (var4 != null) {
  1787.             if (var4.getContent().type == 1) {
  1788.                var3 = true;
  1789.             }
  1790.  
  1791.             var4.initContent(this.current, this);
  1792.          } else {
  1793.             this.current.matched = true;
  1794.          }
  1795.  
  1796.          this.parseAttributes(var2);
  1797.          if (this.token == -10) {
  1798.             if (var4 != null && !var4.acceptEmpty()) {
  1799.                this.reportMismatch(0);
  1800.             }
  1801.  
  1802.             var3 = true;
  1803.          } else if (this.token != 62) {
  1804.             if (var2.getAttributes() == EnumWrapper.emptyEnumeration) {
  1805.                this.error("No attribute is declared for element '" + var2.getTagName() + "', expected " + this.tokenString(62));
  1806.             }
  1807.  
  1808.             this.error("Expected " + this.tokenString(62) + " instead of " + this.tokenString(this.token));
  1809.          }
  1810.  
  1811.          if (var3) {
  1812.             this.pop();
  1813.             this.nextToken();
  1814.          } else {
  1815.             this.nextToken();
  1816.             this.parseElement();
  1817.          }
  1818.       }
  1819.    }
  1820.  
  1821.    final void parseContent(Element var1) throws ParseException {
  1822.       while(this.nextToken() != -9) {
  1823.          switch (this.token) {
  1824.             case -14:
  1825.                this.parseCDATA();
  1826.                break;
  1827.             case -11:
  1828.                this.parseComment();
  1829.                break;
  1830.             case -8:
  1831.                this.parseElement();
  1832.                break;
  1833.             case -6:
  1834.                this.parsePI(false);
  1835.                break;
  1836.             case -5:
  1837.                this.parseText(38, 38);
  1838.                break;
  1839.             case 60:
  1840.                this.parseElement();
  1841.                break;
  1842.             default:
  1843.                this.error("Bad token in element content: " + this.tokenString(this.token));
  1844.          }
  1845.       }
  1846.  
  1847.       if (!this.current.matched) {
  1848.          this.error("Content mismatch, stopped at state " + this.current.state);
  1849.       }
  1850.  
  1851.       if (this.lookahead != 62) {
  1852.          this.scanName("element close tag");
  1853.          if (this.name != this.current.e.getTagName()) {
  1854.             this.error("Close tag mismatch: " + this.name + " instead of " + this.current.e.getTagName());
  1855.          }
  1856.       }
  1857.  
  1858.       this.parseToken(62, ">");
  1859.    }
  1860.  
  1861.    final void error(String var1) throws ParseException {
  1862.       int var2 = 1;
  1863.       if (this.token == -4) {
  1864.          var2 = this.name.toString().length();
  1865.       }
  1866.  
  1867.       throw new ParseException(var1, this.reader.line, this.reader.column - 1 - var2, this.reader.owner);
  1868.    }
  1869.  
  1870.    final void scanName(String var1) throws ParseException {
  1871.       Name var2 = null;
  1872.       Name var3 = null;
  1873.       boolean var4 = false;
  1874.       if (this.nameappend == 0) {
  1875.          this.bufAt = 0;
  1876.       }
  1877.  
  1878.       int var5 = this.bufAt;
  1879.       if (!isNameSpaceSeparatorChar((char)this.lookahead)) {
  1880.          this.bufAt = this.scanSimpleName(this.bufAt, var1);
  1881.          var4 = true;
  1882.       }
  1883.  
  1884.       if (this.nametoken == 0 && this.simplename == 0 && isNameSpaceSeparatorChar((char)this.lookahead)) {
  1885.          ++this.bufAt;
  1886.          this.advance();
  1887.          if (isNameSpaceSeparatorChar((char)this.lookahead)) {
  1888.             ++this.bufAt;
  1889.             this.advance();
  1890.             if (var4) {
  1891.                var2 = Name.create((new String(this.buf, var5, this.bufAt - var5 - 2)).toUpperCase());
  1892.                if (DTD.isReservedNameSpace(var2)) {
  1893.                   var3 = var2;
  1894.                } else {
  1895.                   var3 = this.current.findNameSpace(var2);
  1896.                   if (var3 == null) {
  1897.                      var3 = this.dtd.findLongNameSpace(var2);
  1898.                      if (var3 == null) {
  1899.                         this.error("Missing name space '" + var2 + "'");
  1900.                      }
  1901.                   }
  1902.                }
  1903.             }
  1904.  
  1905.             var5 = this.bufAt;
  1906.             this.bufAt = this.scanSimpleName(this.bufAt, var1);
  1907.             var2 = Name.create(new String(this.buf, var5, this.bufAt - var5));
  1908.          } else {
  1909.             this.error("Expecting namespace separator ':' instead of '" + (char)this.lookahead + "'");
  1910.          }
  1911.       } else {
  1912.          if (this.nametoken == 0 && this.simplename == 0) {
  1913.             var3 = this.current.defaultNameSpace;
  1914.          }
  1915.  
  1916.          var2 = Name.create(new String(this.buf, var5, this.bufAt - var5));
  1917.       }
  1918.  
  1919.       if (this.nametoken == 0 && this.simplename == 0) {
  1920.          this.current.nameSpace = var3;
  1921.       }
  1922.  
  1923.       if ((this.keyword <= 0 || this.inEntityRef != 0) && var3 != null) {
  1924.          this.name = QualifiedName.create(var2, var3);
  1925.       } else {
  1926.          this.name = var2;
  1927.       }
  1928.  
  1929.       this.token = -4;
  1930.    }
  1931. }
  1932.