| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2000 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xerces" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, International |
| * Business Machines, Inc., http://www.apache.org. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| package org.apache.xerces.validators.dtd; |
| |
| import org.apache.xerces.dom.DocumentImpl; |
| import org.apache.xerces.framework.XMLContentSpec; |
| import org.apache.xerces.framework.XMLDTDScanner; |
| import org.apache.xerces.readers.XMLEntityHandler; |
| import org.apache.xerces.utils.QName; |
| import org.apache.xerces.utils.StringPool; |
| import org.apache.xerces.validators.common.Grammar; |
| import org.apache.xerces.validators.common.XMLAttributeDecl; |
| import org.apache.xerces.validators.common.XMLElementDecl; |
| import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl; |
| import org.apache.xerces.validators.schema.XUtil; |
| |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.ProcessingInstruction; |
| import org.w3c.dom.Text; |
| |
| /** |
| * A DTD grammar. This class is an EventHandler to receive callbacks from |
| * the XMLDTDScanner. When the callbacks are received, the grammar structures |
| * are directly populated from the callback information. |
| * <p> |
| * In addition to being a recipient of scanner callbacks, the DTD grammar |
| * class can act as a pass-through filter for the DTD events. This is useful |
| * for parsers that must expose the DTD information to the application. (e.g. |
| * SAX2 DeclHandler callbacks.) |
| * |
| * @author Andy Clark |
| * @version $Id$ |
| */ |
| public class DTDGrammar |
| extends Grammar |
| implements XMLDTDScanner.EventHandler { |
| |
| // REVISIT: The grammar access currently implemented in this grammar |
| // instance is a draft implementation and should be revisited |
| // in order to design a proper DTD for the this grammar |
| // representation. -Ac |
| |
| // |
| // Constants |
| // |
| |
| /** Chunk shift. */ |
| private static final int CHUNK_SHIFT = 8; // 2^8 = 256 |
| |
| /** Chunk size. */ |
| private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT); |
| |
| /** Chunk mask. */ |
| private static final int CHUNK_MASK = CHUNK_SIZE - 1; |
| |
| /** Initial chunk count. */ |
| private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k |
| |
| // |
| // Data |
| // |
| |
| // string pool |
| |
| /** String pool. */ |
| private StringPool fStringPool; |
| |
| // "compiled" information structures |
| |
| /** Element declaration. */ |
| private XMLElementDecl fElementDecl = new XMLElementDecl(); |
| |
| /** Attribute declaration. */ |
| private XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl(); |
| |
| /** Content spec node. */ |
| private XMLContentSpec fContentSpec = new XMLContentSpec(); |
| |
| // grammar document |
| |
| /** Grammar document. */ |
| private Document fGrammarDocument; |
| |
| /** Root element. */ |
| private Element fRootElement; |
| |
| private QName fRootElementQName = new QName(); |
| |
| /** Current element. */ |
| private Element fCurrentElement; |
| |
| // pass-through |
| |
| /** flag if the elementDecl is External. */ |
| private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][]; |
| /** Mapping for element declarations. */ |
| private int fElementDeclMap[][] = new int[INITIAL_CHUNK_COUNT][]; |
| |
| /** flag if the AttributeDecl is External. */ |
| private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][]; |
| /** Mapping for attribute declarations. */ |
| private int fAttributeDeclMap[][] = new int[INITIAL_CHUNK_COUNT][]; |
| |
| /** Mapping for content spec nodes. */ |
| private int fContentSpecMap[][] = new int[INITIAL_CHUNK_COUNT][]; |
| |
| // temp vars |
| |
| private QName fQName = new QName(); |
| |
| // |
| // Constructors |
| // |
| |
| /** Default constructor. */ |
| public DTDGrammar(StringPool stringPool) { |
| reset(stringPool); |
| } |
| |
| // |
| // Public methods |
| // |
| |
| /** Resets the DTD grammar. */ |
| public void reset(StringPool stringPool) { |
| fStringPool = stringPool; |
| } |
| |
| // |
| // XMLDTDScanner.EventHandler methods |
| // |
| |
| /** Start of DTD. */ |
| public void callStartDTD() throws Exception { |
| |
| // setup grammar document |
| setGrammarDocument(null); |
| fGrammarDocument = new DocumentImpl(); |
| fRootElement = fGrammarDocument.createElement("dtd"); |
| fCurrentElement = fRootElement; |
| |
| } // callStartDTD() |
| |
| /** End of DTD. */ |
| public void callEndDTD() throws Exception { |
| |
| // set grammar document |
| setGrammarDocument(fGrammarDocument); |
| |
| } // callEndDTD() |
| |
| /** |
| * Signal the Text declaration of an external entity. |
| * |
| * @param version the handle in the string pool for the version number |
| * @param encoding the handle in the string pool for the encoding |
| * @exception java.lang.Exception |
| */ |
| public void callTextDecl(int version, int encoding) throws Exception { |
| |
| // create text decl |
| Element textDecl = fGrammarDocument.createElement("textDecl"); |
| textDecl.setAttribute("version", fStringPool.toString(version)); |
| textDecl.setAttribute("encoding", fStringPool.toString(encoding)); |
| fCurrentElement.appendChild(textDecl); |
| |
| } // callTextDecl(int,int) |
| |
| /** |
| * Called when the doctype decl is scanned |
| * |
| * @param rootElementType handle of the rootElement |
| * @param publicId StringPool handle of the public id |
| * @param systemId StringPool handle of the system id |
| * @exception java.lang.Exception |
| */ |
| public void doctypeDecl(QName rootElement, int publicId, int systemId) |
| throws Exception { |
| |
| // create doctype decl |
| Element doctypeDecl = fGrammarDocument.createElement("doctypeDecl"); |
| doctypeDecl.setAttribute("name", fStringPool.toString(rootElement.rawname)); |
| if (rootElement.uri != -1) { |
| doctypeDecl.setAttribute("xmlns:"+fStringPool.toString(rootElement.prefix), |
| fStringPool.toString(rootElement.uri)); |
| } |
| doctypeDecl.setAttribute("publicId", fStringPool.toString(publicId)); |
| doctypeDecl.setAttribute("systemId", fStringPool.toString(systemId)); |
| fCurrentElement.appendChild(doctypeDecl); |
| |
| //fRootElementQName.setValues(-1, rootElement.rawname, -1, -1); |
| fRootElementQName.setValues(rootElement); |
| |
| } // doctypeDecl(QName,int,int); |
| |
| /** |
| * Called when the DTDScanner starts reading from the external subset |
| * |
| * @param publicId StringPool handle of the public id |
| * @param systemId StringPool handle of the system id |
| * @exception java.lang.Exception |
| */ |
| public void startReadingFromExternalSubset(int publicId, int systemId) |
| throws Exception { |
| |
| // create external subset |
| Element externalSubset = fGrammarDocument.createElement("external"); |
| externalSubset.setAttribute("publicId", fStringPool.toString(publicId)); |
| externalSubset.setAttribute("systemId", fStringPool.toString(systemId)); |
| fCurrentElement.appendChild(externalSubset); |
| fCurrentElement = externalSubset; |
| |
| } // startReadingFromExternalSubset(int,int) |
| |
| /** |
| * Called when the DTDScanner stop reading from the external subset |
| * |
| * @exception java.lang.Exception |
| */ |
| public void stopReadingFromExternalSubset() throws Exception { |
| |
| // get out of external subset |
| fCurrentElement = (Element)fCurrentElement.getParentNode(); |
| |
| } // stopReadingFromExternalSubset() |
| |
| /** |
| * Add an element declaration (forward reference) |
| * |
| * @param handle to the name of the element being declared |
| * @return handle to the element whose declaration was added |
| * @exception java.lang.Exception |
| */ |
| public int addElementDecl(QName elementDecl) throws Exception { |
| |
| // create element decl element |
| Element elementDeclElement = fGrammarDocument.createElement("elementDecl"); |
| elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart)); |
| if (elementDecl.uri != -1) { |
| elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix), |
| fStringPool.toString(elementDecl.uri)); |
| } |
| fCurrentElement.appendChild(elementDeclElement); |
| |
| // create element decl |
| int elementDeclIndex = createElementDecl(); |
| |
| // set element decl values |
| fElementDecl.clear(); |
| fElementDecl.name.setValues(elementDecl); |
| setElementDecl(elementDeclIndex, fElementDecl); |
| |
| // return index |
| return elementDeclIndex; |
| |
| } // addElementDecl(QName):int |
| |
| /** |
| * Add an element declaration |
| * |
| * @param handle to the name of the element being declared |
| * @param contentSpecType handle to the type name of the content spec |
| * @param ContentSpec handle to the content spec node for the contentSpecType |
| * @return handle to the element declaration that was added |
| * @exception java.lang.Exception |
| */ |
| public int addElementDecl(QName elementDecl, |
| int contentSpecType, |
| int contentSpec, |
| boolean isExternal) throws Exception { |
| |
| // create element decl element |
| Element elementDeclElement = fGrammarDocument.createElement("elementDecl"); |
| elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart)); |
| if (elementDecl.uri != -1) { |
| elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix), |
| fStringPool.toString(elementDecl.uri)); |
| } |
| elementDeclElement.setAttribute("type", fStringPool.toString(contentSpecType)); |
| // REVISIT: Traverse content spec structure, building content model |
| // description to put into grammar document. |
| fCurrentElement.appendChild(elementDeclElement); |
| |
| // create element decl |
| int elementDeclIndex = createElementDecl(); |
| |
| // set element decl values |
| fElementDecl.clear(); |
| fElementDecl.name.setValues(elementDecl); |
| fElementDecl.type = contentSpecType; |
| fElementDecl.contentSpecIndex = contentSpec; |
| setElementDecl(elementDeclIndex, fElementDecl); |
| |
| int chunk = elementDeclIndex >> CHUNK_SHIFT; |
| int index = elementDeclIndex & CHUNK_MASK; |
| ensureElementDeclCapacity(chunk); |
| fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0; |
| |
| // return index |
| return elementDeclIndex; |
| |
| } // addElementDecl(QName,int,int):int |
| |
| protected void putElementNameMapping(QName name, int scope, |
| int elementDeclIndex) { |
| fQName.uri = -1; |
| fQName.localpart = name.rawname; |
| super.putElementNameMapping(fQName, scope, elementDeclIndex); |
| } |
| |
| /*** |
| public int getElementDeclIndex(int localpartIndex, int scopeIndex) { |
| //System.out.println("getElementDeclIndex: "+localpartIndex+", "+scopeIndex); |
| return super.getElementDeclIndex(localpartIndex, scopeIndex); |
| } |
| |
| public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) { |
| //System.out.println("!!! getElementDeclIndex: "+uriIndex+", "+localpartIndex+", "+scopeIndex); |
| return super.getElementDeclIndex(localpartIndex, -1); |
| } |
| /***/ |
| |
| public int getElementDeclIndex(QName element, int scopeIndex) { |
| //System.out.println("getElementDeclIndex: "+element+", "+scopeIndex); |
| return super.getElementDeclIndex(element.rawname, -1); |
| } |
| |
| public void setElementDeclDTD(int elementDeclIndex, XMLElementDecl elementDecl) { |
| super.setElementDecl(elementDeclIndex, elementDecl); |
| } |
| |
| private XMLContentSpec fTempContentSpec = new XMLContentSpec(); |
| |
| /*** |
| public void setContentSpecLeaf(int contentSpecIndex, QName elementName) { |
| fTempContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName.rawname, -1); |
| super.setContentSpec(contentSpecIndex, fTempContentSpec); |
| } |
| /***/ |
| |
| public void setElementDeclIsExternal(int elementDeclIndex, boolean isExternal) { |
| int chunk = elementDeclIndex >> CHUNK_SHIFT; |
| int index = elementDeclIndex & CHUNK_MASK; |
| ensureElementDeclCapacity(chunk); |
| fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0; |
| } |
| |
| // getters for isExternals |
| public boolean getElementDeclIsExternal(int elementDeclIndex) { |
| if (elementDeclIndex < 0) { |
| return false; |
| } |
| int chunk = elementDeclIndex >> CHUNK_SHIFT; |
| int index = elementDeclIndex & CHUNK_MASK; |
| return (fElementDeclIsExternal[chunk][index] != 0); |
| } |
| |
| public boolean getAttributeDeclIsExternal(int attributeDeclIndex) { |
| if (attributeDeclIndex < 0) { |
| return false; |
| } |
| int chunk = attributeDeclIndex >> CHUNK_SHIFT; |
| int index = attributeDeclIndex & CHUNK_MASK; |
| return (fAttributeDeclIsExternal[chunk][index] != 0); |
| } |
| |
| public boolean getRootElementQName(QName root) { |
| if (fRootElementQName.rawname == -1) { |
| return false; |
| } |
| root.setValues(fRootElementQName); |
| return true; |
| } |
| |
| /** |
| * Add an attribute definition |
| * |
| * @param handle to the element whose attribute is being declared |
| * @param attName StringPool handle to the attribute name being declared |
| * @param attType type of the attribute |
| * @param enumeration StringPool handle of the attribute's enumeration list (if any) |
| * @param attDefaultType an integer value denoting the DefaultDecl value |
| * @param attDefaultValue StringPool handle of this attribute's default value |
| * @return handle to the attribute definition |
| * @exception java.lang.Exception |
| */ |
| public int addAttDef(QName elementDecl, QName attributeDecl, |
| int attType, boolean attList, int enumeration, |
| int attDefaultType, int attDefaultValue, boolean isExternal) |
| throws Exception { |
| /**** |
| System.out.println("---add attr--- "+attributeDecl.localpart |
| +","+attType |
| +","+attDefaultType |
| +","+isExternal); |
| /****/ |
| |
| // create attribute decl element |
| Element attributeDeclElement = fGrammarDocument.createElement("attributeDecl"); |
| attributeDeclElement.setAttribute("element", fStringPool.toString(elementDecl.localpart)); |
| attributeDeclElement.setAttribute("name", fStringPool.toString(attributeDecl.localpart)); |
| if (attributeDecl.uri != -1) { |
| attributeDeclElement.setAttribute("xmlns:"+fStringPool.toString(attributeDecl.prefix), |
| fStringPool.toString(attributeDecl.uri)); |
| } |
| attributeDeclElement.setAttribute("type", fStringPool.toString(attType)); |
| // REVISIT: Add enumeration information to grammar document. |
| // REVISIT: Do the default type, value better. |
| attributeDeclElement.setAttribute("defaultType", fStringPool.toString(attDefaultType)); |
| attributeDeclElement.setAttribute("defaultValue", fStringPool.toString(attDefaultValue)); |
| fCurrentElement.appendChild(attributeDeclElement); |
| |
| // create attribute decl |
| int attributeDeclIndex = createAttributeDecl(); |
| |
| // find the dataTypeValidator associcated with this attType |
| String attTypeString = ""; |
| switch (attType) { |
| case XMLAttributeDecl.TYPE_CDATA: |
| attTypeString = "string"; |
| case XMLAttributeDecl.TYPE_ENTITY: |
| attTypeString = "ENTITY";; |
| case XMLAttributeDecl.TYPE_ENUMERATION: |
| attTypeString = "ENUMERATION";; |
| case XMLAttributeDecl.TYPE_ID: |
| attTypeString = "ID";; |
| case XMLAttributeDecl.TYPE_IDREF: |
| attTypeString = "IDREF";; |
| case XMLAttributeDecl.TYPE_NMTOKEN: |
| attTypeString = "NMTOKEN";; |
| case XMLAttributeDecl.TYPE_NOTATION: |
| attTypeString = "NOTATION";; |
| default: |
| ; |
| } |
| |
| // set attribute decl values |
| fAttributeDecl.clear(); |
| fAttributeDecl.name.setValues(attributeDecl); |
| fAttributeDecl.type = attType; |
| fAttributeDecl.list = attList; |
| fAttributeDecl.enumeration = enumeration; |
| fAttributeDecl.datatypeValidator = |
| DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(attTypeString); |
| // REVISIT: Don't forget the enumeration |
| fAttributeDecl.defaultType = attDefaultType; |
| fAttributeDecl.defaultValue = fStringPool.toString(attDefaultValue); |
| |
| int elementDeclIndex = getElementDeclIndex(elementDecl, -1); |
| setAttributeDecl(elementDeclIndex, attributeDeclIndex, fAttributeDecl); |
| |
| int chunk = attributeDeclIndex >> CHUNK_SHIFT; |
| int index = attributeDeclIndex & CHUNK_MASK; |
| ensureAttributeDeclCapacity(chunk); |
| fAttributeDeclIsExternal[chunk][index] = isExternal ? 1 : 0; |
| |
| // return index |
| return attributeDeclIndex; |
| |
| } // addAttDef(QName,QName,int,int,int,int):int |
| |
| /** |
| * create an XMLContentSpec for a leaf |
| * |
| * @param nameIndex StringPool handle to the name (Element) for the node |
| * @return handle to the newly create XMLContentSpec |
| * @exception java.lang.Exception |
| */ |
| public int addUniqueLeafNode(int nameIndex) throws Exception { |
| |
| // create content spec node |
| int contentSpecIndex = createContentSpec(); |
| |
| // set content spec node values |
| fContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, |
| nameIndex, -1); |
| setContentSpec(contentSpecIndex, fContentSpec); |
| |
| // return index |
| return contentSpecIndex; |
| |
| } // addUniqueLeafNode(int):int |
| |
| /** |
| * Create an XMLContentSpec for a single non-leaf |
| * |
| * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_* |
| * @param nodeValue handle to an XMLContentSpec |
| * @return handle to the newly create XMLContentSpec |
| * @exception java.lang.Exception |
| */ |
| public int addContentSpecNode(int nodeType, |
| int nodeValue) throws Exception { |
| |
| // create content spec node |
| int contentSpecIndex = createContentSpec(); |
| |
| // set content spec node values |
| fContentSpec.setValues(nodeType, nodeValue, -1); |
| setContentSpec(contentSpecIndex, fContentSpec); |
| |
| // return index |
| return contentSpecIndex; |
| |
| } // addContentSpecNode(int,int):int |
| |
| /** |
| * Create an XMLContentSpec for a two child leaf |
| * |
| * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_* |
| * @param leftNodeIndex handle to an XMLContentSpec |
| * @param rightNodeIndex handle to an XMLContentSpec |
| * @return handle to the newly create XMLContentSpec |
| * @exception java.lang.Exception |
| */ |
| public int addContentSpecNode(int nodeType, |
| int leftNodeIndex, |
| int rightNodeIndex) throws Exception { |
| |
| // create content spec node |
| int contentSpecIndex = createContentSpec(); |
| |
| // set content spec node values |
| fContentSpec.setValues(nodeType, |
| leftNodeIndex, rightNodeIndex); |
| setContentSpec(contentSpecIndex, fContentSpec); |
| |
| // return index |
| return contentSpecIndex; |
| |
| } // addContentSpecNode(int,int,int):int |
| |
| /** |
| * Create a string representation of an XMLContentSpec tree |
| * |
| * @param handle to an XMLContentSpec |
| * @return String representation of the content spec tree |
| * @exception java.lang.Exception |
| */ |
| public String getContentSpecNodeAsString(int nodeIndex) throws Exception { |
| return XMLContentSpec.toString(this, fStringPool, nodeIndex); |
| } |
| |
| /** |
| * Start the scope of an entity declaration. |
| * |
| * @return <code>true</code> on success; otherwise |
| * <code>false</code> if the entity declaration is recursive. |
| * @exception java.lang.Exception |
| */ |
| public boolean startEntityDecl(boolean isPE, int entityName) |
| throws Exception { |
| |
| // create entity decl |
| Element entityDecl = fGrammarDocument.createElement("entityDecl"); |
| entityDecl.setAttribute("name", fStringPool.toString(entityName)); |
| entityDecl.setAttribute("parameter", isPE ? "true" : "false"); |
| fCurrentElement.appendChild(entityDecl); |
| fCurrentElement = entityDecl; |
| |
| // success |
| return true; |
| |
| } // startEntityDecl(boolean,int):boolean |
| |
| /** |
| * End the scope of an entity declaration. |
| * @exception java.lang.Exception |
| */ |
| public void endEntityDecl() throws Exception { |
| |
| // get out of entity decl |
| fCurrentElement = (Element)fCurrentElement.getParentNode(); |
| |
| } // endEntityDecl() |
| |
| /** |
| * Add a declaration for an internal parameter entity |
| * |
| * @param name StringPool handle of the parameter entity name |
| * @param value StringPool handle of the parameter entity value |
| * @return handle to the parameter entity declaration |
| * @exception java.lang.Exception |
| */ |
| public int addInternalPEDecl(int name, int value) throws Exception { |
| |
| // create internal PE decl |
| Element internalPEDecl = fGrammarDocument.createElement("internalPEDecl"); |
| internalPEDecl.setAttribute("name", fStringPool.toString(name)); |
| internalPEDecl.setAttribute("value", fStringPool.toString(value)); |
| fCurrentElement.appendChild(internalPEDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int peDeclIndex = -1; |
| |
| // return index |
| return peDeclIndex; |
| |
| } // addInternalPEDecl(int,int):int |
| |
| /** |
| * Add a declaration for an external parameter entity |
| * |
| * @param name StringPool handle of the parameter entity name |
| * @param publicId StringPool handle of the publicId |
| * @param systemId StringPool handle of the systemId |
| * @return handle to the parameter entity declaration |
| * @exception java.lang.Exception |
| */ |
| public int addExternalPEDecl(int name, |
| int publicId, |
| int systemId) throws Exception { |
| |
| // create external PE decl |
| Element externalPEDecl = fGrammarDocument.createElement("externalPEDecl"); |
| externalPEDecl.setAttribute("name", fStringPool.toString(name)); |
| externalPEDecl.setAttribute("publicId", fStringPool.toString(publicId)); |
| externalPEDecl.setAttribute("systemId", fStringPool.toString(systemId)); |
| fCurrentElement.appendChild(externalPEDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int peDeclIndex = -1; |
| |
| // return index |
| return peDeclIndex; |
| |
| } // addExternalPEDecl(int,int,int):int |
| |
| /** |
| * Add a declaration for an internal entity |
| * |
| * @param name StringPool handle of the entity name |
| * @param value StringPool handle of the entity value |
| * @return handle to the entity declaration |
| * @exception java.lang.Exception |
| */ |
| public int addInternalEntityDecl(int name, int value) throws Exception { |
| |
| // create internal entity decl |
| Element internalEntityDecl = fGrammarDocument.createElement("internalEntityDecl"); |
| internalEntityDecl.setAttribute("name", fStringPool.toString(name)); |
| internalEntityDecl.setAttribute("value", fStringPool.toString(value)); |
| fCurrentElement.appendChild(internalEntityDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int internalEntityDeclIndex = -1; |
| |
| // return index |
| return internalEntityDeclIndex; |
| |
| } // addInternalEntityDecl(int,int):int |
| |
| /** |
| * Add a declaration for an entity |
| * |
| * @param name StringPool handle of the entity name |
| * @param publicId StringPool handle of the publicId |
| * @param systemId StringPool handle of the systemId |
| * @return handle to the entity declaration |
| * @exception java.lang.Exception |
| */ |
| public int addExternalEntityDecl(int name, |
| int publicId, |
| int systemId) throws Exception { |
| |
| // create external entity decl |
| Element externalEntityDecl = fGrammarDocument.createElement("externalEntityDecl"); |
| externalEntityDecl.setAttribute("name", fStringPool.toString(name)); |
| externalEntityDecl.setAttribute("publicId", fStringPool.toString(publicId)); |
| externalEntityDecl.setAttribute("systemId", fStringPool.toString(systemId)); |
| fCurrentElement.appendChild(externalEntityDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int externalEntityDeclIndex = -1; |
| |
| // return index |
| return externalEntityDeclIndex; |
| |
| } // addExternalEntityDecl(int,int,int):int |
| |
| /** |
| * Add a declaration for an unparsed entity |
| * |
| * @param name StringPool handle of the entity name |
| * @param publicId StringPool handle of the publicId |
| * @param systemId StringPool handle of the systemId |
| * @param notationName StringPool handle of the notationName |
| * @return handle to the entity declaration |
| * @exception java.lang.Exception |
| */ |
| public int addUnparsedEntityDecl(int name, |
| int publicId, int systemId, |
| int notationName) throws Exception { |
| |
| // create external entity decl |
| Element unparsedEntityDecl = fGrammarDocument.createElement("unparsedEntityDecl"); |
| unparsedEntityDecl.setAttribute("name", fStringPool.toString(name)); |
| unparsedEntityDecl.setAttribute("publicId", fStringPool.toString(publicId)); |
| unparsedEntityDecl.setAttribute("systemId", fStringPool.toString(systemId)); |
| unparsedEntityDecl.setAttribute("notation", fStringPool.toString(notationName)); |
| fCurrentElement.appendChild(unparsedEntityDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int unparsedEntityDeclIndex = -1; |
| |
| // return index |
| return unparsedEntityDeclIndex; |
| |
| } // addUnparsedEntityDecl(int,int,int,int):int |
| |
| /** |
| * Called when the scanner start scanning an enumeration |
| * @return StringPool handle to a string list that will hold the enumeration names |
| * @exception java.lang.Exception |
| */ |
| public int startEnumeration() throws Exception { |
| |
| // create enumeration |
| Element enumeration = fGrammarDocument.createElement("enumeration"); |
| fCurrentElement.appendChild(enumeration); |
| fCurrentElement = enumeration; |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| //int enumIndex = -1; |
| int enumIndex = fStringPool.startStringList(); |
| |
| // return index |
| return enumIndex; |
| |
| } // startEnumeration():int |
| |
| /** |
| * Add a name to an enumeration |
| * @param enumIndex StringPool handle to the string list for the enumeration |
| * @param elementType handle to the element that owns the attribute with the enumeration |
| * @param attrName StringPool handle to the name of the attribut with the enumeration |
| * @param nameIndex StringPool handle to the name to be added to the enumeration |
| * @param isNotationType true if the enumeration is an enumeration of NOTATION names |
| * @exception java.lang.Exception |
| */ |
| public void addNameToEnumeration(int enumIndex, |
| int elementType, int attrName, |
| int nameIndex, |
| boolean isNotationType) throws Exception { |
| |
| // create enumeration literal |
| Element literal = fGrammarDocument.createElement("literal"); |
| // REVISIT: How is this literal (and its parent enumeration) |
| // associated to an element and attribute name? This |
| // should be done better. |
| literal.setAttribute("element", fStringPool.toString(elementType)); |
| literal.setAttribute("attribute", fStringPool.toString(attrName)); |
| literal.setAttribute("name", fStringPool.toString(nameIndex)); |
| literal.setAttribute("notation", isNotationType ? "true" : "false"); |
| fCurrentElement.appendChild(literal); |
| |
| //add the name to the stringList |
| fStringPool.addStringToList(enumIndex, nameIndex); |
| |
| } // addNameToEnumeration(int,int,int,int,boolean) |
| |
| /** |
| * Finish processing an enumeration |
| * |
| * @param enumIndex handle to the string list which holds the enumeration to be finshed. |
| * @exception java.lang.Exception |
| */ |
| public void endEnumeration(int enumIndex) throws Exception { |
| |
| // get out of enumeration |
| fCurrentElement = (Element)fCurrentElement.getParentNode(); |
| |
| //finish the enumeration stringlist int the fStringPool |
| fStringPool.finishStringList(enumIndex); |
| |
| } // endEnumeration(int) |
| |
| /** |
| * Add a declaration for a notation |
| * |
| * @param notationName |
| * @param publicId |
| * @param systemId |
| * @return handle to the notation declaration |
| * @exception java.lang.Exception |
| */ |
| public int addNotationDecl(int notationName, |
| int publicId, int systemId) throws Exception { |
| |
| // create notation decl |
| Element notationDecl = fGrammarDocument.createElement("notationDecl"); |
| notationDecl.setAttribute("name", fStringPool.toString(notationName)); |
| notationDecl.setAttribute("publicId", fStringPool.toString(publicId)); |
| notationDecl.setAttribute("systemId", fStringPool.toString(systemId)); |
| fCurrentElement.appendChild(notationDecl); |
| |
| // REVISIT: What is my responsibility for creating a handle? |
| int notationDeclIndex = -1; |
| |
| // return index |
| return notationDeclIndex; |
| |
| } // addNotationdecl(int,int,int):int |
| |
| /** |
| * Called when a comment has been scanned |
| * |
| * @param data StringPool handle of the comment text |
| * @exception java.lang.Exception |
| */ |
| public void callComment(int data) throws Exception { |
| } |
| |
| /** |
| * Called when a processing instruction has been scanned |
| * @param piTarget StringPool handle of the PI target |
| * @param piData StringPool handle of the PI data |
| * @exception java.lang.Exception |
| */ |
| public void callProcessingInstruction(int piTarget, int piData) |
| throws Exception { |
| |
| // create pi |
| ProcessingInstruction pi = |
| fGrammarDocument.createProcessingInstruction(fStringPool.toString(piTarget), |
| fStringPool.toString(piData)); |
| fCurrentElement.appendChild(pi); |
| |
| } // callProcessingInstruction(int,int) |
| |
| // deprecated -- removed from DOM Level 2 |
| |
| /** |
| * Supports DOM Level 2 internalSubset additions. |
| * Called when the internal subset is completely scanned. |
| */ |
| public void internalSubset(int internalSubset) throws Exception { |
| } |
| |
| protected boolean isDTD() { |
| return true; |
| } |
| |
| // |
| // Private methods |
| // |
| |
| // ensure capacity |
| |
| /** Ensures storage for element declaration mappings. */ |
| private boolean ensureElementDeclCapacity(int chunk) { |
| try { |
| return fElementDeclMap[chunk][0] == 0; |
| } catch (ArrayIndexOutOfBoundsException ex) { |
| fElementDeclMap = resize(fElementDeclMap, |
| fElementDeclMap.length * 2); |
| fElementDeclIsExternal = resize(fElementDeclIsExternal, |
| fElementDeclIsExternal.length * 2); |
| } catch (NullPointerException ex) { |
| // ignore |
| } |
| fElementDeclMap[chunk] = new int[CHUNK_SIZE]; |
| fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE]; |
| return true; |
| } |
| |
| /** Ensures storage for attribute declaration mappings. */ |
| private boolean ensureAttributeDeclCapacity(int chunk) { |
| try { |
| return fAttributeDeclMap[chunk][0] == 0; |
| } catch (ArrayIndexOutOfBoundsException ex) { |
| fAttributeDeclMap = resize(fAttributeDeclMap, |
| fAttributeDeclMap.length * 2); |
| fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal, |
| fAttributeDeclIsExternal.length * 2); |
| } catch (NullPointerException ex) { |
| // ignore |
| } |
| fAttributeDeclMap[chunk] = new int[CHUNK_SIZE]; |
| fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE]; |
| return true; |
| } |
| |
| /** Ensures storage for content spec mappings. */ |
| private boolean ensureContentSpecCapacity(int chunk) { |
| try { |
| return fContentSpecMap[chunk][0] == 0; |
| } catch (ArrayIndexOutOfBoundsException ex) { |
| fContentSpecMap = resize(fContentSpecMap, |
| fContentSpecMap.length * 2); |
| } catch (NullPointerException ex) { |
| // ignore |
| } |
| fContentSpecMap[chunk] = new int[CHUNK_SIZE]; |
| return true; |
| } |
| |
| // resize initial chunk |
| |
| /** Resizes chunked integer arrays. */ |
| private int[][] resize(int array[][], int newsize) { |
| int newarray[][] = new int[newsize][]; |
| System.arraycopy(array, 0, newarray, 0, array.length); |
| return newarray; |
| } |
| |
| } // class DTDGrammar |