home *** CD-ROM | disk | FTP | other *** search
- package com.ms.xml.parser;
-
- import com.ms.xml.om.Element;
- import com.ms.xml.om.ElementImpl;
- import com.ms.xml.util.Atom;
- import com.ms.xml.util.Name;
- import com.ms.xml.util.XMLOutputStream;
- import java.io.IOException;
- import java.util.BitSet;
- import java.util.Enumeration;
- import java.util.Hashtable;
- import java.util.Vector;
-
- public class ContentModel {
- Node content;
- Terminal end;
- Vector terminalnodes;
- Hashtable symboltable;
- Vector symbols;
- Vector Dtrans;
- public static final byte EMPTY = 1;
- public static final byte ANY = 2;
- public static final byte ELEMENTS = 4;
- byte type;
- static Name nameEMPTY = Name.create("EMPTY", "XML");
- static Name nameANY = Name.create("ANY", "XML");
-
- final Node parseList(Parser var1) throws ParseException {
- Hashtable var2 = new Hashtable();
- var2.put(var1.name, var1.name);
- Object var3 = this.parseNode(var1);
- int var4 = var1.token;
- switch (var1.token) {
- case 41:
- return (Node)var3;
- case 44:
- var1.nextToken();
- var3 = new Sequence((Node)var3, this.parseNode(var1));
- break;
- case 124:
- var1.nextToken();
- if (var1.token == -4) {
- if (var2.contains(var1.name)) {
- var1.error("Warning: Repeated element in content model: " + var1.name);
- } else {
- var2.put(var1.name, var1.name);
- }
- }
-
- var3 = new Choice((Node)var3, this.parseNode(var1));
- break;
- default:
- var1.error("Illegal token in content model: " + var1.tokenString(var1.token));
- }
-
- while(var1.token != 41) {
- if (var4 == 44 && var1.token == 44) {
- var1.nextToken();
- var3 = new Sequence((Node)var3, this.parseNode(var1));
- } else if (var4 == 124 && var1.token == 124) {
- var1.nextToken();
- if (var1.token == -4) {
- if (var2.contains(var1.name)) {
- var1.error("Repeated element in content model: " + var1.name);
- } else {
- var2.put(var1.name, var1.name);
- }
- }
-
- var3 = new Choice((Node)var3, this.parseNode(var1));
- } else {
- var1.error("Illegal token in content model: " + var1.tokenString(var1.token));
- }
- }
-
- return (Node)var3;
- }
-
- public String toString() {
- String var1;
- switch (this.type) {
- case 1:
- var1 = "EMPTY";
- break;
- case 2:
- var1 = "ANY";
- break;
- case 3:
- default:
- var1 = "*UNKNOWN*";
- break;
- case 4:
- var1 = "ELEMENTS";
- }
-
- return "Content: type=" + var1;
- }
-
- final boolean checkContent(Context var1, Element var2, Parser var3) throws ParseException {
- if (this.type == 2) {
- var1.matched = true;
- return true;
- } else {
- Object var4 = null;
- Name var8;
- if (var2.getType() == 11) {
- Entity var5 = var3.dtd.findEntity(var2.getTagName());
- if (var5.getLength() != -1) {
- return true;
- }
-
- var8 = Parser.namePCDATA;
- } else if (var2.getType() == 1) {
- var8 = Parser.namePCDATA;
- } else {
- var8 = var2.getTagName();
- }
-
- if (var8 != null) {
- Integer var9 = (Integer)this.symboltable.get(var8);
- if (var9 != null) {
- int var10 = var9;
- int var7 = ((int[])this.Dtrans.elementAt(var1.state))[var10];
- if (var7 == -1) {
- var3.error("Pattern mismatch in content of '" + var2.getParent().getTagName() + "'. Expected " + this.expectedElements(var1.state));
- } else {
- var1.state = var7;
- var1.matched = ((int[])this.Dtrans.elementAt(var1.state))[this.symbols.size()] > 0;
- }
-
- return true;
- }
-
- Vector var6 = this.expectedElements(var1.state);
- if (var6.isEmpty()) {
- var3.error("Invalid element '" + var8 + "' in content of '" + var1.ed.name + "'. Expected closing tag.");
- } else {
- var3.error("Invalid element '" + var8 + "' in content of '" + var1.ed.name + "'. Expected " + var6);
- }
- } else {
- var3.error("Invalid element in content of '" + var1.ed.name + "'");
- }
-
- return false;
- }
- }
-
- final Node parseMixed(Parser var1) throws ParseException {
- Hashtable var3 = new Hashtable();
- var1.parseKeyword(-18, "PCDATA");
- Object var2 = new Terminal(this, var1.name);
- var3.put(var1.name, var1.name);
- var1.nextToken();
- switch (var1.token) {
- case 41:
- var2 = new Closure((Node)var2);
- if (var1.lookahead == 42) {
- var1.nextToken();
- }
- break;
- case 124:
- for(; var1.token == 124; var2 = new Choice((Node)var2, this.parseNode(var1))) {
- var1.nextToken();
- if (var1.token == -4) {
- if (var3.contains(var1.name)) {
- var1.error("Repeated element in content model: " + var1.name);
- } else {
- var3.put(var1.name, var1.name);
- }
- }
- }
-
- if (var1.token == 41) {
- if (var1.lookahead == 42) {
- var1.nextToken();
- var2 = new Closure((Node)var2);
- } else {
- var1.error("Expected '*' instead of: " + var1.tokenString(var1.token));
- }
- } else {
- var1.error("Illegal token in content model: " + var1.tokenString(var1.token));
- }
- break;
- default:
- var1.error("Illegal token in content model: " + var1.tokenString(var1.token));
- }
-
- var1.nextToken();
- return (Node)var2;
- }
-
- final Node finishNode(Parser var1, Node var2) throws ParseException {
- Object var3;
- switch (var1.lookahead) {
- case 42:
- var1.nextToken();
- var3 = new Closure(var2);
- break;
- case 43:
- var1.nextToken();
- var3 = new ClosurePlus(var2);
- break;
- case 63:
- var1.nextToken();
- var3 = new Qmark(var2);
- break;
- default:
- var3 = var2;
- }
-
- var1.nextToken();
- return (Node)var3;
- }
-
- public Element toSchema() {
- Object var1 = null;
- switch (this.type) {
- case 1:
- var1 = new ElementImpl(nameEMPTY, 0);
- break;
- case 2:
- var1 = new ElementImpl(nameANY, 0);
- case 3:
- default:
- break;
- case 4:
- if (this.content != null) {
- ElementImpl var2 = new ElementImpl(Name.create("DUMMYNODE"), 0);
- ((Sequence)this.content).left.toSchema(35, 0, var2);
- var1 = var2.getChild(0);
- }
- }
-
- return (Element)var1;
- }
-
- public void save(Atom var1, XMLOutputStream var2) throws IOException {
- switch (this.type) {
- case 1:
- var2.writeChars("EMPTY");
- return;
- case 2:
- var2.writeChars("ANY");
- return;
- case 4:
- if (this.content != null) {
- ((Sequence)this.content).left.save(var2, 35, 0, var1);
- return;
- }
- case 3:
- default:
- }
- }
-
- public byte getType() {
- return this.type;
- }
-
- final boolean acceptEmpty(Context var1) {
- if (this.type != 2 && this.type != 1) {
- return ((int[])this.Dtrans.elementAt(var1.state))[this.symbols.size()] > 0;
- } else {
- return true;
- }
- }
-
- final Vector expectedElements(int var1) {
- int[] var2 = (int[])this.Dtrans.elementAt(var1);
- Vector var3 = new Vector();
- Enumeration var4 = this.terminalnodes.elements();
-
- while(var4.hasMoreElements()) {
- Name var5 = ((Terminal)var4.nextElement()).name;
- if (var5 != null && !var3.contains(var5)) {
- Integer var6 = (Integer)this.symboltable.get(var5);
- if (var6 != null && var2[var6] != -1) {
- var3.addElement(var5);
- }
- }
- }
-
- return var3;
- }
-
- final void initContent(Context var1, Parser var2) throws ParseException {
- var1.state = 0;
- if (this.Dtrans != null && this.Dtrans.size() > 0) {
- var1.matched = ((int[])this.Dtrans.elementAt(var1.state))[this.symbols.size()] > 0;
- } else {
- var1.matched = true;
- }
- }
-
- final void parseModel(Parser var1) throws ParseException {
- this.terminalnodes = new Vector();
- this.symboltable = new Hashtable();
- this.symbols = new Vector();
- this.content = this.parseRootNode(var1);
- this.end = new Terminal(this, (Name)null);
- this.content = new Sequence(this.content, this.end);
- int var2 = this.terminalnodes.size();
- BitSet[] var3 = new BitSet[var2];
-
- for(int var4 = 0; var4 < var2; ++var4) {
- var3[var4] = new BitSet(var2);
- }
-
- this.content.calcfollowpos(var3);
- Vector var17 = new Vector();
- this.Dtrans = new Vector();
- Vector var5 = new Vector();
- Hashtable var6 = new Hashtable();
- BitSet var7 = new BitSet(var2);
- var6.put(var7, new Integer(-1));
- int var8 = 0;
- BitSet var9 = this.content.firstpos(var2);
- var6.put(var9, new Integer(var17.size()));
- var5.addElement(var9);
- var17.addElement(var9);
- int[] var10 = new int[this.symbols.size() + 1];
- this.Dtrans.addElement(var10);
- if (var9.get(this.end.pos)) {
- var10[this.symbols.size()] = 1;
- }
-
- while(var5.size() > 0) {
- int[] var11 = (int[])this.Dtrans.elementAt(var8);
- var9 = (BitSet)var5.elementAt(0);
- var5.removeElementAt(0);
-
- for(int var12 = 0; var12 < this.symbols.size(); ++var12) {
- Name var13 = (Name)this.symbols.elementAt(var12);
- BitSet var14 = new BitSet(var2);
-
- for(int var15 = 0; var15 < var2; ++var15) {
- if (var9.get(var15) && ((Terminal)this.terminalnodes.elementAt(var15)).name == var13) {
- var14.or(var3[var15]);
- }
- }
-
- Integer var20 = (Integer)var6.get(var14);
- int var16;
- if (var20 == null) {
- var16 = var17.size();
- var6.put(var14, new Integer(var16));
- var5.addElement(var14);
- var17.addElement(var14);
- var10 = new int[this.symbols.size() + 1];
- this.Dtrans.addElement(var10);
- if (var14.get(this.end.pos)) {
- var10[this.symbols.size()] = 1;
- }
- } else {
- var16 = var20;
- }
-
- var11[var12] = var16;
- }
-
- ++var8;
- }
-
- }
-
- final Node parseNode(Parser var1) throws ParseException {
- Object var2;
- switch (var1.token) {
- case -4:
- var2 = new Terminal(this, var1.name);
- break;
- case 40:
- var1.nextToken();
- var2 = this.parseList(var1);
- break;
- default:
- var2 = null;
- var1.error("Illegal token in content model: " + var1.tokenString(var1.token));
- }
-
- return this.finishNode(var1, (Node)var2);
- }
-
- final Node parseRootNode(Parser var1) throws ParseException {
- Object var2;
- switch (var1.token) {
- case -4:
- var2 = new Terminal(this, var1.name);
- break;
- case 40:
- var1.nextToken();
- if (var1.token == 35) {
- return this.parseMixed(var1);
- }
-
- var2 = this.parseList(var1);
- break;
- default:
- var2 = null;
- var1.error("Expected ANY, EMPTY or '(' instead of: " + var1.tokenString(var1.token));
- }
-
- return this.finishNode(var1, (Node)var2);
- }
- }
-