0001: /*
0002: * The Apache Software License, Version 1.1
0003: *
0004: *
0005: * Copyright (c) 2000 The Apache Software Foundation. All rights
0006: * reserved.
0007: *
0008: * Redistribution and use in source and binary forms, with or without
0009: * modification, are permitted provided that the following conditions
0010: * are met:
0011: *
0012: * 1. Redistributions of source code must retain the above copyright
0013: * notice, this list of conditions and the following disclaimer.
0014: *
0015: * 2. Redistributions in binary form must reproduce the above copyright
0016: * notice, this list of conditions and the following disclaimer in
0017: * the documentation and/or other materials provided with the
0018: * distribution.
0019: *
0020: * 3. The end-user documentation included with the redistribution,
0021: * if any, must include the following acknowledgment:
0022: * "This product includes software developed by the
0023: * Apache Software Foundation (http://www.apache.org/)."
0024: * Alternately, this acknowledgment may appear in the software itself,
0025: * if and wherever such third-party acknowledgments normally appear.
0026: *
0027: * 4. The names "Xerces" and "Apache Software Foundation" must
0028: * not be used to endorse or promote products derived from this
0029: * software without prior written permission. For written
0030: * permission, please contact apache@apache.org.
0031: *
0032: * 5. Products derived from this software may not be called "Apache",
0033: * nor may "Apache" appear in their name, without prior written
0034: * permission of the Apache Software Foundation.
0035: *
0036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047: * SUCH DAMAGE.
0048: * ====================================================================
0049: *
0050: * This software consists of voluntary contributions made by many
0051: * individuals on behalf of the Apache Software Foundation and was
0052: * originally based on software copyright (c) 1999, International
0053: * Business Machines, Inc., http://www.apache.org. For more
0054: * information on the Apache Software Foundation, please see
0055: * <http://www.apache.org/>.
0056: */
0057:
0058: package org.apache.xerces.validators.dtd;
0059:
0060: import org.apache.xerces.dom.DocumentImpl;
0061: import org.apache.xerces.framework.XMLContentSpec;
0062: import org.apache.xerces.framework.XMLDTDScanner;
0063: import org.apache.xerces.readers.XMLEntityHandler;
0064: import org.apache.xerces.utils.QName;
0065: import org.apache.xerces.utils.StringPool;
0066: import org.apache.xerces.validators.common.Grammar;
0067: import org.apache.xerces.validators.common.XMLAttributeDecl;
0068: import org.apache.xerces.validators.common.XMLElementDecl;
0069: import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
0070: import org.apache.xerces.validators.schema.XUtil;
0071:
0072: import org.w3c.dom.Document;
0073: import org.w3c.dom.Element;
0074: import org.w3c.dom.ProcessingInstruction;
0075: import org.w3c.dom.Text;
0076:
0077: /**
0078: * A DTD grammar. This class is an EventHandler to receive callbacks from
0079: * the XMLDTDScanner. When the callbacks are received, the grammar structures
0080: * are directly populated from the callback information.
0081: * <p>
0082: * In addition to being a recipient of scanner callbacks, the DTD grammar
0083: * class can act as a pass-through filter for the DTD events. This is useful
0084: * for parsers that must expose the DTD information to the application. (e.g.
0085: * SAX2 DeclHandler callbacks.)
0086: *
0087: * @author Andy Clark
0088: * @version $Id: DTDGrammar.java,v 1.10 2001/07/20 17:27:38 lmartin Exp $
0089: */
0090: public class DTDGrammar extends Grammar implements
0091: XMLDTDScanner.EventHandler {
0092:
0093: // REVISIT: The grammar access currently implemented in this grammar
0094: // instance is a draft implementation and should be revisited
0095: // in order to design a proper DTD for the this grammar
0096: // representation. -Ac
0097:
0098: //
0099: // Constants
0100: //
0101:
0102: /** Chunk shift. */
0103: private static final int CHUNK_SHIFT = 8; // 2^8 = 256
0104:
0105: /** Chunk size. */
0106: private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
0107:
0108: /** Chunk mask. */
0109: private static final int CHUNK_MASK = CHUNK_SIZE - 1;
0110:
0111: /** Initial chunk count. */
0112: private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
0113:
0114: //
0115: // Data
0116: //
0117:
0118: // string pool
0119:
0120: /** String pool. */
0121: private StringPool fStringPool;
0122:
0123: // "compiled" information structures
0124:
0125: /** Element declaration. */
0126: private XMLElementDecl fElementDecl = new XMLElementDecl();
0127:
0128: /** Attribute declaration. */
0129: private XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
0130:
0131: /** Content spec node. */
0132: private XMLContentSpec fContentSpec = new XMLContentSpec();
0133:
0134: // grammar document
0135:
0136: /** Grammar document. */
0137: private Document fGrammarDocument;
0138:
0139: /** Root element. */
0140: private Element fRootElement;
0141:
0142: private QName fRootElementQName = new QName();
0143:
0144: /** Current element. */
0145: private Element fCurrentElement;
0146:
0147: // pass-through
0148:
0149: /** flag if the elementDecl is External. */
0150: private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
0151: /** Mapping for element declarations. */
0152: private int fElementDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];
0153:
0154: /** flag if the AttributeDecl is External. */
0155: private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
0156: /** Mapping for attribute declarations. */
0157: private int fAttributeDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];
0158:
0159: /** Mapping for content spec nodes. */
0160: private int fContentSpecMap[][] = new int[INITIAL_CHUNK_COUNT][];
0161:
0162: // temp vars
0163:
0164: private QName fQName = new QName();
0165:
0166: //
0167: // Constructors
0168: //
0169:
0170: /** Default constructor. */
0171: public DTDGrammar(StringPool stringPool) {
0172: reset(stringPool);
0173: }
0174:
0175: //
0176: // Public methods
0177: //
0178:
0179: /** Resets the DTD grammar. */
0180: public void reset(StringPool stringPool) {
0181: fStringPool = stringPool;
0182: }
0183:
0184: //
0185: // XMLDTDScanner.EventHandler methods
0186: //
0187:
0188: /** Start of DTD. */
0189: public void callStartDTD() throws Exception {
0190:
0191: // setup grammar document
0192: setGrammarDocument(null);
0193: fGrammarDocument = new DocumentImpl();
0194: fRootElement = fGrammarDocument.createElement("dtd");
0195: fCurrentElement = fRootElement;
0196:
0197: } // callStartDTD()
0198:
0199: /** End of DTD. */
0200: public void callEndDTD() throws Exception {
0201:
0202: // set grammar document
0203: setGrammarDocument(fGrammarDocument);
0204:
0205: } // callEndDTD()
0206:
0207: /**
0208: * Signal the Text declaration of an external entity.
0209: *
0210: * @param version the handle in the string pool for the version number
0211: * @param encoding the handle in the string pool for the encoding
0212: * @exception java.lang.Exception
0213: */
0214: public void callTextDecl(int version, int encoding)
0215: throws Exception {
0216:
0217: // create text decl
0218: Element textDecl = fGrammarDocument.createElement("textDecl");
0219: textDecl.setAttribute("version", fStringPool.toString(version));
0220: textDecl.setAttribute("encoding", fStringPool
0221: .toString(encoding));
0222: fCurrentElement.appendChild(textDecl);
0223:
0224: } // callTextDecl(int,int)
0225:
0226: /**
0227: * Called when the doctype decl is scanned
0228: *
0229: * @param rootElementType handle of the rootElement
0230: * @param publicId StringPool handle of the public id
0231: * @param systemId StringPool handle of the system id
0232: * @exception java.lang.Exception
0233: */
0234: public void doctypeDecl(QName rootElement, int publicId,
0235: int systemId) throws Exception {
0236:
0237: // create doctype decl
0238: Element doctypeDecl = fGrammarDocument
0239: .createElement("doctypeDecl");
0240: doctypeDecl.setAttribute("name", fStringPool
0241: .toString(rootElement.rawname));
0242: if (rootElement.uri != StringPool.EMPTY_STRING) {
0243: doctypeDecl.setAttribute("xmlns:"
0244: + fStringPool.toString(rootElement.prefix),
0245: fStringPool.toString(rootElement.uri));
0246: }
0247: doctypeDecl.setAttribute("publicId", fStringPool
0248: .toString(publicId));
0249: doctypeDecl.setAttribute("systemId", fStringPool
0250: .toString(systemId));
0251: fCurrentElement.appendChild(doctypeDecl);
0252:
0253: //fRootElementQName.setValues(-1, rootElement.rawname, -1, -1);
0254: fRootElementQName.setValues(rootElement);
0255:
0256: } // doctypeDecl(QName,int,int);
0257:
0258: /**
0259: * Called when the DTDScanner starts reading from the external subset
0260: *
0261: * @param publicId StringPool handle of the public id
0262: * @param systemId StringPool handle of the system id
0263: * @exception java.lang.Exception
0264: */
0265: public void startReadingFromExternalSubset(int publicId,
0266: int systemId) throws Exception {
0267:
0268: // create external subset
0269: Element externalSubset = fGrammarDocument
0270: .createElement("external");
0271: externalSubset.setAttribute("publicId", fStringPool
0272: .toString(publicId));
0273: externalSubset.setAttribute("systemId", fStringPool
0274: .toString(systemId));
0275: fCurrentElement.appendChild(externalSubset);
0276: fCurrentElement = externalSubset;
0277:
0278: } // startReadingFromExternalSubset(int,int)
0279:
0280: /**
0281: * Called when the DTDScanner stop reading from the external subset
0282: *
0283: * @exception java.lang.Exception
0284: */
0285: public void stopReadingFromExternalSubset() throws Exception {
0286:
0287: // get out of external subset
0288: fCurrentElement = (Element) fCurrentElement.getParentNode();
0289:
0290: } // stopReadingFromExternalSubset()
0291:
0292: /**
0293: * Add an element declaration (forward reference)
0294: *
0295: * @param handle to the name of the element being declared
0296: * @return handle to the element whose declaration was added
0297: * @exception java.lang.Exception
0298: */
0299: public int addElementDecl(QName elementDecl) throws Exception {
0300:
0301: // create element decl element
0302: Element elementDeclElement = fGrammarDocument
0303: .createElement("elementDecl");
0304: elementDeclElement.setAttribute("name", fStringPool
0305: .toString(elementDecl.localpart));
0306: if (elementDecl.uri != StringPool.EMPTY_STRING) {
0307: elementDeclElement.setAttribute("xmlns:"
0308: + fStringPool.toString(elementDecl.prefix),
0309: fStringPool.toString(elementDecl.uri));
0310: }
0311: fCurrentElement.appendChild(elementDeclElement);
0312:
0313: // create element decl
0314: int elementDeclIndex = createElementDecl();
0315:
0316: // set element decl values
0317: fElementDecl.clear();
0318: fElementDecl.name.setValues(elementDecl);
0319: setElementDecl(elementDeclIndex, fElementDecl);
0320:
0321: // return index
0322: return elementDeclIndex;
0323:
0324: } // addElementDecl(QName):int
0325:
0326: /**
0327: * Add an element declaration
0328: *
0329: * @param handle to the name of the element being declared
0330: * @param contentSpecType handle to the type name of the content spec
0331: * @param ContentSpec handle to the content spec node for the contentSpecType
0332: * @return handle to the element declaration that was added
0333: * @exception java.lang.Exception
0334: */
0335: public int addElementDecl(QName elementDecl, int contentSpecType,
0336: int contentSpec, boolean isExternal) throws Exception {
0337:
0338: // create element decl element
0339: Element elementDeclElement = fGrammarDocument
0340: .createElement("elementDecl");
0341: elementDeclElement.setAttribute("name", fStringPool
0342: .toString(elementDecl.localpart));
0343: if (elementDecl.uri != StringPool.EMPTY_STRING) {
0344: elementDeclElement.setAttribute("xmlns:"
0345: + fStringPool.toString(elementDecl.prefix),
0346: fStringPool.toString(elementDecl.uri));
0347: }
0348: elementDeclElement.setAttribute("type", fStringPool
0349: .toString(contentSpecType));
0350: // REVISIT: Traverse content spec structure, building content model
0351: // description to put into grammar document.
0352: fCurrentElement.appendChild(elementDeclElement);
0353:
0354: // create element decl
0355: int elementDeclIndex = createElementDecl();
0356:
0357: // set element decl values
0358: fElementDecl.clear();
0359: fElementDecl.name.setValues(elementDecl);
0360: fElementDecl.type = contentSpecType;
0361: fElementDecl.contentSpecIndex = contentSpec;
0362: setElementDecl(elementDeclIndex, fElementDecl);
0363:
0364: int chunk = elementDeclIndex >> CHUNK_SHIFT;
0365: int index = elementDeclIndex & CHUNK_MASK;
0366: ensureElementDeclCapacity(chunk);
0367: fElementDeclIsExternal[chunk][index] = isExternal ? 1 : 0;
0368:
0369: // return index
0370: return elementDeclIndex;
0371:
0372: } // addElementDecl(QName,int,int):int
0373:
0374: protected void putElementNameMapping(QName name, int scope,
0375: int elementDeclIndex) {
0376: fQName.uri = StringPool.EMPTY_STRING;
0377: fQName.localpart = name.rawname;
0378: super .putElementNameMapping(fQName, scope, elementDeclIndex);
0379: }
0380:
0381: /***
0382: public int getElementDeclIndex(int localpartIndex, int scopeIndex) {
0383: //System.out.println("getElementDeclIndex: "+localpartIndex+", "+scopeIndex);
0384: return super.getElementDeclIndex(localpartIndex, scopeIndex);
0385: }
0386:
0387: public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) {
0388: //System.out.println("!!! getElementDeclIndex: "+uriIndex+", "+localpartIndex+", "+scopeIndex);
0389: return super.getElementDeclIndex(localpartIndex, -1);
0390: }
0391: /***/
0392:
0393: public int getElementDeclIndex(QName element, int scopeIndex) {
0394: //System.out.println("getElementDeclIndex: "+element+", "+scopeIndex);
0395: return super .getElementDeclIndex(element.rawname, -1);
0396: }
0397:
0398: public void setElementDeclDTD(int elementDeclIndex,
0399: XMLElementDecl elementDecl) {
0400: super .setElementDecl(elementDeclIndex, elementDecl);
0401: }
0402:
0403: private XMLContentSpec fTempContentSpec = new XMLContentSpec();
0404:
0405: /***
0406: public void setContentSpecLeaf(int contentSpecIndex, QName elementName) {
0407: fTempContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName.rawname, -1);
0408: super.setContentSpec(contentSpecIndex, fTempContentSpec);
0409: }
0410: /***/
0411:
0412: public void setElementDeclIsExternal(int elementDeclIndex,
0413: boolean isExternal) {
0414: int chunk = elementDeclIndex >> CHUNK_SHIFT;
0415: int index = elementDeclIndex & CHUNK_MASK;
0416: ensureElementDeclCapacity(chunk);
0417: fElementDeclIsExternal[chunk][index] = isExternal ? 1 : 0;
0418: }
0419:
0420: // getters for isExternals
0421: public boolean getElementDeclIsExternal(int elementDeclIndex) {
0422: if (elementDeclIndex < 0) {
0423: return false;
0424: }
0425: int chunk = elementDeclIndex >> CHUNK_SHIFT;
0426: int index = elementDeclIndex & CHUNK_MASK;
0427: return (fElementDeclIsExternal[chunk][index] != 0);
0428: }
0429:
0430: public boolean getAttributeDeclIsExternal(int attributeDeclIndex) {
0431: if (attributeDeclIndex < 0) {
0432: return false;
0433: }
0434: int chunk = attributeDeclIndex >> CHUNK_SHIFT;
0435: int index = attributeDeclIndex & CHUNK_MASK;
0436: return (fAttributeDeclIsExternal[chunk][index] != 0);
0437: }
0438:
0439: public boolean getRootElementQName(QName root) {
0440: if (fRootElementQName.rawname == -1) {
0441: return false;
0442: }
0443: root.setValues(fRootElementQName);
0444: return true;
0445: }
0446:
0447: /**
0448: * Add an attribute definition
0449: *
0450: * @param handle to the element whose attribute is being declared
0451: * @param attName StringPool handle to the attribute name being declared
0452: * @param attType type of the attribute
0453: * @param enumeration StringPool handle of the attribute's enumeration list (if any)
0454: * @param attDefaultType an integer value denoting the DefaultDecl value
0455: * @param attDefaultValue StringPool handle of this attribute's default value
0456: * @return handle to the attribute definition
0457: * @exception java.lang.Exception
0458: */
0459: public int addAttDef(QName elementDecl, QName attributeDecl,
0460: int attType, boolean attList, int enumeration,
0461: int attDefaultType, int attDefaultValue, boolean isExternal)
0462: throws Exception {
0463: /****
0464: System.out.println("---add attr--- "+attributeDecl.localpart
0465: +","+attType
0466: +","+attDefaultType
0467: +","+isExternal);
0468: /****/
0469:
0470: // create attribute decl element
0471: Element attributeDeclElement = fGrammarDocument
0472: .createElement("attributeDecl");
0473: attributeDeclElement.setAttribute("element", fStringPool
0474: .toString(elementDecl.localpart));
0475: attributeDeclElement.setAttribute("name", fStringPool
0476: .toString(attributeDecl.localpart));
0477: if (attributeDecl.uri != StringPool.EMPTY_STRING) {
0478: attributeDeclElement.setAttribute("xmlns:"
0479: + fStringPool.toString(attributeDecl.prefix),
0480: fStringPool.toString(attributeDecl.uri));
0481: }
0482: attributeDeclElement.setAttribute("type", fStringPool
0483: .toString(attType));
0484: // REVISIT: Add enumeration information to grammar document.
0485: // REVISIT: Do the default type, value better.
0486: attributeDeclElement.setAttribute("defaultType", fStringPool
0487: .toString(attDefaultType));
0488: attributeDeclElement.setAttribute("defaultValue", fStringPool
0489: .toString(attDefaultValue));
0490: fCurrentElement.appendChild(attributeDeclElement);
0491:
0492: // create attribute decl
0493: int attributeDeclIndex = createAttributeDecl();
0494:
0495: // find the dataTypeValidator associcated with this attType
0496: String attTypeString = "";
0497: switch (attType) {
0498: case XMLAttributeDecl.TYPE_CDATA:
0499: attTypeString = "string";
0500: case XMLAttributeDecl.TYPE_ENTITY:
0501: attTypeString = "ENTITY";
0502: ;
0503: case XMLAttributeDecl.TYPE_ENUMERATION:
0504: attTypeString = "ENUMERATION";
0505: ;
0506: case XMLAttributeDecl.TYPE_ID:
0507: attTypeString = "ID";
0508: ;
0509: case XMLAttributeDecl.TYPE_IDREF:
0510: attTypeString = "IDREF";
0511: ;
0512: case XMLAttributeDecl.TYPE_NMTOKEN:
0513: attTypeString = "NMTOKEN";
0514: ;
0515: case XMLAttributeDecl.TYPE_NOTATION:
0516: attTypeString = "NOTATION";
0517: ;
0518: default:
0519: ;
0520: }
0521:
0522: // set attribute decl values
0523: fAttributeDecl.clear();
0524: fAttributeDecl.name.setValues(attributeDecl);
0525: fAttributeDecl.type = attType;
0526: fAttributeDecl.list = attList;
0527: fAttributeDecl.enumeration = enumeration;
0528: /***
0529: fAttributeDecl.datatypeValidator =
0530: DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(attTypeString);
0531: ****/
0532: fAttributeDecl.defaultType = attDefaultType;
0533: fAttributeDecl.defaultValue = fStringPool
0534: .toString(attDefaultValue);
0535:
0536: int elementDeclIndex = getElementDeclIndex(elementDecl, -1);
0537: setAttributeDecl(elementDeclIndex, attributeDeclIndex,
0538: fAttributeDecl);
0539:
0540: int chunk = attributeDeclIndex >> CHUNK_SHIFT;
0541: int index = attributeDeclIndex & CHUNK_MASK;
0542: ensureAttributeDeclCapacity(chunk);
0543: fAttributeDeclIsExternal[chunk][index] = isExternal ? 1 : 0;
0544:
0545: // return index
0546: return attributeDeclIndex;
0547:
0548: } // addAttDef(QName,QName,int,int,int,int):int
0549:
0550: /**
0551: * create an XMLContentSpec for a leaf
0552: *
0553: * @param nameIndex StringPool handle to the name (Element) for the node
0554: * @return handle to the newly create XMLContentSpec
0555: * @exception java.lang.Exception
0556: */
0557: public int addUniqueLeafNode(int nameIndex) throws Exception {
0558:
0559: // create content spec node
0560: int contentSpecIndex = createContentSpec();
0561:
0562: // set content spec node values
0563: fContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF,
0564: nameIndex, -1);
0565: setContentSpec(contentSpecIndex, fContentSpec);
0566:
0567: // return index
0568: return contentSpecIndex;
0569:
0570: } // addUniqueLeafNode(int):int
0571:
0572: /**
0573: * Create an XMLContentSpec for a single non-leaf
0574: *
0575: * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
0576: * @param nodeValue handle to an XMLContentSpec
0577: * @return handle to the newly create XMLContentSpec
0578: * @exception java.lang.Exception
0579: */
0580: public int addContentSpecNode(int nodeType, int nodeValue)
0581: throws Exception {
0582:
0583: // create content spec node
0584: int contentSpecIndex = createContentSpec();
0585:
0586: // set content spec node values
0587: fContentSpec.setValues(nodeType, nodeValue, -1);
0588: setContentSpec(contentSpecIndex, fContentSpec);
0589:
0590: // return index
0591: return contentSpecIndex;
0592:
0593: } // addContentSpecNode(int,int):int
0594:
0595: /**
0596: * Create an XMLContentSpec for a two child leaf
0597: *
0598: * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
0599: * @param leftNodeIndex handle to an XMLContentSpec
0600: * @param rightNodeIndex handle to an XMLContentSpec
0601: * @return handle to the newly create XMLContentSpec
0602: * @exception java.lang.Exception
0603: */
0604: public int addContentSpecNode(int nodeType, int leftNodeIndex,
0605: int rightNodeIndex) throws Exception {
0606:
0607: // create content spec node
0608: int contentSpecIndex = createContentSpec();
0609:
0610: // set content spec node values
0611: fContentSpec.setValues(nodeType, leftNodeIndex, rightNodeIndex);
0612: setContentSpec(contentSpecIndex, fContentSpec);
0613:
0614: // return index
0615: return contentSpecIndex;
0616:
0617: } // addContentSpecNode(int,int,int):int
0618:
0619: /**
0620: * Create a string representation of an XMLContentSpec tree
0621: *
0622: * @param handle to an XMLContentSpec
0623: * @return String representation of the content spec tree
0624: * @exception java.lang.Exception
0625: */
0626: public String getContentSpecNodeAsString(int nodeIndex)
0627: throws Exception {
0628: return XMLContentSpec.toString(this , fStringPool, nodeIndex);
0629: }
0630:
0631: /**
0632: * Start the scope of an entity declaration.
0633: *
0634: * @return <code>true</code> on success; otherwise
0635: * <code>false</code> if the entity declaration is recursive.
0636: * @exception java.lang.Exception
0637: */
0638: public boolean startEntityDecl(boolean isPE, int entityName)
0639: throws Exception {
0640:
0641: // create entity decl
0642: Element entityDecl = fGrammarDocument
0643: .createElement("entityDecl");
0644: entityDecl.setAttribute("name", fStringPool
0645: .toString(entityName));
0646: entityDecl.setAttribute("parameter", isPE ? "true" : "false");
0647: fCurrentElement.appendChild(entityDecl);
0648: fCurrentElement = entityDecl;
0649:
0650: // success
0651: return true;
0652:
0653: } // startEntityDecl(boolean,int):boolean
0654:
0655: /**
0656: * End the scope of an entity declaration.
0657: * @exception java.lang.Exception
0658: */
0659: public void endEntityDecl() throws Exception {
0660:
0661: // get out of entity decl
0662: fCurrentElement = (Element) fCurrentElement.getParentNode();
0663:
0664: } // endEntityDecl()
0665:
0666: /**
0667: * Add a declaration for an internal parameter entity
0668: *
0669: * @param name StringPool handle of the parameter entity name
0670: * @param value StringPool handle of the parameter entity value
0671: * @return handle to the parameter entity declaration
0672: * @exception java.lang.Exception
0673: */
0674: public int addInternalPEDecl(int name, int value) throws Exception {
0675:
0676: // create internal PE decl
0677: Element internalPEDecl = fGrammarDocument
0678: .createElement("internalPEDecl");
0679: internalPEDecl.setAttribute("name", fStringPool.toString(name));
0680: internalPEDecl.setAttribute("value", fStringPool
0681: .toString(value));
0682: fCurrentElement.appendChild(internalPEDecl);
0683:
0684: // REVISIT: What is my responsibility for creating a handle?
0685: int peDeclIndex = -1;
0686:
0687: // return index
0688: return peDeclIndex;
0689:
0690: } // addInternalPEDecl(int,int):int
0691:
0692: /**
0693: * Add a declaration for an external parameter entity
0694: *
0695: * @param name StringPool handle of the parameter entity name
0696: * @param publicId StringPool handle of the publicId
0697: * @param systemId StringPool handle of the systemId
0698: * @return handle to the parameter entity declaration
0699: * @exception java.lang.Exception
0700: */
0701: public int addExternalPEDecl(int name, int publicId, int systemId)
0702: throws Exception {
0703:
0704: // create external PE decl
0705: Element externalPEDecl = fGrammarDocument
0706: .createElement("externalPEDecl");
0707: externalPEDecl.setAttribute("name", fStringPool.toString(name));
0708: externalPEDecl.setAttribute("publicId", fStringPool
0709: .toString(publicId));
0710: externalPEDecl.setAttribute("systemId", fStringPool
0711: .toString(systemId));
0712: fCurrentElement.appendChild(externalPEDecl);
0713:
0714: // REVISIT: What is my responsibility for creating a handle?
0715: int peDeclIndex = -1;
0716:
0717: // return index
0718: return peDeclIndex;
0719:
0720: } // addExternalPEDecl(int,int,int):int
0721:
0722: /**
0723: * Add a declaration for an internal entity
0724: *
0725: * @param name StringPool handle of the entity name
0726: * @param value StringPool handle of the entity value
0727: * @return handle to the entity declaration
0728: * @exception java.lang.Exception
0729: */
0730: public int addInternalEntityDecl(int name, int value)
0731: throws Exception {
0732:
0733: // create internal entity decl
0734: Element internalEntityDecl = fGrammarDocument
0735: .createElement("internalEntityDecl");
0736: internalEntityDecl.setAttribute("name", fStringPool
0737: .toString(name));
0738: internalEntityDecl.setAttribute("value", fStringPool
0739: .toString(value));
0740: fCurrentElement.appendChild(internalEntityDecl);
0741:
0742: // REVISIT: What is my responsibility for creating a handle?
0743: int internalEntityDeclIndex = -1;
0744:
0745: // return index
0746: return internalEntityDeclIndex;
0747:
0748: } // addInternalEntityDecl(int,int):int
0749:
0750: /**
0751: * Add a declaration for an entity
0752: *
0753: * @param name StringPool handle of the entity name
0754: * @param publicId StringPool handle of the publicId
0755: * @param systemId StringPool handle of the systemId
0756: * @return handle to the entity declaration
0757: * @exception java.lang.Exception
0758: */
0759: public int addExternalEntityDecl(int name, int publicId,
0760: int systemId) throws Exception {
0761:
0762: // create external entity decl
0763: Element externalEntityDecl = fGrammarDocument
0764: .createElement("externalEntityDecl");
0765: externalEntityDecl.setAttribute("name", fStringPool
0766: .toString(name));
0767: externalEntityDecl.setAttribute("publicId", fStringPool
0768: .toString(publicId));
0769: externalEntityDecl.setAttribute("systemId", fStringPool
0770: .toString(systemId));
0771: fCurrentElement.appendChild(externalEntityDecl);
0772:
0773: // REVISIT: What is my responsibility for creating a handle?
0774: int externalEntityDeclIndex = -1;
0775:
0776: // return index
0777: return externalEntityDeclIndex;
0778:
0779: } // addExternalEntityDecl(int,int,int):int
0780:
0781: /**
0782: * Add a declaration for an unparsed entity
0783: *
0784: * @param name StringPool handle of the entity name
0785: * @param publicId StringPool handle of the publicId
0786: * @param systemId StringPool handle of the systemId
0787: * @param notationName StringPool handle of the notationName
0788: * @return handle to the entity declaration
0789: * @exception java.lang.Exception
0790: */
0791: public int addUnparsedEntityDecl(int name, int publicId,
0792: int systemId, int notationName) throws Exception {
0793:
0794: // create external entity decl
0795: Element unparsedEntityDecl = fGrammarDocument
0796: .createElement("unparsedEntityDecl");
0797: unparsedEntityDecl.setAttribute("name", fStringPool
0798: .toString(name));
0799: unparsedEntityDecl.setAttribute("publicId", fStringPool
0800: .toString(publicId));
0801: unparsedEntityDecl.setAttribute("systemId", fStringPool
0802: .toString(systemId));
0803: unparsedEntityDecl.setAttribute("notation", fStringPool
0804: .toString(notationName));
0805: fCurrentElement.appendChild(unparsedEntityDecl);
0806:
0807: // REVISIT: What is my responsibility for creating a handle?
0808: int unparsedEntityDeclIndex = -1;
0809:
0810: // return index
0811: return unparsedEntityDeclIndex;
0812:
0813: } // addUnparsedEntityDecl(int,int,int,int):int
0814:
0815: /**
0816: * Called when the scanner start scanning an enumeration
0817: * @return StringPool handle to a string list that will hold the enumeration names
0818: * @exception java.lang.Exception
0819: */
0820: public int startEnumeration() throws Exception {
0821:
0822: // create enumeration
0823: Element enumeration = fGrammarDocument
0824: .createElement("enumeration");
0825: fCurrentElement.appendChild(enumeration);
0826: fCurrentElement = enumeration;
0827:
0828: // REVISIT: What is my responsibility for creating a handle?
0829: //int enumIndex = -1;
0830: int enumIndex = fStringPool.startStringList();
0831:
0832: // return index
0833: return enumIndex;
0834:
0835: } // startEnumeration():int
0836:
0837: /**
0838: * Add a name to an enumeration
0839: * @param enumIndex StringPool handle to the string list for the enumeration
0840: * @param elementType handle to the element that owns the attribute with the enumeration
0841: * @param attrName StringPool handle to the name of the attribut with the enumeration
0842: * @param nameIndex StringPool handle to the name to be added to the enumeration
0843: * @param isNotationType true if the enumeration is an enumeration of NOTATION names
0844: * @exception java.lang.Exception
0845: */
0846: public void addNameToEnumeration(int enumIndex, int elementType,
0847: int attrName, int nameIndex, boolean isNotationType)
0848: throws Exception {
0849:
0850: // create enumeration literal
0851: Element literal = fGrammarDocument.createElement("literal");
0852: // REVISIT: How is this literal (and its parent enumeration)
0853: // associated to an element and attribute name? This
0854: // should be done better.
0855: literal.setAttribute("element", fStringPool
0856: .toString(elementType));
0857: literal.setAttribute("attribute", fStringPool
0858: .toString(attrName));
0859: literal.setAttribute("name", fStringPool.toString(nameIndex));
0860: literal.setAttribute("notation", isNotationType ? "true"
0861: : "false");
0862: fCurrentElement.appendChild(literal);
0863:
0864: //add the name to the stringList
0865: fStringPool.addStringToList(enumIndex, nameIndex);
0866:
0867: } // addNameToEnumeration(int,int,int,int,boolean)
0868:
0869: /**
0870: * Finish processing an enumeration
0871: *
0872: * @param enumIndex handle to the string list which holds the enumeration to be finshed.
0873: * @exception java.lang.Exception
0874: */
0875: public void endEnumeration(int enumIndex) throws Exception {
0876:
0877: // get out of enumeration
0878: fCurrentElement = (Element) fCurrentElement.getParentNode();
0879:
0880: //finish the enumeration stringlist int the fStringPool
0881: fStringPool.finishStringList(enumIndex);
0882:
0883: } // endEnumeration(int)
0884:
0885: /**
0886: * Add a declaration for a notation
0887: *
0888: * @param notationName
0889: * @param publicId
0890: * @param systemId
0891: * @return handle to the notation declaration
0892: * @exception java.lang.Exception
0893: */
0894: public int addNotationDecl(int notationName, int publicId,
0895: int systemId) throws Exception {
0896:
0897: // create notation decl
0898: Element notationDecl = fGrammarDocument
0899: .createElement("notationDecl");
0900: notationDecl.setAttribute("name", fStringPool
0901: .toString(notationName));
0902: notationDecl.setAttribute("publicId", fStringPool
0903: .toString(publicId));
0904: notationDecl.setAttribute("systemId", fStringPool
0905: .toString(systemId));
0906: fCurrentElement.appendChild(notationDecl);
0907:
0908: // REVISIT: What is my responsibility for creating a handle?
0909: int notationDeclIndex = -1;
0910:
0911: // return index
0912: return notationDeclIndex;
0913:
0914: } // addNotationdecl(int,int,int):int
0915:
0916: /**
0917: * Called when a comment has been scanned
0918: *
0919: * @param data StringPool handle of the comment text
0920: * @exception java.lang.Exception
0921: */
0922: public void callComment(int data) throws Exception {
0923: }
0924:
0925: /**
0926: * Called when a processing instruction has been scanned
0927: * @param piTarget StringPool handle of the PI target
0928: * @param piData StringPool handle of the PI data
0929: * @exception java.lang.Exception
0930: */
0931: public void callProcessingInstruction(int piTarget, int piData)
0932: throws Exception {
0933:
0934: // create pi
0935: ProcessingInstruction pi = fGrammarDocument
0936: .createProcessingInstruction(fStringPool
0937: .toString(piTarget), fStringPool
0938: .toString(piData));
0939: fCurrentElement.appendChild(pi);
0940:
0941: } // callProcessingInstruction(int,int)
0942:
0943: // deprecated -- removed from DOM Level 2
0944:
0945: /**
0946: * Supports DOM Level 2 internalSubset additions.
0947: * Called when the internal subset is completely scanned.
0948: */
0949: public void internalSubset(int internalSubset) throws Exception {
0950: }
0951:
0952: protected boolean isDTD() {
0953: return true;
0954: }
0955:
0956: //
0957: // Private methods
0958: //
0959:
0960: // ensure capacity
0961:
0962: /** Ensures storage for element declaration mappings. */
0963: private void ensureElementDeclCapacity(int chunk) {
0964: if (chunk >= fElementDeclMap.length) {
0965: fElementDeclMap = resize(fElementDeclMap,
0966: fElementDeclMap.length * 2);
0967: fElementDeclIsExternal = resize(fElementDeclIsExternal,
0968: fElementDeclIsExternal.length * 2);
0969: } else if (fElementDeclMap[chunk] != null) {
0970: return;
0971: }
0972: fElementDeclMap[chunk] = new int[CHUNK_SIZE];
0973: fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
0974: }
0975:
0976: /** Ensures storage for attribute declaration mappings. */
0977: private void ensureAttributeDeclCapacity(int chunk) {
0978: if (chunk >= fAttributeDeclMap.length) {
0979: fAttributeDeclMap = resize(fAttributeDeclMap,
0980: fAttributeDeclMap.length * 2);
0981: fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal,
0982: fAttributeDeclIsExternal.length * 2);
0983: } else if (fAttributeDeclMap[chunk] != null) {
0984: return;
0985: }
0986: fAttributeDeclMap[chunk] = new int[CHUNK_SIZE];
0987: fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
0988: }
0989:
0990: /** Ensures storage for content spec mappings. */
0991: private void ensureContentSpecCapacity(int chunk) {
0992: if (chunk >= fContentSpecMap.length) {
0993: fContentSpecMap = resize(fContentSpecMap,
0994: fContentSpecMap.length * 2);
0995: } else if (fContentSpecMap[chunk] != null) {
0996: return;
0997: }
0998: fContentSpecMap[chunk] = new int[CHUNK_SIZE];
0999: }
1000:
1001: // resize initial chunk
1002:
1003: /** Resizes chunked integer arrays. */
1004: private int[][] resize(int array[][], int newsize) {
1005: int newarray[][] = new int[newsize][];
1006: System.arraycopy(array, 0, newarray, 0, array.length);
1007: return newarray;
1008: }
1009:
1010: } // class DTDGrammar
|