286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * The Apache Software License, Version 1.1
286N/A *
286N/A *
286N/A * Copyright (c) 1999-2002 The Apache Software Foundation.
286N/A * All rights reserved.
286N/A *
286N/A * Redistribution and use in source and binary forms, with or without
286N/A * modification, are permitted provided that the following conditions
286N/A * are met:
286N/A *
286N/A * 1. Redistributions of source code must retain the above copyright
286N/A * notice, this list of conditions and the following disclaimer.
286N/A *
286N/A * 2. Redistributions in binary form must reproduce the above copyright
286N/A * notice, this list of conditions and the following disclaimer in
286N/A * the documentation and/or other materials provided with the
286N/A * distribution.
286N/A *
286N/A * 3. The end-user documentation included with the redistribution,
286N/A * if any, must include the following acknowledgment:
286N/A * "This product includes software developed by the
286N/A * Apache Software Foundation (http://www.apache.org/)."
286N/A * Alternately, this acknowledgment may appear in the software itself,
286N/A * if and wherever such third-party acknowledgments normally appear.
286N/A *
286N/A * 4. The names "Xerces" and "Apache Software Foundation" must
286N/A * not be used to endorse or promote products derived from this
286N/A * software without prior written permission. For written
286N/A * permission, please contact apache@apache.org.
286N/A *
286N/A * 5. Products derived from this software may not be called "Apache",
286N/A * nor may "Apache" appear in their name, without prior written
286N/A * permission of the Apache Software Foundation.
286N/A *
286N/A * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
286N/A * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
286N/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
286N/A * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
286N/A * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
286N/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
286N/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
286N/A * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
286N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
286N/A * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
286N/A * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
286N/A * SUCH DAMAGE.
286N/A * ====================================================================
286N/A *
286N/A * This software consists of voluntary contributions made by many
286N/A * individuals on behalf of the Apache Software Foundation and was
286N/A * originally based on software copyright (c) 1999, International
286N/A * Business Machines, Inc., http://www.apache.org. For more
286N/A * information on the Apache Software Foundation, please see
286N/A * <http://www.apache.org/>.
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xerces.internal.impl.dtd;
286N/A
286N/Aimport java.util.ArrayList;
286N/Aimport java.util.Hashtable;
286N/A
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.CMAny;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.CMBinOp;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.CMLeaf;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.CMUniOp;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.ContentModelValidator;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.DFAContentModel;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.MixedContentModel;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dtd.models.SimpleContentModel;
286N/Aimport com.sun.org.apache.xerces.internal.impl.dv.DatatypeValidator;
286N/Aimport com.sun.org.apache.xerces.internal.impl.validation.EntityState;
286N/Aimport com.sun.org.apache.xerces.internal.util.SymbolTable;
286N/Aimport com.sun.org.apache.xerces.internal.xni.Augmentations;
286N/Aimport com.sun.org.apache.xerces.internal.xni.QName;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLLocator;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XMLString;
286N/Aimport com.sun.org.apache.xerces.internal.xni.XNIException;
286N/Aimport com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
286N/Aimport com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource;
286N/Aimport com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
286N/A
286N/A/**
286N/A * A DTD grammar. This class implements the XNI handler interfaces
286N/A * for DTD information so that it can build the approprate validation
286N/A * structures automatically from the callbacks.
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A * @author Eric Ye, IBM
286N/A * @author Jeffrey Rodriguez, IBM
286N/A * @author Andy Clark, IBM
286N/A * @author Neil Graham, IBM
286N/A *
286N/A * @version $Id: DTDGrammar.java,v 1.4 2010/08/11 07:18:37 joehw Exp $
286N/A */
286N/Apublic class DTDGrammar
286N/A implements XMLDTDHandler, XMLDTDContentModelHandler, EntityState, Grammar {
286N/A
286N/A //
286N/A // Constants
286N/A //
286N/A
286N/A /** Top level scope (-1). */
286N/A public static final int TOP_LEVEL_SCOPE = -1;
286N/A
286N/A // private
286N/A
286N/A /** Chunk shift (8). */
286N/A private static final int CHUNK_SHIFT = 8; // 2^8 = 256
286N/A
286N/A /** Chunk size (1 << CHUNK_SHIFT). */
286N/A private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
286N/A
286N/A /** Chunk mask (CHUNK_SIZE - 1). */
286N/A private static final int CHUNK_MASK = CHUNK_SIZE - 1;
286N/A
286N/A /** Initial chunk count (1 << (10 - CHUNK_SHIFT)). */
286N/A private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
286N/A
286N/A /** List flag (0x80). */
286N/A private static final short LIST_FLAG = 0x80;
286N/A
286N/A /** List mask (~LIST_FLAG). */
286N/A private static final short LIST_MASK = ~LIST_FLAG;
286N/A
286N/A // debugging
286N/A
286N/A /** Debug DTDGrammar. */
286N/A private static final boolean DEBUG = false;
286N/A
286N/A //
286N/A // Data
286N/A //
286N/A
286N/A protected XMLDTDSource fDTDSource = null;
286N/A protected XMLDTDContentModelSource fDTDContentModelSource = null;
286N/A
286N/A /** Current element index. */
286N/A protected int fCurrentElementIndex;
286N/A
286N/A /** Current attribute index. */
286N/A protected int fCurrentAttributeIndex;
286N/A
286N/A /** fReadingExternalDTD */
286N/A protected boolean fReadingExternalDTD = false;
286N/A
286N/A /** Symbol table. */
286N/A private SymbolTable fSymbolTable;
286N/A
286N/A // The XMLDTDDescription with which this Grammar is associated
286N/A protected XMLDTDDescription fGrammarDescription = null;
286N/A
286N/A // element declarations
286N/A
286N/A /** Number of element declarations. */
286N/A private int fElementDeclCount = 0;
286N/A
286N/A /** Element declaration name. */
286N/A private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /**
286N/A * Element declaration type.
286N/A * @see XMLElementDecl
286N/A */
286N/A private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /**
286N/A * Element declaration content spec index. This index value is used
286N/A * to refer to the content spec information tables.
286N/A */
286N/A private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /**
286N/A * Element declaration content model validator. This validator is
286N/A * constructed from the content spec nodes.
286N/A */
286N/A private ContentModelValidator fElementDeclContentModelValidator[][] = new ContentModelValidator[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /** First attribute declaration of an element declaration. */
286N/A private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /** Last attribute declaration of an element declaration. */
286N/A private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // attribute declarations
286N/A
286N/A /** Number of attribute declarations. */
286N/A private int fAttributeDeclCount = 0 ;
286N/A
286N/A /** Attribute declaration name. */
286N/A private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // is this grammar immutable? (fully constructed and not changeable)
286N/A private boolean fIsImmutable = false;
286N/A
286N/A /**
286N/A * Attribute declaration type.
286N/A * @see XMLAttributeDecl
286N/A */
286N/A private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
286N/A
286N/A /** Attribute declaration enumeration values. */
286N/A private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
286N/A private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
286N/A private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
286N/A private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
286N/A private String fAttributeDeclNonNormalizedDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
286N/A private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // content specs
286N/A
286N/A // here saves the content spec binary trees for element decls,
286N/A // each element with a content model will hold a pointer which is
286N/A // the index of the head node of the content spec tree.
286N/A
286N/A private int fContentSpecCount = 0;
286N/A private short fContentSpecType[][] = new short[INITIAL_CHUNK_COUNT][];
286N/A private Object fContentSpecValue[][] = new Object[INITIAL_CHUNK_COUNT][];
286N/A private Object fContentSpecOtherValue[][] = new Object[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // entities
286N/A
286N/A private int fEntityCount = 0;
286N/A private String fEntityName[][] = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fEntityValue = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fEntityPublicId = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fEntitySystemId = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fEntityBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fEntityNotation = new String[INITIAL_CHUNK_COUNT][];
286N/A private byte[][] fEntityIsPE = new byte[INITIAL_CHUNK_COUNT][];
286N/A private byte[][] fEntityInExternal = new byte[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // notations
286N/A
286N/A private int fNotationCount = 0;
286N/A private String fNotationName[][] = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fNotationPublicId = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fNotationSystemId = new String[INITIAL_CHUNK_COUNT][];
286N/A private String[][] fNotationBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // other information
286N/A
286N/A /** Element index mapping table. */
286N/A private QNameHashtable fElementIndexMap = new QNameHashtable();
286N/A
286N/A /** Entity index mapping table. */
286N/A private QNameHashtable fEntityIndexMap = new QNameHashtable();
286N/A
286N/A /** Notation index mapping table. */
286N/A private QNameHashtable fNotationIndexMap = new QNameHashtable();
286N/A
286N/A // temp variables
286N/A
286N/A /** Mixed. */
286N/A private boolean fMixed;
286N/A
286N/A /** Temporary qualified name. */
286N/A private final QName fQName = new QName();
286N/A
286N/A /** Temporary qualified name. */
286N/A private final QName fQName2 = new QName();
286N/A
286N/A /** Temporary Attribute decl. */
286N/A protected final XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
286N/A
286N/A // for buildSyntaxTree method
286N/A
286N/A private int fLeafCount = 0;
286N/A private int fEpsilonIndex = -1;
286N/A
286N/A /** Element declaration. */
286N/A private XMLElementDecl fElementDecl = new XMLElementDecl();
286N/A
286N/A /** Entity declaration. */
286N/A private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
286N/A
286N/A /** Simple type. */
286N/A private XMLSimpleType fSimpleType = new XMLSimpleType();
286N/A
286N/A /** Content spec node. */
286N/A private XMLContentSpec fContentSpec = new XMLContentSpec();
286N/A
286N/A /** table of XMLElementDecl */
286N/A Hashtable fElementDeclTab = new Hashtable();
286N/A
286N/A /** Children content model operation stack. */
286N/A private short[] fOpStack = null;
286N/A
286N/A /** Children content model index stack. */
286N/A private int[] fNodeIndexStack = null;
286N/A
286N/A /** Children content model previous node index stack. */
286N/A private int[] fPrevNodeIndexStack = null;
286N/A
286N/A /** Stack depth */
286N/A private int fDepth = 0;
286N/A
286N/A /** Entity stack. */
286N/A private boolean[] fPEntityStack = new boolean[4];
286N/A private int fPEDepth = 0;
286N/A
286N/A // additional fields(columns) for the element Decl pool in the Grammar
286N/A
286N/A /** flag if the elementDecl is External. */
286N/A private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A
286N/A // additional fields(columns) for the attribute Decl pool in the Grammar
286N/A
286N/A /** flag if the AttributeDecl is External. */
286N/A private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
286N/A
286N/A // for mixedElement method
286N/A
286N/A int valueIndex = -1;
286N/A int prevNodeIndex = -1;
286N/A int nodeIndex = -1;
286N/A
286N/A //
286N/A // Constructors
286N/A //
286N/A
286N/A /** Default constructor. */
286N/A public DTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) {
286N/A fSymbolTable = symbolTable;
286N/A fGrammarDescription = desc;
286N/A } // <init>(SymbolTable)
286N/A
286N/A // Grammar methods
286N/A
286N/A // return the XMLDTDDescription object with which this is associated
286N/A public XMLGrammarDescription getGrammarDescription() {
286N/A return fGrammarDescription;
286N/A } // getGrammarDescription(): XMLGrammarDescription
286N/A
286N/A //
286N/A // Public methods
286N/A //
286N/A
286N/A /**
286N/A * Returns true if the specified element declaration is external.
286N/A *
286N/A * @param elementDeclIndex The element declaration index.
286N/A */
286N/A public boolean getElementDeclIsExternal(int elementDeclIndex) {
286N/A
286N/A if (elementDeclIndex < 0) {
286N/A return false;
286N/A }
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A return (fElementDeclIsExternal[chunk][index] != 0);
286N/A
286N/A } // getElementDeclIsExternal(int):boolean
286N/A
286N/A /**
286N/A * Returns true if the specified attribute declaration is external.
286N/A *
286N/A * @param attributeDeclIndex Attribute declaration index.
286N/A */
286N/A public boolean getAttributeDeclIsExternal(int attributeDeclIndex) {
286N/A
286N/A if (attributeDeclIndex < 0) {
286N/A return false;
286N/A }
286N/A
286N/A int chunk = attributeDeclIndex >> CHUNK_SHIFT;
286N/A int index = attributeDeclIndex & CHUNK_MASK;
286N/A return (fAttributeDeclIsExternal[chunk][index] != 0);
286N/A }
286N/A
286N/A public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) {
286N/A if (elementDeclIndex == -1) {
286N/A return -1;
286N/A }
286N/A int attDefIndex = getFirstAttributeDeclIndex(elementDeclIndex);
286N/A while (attDefIndex != -1) {
286N/A getAttributeDecl(attDefIndex, fAttributeDecl);
286N/A
286N/A if (fAttributeDecl.name.rawname == attributeDeclName
286N/A || attributeDeclName.equals(fAttributeDecl.name.rawname) ) {
286N/A return attDefIndex;
286N/A }
286N/A attDefIndex = getNextAttributeDeclIndex(attDefIndex);
286N/A }
286N/A return -1;
286N/A } // getAttributeDeclIndex (int,QName)
286N/A
286N/A //
286N/A // XMLDTDHandler methods
286N/A //
286N/A
286N/A /**
286N/A * The start of the DTD.
286N/A *
286N/A * @param locator The document locator, or null if the document
286N/A * location cannot be reported during the parsing of
286N/A * the document DTD. However, it is <em>strongly</em>
286N/A * recommended that a locator be supplied that can
286N/A * at least report the base system identifier of the
286N/A * DTD.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
286N/A //Initialize stack
286N/A fOpStack = null;
286N/A fNodeIndexStack = null;
286N/A fPrevNodeIndexStack = null;
286N/A } // startDTD(XMLLocator)
286N/A
286N/A /**
286N/A * This method notifies of the start of an entity. The DTD has the
286N/A * pseudo-name of "[dtd]" and parameter entity names start with '%'.
286N/A * <p>
286N/A * <strong>Note:</strong> Since the DTD is an entity, the handler
286N/A * will be notified of the start of the DTD entity by calling the
286N/A * startParameterEntity method with the entity name "[dtd]" <em>before</em> calling
286N/A * the startDTD method.
286N/A *
286N/A * @param name The name of the parameter entity.
286N/A * @param identifier The resource identifier.
286N/A * @param encoding The auto-detected IANA encoding name of the entity
286N/A * stream. This value will be null in those situations
286N/A * where the entity encoding is not auto-detected (e.g.
286N/A * internal parameter entities).
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startParameterEntity(String name,
286N/A XMLResourceIdentifier identifier,
286N/A String encoding,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A // keep track of this entity before fEntityDepth is increased
286N/A if (fPEDepth == fPEntityStack.length) {
286N/A boolean[] entityarray = new boolean[fPEntityStack.length * 2];
286N/A System.arraycopy(fPEntityStack, 0, entityarray, 0, fPEntityStack.length);
286N/A fPEntityStack = entityarray;
286N/A }
286N/A fPEntityStack[fPEDepth] = fReadingExternalDTD;
286N/A fPEDepth++;
286N/A
286N/A } // startParameterEntity(String,XMLResourceIdentifier,String,Augmentations)
286N/A
286N/A /**
286N/A * The start of the DTD external subset.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startExternalSubset(XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A fReadingExternalDTD = true;
286N/A } // startExternalSubset(Augmentations)
286N/A
286N/A /**
286N/A * This method notifies the end of an entity. The DTD has the pseudo-name
286N/A * of "[dtd]" and parameter entity names start with '%'.
286N/A * <p>
286N/A * <strong>Note:</strong> Since the DTD is an entity, the handler
286N/A * will be notified of the end of the DTD entity by calling the
286N/A * endEntity method with the entity name "[dtd]" <em>after</em> calling
286N/A * the endDTD method.
286N/A *
286N/A * @param name The name of the entity.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endParameterEntity(String name, Augmentations augs) throws XNIException {
286N/A
286N/A fPEDepth--;
286N/A fReadingExternalDTD = fPEntityStack[fPEDepth];
286N/A
286N/A } // endParameterEntity(String,Augmentations)
286N/A
286N/A /**
286N/A * The end of the DTD external subset.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endExternalSubset(Augmentations augs) throws XNIException {
286N/A fReadingExternalDTD = false;
286N/A } // endExternalSubset(Augmentations)
286N/A
286N/A /**
286N/A * An element declaration.
286N/A *
286N/A * @param name The name of the element.
286N/A * @param contentModel The element content model.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void elementDecl(String name, String contentModel, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A XMLElementDecl tmpElementDecl = (XMLElementDecl) fElementDeclTab.get(name) ;
286N/A
286N/A // check if it is already defined
286N/A if ( tmpElementDecl != null ) {
286N/A if (tmpElementDecl.type == -1) {
286N/A fCurrentElementIndex = getElementDeclIndex(name);
286N/A }
286N/A else {
286N/A // duplicate element, ignored.
286N/A return;
286N/A }
286N/A }
286N/A else {
286N/A fCurrentElementIndex = createElementDecl();//create element decl
286N/A }
286N/A
286N/A XMLElementDecl elementDecl = new XMLElementDecl();
286N/A
286N/A fQName.setValues(null, name, name, null);
286N/A
286N/A elementDecl.name.setValues(fQName);
286N/A
286N/A elementDecl.contentModelValidator = null;
286N/A elementDecl.scope= -1;
286N/A if (contentModel.equals("EMPTY")) {
286N/A elementDecl.type = XMLElementDecl.TYPE_EMPTY;
286N/A }
286N/A else if (contentModel.equals("ANY")) {
286N/A elementDecl.type = XMLElementDecl.TYPE_ANY;
286N/A }
286N/A else if (contentModel.startsWith("(") ) {
286N/A if (contentModel.indexOf("#PCDATA") > 0 ) {
286N/A elementDecl.type = XMLElementDecl.TYPE_MIXED;
286N/A }
286N/A else {
286N/A elementDecl.type = XMLElementDecl.TYPE_CHILDREN;
286N/A }
286N/A }
286N/A
286N/A
286N/A //add(or set) this elementDecl to the local cache
286N/A this.fElementDeclTab.put(name, elementDecl );
286N/A
286N/A fElementDecl = elementDecl;
286N/A addContentSpecToElement(elementDecl);
286N/A
286N/A if ( DEBUG ) {
286N/A System.out.println( "name = " + fElementDecl.name.localpart );
286N/A System.out.println( "Type = " + fElementDecl.type );
286N/A }
286N/A
286N/A setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
286N/A
286N/A int chunk = fCurrentElementIndex >> CHUNK_SHIFT;
286N/A int index = fCurrentElementIndex & CHUNK_MASK;
286N/A ensureElementDeclCapacity(chunk);
286N/A fElementDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0;
286N/A
286N/A } // elementDecl(String,String)
286N/A
286N/A /**
286N/A * An attribute declaration.
286N/A *
286N/A * @param elementName The name of the element that this attribute
286N/A * is associated with.
286N/A * @param attributeName The name of the attribute.
286N/A * @param type The attribute type. This value will be one of
286N/A * the following: "CDATA", "ENTITY", "ENTITIES",
286N/A * "ENUMERATION", "ID", "IDREF", "IDREFS",
286N/A * "NMTOKEN", "NMTOKENS", or "NOTATION".
286N/A * @param enumeration If the type has the value "ENUMERATION", this
286N/A * array holds the allowed attribute values;
286N/A * otherwise, this array is null.
286N/A * @param defaultType The attribute default type. This value will be
286N/A * one of the following: "#FIXED", "#IMPLIED",
286N/A * "#REQUIRED", or null.
286N/A * @param defaultValue The attribute default value, or null if no
286N/A * default value is specified.
286N/A * @param nonNormalizedDefaultValue The attribute default value with no normalization
286N/A * performed, or null if no default value is specified.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void attributeDecl(String elementName, String attributeName,
286N/A String type, String[] enumeration,
286N/A String defaultType, XMLString defaultValue,
286N/A XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
286N/A
286N/A if ( this.fElementDeclTab.containsKey( (String) elementName) ) {
286N/A //if ElementDecl has already being created in the Grammar then remove from table,
286N/A //this.fElementDeclTab.remove( (String) elementName );
286N/A }
286N/A // then it is forward reference to a element decl, create the elementDecl first.
286N/A else {
286N/A fCurrentElementIndex = createElementDecl();//create element decl
286N/A
286N/A XMLElementDecl elementDecl = new XMLElementDecl();
286N/A elementDecl.name.setValues(null, elementName, elementName, null);
286N/A
286N/A elementDecl.scope= -1;
286N/A
286N/A //add(or set) this elementDecl to the local cache
286N/A this.fElementDeclTab.put(elementName, elementDecl );
286N/A
286N/A //set internal structure
286N/A setElementDecl(fCurrentElementIndex, elementDecl );
286N/A }
286N/A
286N/A //Get Grammar index to grammar array
286N/A int elementIndex = getElementDeclIndex(elementName);
286N/A
286N/A //return, when more than one definition is provided for the same attribute of given element type
286N/A //only the first declaration is binding and later declarations are ignored
286N/A if (getAttributeDeclIndex(elementIndex, attributeName) != -1) {
286N/A return;
286N/A }
286N/A
286N/A fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl
286N/A
286N/A fSimpleType.clear();
286N/A if ( defaultType != null ) {
286N/A if ( defaultType.equals( "#FIXED") ) {
286N/A fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_FIXED;
286N/A } else if ( defaultType.equals( "#IMPLIED") ) {
286N/A fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
286N/A } else if ( defaultType.equals( "#REQUIRED") ) {
286N/A fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_REQUIRED;
286N/A }
286N/A }
286N/A if ( DEBUG ) {
286N/A System.out.println("defaultvalue = " + defaultValue.toString() );
286N/A }
286N/A fSimpleType.defaultValue = defaultValue!=null ? defaultValue.toString() : null;
286N/A fSimpleType.nonNormalizedDefaultValue = nonNormalizedDefaultValue!=null ? nonNormalizedDefaultValue.toString() : null;
286N/A fSimpleType.enumeration = enumeration;
286N/A
286N/A if (type.equals("CDATA")) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_CDATA;
286N/A }
286N/A else if ( type.equals("ID") ) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_ID;
286N/A }
286N/A else if ( type.startsWith("IDREF") ) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_IDREF;
286N/A if (type.indexOf("S") > 0) {
286N/A fSimpleType.list = true;
286N/A }
286N/A }
286N/A else if (type.equals("ENTITIES")) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
286N/A fSimpleType.list = true;
286N/A }
286N/A else if (type.equals("ENTITY")) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
286N/A }
286N/A else if (type.equals("NMTOKENS")) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
286N/A fSimpleType.list = true;
286N/A }
286N/A else if (type.equals("NMTOKEN")) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
286N/A }
286N/A else if (type.startsWith("NOTATION") ) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_NOTATION;
286N/A }
286N/A else if (type.startsWith("ENUMERATION") ) {
286N/A fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
286N/A }
286N/A else {
286N/A // REVISIT: Report error message. -Ac
286N/A System.err.println("!!! unknown attribute type "+type);
286N/A }
286N/A // REVISIT: The datatype should be stored with the attribute value
286N/A // and not special-cased in the XMLValidator. -Ac
286N/A //fSimpleType.datatypeValidator = fDatatypeValidatorFactory.createDatatypeValidator(type, null, facets, fSimpleType.list);
286N/A
286N/A fQName.setValues(null, attributeName, attributeName, null);
286N/A fAttributeDecl.setValues( fQName, fSimpleType, false );
286N/A
286N/A setAttributeDecl(elementIndex, fCurrentAttributeIndex, fAttributeDecl);
286N/A
286N/A int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT;
286N/A int index = fCurrentAttributeIndex & CHUNK_MASK;
286N/A ensureAttributeDeclCapacity(chunk);
286N/A fAttributeDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0;
286N/A
286N/A } // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations)
286N/A
286N/A /**
286N/A * An internal entity declaration.
286N/A *
286N/A * @param name The name of the entity. Parameter entity names start with
286N/A * '%', whereas the name of a general entity is just the
286N/A * entity name.
286N/A * @param text The value of the entity.
286N/A * @param nonNormalizedText The non-normalized value of the entity. This
286N/A * value contains the same sequence of characters that was in
286N/A * the internal entity declaration, without any entity
286N/A * references expanded.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void internalEntityDecl(String name, XMLString text,
286N/A XMLString nonNormalizedText,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A int entityIndex = getEntityDeclIndex(name);
286N/A if( entityIndex == -1){
286N/A entityIndex = createEntityDecl();
286N/A boolean isPE = name.startsWith("%");
286N/A boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
286N/A XMLEntityDecl entityDecl = new XMLEntityDecl();
286N/A entityDecl.setValues(name,null,null, null, null,
286N/A text.toString(), isPE, inExternal);
286N/A
286N/A setEntityDecl(entityIndex, entityDecl);
286N/A }
286N/A
286N/A } // internalEntityDecl(String,XMLString,XMLString)
286N/A
286N/A /**
286N/A * An external entity declaration.
286N/A *
286N/A * @param name The name of the entity. Parameter entity names start
286N/A * with '%', whereas the name of a general entity is just
286N/A * the entity name.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this external entity declaration.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void externalEntityDecl(String name,
286N/A XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A int entityIndex = getEntityDeclIndex(name);
286N/A if( entityIndex == -1){
286N/A entityIndex = createEntityDecl();
286N/A boolean isPE = name.startsWith("%");
286N/A boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
286N/A
286N/A XMLEntityDecl entityDecl = new XMLEntityDecl();
286N/A entityDecl.setValues(name, identifier.getPublicId(), identifier.getLiteralSystemId(),
286N/A identifier.getBaseSystemId(),
286N/A null, null, isPE, inExternal);
286N/A
286N/A setEntityDecl(entityIndex, entityDecl);
286N/A }
286N/A } // externalEntityDecl(String, XMLResourceIdentifier, Augmentations)
286N/A
286N/A /**
286N/A * An unparsed entity declaration.
286N/A *
286N/A * @param name The name of the entity.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this entity.
286N/A * @param notation The name of the notation.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
286N/A String notation,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A XMLEntityDecl entityDecl = new XMLEntityDecl();
286N/A boolean isPE = name.startsWith("%");
286N/A boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
286N/A
286N/A entityDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(),
286N/A identifier.getBaseSystemId(), notation,
286N/A null, isPE, inExternal);
286N/A int entityIndex = getEntityDeclIndex(name);
286N/A if (entityIndex == -1) {
286N/A entityIndex = createEntityDecl();
286N/A setEntityDecl(entityIndex, entityDecl);
286N/A }
286N/A
286N/A } // unparsedEntityDecl(String,StringXMLResourceIdentifier,Augmentations)
286N/A
286N/A /**
286N/A * A notation declaration
286N/A *
286N/A * @param name The name of the notation.
286N/A * @param identifier An object containing all location information
286N/A * pertinent to this notation.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void notationDecl(String name, XMLResourceIdentifier identifier,
286N/A Augmentations augs) throws XNIException {
286N/A
286N/A XMLNotationDecl notationDecl = new XMLNotationDecl();
286N/A notationDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(),
286N/A identifier.getBaseSystemId());
286N/A int notationIndex = getNotationDeclIndex(name);
286N/A if (notationIndex == -1) {
286N/A notationIndex = createNotationDecl();
286N/A setNotationDecl(notationIndex, notationDecl);
286N/A }
286N/A
286N/A } // notationDecl(String,XMLResourceIdentifier,Augmentations)
286N/A
286N/A /**
286N/A * The end of the DTD.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endDTD(Augmentations augs) throws XNIException {
286N/A fIsImmutable = true;
286N/A // make sure our description contains useful stuff...
286N/A if (fGrammarDescription.getRootName() == null) {
286N/A // we don't know what the root is; so use possibleRoots...
286N/A int chunk, index = 0;
286N/A String currName = null;
286N/A final int size = fElementDeclCount;
286N/A ArrayList elements = new ArrayList(size);
286N/A for (int i = 0; i < size; ++i) {
286N/A chunk = i >> CHUNK_SHIFT;
286N/A index = i & CHUNK_MASK;
286N/A currName = fElementDeclName[chunk][index].rawname;
286N/A elements.add(currName);
286N/A }
286N/A fGrammarDescription.setPossibleRoots(elements);
286N/A }
286N/A } // endDTD()
286N/A
286N/A // sets the source of this handler
286N/A public void setDTDSource(XMLDTDSource source) {
286N/A fDTDSource = source;
286N/A } // setDTDSource(XMLDTDSource)
286N/A
286N/A // returns the source of this handler
286N/A public XMLDTDSource getDTDSource() {
286N/A return fDTDSource;
286N/A } // getDTDSource(): XMLDTDSource
286N/A
286N/A // no-op methods
286N/A
286N/A /**
286N/A * Notifies of the presence of a TextDecl line in an entity. If present,
286N/A * this method will be called immediately following the startEntity call.
286N/A * <p>
286N/A * <strong>Note:</strong> This method is only called for external
286N/A * parameter entities referenced in the DTD.
286N/A *
286N/A * @param version The XML version, or null if not specified.
286N/A * @param encoding The IANA encoding name of the entity.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void textDecl(String version, String encoding, Augmentations augs)
286N/A throws XNIException {}
286N/A
286N/A /**
286N/A * A comment.
286N/A *
286N/A * @param text The text in the comment.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by application to signal an error.
286N/A */
286N/A public void comment(XMLString text, Augmentations augs) throws XNIException {}
286N/A
286N/A /**
286N/A * A processing instruction. Processing instructions consist of a
286N/A * target name and, optionally, text data. The data is only meaningful
286N/A * to the application.
286N/A * <p>
286N/A * Typically, a processing instruction's data will contain a series
286N/A * of pseudo-attributes. These pseudo-attributes follow the form of
286N/A * element attributes but are <strong>not</strong> parsed or presented
286N/A * to the application as anything other than text. The application is
286N/A * responsible for parsing the data.
286N/A *
286N/A * @param target The target.
286N/A * @param data The data or null if none specified.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void processingInstruction(String target, XMLString data,
286N/A Augmentations augs) throws XNIException {}
286N/A
286N/A /**
286N/A * The start of an attribute list.
286N/A *
286N/A * @param elementName The name of the element that this attribute
286N/A * list is associated with.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startAttlist(String elementName, Augmentations augs)
286N/A throws XNIException {}
286N/A
286N/A /**
286N/A * The end of an attribute list.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endAttlist(Augmentations augs) throws XNIException {}
286N/A
286N/A /**
286N/A * The start of a conditional section.
286N/A *
286N/A * @param type The type of the conditional section. This value will
286N/A * either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see XMLDTDHandler#CONDITIONAL_INCLUDE
286N/A * @see XMLDTDHandler#CONDITIONAL_IGNORE
286N/A */
286N/A public void startConditional(short type, Augmentations augs)
286N/A throws XNIException {}
286N/A
286N/A /**
286N/A * Characters within an IGNORE conditional section.
286N/A *
286N/A * @param text The ignored text.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A */
286N/A public void ignoredCharacters(XMLString text, Augmentations augs)
286N/A throws XNIException {}
286N/A
286N/A /**
286N/A * The end of a conditional section.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endConditional(Augmentations augs) throws XNIException {}
286N/A
286N/A //
286N/A // XMLDTDContentModelHandler methods
286N/A //
286N/A
286N/A // set content model source
286N/A public void setDTDContentModelSource(XMLDTDContentModelSource source) {
286N/A fDTDContentModelSource = source;
286N/A }
286N/A
286N/A // get content model source
286N/A public XMLDTDContentModelSource getDTDContentModelSource() {
286N/A return fDTDContentModelSource;
286N/A }
286N/A
286N/A /**
286N/A * The start of a content model. Depending on the type of the content
286N/A * model, specific methods may be called between the call to the
286N/A * startContentModel method and the call to the endContentModel method.
286N/A *
286N/A * @param elementName The name of the element.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void startContentModel(String elementName, Augmentations augs)
286N/A throws XNIException {
286N/A
286N/A XMLElementDecl elementDecl = (XMLElementDecl) this.fElementDeclTab.get( elementName);
286N/A if ( elementDecl != null ) {
286N/A fElementDecl = elementDecl;
286N/A }
286N/A fDepth = 0;
286N/A initializeContentModelStack();
286N/A
286N/A } // startContentModel(String)
286N/A
286N/A /**
286N/A * A start of either a mixed or children content model. A mixed
286N/A * content model will immediately be followed by a call to the
286N/A * <code>pcdata()</code> method. A children content model will
286N/A * contain additional groups and/or elements.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #any
286N/A * @see #empty
286N/A */
286N/A public void startGroup(Augmentations augs) throws XNIException {
286N/A fDepth++;
286N/A initializeContentModelStack();
286N/A fMixed = false;
286N/A } // startGroup()
286N/A
286N/A /**
286N/A * The appearance of "#PCDATA" within a group signifying a
286N/A * mixed content model. This method will be the first called
286N/A * following the content model's <code>startGroup()</code>.
286N/A *
286N/A *@param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #startGroup
286N/A */
286N/A public void pcdata(Augmentations augs) throws XNIException {
286N/A fMixed = true;
286N/A } // pcdata()
286N/A
286N/A /**
286N/A * A referenced element in a mixed or children content model.
286N/A *
286N/A * @param elementName The name of the referenced element.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void element(String elementName, Augmentations augs) throws XNIException {
286N/A if (fMixed) {
286N/A if (fNodeIndexStack[fDepth] == -1 ) {
286N/A fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName);
286N/A }
286N/A else {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE,
286N/A fNodeIndexStack[fDepth],
286N/A addUniqueLeafNode(elementName));
286N/A }
286N/A }
286N/A else {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName);
286N/A }
286N/A } // element(String)
286N/A
286N/A /**
286N/A * The separator between choices or sequences of a mixed or children
286N/A * content model.
286N/A *
286N/A * @param separator The type of children separator.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE
286N/A * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE
286N/A */
286N/A public void separator(short separator, Augmentations augs) throws XNIException {
286N/A
286N/A if (!fMixed) {
286N/A if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_SEQ && separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE ) {
286N/A if (fPrevNodeIndexStack[fDepth] != -1) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
286N/A }
286N/A fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
286N/A fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
286N/A } else if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_CHOICE && separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) {
286N/A if (fPrevNodeIndexStack[fDepth] != -1) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
286N/A }
286N/A fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
286N/A fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
286N/A }
286N/A }
286N/A
286N/A } // separator(short)
286N/A
286N/A /**
286N/A * The occurrence count for a child in a children content model or
286N/A * for the mixed content model group.
286N/A *
286N/A * @param occurrence The occurrence count for the last element
286N/A * or group.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE
286N/A * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE
286N/A * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE
286N/A */
286N/A public void occurrence(short occurrence, Augmentations augs) throws XNIException {
286N/A
286N/A if (!fMixed) {
286N/A if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE ) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[fDepth], -1);
286N/A } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE ) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[fDepth], -1 );
286N/A } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[fDepth], -1 );
286N/A }
286N/A }
286N/A
286N/A } // occurrence(short)
286N/A
286N/A /**
286N/A * The end of a group for mixed or children content models.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endGroup(Augmentations augs) throws XNIException {
286N/A
286N/A if (!fMixed) {
286N/A if (fPrevNodeIndexStack[fDepth] != -1) {
286N/A fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
286N/A }
286N/A int nodeIndex = fNodeIndexStack[fDepth--];
286N/A fNodeIndexStack[fDepth] = nodeIndex;
286N/A }
286N/A
286N/A } // endGroup()
286N/A
286N/A // no-op methods
286N/A
286N/A /**
286N/A * A content model of ANY.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #empty
286N/A * @see #startGroup
286N/A */
286N/A public void any(Augmentations augs) throws XNIException {}
286N/A
286N/A /**
286N/A * A content model of EMPTY.
286N/A *
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A *
286N/A * @see #any
286N/A * @see #startGroup
286N/A */
286N/A public void empty(Augmentations augs) throws XNIException {}
286N/A
286N/A /**
286N/A * The end of a content model.
286N/A * @param augs Additional information that may include infoset
286N/A * augmentations.
286N/A *
286N/A * @throws XNIException Thrown by handler to signal an error.
286N/A */
286N/A public void endContentModel(Augmentations augs) throws XNIException {}
286N/A
286N/A //
286N/A // Grammar methods
286N/A //
286N/A
286N/A /** Returns true if this grammar is namespace aware. */
286N/A public boolean isNamespaceAware() {
286N/A return false;
286N/A } // isNamespaceAware():boolean
286N/A
286N/A /** Returns the symbol table. */
286N/A public SymbolTable getSymbolTable() {
286N/A return fSymbolTable;
286N/A } // getSymbolTable():SymbolTable
286N/A
286N/A /**
286N/A * Returns the index of the first element declaration. This index
286N/A * is then used to query more information about the element declaration.
286N/A *
286N/A * @see #getNextElementDeclIndex
286N/A * @see #getElementDecl
286N/A */
286N/A public int getFirstElementDeclIndex() {
286N/A return fElementDeclCount >= 0 ? 0 : -1;
286N/A } // getFirstElementDeclIndex():int
286N/A
286N/A /**
286N/A * Returns the next index of the element declaration following the
286N/A * specified element declaration.
286N/A *
286N/A * @param elementDeclIndex The element declaration index.
286N/A */
286N/A public int getNextElementDeclIndex(int elementDeclIndex) {
286N/A return elementDeclIndex < fElementDeclCount - 1
286N/A ? elementDeclIndex + 1 : -1;
286N/A } // getNextElementDeclIndex(int):int
286N/A
286N/A /**
286N/A * getElementDeclIndex
286N/A *
286N/A * @param elementDeclName
286N/A *
286N/A * @return index of the elementDeclName in scope
286N/A */
286N/A public int getElementDeclIndex(String elementDeclName) {
286N/A int mapping = fElementIndexMap.get(elementDeclName);
286N/A //System.out.println("getElementDeclIndex("+elementDeclName+") -> "+mapping);
286N/A return mapping;
286N/A } // getElementDeclIndex(String):int
286N/A
286N/A /** Returns the element decl index.
286N/A * @param elementDeclQName qualilfied name of the element
286N/A */
286N/A public int getElementDeclIndex(QName elementDeclQName) {
286N/A return getElementDeclIndex(elementDeclQName.rawname);
286N/A } // getElementDeclIndex(QName):int
286N/A
286N/A /** make separate function for getting contentSpecType of element.
286N/A * we can avoid setting of the element values.
286N/A */
286N/A
286N/A public short getContentSpecType(int elementIndex){
286N/A if (elementIndex < 0 || elementIndex >= fElementDeclCount) {
286N/A return -1 ;
286N/A }
286N/A
286N/A int chunk = elementIndex >> CHUNK_SHIFT;
286N/A int index = elementIndex & CHUNK_MASK;
286N/A
286N/A if(fElementDeclType[chunk][index] == -1){
286N/A return -1 ;
286N/A }
286N/A else{
286N/A return (short) (fElementDeclType[chunk][index] & LIST_MASK);
286N/A }
286N/A
286N/A }//getContentSpecType
286N/A
286N/A /**
286N/A * getElementDecl
286N/A *
286N/A * @param elementDeclIndex
286N/A * @param elementDecl The values of this structure are set by this call.
286N/A *
286N/A * @return True if find the element, False otherwise.
286N/A */
286N/A public boolean getElementDecl(int elementDeclIndex,
286N/A XMLElementDecl elementDecl) {
286N/A
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return false;
286N/A }
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A elementDecl.name.setValues(fElementDeclName[chunk][index]);
286N/A
286N/A if (fElementDeclType[chunk][index] == -1) {
286N/A elementDecl.type = -1;
286N/A elementDecl.simpleType.list = false;
286N/A } else {
286N/A elementDecl.type = (short) (fElementDeclType[chunk][index] & LIST_MASK);
286N/A elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
286N/A }
286N/A
286N/A /* Validators are null until we add that code */
286N/A if (elementDecl.type == XMLElementDecl.TYPE_CHILDREN || elementDecl.type == XMLElementDecl.TYPE_MIXED) {
286N/A elementDecl.contentModelValidator = getElementContentModelValidator(elementDeclIndex);
286N/A }
286N/A
286N/A elementDecl.simpleType.datatypeValidator = null;
286N/A elementDecl.simpleType.defaultType = -1;
286N/A elementDecl.simpleType.defaultValue = null;
286N/A
286N/A return true;
286N/A
286N/A } // getElementDecl(int,XMLElementDecl):boolean
286N/A
286N/A QName getElementDeclName(int elementDeclIndex) {
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return null;
286N/A }
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A return fElementDeclName[chunk][index];
286N/A }
286N/A
286N/A // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac
286N/A
286N/A /**
286N/A * getFirstAttributeDeclIndex
286N/A *
286N/A * @param elementDeclIndex
286N/A *
286N/A * @return index of the first attribute for element declaration elementDeclIndex
286N/A */
286N/A public int getFirstAttributeDeclIndex(int elementDeclIndex) {
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A return fElementDeclFirstAttributeDeclIndex[chunk][index];
286N/A } // getFirstAttributeDeclIndex
286N/A
286N/A /**
286N/A * getNextAttributeDeclIndex
286N/A *
286N/A * @param attributeDeclIndex
286N/A *
286N/A * @return index of the next attribute of the attribute at attributeDeclIndex
286N/A */
286N/A public int getNextAttributeDeclIndex(int attributeDeclIndex) {
286N/A int chunk = attributeDeclIndex >> CHUNK_SHIFT;
286N/A int index = attributeDeclIndex & CHUNK_MASK;
286N/A
286N/A return fAttributeDeclNextAttributeDeclIndex[chunk][index];
286N/A } // getNextAttributeDeclIndex
286N/A
286N/A /**
286N/A * getAttributeDecl
286N/A *
286N/A * @param attributeDeclIndex
286N/A * @param attributeDecl The values of this structure are set by this call.
286N/A *
286N/A * @return true if getAttributeDecl was able to fill in the value of attributeDecl
286N/A */
286N/A public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
286N/A if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
286N/A return false;
286N/A }
286N/A int chunk = attributeDeclIndex >> CHUNK_SHIFT;
286N/A int index = attributeDeclIndex & CHUNK_MASK;
286N/A
286N/A attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
286N/A
286N/A short attributeType;
286N/A boolean isList;
286N/A
286N/A if (fAttributeDeclType[chunk][index] == -1) {
286N/A
286N/A attributeType = -1;
286N/A isList = false;
286N/A } else {
286N/A attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK);
286N/A isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
286N/A }
286N/A attributeDecl.simpleType.setValues(attributeType,fAttributeDeclName[chunk][index].localpart,
286N/A fAttributeDeclEnumeration[chunk][index],
286N/A isList, fAttributeDeclDefaultType[chunk][index],
286N/A fAttributeDeclDefaultValue[chunk][index],
286N/A fAttributeDeclNonNormalizedDefaultValue[chunk][index],
286N/A fAttributeDeclDatatypeValidator[chunk][index]);
286N/A return true;
286N/A
286N/A } // getAttributeDecl
286N/A
286N/A
286N/A /**
286N/A * Returns whether the given attribute is of type CDATA or not
286N/A *
286N/A * @param elName The element name.
286N/A * @param atName The attribute name.
286N/A *
286N/A * @return true if the attribute is of type CDATA
286N/A */
286N/A public boolean isCDATAAttribute(QName elName, QName atName) {
286N/A int elDeclIdx = getElementDeclIndex(elName);
286N/A if (getAttributeDecl(elDeclIdx, fAttributeDecl)
286N/A && fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA){
286N/A return false;
286N/A }
286N/A return true;
286N/A }
286N/A
286N/A /**
286N/A * getEntityDeclIndex
286N/A *
286N/A * @param entityDeclName
286N/A *
286N/A * @return the index of the EntityDecl
286N/A */
286N/A public int getEntityDeclIndex(String entityDeclName) {
286N/A if (entityDeclName == null) {
286N/A return -1;
286N/A }
286N/A
286N/A return fEntityIndexMap.get(entityDeclName);
286N/A } // getEntityDeclIndex
286N/A
286N/A /**
286N/A * getEntityDecl
286N/A *
286N/A * @param entityDeclIndex
286N/A * @param entityDecl
286N/A *
286N/A * @return true if getEntityDecl was able to fill entityDecl with the contents of the entity
286N/A * with index entityDeclIndex
286N/A */
286N/A public boolean getEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
286N/A if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) {
286N/A return false;
286N/A }
286N/A int chunk = entityDeclIndex >> CHUNK_SHIFT;
286N/A int index = entityDeclIndex & CHUNK_MASK;
286N/A
286N/A entityDecl.setValues(fEntityName[chunk][index],
286N/A fEntityPublicId[chunk][index],
286N/A fEntitySystemId[chunk][index],
286N/A fEntityBaseSystemId[chunk][index],
286N/A fEntityNotation[chunk][index],
286N/A fEntityValue[chunk][index],
286N/A fEntityIsPE[chunk][index] == 0 ? false : true ,
286N/A fEntityInExternal[chunk][index] == 0 ? false : true );
286N/A
286N/A return true;
286N/A } // getEntityDecl
286N/A
286N/A /**
286N/A * getNotationDeclIndex
286N/A *
286N/A * @param notationDeclName
286N/A *
286N/A * @return the index if found a notation with the name, otherwise -1.
286N/A */
286N/A public int getNotationDeclIndex(String notationDeclName) {
286N/A if (notationDeclName == null) {
286N/A return -1;
286N/A }
286N/A
286N/A return fNotationIndexMap.get(notationDeclName);
286N/A } // getNotationDeclIndex
286N/A
286N/A /**
286N/A * getNotationDecl
286N/A *
286N/A * @param notationDeclIndex
286N/A * @param notationDecl
286N/A *
286N/A * @return return true of getNotationDecl can fill notationDecl with information about
286N/A * the notation at notationDeclIndex.
286N/A */
286N/A public boolean getNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
286N/A if (notationDeclIndex < 0 || notationDeclIndex >= fNotationCount) {
286N/A return false;
286N/A }
286N/A int chunk = notationDeclIndex >> CHUNK_SHIFT;
286N/A int index = notationDeclIndex & CHUNK_MASK;
286N/A
286N/A notationDecl.setValues(fNotationName[chunk][index],
286N/A fNotationPublicId[chunk][index],
286N/A fNotationSystemId[chunk][index],
286N/A fNotationBaseSystemId[chunk][index]);
286N/A
286N/A return true;
286N/A
286N/A } // getNotationDecl
286N/A
286N/A /**
286N/A * getContentSpec
286N/A *
286N/A * @param contentSpecIndex
286N/A * @param contentSpec
286N/A *
286N/A * @return true if find the requested contentSpec node, false otherwise
286N/A */
286N/A public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
286N/A if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount )
286N/A return false;
286N/A
286N/A int chunk = contentSpecIndex >> CHUNK_SHIFT;
286N/A int index = contentSpecIndex & CHUNK_MASK;
286N/A
286N/A contentSpec.type = fContentSpecType[chunk][index];
286N/A contentSpec.value = fContentSpecValue[chunk][index];
286N/A contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
286N/A return true;
286N/A }
286N/A
286N/A /**
286N/A * Returns the index to the content spec for the given element
286N/A * declaration, or <code>-1</code> if the element declaration
286N/A * index was invalid.
286N/A */
286N/A public int getContentSpecIndex(int elementDeclIndex) {
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return -1;
286N/A }
286N/A final int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A final int index = elementDeclIndex & CHUNK_MASK;
286N/A return fElementDeclContentSpecIndex[chunk][index];
286N/A }
286N/A
286N/A /**
286N/A * getContentSpecAsString
286N/A *
286N/A * @param elementDeclIndex
286N/A *
286N/A * @return String
286N/A */
286N/A public String getContentSpecAsString(int elementDeclIndex){
286N/A
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return null;
286N/A }
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
286N/A
286N/A // lookup content spec node
286N/A XMLContentSpec contentSpec = new XMLContentSpec();
286N/A
286N/A if (getContentSpec(contentSpecIndex, contentSpec)) {
286N/A
286N/A // build string
286N/A StringBuffer str = new StringBuffer();
286N/A int parentContentSpecType = contentSpec.type & 0x0f;
286N/A int nextContentSpec;
286N/A switch (parentContentSpecType) {
286N/A case XMLContentSpec.CONTENTSPECNODE_LEAF: {
286N/A str.append('(');
286N/A if (contentSpec.value == null && contentSpec.otherValue == null) {
286N/A str.append("#PCDATA");
286N/A }
286N/A else {
286N/A str.append(contentSpec.value);
286N/A }
286N/A str.append(')');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A nextContentSpec = contentSpec.type;
286N/A
286N/A if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A str.append('(');
286N/A str.append(contentSpec.value);
286N/A str.append(')');
286N/A } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A str.append('(' );
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A str.append(')');
286N/A } else {
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A }
286N/A str.append('?');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A nextContentSpec = contentSpec.type;
286N/A
286N/A if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A str.append('(');
286N/A if (contentSpec.value == null && contentSpec.otherValue == null) {
286N/A str.append("#PCDATA");
286N/A }
286N/A else if (contentSpec.otherValue != null) {
286N/A str.append("##any:uri=").append(contentSpec.otherValue);
286N/A }
286N/A else if (contentSpec.value == null) {
286N/A str.append("##any");
286N/A }
286N/A else {
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A }
286N/A str.append(')');
286N/A } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A str.append('(' );
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A str.append(')');
286N/A } else {
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A }
286N/A str.append('*');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A nextContentSpec = contentSpec.type;
286N/A
286N/A if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A str.append('(');
286N/A if (contentSpec.value == null && contentSpec.otherValue == null) {
286N/A str.append("#PCDATA");
286N/A }
286N/A else if (contentSpec.otherValue != null) {
286N/A str.append("##any:uri=").append(contentSpec.otherValue);
286N/A }
286N/A else if (contentSpec.value == null) {
286N/A str.append("##any");
286N/A }
286N/A else {
286N/A str.append(contentSpec.value);
286N/A }
286N/A str.append(')');
286N/A } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A str.append('(' );
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A str.append(')');
286N/A } else {
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType);
286N/A }
286N/A str.append('+');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_CHOICE:
286N/A case XMLContentSpec.CONTENTSPECNODE_SEQ: {
286N/A appendContentSpec(contentSpec, str,
286N/A true, parentContentSpecType );
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY: {
286N/A str.append("##any");
286N/A if (contentSpec.otherValue != null) {
286N/A str.append(":uri=");
286N/A str.append(contentSpec.otherValue);
286N/A }
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
286N/A str.append("##other:uri=");
286N/A str.append(contentSpec.otherValue);
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
286N/A str.append("##local");
286N/A break;
286N/A }
286N/A default: {
286N/A str.append("???");
286N/A }
286N/A
286N/A } // switch type
286N/A
286N/A // return string
286N/A return str.toString();
286N/A }
286N/A
286N/A // not found
286N/A return null;
286N/A
286N/A } // getContentSpecAsString(int):String
286N/A
286N/A // debugging
286N/A
286N/A public void printElements( ) {
286N/A int elementDeclIndex = 0;
286N/A XMLElementDecl elementDecl = new XMLElementDecl();
286N/A while (getElementDecl(elementDeclIndex++, elementDecl)) {
286N/A
286N/A System.out.println("element decl: "+elementDecl.name+
286N/A ", "+ elementDecl.name.rawname );
286N/A
286N/A // ", "+ elementDecl.contentModelValidator.toString());
286N/A }
286N/A }
286N/A
286N/A public void printAttributes(int elementDeclIndex) {
286N/A int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
286N/A System.out.print(elementDeclIndex);
286N/A System.out.print(" [");
286N/A while (attributeDeclIndex != -1) {
286N/A System.out.print(' ');
286N/A System.out.print(attributeDeclIndex);
286N/A printAttribute(attributeDeclIndex);
286N/A attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
286N/A if (attributeDeclIndex != -1) {
286N/A System.out.print(",");
286N/A }
286N/A }
286N/A System.out.println(" ]");
286N/A }
286N/A
286N/A //
286N/A // Protected methods
286N/A //
286N/A
286N/A /**
286N/A * Adds the content spec to the given element declaration.
286N/A */
286N/A protected void addContentSpecToElement(XMLElementDecl elementDecl) {
286N/A if ((fDepth == 0 || (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED)) &&
286N/A fNodeIndexStack != null) {
286N/A if (elementDecl.type == XMLElementDecl.TYPE_MIXED) {
286N/A int pcdata = addUniqueLeafNode(null);
286N/A if (fNodeIndexStack[0] == -1) {
286N/A fNodeIndexStack[0] = pcdata;
286N/A }
286N/A else {
286N/A fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE,
286N/A pcdata, fNodeIndexStack[0]);
286N/A }
286N/A }
286N/A setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * getElementContentModelValidator
286N/A *
286N/A * @param elementDeclIndex
286N/A *
286N/A * @return its ContentModelValidator if any.
286N/A */
286N/A protected ContentModelValidator getElementContentModelValidator(int elementDeclIndex) {
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A ContentModelValidator contentModel = fElementDeclContentModelValidator[chunk][index];
286N/A
286N/A // If we have one, just return that. Otherwise, gotta create one
286N/A if (contentModel != null) {
286N/A return contentModel;
286N/A }
286N/A
286N/A int contentType = fElementDeclType[chunk][index];
286N/A if (contentType == XMLElementDecl.TYPE_SIMPLE) {
286N/A return null;
286N/A }
286N/A
286N/A // Get the type of content this element has
286N/A int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
286N/A
286N/A /***
286N/A if ( contentSpecIndex == -1 )
286N/A return null;
286N/A /***/
286N/A
286N/A XMLContentSpec contentSpec = new XMLContentSpec();
286N/A getContentSpec( contentSpecIndex, contentSpec );
286N/A
286N/A // And create the content model according to the spec type
286N/A if ( contentType == XMLElementDecl.TYPE_MIXED ) {
286N/A //
286N/A // Just create a mixel content model object. This type of
286N/A // content model is optimized for mixed content validation.
286N/A //
286N/A ChildrenList children = new ChildrenList();
286N/A contentSpecTree(contentSpecIndex, contentSpec, children);
286N/A contentModel = new MixedContentModel(children.qname,
286N/A children.type,
286N/A 0, children.length,
286N/A false);
286N/A } else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
286N/A // This method will create an optimal model for the complexity
286N/A // of the element's defined model. If its simple, it will create
286N/A // a SimpleContentModel object. If its a simple list, it will
286N/A // create a SimpleListContentModel object. If its complex, it
286N/A // will create a DFAContentModel object.
286N/A //
286N/A contentModel = createChildModel(contentSpecIndex);
286N/A } else {
286N/A throw new RuntimeException("Unknown content type for a element decl "
286N/A + "in getElementContentModelValidator() in AbstractDTDGrammar class");
286N/A }
286N/A
286N/A // Add the new model to the content model for this element
286N/A fElementDeclContentModelValidator[chunk][index] = contentModel;
286N/A
286N/A return contentModel;
286N/A
286N/A } // getElementContentModelValidator(int):ContentModelValidator
286N/A
286N/A protected int createElementDecl() {
286N/A int chunk = fElementDeclCount >> CHUNK_SHIFT;
286N/A int index = fElementDeclCount & CHUNK_MASK;
286N/A ensureElementDeclCapacity(chunk);
286N/A fElementDeclName[chunk][index] = new QName();
286N/A fElementDeclType[chunk][index] = -1;
286N/A fElementDeclContentModelValidator[chunk][index] = null;
286N/A fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
286N/A fElementDeclLastAttributeDeclIndex[chunk][index] = -1;
286N/A return fElementDeclCount++;
286N/A }
286N/A
286N/A protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return;
286N/A }
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A fElementDeclName[chunk][index].setValues(elementDecl.name);
286N/A fElementDeclType[chunk][index] = elementDecl.type;
286N/A
286N/A fElementDeclContentModelValidator[chunk][index] = elementDecl.contentModelValidator;
286N/A
286N/A if (elementDecl.simpleType.list == true ) {
286N/A fElementDeclType[chunk][index] |= LIST_FLAG;
286N/A }
286N/A
286N/A fElementIndexMap.put(elementDecl.name.rawname, elementDeclIndex);
286N/A }
286N/A
286N/A
286N/A
286N/A
286N/A protected void putElementNameMapping(QName name, int scope,
286N/A int elementDeclIndex) {
286N/A }
286N/A
286N/A protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){
286N/A
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return;
286N/A }
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
286N/A }
286N/A
286N/A protected void setContentSpecIndex(int elementDeclIndex, int contentSpecIndex){
286N/A
286N/A if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
286N/A return;
286N/A }
286N/A
286N/A int chunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int index = elementDeclIndex & CHUNK_MASK;
286N/A
286N/A fElementDeclContentSpecIndex[chunk][index] = contentSpecIndex;
286N/A }
286N/A
286N/A
286N/A protected int createAttributeDecl() {
286N/A int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
286N/A int index = fAttributeDeclCount & CHUNK_MASK;
286N/A
286N/A ensureAttributeDeclCapacity(chunk);
286N/A fAttributeDeclName[chunk][index] = new QName();
286N/A fAttributeDeclType[chunk][index] = -1;
286N/A fAttributeDeclDatatypeValidator[chunk][index] = null;
286N/A fAttributeDeclEnumeration[chunk][index] = null;
286N/A fAttributeDeclDefaultType[chunk][index] = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
286N/A fAttributeDeclDefaultValue[chunk][index] = null;
286N/A fAttributeDeclNonNormalizedDefaultValue[chunk][index] = null;
286N/A fAttributeDeclNextAttributeDeclIndex[chunk][index] = -1;
286N/A return fAttributeDeclCount++;
286N/A }
286N/A
286N/A
286N/A protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex,
286N/A XMLAttributeDecl attributeDecl) {
286N/A int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
286N/A int attrIndex = attributeDeclIndex & CHUNK_MASK;
286N/A fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name);
286N/A fAttributeDeclType[attrChunk][attrIndex] = attributeDecl.simpleType.type;
286N/A
286N/A if (attributeDecl.simpleType.list) {
286N/A fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
286N/A }
286N/A fAttributeDeclEnumeration[attrChunk][attrIndex] = attributeDecl.simpleType.enumeration;
286N/A fAttributeDeclDefaultType[attrChunk][attrIndex] = attributeDecl.simpleType.defaultType;
286N/A fAttributeDeclDatatypeValidator[attrChunk][attrIndex] = attributeDecl.simpleType.datatypeValidator;
286N/A
286N/A fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.defaultValue;
286N/A fAttributeDeclNonNormalizedDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.nonNormalizedDefaultValue;
286N/A
286N/A int elemChunk = elementDeclIndex >> CHUNK_SHIFT;
286N/A int elemIndex = elementDeclIndex & CHUNK_MASK;
286N/A int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
286N/A while (index != -1) {
286N/A if (index == attributeDeclIndex) {
286N/A break;
286N/A }
286N/A attrChunk = index >> CHUNK_SHIFT;
286N/A attrIndex = index & CHUNK_MASK;
286N/A index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
286N/A }
286N/A if (index == -1) {
286N/A if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
286N/A fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
286N/A } else {
286N/A index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
286N/A attrChunk = index >> CHUNK_SHIFT;
286N/A attrIndex = index & CHUNK_MASK;
286N/A fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
286N/A }
286N/A fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
286N/A }
286N/A }
286N/A
286N/A protected int createContentSpec() {
286N/A int chunk = fContentSpecCount >> CHUNK_SHIFT;
286N/A int index = fContentSpecCount & CHUNK_MASK;
286N/A
286N/A ensureContentSpecCapacity(chunk);
286N/A fContentSpecType[chunk][index] = -1;
286N/A fContentSpecValue[chunk][index] = null;
286N/A fContentSpecOtherValue[chunk][index] = null;
286N/A
286N/A return fContentSpecCount++;
286N/A }
286N/A
286N/A protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
286N/A int chunk = contentSpecIndex >> CHUNK_SHIFT;
286N/A int index = contentSpecIndex & CHUNK_MASK;
286N/A
286N/A fContentSpecType[chunk][index] = contentSpec.type;
286N/A fContentSpecValue[chunk][index] = contentSpec.value;
286N/A fContentSpecOtherValue[chunk][index] = contentSpec.otherValue;
286N/A }
286N/A
286N/A
286N/A protected int createEntityDecl() {
286N/A int chunk = fEntityCount >> CHUNK_SHIFT;
286N/A int index = fEntityCount & CHUNK_MASK;
286N/A
286N/A ensureEntityDeclCapacity(chunk);
286N/A fEntityIsPE[chunk][index] = 0;
286N/A fEntityInExternal[chunk][index] = 0;
286N/A
286N/A return fEntityCount++;
286N/A }
286N/A
286N/A protected void setEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
286N/A int chunk = entityDeclIndex >> CHUNK_SHIFT;
286N/A int index = entityDeclIndex & CHUNK_MASK;
286N/A
286N/A fEntityName[chunk][index] = entityDecl.name;
286N/A fEntityValue[chunk][index] = entityDecl.value;
286N/A fEntityPublicId[chunk][index] = entityDecl.publicId;
286N/A fEntitySystemId[chunk][index] = entityDecl.systemId;
286N/A fEntityBaseSystemId[chunk][index] = entityDecl.baseSystemId;
286N/A fEntityNotation[chunk][index] = entityDecl.notation;
286N/A fEntityIsPE[chunk][index] = entityDecl.isPE ? (byte)1 : (byte)0;
286N/A fEntityInExternal[chunk][index] = entityDecl.inExternal ? (byte)1 : (byte)0;
286N/A
286N/A fEntityIndexMap.put(entityDecl.name, entityDeclIndex);
286N/A }
286N/A
286N/A protected int createNotationDecl() {
286N/A int chunk = fNotationCount >> CHUNK_SHIFT;
286N/A ensureNotationDeclCapacity(chunk);
286N/A return fNotationCount++;
286N/A }
286N/A
286N/A protected void setNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
286N/A int chunk = notationDeclIndex >> CHUNK_SHIFT;
286N/A int index = notationDeclIndex & CHUNK_MASK;
286N/A
286N/A fNotationName[chunk][index] = notationDecl.name;
286N/A fNotationPublicId[chunk][index] = notationDecl.publicId;
286N/A fNotationSystemId[chunk][index] = notationDecl.systemId;
286N/A fNotationBaseSystemId[chunk][index] = notationDecl.baseSystemId;
286N/A
286N/A fNotationIndexMap.put(notationDecl.name, notationDeclIndex);
286N/A }
286N/A
286N/A /**
286N/A * Create an XMLContentSpec for a single non-leaf
286N/A *
286N/A * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
286N/A * @param nodeValue handle to an XMLContentSpec
286N/A * @return handle to the newly create XMLContentSpec
286N/A */
286N/A protected int addContentSpecNode(short nodeType, String nodeValue) {
286N/A
286N/A // create content spec node
286N/A int contentSpecIndex = createContentSpec();
286N/A
286N/A // set content spec node values
286N/A fContentSpec.setValues(nodeType, nodeValue, null);
286N/A setContentSpec(contentSpecIndex, fContentSpec);
286N/A
286N/A // return index
286N/A return contentSpecIndex;
286N/A
286N/A } // addContentSpecNode(short,String):int
286N/A
286N/A /**
286N/A * create an XMLContentSpec for a leaf
286N/A *
286N/A * @param elementName the name (Element) for the node
286N/A * @return handle to the newly create XMLContentSpec
286N/A */
286N/A protected int addUniqueLeafNode(String elementName) {
286N/A
286N/A // create content spec node
286N/A int contentSpecIndex = createContentSpec();
286N/A
286N/A // set content spec node values
286N/A fContentSpec.setValues( XMLContentSpec.CONTENTSPECNODE_LEAF,
286N/A elementName, null);
286N/A setContentSpec(contentSpecIndex, fContentSpec);
286N/A
286N/A // return index
286N/A return contentSpecIndex;
286N/A
286N/A } // addUniqueLeafNode(String):int
286N/A
286N/A /**
286N/A * Create an XMLContentSpec for a two child leaf
286N/A *
286N/A * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
286N/A * @param leftNodeIndex handle to an XMLContentSpec
286N/A * @param rightNodeIndex handle to an XMLContentSpec
286N/A * @return handle to the newly create XMLContentSpec
286N/A */
286N/A protected int addContentSpecNode(short nodeType,
286N/A int leftNodeIndex, int rightNodeIndex) {
286N/A
286N/A // create content spec node
286N/A int contentSpecIndex = createContentSpec();
286N/A
286N/A // set content spec node values
286N/A int[] leftIntArray = new int[1];
286N/A int[] rightIntArray = new int[1];
286N/A
286N/A leftIntArray[0] = leftNodeIndex;
286N/A rightIntArray[0] = rightNodeIndex;
286N/A fContentSpec.setValues(nodeType, leftIntArray, rightIntArray);
286N/A setContentSpec(contentSpecIndex, fContentSpec);
286N/A
286N/A // return index
286N/A return contentSpecIndex;
286N/A
286N/A } // addContentSpecNode(short,int,int):int
286N/A
286N/A /** Initialize content model stack. */
286N/A protected void initializeContentModelStack() {
286N/A
286N/A if (fOpStack == null) {
286N/A fOpStack = new short[8];
286N/A fNodeIndexStack = new int[8];
286N/A fPrevNodeIndexStack = new int[8];
286N/A } else if (fDepth == fOpStack.length) {
286N/A short[] newStack = new short[fDepth * 2];
286N/A System.arraycopy(fOpStack, 0, newStack, 0, fDepth);
286N/A fOpStack = newStack;
286N/A int[] newIntStack = new int[fDepth * 2];
286N/A System.arraycopy(fNodeIndexStack, 0, newIntStack, 0, fDepth);
286N/A fNodeIndexStack = newIntStack;
286N/A newIntStack = new int[fDepth * 2];
286N/A System.arraycopy(fPrevNodeIndexStack, 0, newIntStack, 0, fDepth);
286N/A fPrevNodeIndexStack = newIntStack;
286N/A }
286N/A fOpStack[fDepth] = -1;
286N/A fNodeIndexStack[fDepth] = -1;
286N/A fPrevNodeIndexStack[fDepth] = -1;
286N/A
286N/A } // initializeContentModelStack()
286N/A
286N/A boolean isImmutable() {
286N/A return fIsImmutable;
286N/A }
286N/A
286N/A //
286N/A // Private methods
286N/A //
286N/A
286N/A private void appendContentSpec(XMLContentSpec contentSpec,
286N/A StringBuffer str, boolean parens,
286N/A int parentContentSpecType ) {
286N/A
286N/A int thisContentSpec = contentSpec.type & 0x0f;
286N/A switch (thisContentSpec) {
286N/A case XMLContentSpec.CONTENTSPECNODE_LEAF: {
286N/A if (contentSpec.value == null && contentSpec.otherValue == null) {
286N/A str.append("#PCDATA");
286N/A }
286N/A else if (contentSpec.value == null && contentSpec.otherValue != null) {
286N/A str.append("##any:uri=").append(contentSpec.otherValue);
286N/A }
286N/A else if (contentSpec.value == null) {
286N/A str.append("##any");
286N/A }
286N/A else {
286N/A str.append(contentSpec.value);
286N/A }
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
286N/A if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A str.append('(');
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec );
286N/A str.append(')');
286N/A }
286N/A else {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A appendContentSpec( contentSpec, str, true, thisContentSpec );
286N/A }
286N/A str.append('?');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
286N/A if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A str.append('(');
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec);
286N/A str.append(')' );
286N/A }
286N/A else {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec);
286N/A }
286N/A str.append('*');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
286N/A if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
286N/A
286N/A str.append('(');
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec);
286N/A str.append(')' );
286N/A }
286N/A else {
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec);
286N/A }
286N/A str.append('+');
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_CHOICE:
286N/A case XMLContentSpec.CONTENTSPECNODE_SEQ: {
286N/A if (parens) {
286N/A str.append('(');
286N/A }
286N/A int type = contentSpec.type;
286N/A int otherValue = ((int[])contentSpec.otherValue)[0];
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpec);
286N/A appendContentSpec(contentSpec, str, contentSpec.type != type, thisContentSpec);
286N/A if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
286N/A str.append('|');
286N/A }
286N/A else {
286N/A str.append(',');
286N/A }
286N/A getContentSpec(otherValue, contentSpec);
286N/A appendContentSpec(contentSpec, str, true, thisContentSpec);
286N/A if (parens) {
286N/A str.append(')');
286N/A }
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY: {
286N/A str.append("##any");
286N/A if (contentSpec.otherValue != null) {
286N/A str.append(":uri=");
286N/A str.append(contentSpec.otherValue);
286N/A }
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
286N/A str.append("##other:uri=");
286N/A str.append(contentSpec.otherValue);
286N/A break;
286N/A }
286N/A case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
286N/A str.append("##local");
286N/A break;
286N/A }
286N/A default: {
286N/A str.append("???");
286N/A break;
286N/A }
286N/A
286N/A } // switch type
286N/A
286N/A } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
286N/A
286N/A // debugging
286N/A
286N/A private void printAttribute(int attributeDeclIndex) {
286N/A
286N/A XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
286N/A if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
286N/A System.out.print(" { ");
286N/A System.out.print(attributeDecl.name.localpart);
286N/A System.out.print(" }");
286N/A }
286N/A
286N/A } // printAttribute(int)
286N/A
286N/A // content models
286N/A
286N/A /**
286N/A * When the element has a 'CHILDREN' model, this method is called to
286N/A * create the content model object. It looks for some special case simple
286N/A * models and creates SimpleContentModel objects for those. For the rest
286N/A * it creates the standard DFA style model.
286N/A */
286N/A private synchronized ContentModelValidator createChildModel(int contentSpecIndex) {
286N/A
286N/A //
286N/A // Get the content spec node for the element we are working on.
286N/A // This will tell us what kind of node it is, which tells us what
286N/A // kind of model we will try to create.
286N/A //
286N/A XMLContentSpec contentSpec = new XMLContentSpec();
286N/A getContentSpec(contentSpecIndex, contentSpec);
286N/A
286N/A if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY ||
286N/A (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
286N/A (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
286N/A // let fall through to build a DFAContentModel
286N/A }
286N/A
286N/A else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A //
286N/A // Check that the left value is not -1, since any content model
286N/A // with PCDATA should be MIXED, so we should not have gotten here.
286N/A //
286N/A if (contentSpec.value == null && contentSpec.otherValue == null)
286N/A throw new RuntimeException("ImplementationMessages.VAL_NPCD");
286N/A
286N/A //
286N/A // Its a single leaf, so its an 'a' type of content model, i.e.
286N/A // just one instance of one element. That one is definitely a
286N/A // simple content model.
286N/A //
286N/A
286N/A fQName.setValues(null, (String)contentSpec.value,
286N/A (String)contentSpec.value, (String)contentSpec.otherValue);
286N/A return new SimpleContentModel(contentSpec.type, fQName, null);
286N/A } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
286N/A || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
286N/A //
286N/A // Lets see if both of the children are leafs. If so, then it
286N/A // it has to be a simple content model
286N/A //
286N/A XMLContentSpec contentSpecLeft = new XMLContentSpec();
286N/A XMLContentSpec contentSpecRight = new XMLContentSpec();
286N/A
286N/A getContentSpec( ((int[])contentSpec.value)[0], contentSpecLeft);
286N/A getContentSpec( ((int[])contentSpec.otherValue)[0], contentSpecRight);
286N/A
286N/A if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
286N/A && (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
286N/A //
286N/A // Its a simple choice or sequence, so we can do a simple
286N/A // content model for it.
286N/A //
286N/A fQName.setValues(null, (String)contentSpecLeft.value,
286N/A (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
286N/A fQName2.setValues(null, (String)contentSpecRight.value,
286N/A (String)contentSpecRight.value, (String)contentSpecRight.otherValue);
286N/A return new SimpleContentModel(contentSpec.type, fQName, fQName2);
286N/A }
286N/A } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
286N/A || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
286N/A || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
286N/A //
286N/A // Its a repetition, so see if its one child is a leaf. If so
286N/A // its a repetition of a single element, so we can do a simple
286N/A // content model for that.
286N/A //
286N/A XMLContentSpec contentSpecLeft = new XMLContentSpec();
286N/A getContentSpec(((int[])contentSpec.value)[0], contentSpecLeft);
286N/A
286N/A if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A //
286N/A // It is, so we can create a simple content model here that
286N/A // will check for this repetition. We pass -1 for the unused
286N/A // right node.
286N/A //
286N/A fQName.setValues(null, (String)contentSpecLeft.value,
286N/A (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
286N/A return new SimpleContentModel(contentSpec.type, fQName, null);
286N/A }
286N/A } else {
286N/A throw new RuntimeException("ImplementationMessages.VAL_CST");
286N/A }
286N/A
286N/A //
286N/A // Its not a simple content model, so here we have to create a DFA
286N/A // for this element. So we create a DFAContentModel object. He
286N/A // encapsulates all of the work to create the DFA.
286N/A //
286N/A
286N/A fLeafCount = 0;
286N/A //int leafCount = countLeaves(contentSpecIndex);
286N/A fLeafCount = 0;
286N/A CMNode cmn = buildSyntaxTree(contentSpecIndex, contentSpec);
286N/A
286N/A // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
286N/A return new DFAContentModel( cmn, fLeafCount, false);
286N/A
286N/A } // createChildModel(int):ContentModelValidator
286N/A
286N/A private final CMNode buildSyntaxTree(int startNode,
286N/A XMLContentSpec contentSpec) {
286N/A
286N/A // We will build a node at this level for the new tree
286N/A CMNode nodeRet = null;
286N/A getContentSpec(startNode, contentSpec);
286N/A if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) {
286N/A //nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++);
286N/A nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++);
286N/A }
286N/A else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
286N/A nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++);
286N/A }
286N/A else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
286N/A nodeRet = new CMAny(contentSpec.type, null, fLeafCount++);
286N/A }
286N/A //
286N/A // If this node is a leaf, then its an easy one. We just add it
286N/A // to the tree.
286N/A //
286N/A else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
286N/A //
286N/A // Create a new leaf node, and pass it the current leaf count,
286N/A // which is its DFA state position. Bump the leaf count after
286N/A // storing it. This makes the positions zero based since we
286N/A // store first and then increment.
286N/A //
286N/A fQName.setValues(null, (String)contentSpec.value,
286N/A (String)contentSpec.value, (String)contentSpec.otherValue);
286N/A nodeRet = new CMLeaf(fQName, fLeafCount++);
286N/A }
286N/A else {
286N/A //
286N/A // Its not a leaf, so we have to recurse its left and maybe right
286N/A // nodes. Save both values before we recurse and trash the node.
286N/A final int leftNode = ((int[])contentSpec.value)[0];
286N/A final int rightNode = ((int[])contentSpec.otherValue)[0];
286N/A
286N/A if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
286N/A || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
286N/A //
286N/A // Recurse on both children, and return a binary op node
286N/A // with the two created sub nodes as its children. The node
286N/A // type is the same type as the source.
286N/A //
286N/A
286N/A nodeRet = new CMBinOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec)
286N/A , buildSyntaxTree(rightNode, contentSpec));
286N/A }
286N/A else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) {
286N/A nodeRet = new CMUniOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
286N/A }
286N/A else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
286N/A || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
286N/A || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
286N/A nodeRet = new CMUniOp(contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
286N/A }
286N/A else {
286N/A throw new RuntimeException("ImplementationMessages.VAL_CST");
286N/A }
286N/A }
286N/A // And return our new node for this level
286N/A return nodeRet;
286N/A }
286N/A
286N/A /**
286N/A * Build a vector of valid QNames from Content Spec
286N/A * table.
286N/A *
286N/A * @param contentSpecIndex
286N/A * Content Spec index
286N/A * @param vectorQName
286N/A * Array of QName
286N/A * @exception RuntimeException
286N/A */
286N/A private void contentSpecTree(int contentSpecIndex,
286N/A XMLContentSpec contentSpec,
286N/A ChildrenList children) {
286N/A
286N/A // Handle any and leaf nodes
286N/A getContentSpec( contentSpecIndex, contentSpec);
286N/A if ( contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
286N/A (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
286N/A (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL ||
286N/A (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
286N/A
286N/A // resize arrays, if needed
286N/A if (children.length == children.qname.length) {
286N/A QName[] newQName = new QName[children.length * 2];
286N/A System.arraycopy(children.qname, 0, newQName, 0, children.length);
286N/A children.qname = newQName;
286N/A int[] newType = new int[children.length * 2];
286N/A System.arraycopy(children.type, 0, newType, 0, children.length);
286N/A children.type = newType;
286N/A }
286N/A
286N/A // save values and return length
286N/A children.qname[children.length] = new QName(null, (String)contentSpec.value,
286N/A (String) contentSpec.value,
286N/A (String) contentSpec.otherValue);
286N/A children.type[children.length] = contentSpec.type;
286N/A children.length++;
286N/A return;
286N/A }
286N/A
286N/A //
286N/A // Its not a leaf, so we have to recurse its left and maybe right
286N/A // nodes. Save both values before we recurse and trash the node.
286N/A //
286N/A final int leftNode = contentSpec.value != null
286N/A ? ((int[])(contentSpec.value))[0] : -1;
286N/A int rightNode = -1 ;
286N/A if (contentSpec.otherValue != null )
286N/A rightNode = ((int[])(contentSpec.otherValue))[0];
286N/A else
286N/A return;
286N/A
286N/A if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
286N/A contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
286N/A contentSpecTree(leftNode, contentSpec, children);
286N/A contentSpecTree(rightNode, contentSpec, children);
286N/A return;
286N/A }
286N/A
286N/A if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ||
286N/A contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
286N/A contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
286N/A contentSpecTree(leftNode, contentSpec, children);
286N/A return;
286N/A }
286N/A
286N/A // error
286N/A throw new RuntimeException("Invalid content spec type seen in contentSpecTree() method of AbstractDTDGrammar class : "+contentSpec.type);
286N/A
286N/A } // contentSpecTree(int,XMLContentSpec,ChildrenList)
286N/A
286N/A // ensure capacity
286N/A
286N/A private void ensureElementDeclCapacity(int chunk) {
286N/A if (chunk >= fElementDeclName.length) {
286N/A fElementDeclIsExternal = resize(fElementDeclIsExternal,
286N/A fElementDeclIsExternal.length * 2);
286N/A
286N/A fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
286N/A fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
286N/A fElementDeclContentModelValidator = resize(fElementDeclContentModelValidator, fElementDeclContentModelValidator.length * 2);
286N/A fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex,fElementDeclContentSpecIndex.length * 2);
286N/A fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
286N/A fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
286N/A }
286N/A else if (fElementDeclName[chunk] != null) {
286N/A return;
286N/A }
286N/A
286N/A fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
286N/A fElementDeclName[chunk] = new QName[CHUNK_SIZE];
286N/A fElementDeclType[chunk] = new short[CHUNK_SIZE];
286N/A fElementDeclContentModelValidator[chunk] = new ContentModelValidator[CHUNK_SIZE];
286N/A fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
286N/A fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
286N/A fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
286N/A return;
286N/A }
286N/A
286N/A private void ensureAttributeDeclCapacity(int chunk) {
286N/A
286N/A if (chunk >= fAttributeDeclName.length) {
286N/A fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal,
286N/A fAttributeDeclIsExternal.length * 2);
286N/A fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
286N/A fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
286N/A fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
286N/A fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
286N/A fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2);
286N/A fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
286N/A fAttributeDeclNonNormalizedDefaultValue = resize(fAttributeDeclNonNormalizedDefaultValue, fAttributeDeclNonNormalizedDefaultValue.length * 2);
286N/A fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
286N/A }
286N/A else if (fAttributeDeclName[chunk] != null) {
286N/A return;
286N/A }
286N/A
286N/A fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
286N/A fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
286N/A fAttributeDeclType[chunk] = new short[CHUNK_SIZE];
286N/A fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][];
286N/A fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE];
286N/A fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
286N/A fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
286N/A fAttributeDeclNonNormalizedDefaultValue[chunk] = new String[CHUNK_SIZE];
286N/A fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
286N/A return;
286N/A }
286N/A
286N/A private void ensureEntityDeclCapacity(int chunk) {
286N/A if (chunk >= fEntityName.length) {
286N/A fEntityName = resize(fEntityName, fEntityName.length * 2);
286N/A fEntityValue = resize(fEntityValue, fEntityValue.length * 2);
286N/A fEntityPublicId = resize(fEntityPublicId, fEntityPublicId.length * 2);
286N/A fEntitySystemId = resize(fEntitySystemId, fEntitySystemId.length * 2);
286N/A fEntityBaseSystemId = resize(fEntityBaseSystemId, fEntityBaseSystemId.length * 2);
286N/A fEntityNotation = resize(fEntityNotation, fEntityNotation.length * 2);
286N/A fEntityIsPE = resize(fEntityIsPE, fEntityIsPE.length * 2);
286N/A fEntityInExternal = resize(fEntityInExternal, fEntityInExternal.length * 2);
286N/A }
286N/A else if (fEntityName[chunk] != null) {
286N/A return;
286N/A }
286N/A
286N/A fEntityName[chunk] = new String[CHUNK_SIZE];
286N/A fEntityValue[chunk] = new String[CHUNK_SIZE];
286N/A fEntityPublicId[chunk] = new String[CHUNK_SIZE];
286N/A fEntitySystemId[chunk] = new String[CHUNK_SIZE];
286N/A fEntityBaseSystemId[chunk] = new String[CHUNK_SIZE];
286N/A fEntityNotation[chunk] = new String[CHUNK_SIZE];
286N/A fEntityIsPE[chunk] = new byte[CHUNK_SIZE];
286N/A fEntityInExternal[chunk] = new byte[CHUNK_SIZE];
286N/A return;
286N/A }
286N/A
286N/A private void ensureNotationDeclCapacity(int chunk) {
286N/A if (chunk >= fNotationName.length) {
286N/A fNotationName = resize(fNotationName, fNotationName.length * 2);
286N/A fNotationPublicId = resize(fNotationPublicId, fNotationPublicId.length * 2);
286N/A fNotationSystemId = resize(fNotationSystemId, fNotationSystemId.length * 2);
286N/A fNotationBaseSystemId = resize(fNotationBaseSystemId, fNotationBaseSystemId.length * 2);
286N/A }
286N/A else if (fNotationName[chunk] != null) {
286N/A return;
286N/A }
286N/A
286N/A fNotationName[chunk] = new String[CHUNK_SIZE];
286N/A fNotationPublicId[chunk] = new String[CHUNK_SIZE];
286N/A fNotationSystemId[chunk] = new String[CHUNK_SIZE];
286N/A fNotationBaseSystemId[chunk] = new String[CHUNK_SIZE];
286N/A return;
286N/A }
286N/A
286N/A private void ensureContentSpecCapacity(int chunk) {
286N/A if (chunk >= fContentSpecType.length) {
286N/A fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
286N/A fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
286N/A fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
286N/A }
286N/A else if (fContentSpecType[chunk] != null) {
286N/A return;
286N/A }
286N/A
286N/A fContentSpecType[chunk] = new short[CHUNK_SIZE];
286N/A fContentSpecValue[chunk] = new Object[CHUNK_SIZE];
286N/A fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE];
286N/A return;
286N/A }
286N/A
286N/A //
286N/A // Private static methods
286N/A //
286N/A
286N/A // resize chunks
286N/A
286N/A private static byte[][] resize(byte array[][], int newsize) {
286N/A byte newarray[][] = new byte[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static short[][] resize(short array[][], int newsize) {
286N/A short newarray[][] = new short[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static int[][] resize(int array[][], int newsize) {
286N/A int newarray[][] = new int[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
286N/A DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static ContentModelValidator[][] resize(ContentModelValidator array[][], int newsize) {
286N/A ContentModelValidator newarray[][] = new ContentModelValidator[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static Object[][] resize(Object array[][], int newsize) {
286N/A Object newarray[][] = new Object[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static QName[][] resize(QName array[][], int newsize) {
286N/A QName newarray[][] = new QName[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static String[][] resize(String array[][], int newsize) {
286N/A String newarray[][] = new String[newsize][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A private static String[][][] resize(String array[][][], int newsize) {
286N/A String newarray[][][] = new String[newsize] [][];
286N/A System.arraycopy(array, 0, newarray, 0, array.length);
286N/A return newarray;
286N/A }
286N/A
286N/A //
286N/A // Classes
286N/A //
286N/A
286N/A /**
286N/A * Children list for <code>contentSpecTree</code> method.
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A * @author Eric Ye, IBM
286N/A */
286N/A private static class ChildrenList {
286N/A
286N/A //
286N/A // Data
286N/A //
286N/A
286N/A /** Length. */
286N/A public int length = 0;
286N/A
286N/A // NOTE: The following set of data is mutually exclusive. It is
286N/A // written this way because Java doesn't have a native
286N/A // union data structure. -Ac
286N/A
286N/A /** Left and right children names. */
286N/A public QName[] qname = new QName[2];
286N/A
286N/A /** Left and right children types. */
286N/A public int[] type = new int[2];
286N/A
286N/A //
286N/A // Constructors
286N/A //
286N/A
286N/A public ChildrenList () {}
286N/A
286N/A } // class ChildrenList
286N/A
286N/A //
286N/A // Classes
286N/A //
286N/A
286N/A /**
286N/A * A simple Hashtable implementation that takes a tuple (String, String)
286N/A * as the key and a int as value.
286N/A *
286N/A * @xerces.internal
286N/A *
286N/A * @author Eric Ye, IBM
286N/A * @author Andy Clark, IBM
286N/A */
286N/A protected static final class QNameHashtable {
286N/A
286N/A //
286N/A // Constants
286N/A //
286N/A
286N/A /** Initial bucket size (4). */
286N/A private static final int INITIAL_BUCKET_SIZE = 4;
286N/A
286N/A // NOTE: Changed previous hashtable size from 512 to 101 so
286N/A // that we get a better distribution for hashing. -Ac
286N/A /** Hashtable size (101). */
286N/A private static final int HASHTABLE_SIZE = 101;
286N/A
286N/A //
286N/A // Data
286N/A //
286N/A private Object[][] fHashTable = new Object[HASHTABLE_SIZE][];
286N/A
286N/A //
286N/A // Public methods
286N/A //
286N/A /** Associates the given value with the specified key tuple. */
286N/A public void put(String key, int value) {
286N/A
286N/A int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
286N/A Object[] bucket = fHashTable[hash];
286N/A
286N/A if (bucket == null) {
286N/A bucket = new Object[1 + 2*INITIAL_BUCKET_SIZE];
286N/A bucket[0] = new int[]{1};
286N/A bucket[1] = key;
286N/A bucket[2] = new int[]{value};
286N/A fHashTable[hash] = bucket;
286N/A } else {
286N/A int count = ((int[])bucket[0])[0];
286N/A int offset = 1 + 2*count;
286N/A if (offset == bucket.length) {
286N/A int newSize = count + INITIAL_BUCKET_SIZE;
286N/A Object[] newBucket = new Object[1 + 2*newSize];
286N/A System.arraycopy(bucket, 0, newBucket, 0, offset);
286N/A bucket = newBucket;
286N/A fHashTable[hash] = bucket;
286N/A }
286N/A boolean found = false;
286N/A int j=1;
286N/A for (int i=0; i<count; i++){
286N/A if ((String)bucket[j] == key) {
286N/A ((int[])bucket[j+1])[0] = value;
286N/A found = true;
286N/A break;
286N/A }
286N/A j += 2;
286N/A }
286N/A if (! found) {
286N/A bucket[offset++] = key;
286N/A bucket[offset]= new int[]{value};
286N/A ((int[])bucket[0])[0] = ++count;
286N/A }
286N/A
286N/A }
286N/A //System.out.println("put("+key+" -> "+value+')');
286N/A //System.out.println("get("+key+") -> "+get(key));
286N/A
286N/A } // put(int,String,String,int)
286N/A
286N/A /** Returns the value associated with the specified key tuple. */
286N/A public int get(String key) {
286N/A int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
286N/A Object[] bucket = fHashTable[hash];
286N/A
286N/A if (bucket == null) {
286N/A return -1;
286N/A }
286N/A int count = ((int[])bucket[0])[0];
286N/A
286N/A int j=1;
286N/A for (int i=0; i<count; i++){
286N/A if ((String)bucket[j] == key) {
286N/A return ((int[])bucket[j+1])[0];
286N/A }
286N/A j += 2;
286N/A }
286N/A return -1;
286N/A
286N/A } // get(int,String,String)
286N/A
286N/A } // class QNameHashtable
286N/A
286N/A //
286N/A // EntityState methods
286N/A //
286N/A public boolean isEntityDeclared (String name){
286N/A return (getEntityDeclIndex(name)!=-1)?true:false;
286N/A }
286N/A
286N/A public boolean isEntityUnparsed (String name){
286N/A int entityIndex = getEntityDeclIndex(name);
286N/A if (entityIndex >-1) {
286N/A int chunk = entityIndex >> CHUNK_SHIFT;
286N/A int index = entityIndex & CHUNK_MASK;
286N/A //for unparsed entity notation!=null
286N/A return (fEntityNotation[chunk][index]!=null)?true:false;
286N/A }
286N/A return false;
286N/A }
286N/A} // class DTDGrammar