Source Code Cross Referenced for DTDGrammar.java in  » XML » xerces-2_9_1 » org » apache » xerces » impl » dtd » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xerces 2_9_1 » org.apache.xerces.impl.dtd 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.xerces.impl.dtd;
0019:
0020:        import java.util.Hashtable;
0021:        import java.util.Vector;
0022:
0023:        import org.apache.xerces.impl.dtd.models.CMAny;
0024:        import org.apache.xerces.impl.dtd.models.CMBinOp;
0025:        import org.apache.xerces.impl.dtd.models.CMLeaf;
0026:        import org.apache.xerces.impl.dtd.models.CMNode;
0027:        import org.apache.xerces.impl.dtd.models.CMUniOp;
0028:        import org.apache.xerces.impl.dtd.models.ContentModelValidator;
0029:        import org.apache.xerces.impl.dtd.models.DFAContentModel;
0030:        import org.apache.xerces.impl.dtd.models.MixedContentModel;
0031:        import org.apache.xerces.impl.dtd.models.SimpleContentModel;
0032:        import org.apache.xerces.impl.dv.DatatypeValidator;
0033:        import org.apache.xerces.impl.validation.EntityState;
0034:        import org.apache.xerces.util.SymbolTable;
0035:        import org.apache.xerces.xni.Augmentations;
0036:        import org.apache.xerces.xni.QName;
0037:        import org.apache.xerces.xni.XMLDTDContentModelHandler;
0038:        import org.apache.xerces.xni.XMLDTDHandler;
0039:        import org.apache.xerces.xni.XMLLocator;
0040:        import org.apache.xerces.xni.XMLResourceIdentifier;
0041:        import org.apache.xerces.xni.XMLString;
0042:        import org.apache.xerces.xni.XNIException;
0043:        import org.apache.xerces.xni.grammars.Grammar;
0044:        import org.apache.xerces.xni.grammars.XMLGrammarDescription;
0045:        import org.apache.xerces.xni.parser.XMLDTDContentModelSource;
0046:        import org.apache.xerces.xni.parser.XMLDTDSource;
0047:
0048:        /**
0049:         * A DTD grammar. This class implements the XNI handler interfaces
0050:         * for DTD information so that it can build the approprate validation
0051:         * structures automatically from the callbacks.
0052:         * 
0053:         * @xerces.internal
0054:         *
0055:         * @author Eric Ye, IBM
0056:         * @author Jeffrey Rodriguez, IBM
0057:         * @author Andy Clark, IBM
0058:         * @author Neil Graham, IBM
0059:         *
0060:         * @version $Id: DTDGrammar.java 572055 2007-09-02 17:55:43Z mrglavas $
0061:         */
0062:        public class DTDGrammar implements  XMLDTDHandler,
0063:                XMLDTDContentModelHandler, EntityState, Grammar {
0064:
0065:            //
0066:            // Constants
0067:            //
0068:
0069:            /** Top level scope (-1). */
0070:            public static final int TOP_LEVEL_SCOPE = -1;
0071:
0072:            // private
0073:
0074:            /** Chunk shift (8). */
0075:            private static final int CHUNK_SHIFT = 8; // 2^8 = 256
0076:
0077:            /** Chunk size (1 << CHUNK_SHIFT). */
0078:            private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
0079:
0080:            /** Chunk mask (CHUNK_SIZE - 1). */
0081:            private static final int CHUNK_MASK = CHUNK_SIZE - 1;
0082:
0083:            /** Initial chunk count (1 << (10 - CHUNK_SHIFT)). */
0084:            private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
0085:
0086:            /** List flag (0x80). */
0087:            private static final short LIST_FLAG = 0x80;
0088:
0089:            /** List mask (~LIST_FLAG). */
0090:            private static final short LIST_MASK = ~LIST_FLAG;
0091:
0092:            // debugging
0093:
0094:            /** Debug DTDGrammar. */
0095:            private static final boolean DEBUG = false;
0096:
0097:            //
0098:            // Data
0099:            //
0100:
0101:            protected XMLDTDSource fDTDSource = null;
0102:            protected XMLDTDContentModelSource fDTDContentModelSource = null;
0103:
0104:            /** Current element index. */
0105:            protected int fCurrentElementIndex;
0106:
0107:            /** Current attribute index. */
0108:            protected int fCurrentAttributeIndex;
0109:
0110:            /** fReadingExternalDTD */
0111:            protected boolean fReadingExternalDTD = false;
0112:
0113:            /** Symbol table. */
0114:            private SymbolTable fSymbolTable;
0115:
0116:            // The XMLDTDDescription with which this Grammar is associated
0117:            protected XMLDTDDescription fGrammarDescription = null;
0118:
0119:            // element declarations
0120:
0121:            /** Number of element declarations. */
0122:            private int fElementDeclCount = 0;
0123:
0124:            /** Element declaration name. */
0125:            private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
0126:
0127:            /** 
0128:             * Element declaration type. 
0129:             * @see XMLElementDecl
0130:             */
0131:            private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
0132:
0133:            /** 
0134:             * Element declaration content spec index. This index value is used
0135:             * to refer to the content spec information tables.
0136:             */
0137:            private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
0138:
0139:            /** 
0140:             * Element declaration content model validator. This validator is
0141:             * constructed from the content spec nodes.
0142:             */
0143:            private ContentModelValidator fElementDeclContentModelValidator[][] = new ContentModelValidator[INITIAL_CHUNK_COUNT][];
0144:
0145:            /** First attribute declaration of an element declaration. */
0146:            private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
0147:
0148:            /** Last attribute declaration of an element declaration. */
0149:            private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
0150:
0151:            // attribute declarations
0152:
0153:            /** Number of attribute declarations. */
0154:            private int fAttributeDeclCount = 0;
0155:
0156:            /** Attribute declaration name. */
0157:            private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
0158:
0159:            // is this grammar immutable?  (fully constructed and not changeable)
0160:            private boolean fIsImmutable = false;
0161:
0162:            /** 
0163:             * Attribute declaration type.
0164:             * @see XMLAttributeDecl
0165:             */
0166:            private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
0167:
0168:            /** Attribute declaration enumeration values. */
0169:            private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
0170:            private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
0171:            private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
0172:            private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
0173:            private String fAttributeDeclNonNormalizedDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
0174:            private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
0175:
0176:            // content specs
0177:
0178:            // here saves the content spec binary trees for element decls, 
0179:            // each element with a content model will hold a pointer which is 
0180:            // the index of the head node of the content spec tree. 
0181:
0182:            private int fContentSpecCount = 0;
0183:            private short fContentSpecType[][] = new short[INITIAL_CHUNK_COUNT][];
0184:            private Object fContentSpecValue[][] = new Object[INITIAL_CHUNK_COUNT][];
0185:            private Object fContentSpecOtherValue[][] = new Object[INITIAL_CHUNK_COUNT][];
0186:
0187:            // entities
0188:
0189:            private int fEntityCount = 0;
0190:            private String fEntityName[][] = new String[INITIAL_CHUNK_COUNT][];
0191:            private String[][] fEntityValue = new String[INITIAL_CHUNK_COUNT][];
0192:            private String[][] fEntityPublicId = new String[INITIAL_CHUNK_COUNT][];
0193:            private String[][] fEntitySystemId = new String[INITIAL_CHUNK_COUNT][];
0194:            private String[][] fEntityBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
0195:            private String[][] fEntityNotation = new String[INITIAL_CHUNK_COUNT][];
0196:            private byte[][] fEntityIsPE = new byte[INITIAL_CHUNK_COUNT][];
0197:            private byte[][] fEntityInExternal = new byte[INITIAL_CHUNK_COUNT][];
0198:
0199:            // notations
0200:
0201:            private int fNotationCount = 0;
0202:            private String fNotationName[][] = new String[INITIAL_CHUNK_COUNT][];
0203:            private String[][] fNotationPublicId = new String[INITIAL_CHUNK_COUNT][];
0204:            private String[][] fNotationSystemId = new String[INITIAL_CHUNK_COUNT][];
0205:            private String[][] fNotationBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
0206:
0207:            // other information
0208:
0209:            /** Element index mapping table. */
0210:            private QNameHashtable fElementIndexMap = new QNameHashtable();
0211:
0212:            /** Entity index mapping table. */
0213:            private QNameHashtable fEntityIndexMap = new QNameHashtable();
0214:
0215:            /** Notation index mapping table. */
0216:            private QNameHashtable fNotationIndexMap = new QNameHashtable();
0217:
0218:            // temp variables
0219:
0220:            /** Mixed. */
0221:            private boolean fMixed;
0222:
0223:            /** Temporary qualified name. */
0224:            private final QName fQName = new QName();
0225:
0226:            /** Temporary qualified name. */
0227:            private final QName fQName2 = new QName();
0228:
0229:            /** Temporary Attribute decl. */
0230:            protected final XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
0231:
0232:            // for buildSyntaxTree method
0233:
0234:            private int fLeafCount = 0;
0235:            private int fEpsilonIndex = -1;
0236:
0237:            /** Element declaration. */
0238:            private XMLElementDecl fElementDecl = new XMLElementDecl();
0239:
0240:            /** Entity declaration. */
0241:            private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
0242:
0243:            /** Simple type. */
0244:            private XMLSimpleType fSimpleType = new XMLSimpleType();
0245:
0246:            /** Content spec node. */
0247:            private XMLContentSpec fContentSpec = new XMLContentSpec();
0248:
0249:            /** table of XMLElementDecl   */
0250:            Hashtable fElementDeclTab = new Hashtable();
0251:
0252:            /** Children content model operation stack. */
0253:            private short[] fOpStack = null;
0254:
0255:            /** Children content model index stack. */
0256:            private int[] fNodeIndexStack = null;
0257:
0258:            /** Children content model previous node index stack. */
0259:            private int[] fPrevNodeIndexStack = null;
0260:
0261:            /** Stack depth   */
0262:            private int fDepth = 0;
0263:
0264:            /** Entity stack. */
0265:            private boolean[] fPEntityStack = new boolean[4];
0266:            private int fPEDepth = 0;
0267:
0268:            // additional fields(columns) for the element Decl pool in the Grammar
0269:
0270:            /** flag if the elementDecl is External. */
0271:            private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
0272:
0273:            // additional fields(columns) for the attribute Decl pool in the Grammar
0274:
0275:            /** flag if the AttributeDecl is External. */
0276:            private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
0277:
0278:            // for mixedElement method
0279:
0280:            int valueIndex = -1;
0281:            int prevNodeIndex = -1;
0282:            int nodeIndex = -1;
0283:
0284:            //
0285:            // Constructors
0286:            //
0287:
0288:            /** Default constructor. */
0289:            public DTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) {
0290:                fSymbolTable = symbolTable;
0291:                fGrammarDescription = desc;
0292:            } // <init>(SymbolTable)
0293:
0294:            // Grammar methods
0295:
0296:            // return the XMLDTDDescription object with which this is associated
0297:            public XMLGrammarDescription getGrammarDescription() {
0298:                return fGrammarDescription;
0299:            } // getGrammarDescription():  XMLGrammarDescription
0300:
0301:            //
0302:            // Public methods
0303:            //
0304:
0305:            /**
0306:             * Returns true if the specified element declaration is external.
0307:             *
0308:             * @param elementDeclIndex The element declaration index.
0309:             */
0310:            public boolean getElementDeclIsExternal(int elementDeclIndex) {
0311:
0312:                if (elementDeclIndex < 0) {
0313:                    return false;
0314:                }
0315:
0316:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
0317:                int index = elementDeclIndex & CHUNK_MASK;
0318:                return (fElementDeclIsExternal[chunk][index] != 0);
0319:
0320:            } // getElementDeclIsExternal(int):boolean
0321:
0322:            /**
0323:             * Returns true if the specified attribute declaration is external.
0324:             *
0325:             * @param attributeDeclIndex Attribute declaration index.
0326:             */
0327:            public boolean getAttributeDeclIsExternal(int attributeDeclIndex) {
0328:
0329:                if (attributeDeclIndex < 0) {
0330:                    return false;
0331:                }
0332:
0333:                int chunk = attributeDeclIndex >> CHUNK_SHIFT;
0334:                int index = attributeDeclIndex & CHUNK_MASK;
0335:                return (fAttributeDeclIsExternal[chunk][index] != 0);
0336:            }
0337:
0338:            public int getAttributeDeclIndex(int elementDeclIndex,
0339:                    String attributeDeclName) {
0340:                if (elementDeclIndex == -1) {
0341:                    return -1;
0342:                }
0343:                int attDefIndex = getFirstAttributeDeclIndex(elementDeclIndex);
0344:                while (attDefIndex != -1) {
0345:                    getAttributeDecl(attDefIndex, fAttributeDecl);
0346:
0347:                    if (fAttributeDecl.name.rawname == attributeDeclName
0348:                            || attributeDeclName
0349:                                    .equals(fAttributeDecl.name.rawname)) {
0350:                        return attDefIndex;
0351:                    }
0352:                    attDefIndex = getNextAttributeDeclIndex(attDefIndex);
0353:                }
0354:                return -1;
0355:            } // getAttributeDeclIndex (int,QName)
0356:
0357:            //
0358:            // XMLDTDHandler methods
0359:            //
0360:
0361:            /**
0362:             * The start of the DTD.
0363:             *
0364:             * @param locator  The document locator, or null if the document
0365:             *                 location cannot be reported during the parsing of
0366:             *                 the document DTD. However, it is <em>strongly</em>
0367:             *                 recommended that a locator be supplied that can
0368:             *                 at least report the base system identifier of the
0369:             *                 DTD.
0370:             *
0371:             * @param augs Additional information that may include infoset
0372:             *                      augmentations.
0373:             * @throws XNIException Thrown by handler to signal an error.
0374:             */
0375:            public void startDTD(XMLLocator locator, Augmentations augs)
0376:                    throws XNIException {
0377:                //Initialize stack
0378:                fOpStack = null;
0379:                fNodeIndexStack = null;
0380:                fPrevNodeIndexStack = null;
0381:            } // startDTD(XMLLocator)
0382:
0383:            /**
0384:             * This method notifies of the start of an entity. The DTD has the
0385:             * pseudo-name of "[dtd]" and parameter entity names start with '%'.
0386:             * <p>
0387:             * <strong>Note:</strong> Since the DTD is an entity, the handler
0388:             * will be notified of the start of the DTD entity by calling the
0389:             * startParameterEntity method with the entity name "[dtd]" <em>before</em> calling
0390:             * the startDTD method.
0391:             *
0392:             * @param name     The name of the parameter entity.
0393:             * @param identifier The resource identifier.
0394:             * @param encoding The auto-detected IANA encoding name of the entity
0395:             *                 stream. This value will be null in those situations
0396:             *                 where the entity encoding is not auto-detected (e.g.
0397:             *                 internal parameter entities).
0398:             * @param augs Additional information that may include infoset
0399:             *                      augmentations.
0400:             *
0401:             * @throws XNIException Thrown by handler to signal an error.
0402:             */
0403:            public void startParameterEntity(String name,
0404:                    XMLResourceIdentifier identifier, String encoding,
0405:                    Augmentations augs) throws XNIException {
0406:
0407:                // keep track of this entity before fEntityDepth is increased
0408:                if (fPEDepth == fPEntityStack.length) {
0409:                    boolean[] entityarray = new boolean[fPEntityStack.length * 2];
0410:                    System.arraycopy(fPEntityStack, 0, entityarray, 0,
0411:                            fPEntityStack.length);
0412:                    fPEntityStack = entityarray;
0413:                }
0414:                fPEntityStack[fPEDepth] = fReadingExternalDTD;
0415:                fPEDepth++;
0416:
0417:            } // startParameterEntity(String,XMLResourceIdentifier,String,Augmentations)
0418:
0419:            /**
0420:             * The start of the DTD external subset.
0421:             *
0422:             * @param augs Additional information that may include infoset
0423:             *                      augmentations.
0424:             *
0425:             * @throws XNIException Thrown by handler to signal an error.
0426:             */
0427:            public void startExternalSubset(XMLResourceIdentifier identifier,
0428:                    Augmentations augs) throws XNIException {
0429:                fReadingExternalDTD = true;
0430:            } // startExternalSubset(Augmentations)
0431:
0432:            /**
0433:             * This method notifies the end of an entity. The DTD has the pseudo-name
0434:             * of "[dtd]" and parameter entity names start with '%'.
0435:             * <p>
0436:             * <strong>Note:</strong> Since the DTD is an entity, the handler
0437:             * will be notified of the end of the DTD entity by calling the
0438:             * endEntity method with the entity name "[dtd]" <em>after</em> calling
0439:             * the endDTD method.
0440:             *
0441:             * @param name The name of the entity.
0442:             * @param augs Additional information that may include infoset
0443:             *                      augmentations.
0444:             * @throws XNIException Thrown by handler to signal an error.
0445:             */
0446:            public void endParameterEntity(String name, Augmentations augs)
0447:                    throws XNIException {
0448:
0449:                fPEDepth--;
0450:                fReadingExternalDTD = fPEntityStack[fPEDepth];
0451:
0452:            } // endParameterEntity(String,Augmentations)
0453:
0454:            /**
0455:             * The end of the DTD external subset.
0456:             *
0457:             * @param augs Additional information that may include infoset
0458:             *                      augmentations.
0459:             *
0460:             * @throws XNIException Thrown by handler to signal an error.
0461:             */
0462:            public void endExternalSubset(Augmentations augs)
0463:                    throws XNIException {
0464:                fReadingExternalDTD = false;
0465:            } // endExternalSubset(Augmentations)
0466:
0467:            /**
0468:             * An element declaration.
0469:             *
0470:             * @param name         The name of the element.
0471:             * @param contentModel The element content model.
0472:             * @param augs Additional information that may include infoset
0473:             *                      augmentations.
0474:             * @throws XNIException Thrown by handler to signal an error.
0475:             */
0476:            public void elementDecl(String name, String contentModel,
0477:                    Augmentations augs) throws XNIException {
0478:
0479:                XMLElementDecl tmpElementDecl = (XMLElementDecl) fElementDeclTab
0480:                        .get(name);
0481:
0482:                // check if it is already defined
0483:                if (tmpElementDecl != null) {
0484:                    if (tmpElementDecl.type == -1) {
0485:                        fCurrentElementIndex = getElementDeclIndex(name);
0486:                    } else {
0487:                        // duplicate element, ignored.
0488:                        return;
0489:                    }
0490:                } else {
0491:                    fCurrentElementIndex = createElementDecl();//create element decl
0492:                }
0493:
0494:                XMLElementDecl elementDecl = new XMLElementDecl();
0495:
0496:                fQName.setValues(null, name, name, null);
0497:
0498:                elementDecl.name.setValues(fQName);
0499:
0500:                elementDecl.contentModelValidator = null;
0501:                elementDecl.scope = -1;
0502:                if (contentModel.equals("EMPTY")) {
0503:                    elementDecl.type = XMLElementDecl.TYPE_EMPTY;
0504:                } else if (contentModel.equals("ANY")) {
0505:                    elementDecl.type = XMLElementDecl.TYPE_ANY;
0506:                } else if (contentModel.startsWith("(")) {
0507:                    if (contentModel.indexOf("#PCDATA") > 0) {
0508:                        elementDecl.type = XMLElementDecl.TYPE_MIXED;
0509:                    } else {
0510:                        elementDecl.type = XMLElementDecl.TYPE_CHILDREN;
0511:                    }
0512:                }
0513:
0514:                //add(or set) this elementDecl to the local cache
0515:                this .fElementDeclTab.put(name, elementDecl);
0516:
0517:                fElementDecl = elementDecl;
0518:                addContentSpecToElement(elementDecl);
0519:
0520:                if (DEBUG) {
0521:                    System.out.println("name = " + fElementDecl.name.localpart);
0522:                    System.out.println("Type = " + fElementDecl.type);
0523:                }
0524:
0525:                setElementDecl(fCurrentElementIndex, fElementDecl);//set internal structure
0526:
0527:                int chunk = fCurrentElementIndex >> CHUNK_SHIFT;
0528:                int index = fCurrentElementIndex & CHUNK_MASK;
0529:                ensureElementDeclCapacity(chunk);
0530:                fElementDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1
0531:                        : 0;
0532:
0533:            } // elementDecl(String,String)
0534:
0535:            /**
0536:             * An attribute declaration.
0537:             *
0538:             * @param elementName   The name of the element that this attribute
0539:             *                      is associated with.
0540:             * @param attributeName The name of the attribute.
0541:             * @param type          The attribute type. This value will be one of
0542:             *                      the following: "CDATA", "ENTITY", "ENTITIES",
0543:             *                      "ENUMERATION", "ID", "IDREF", "IDREFS",
0544:             *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
0545:             * @param enumeration   If the type has the value "ENUMERATION", this
0546:             *                      array holds the allowed attribute values;
0547:             *                      otherwise, this array is null.
0548:             * @param defaultType   The attribute default type. This value will be
0549:             *                      one of the following: "#FIXED", "#IMPLIED",
0550:             *                      "#REQUIRED", or null.
0551:             * @param defaultValue  The attribute default value, or null if no
0552:             *                      default value is specified.
0553:             * @param nonNormalizedDefaultValue  The attribute default value with no normalization
0554:             *                      performed, or null if no default value is specified.
0555:             *
0556:             * @param augs Additional information that may include infoset
0557:             *                      augmentations.
0558:             * @throws XNIException Thrown by handler to signal an error.
0559:             */
0560:            public void attributeDecl(String elementName, String attributeName,
0561:                    String type, String[] enumeration, String defaultType,
0562:                    XMLString defaultValue,
0563:                    XMLString nonNormalizedDefaultValue, Augmentations augs)
0564:                    throws XNIException {
0565:
0566:                if (this .fElementDeclTab.containsKey((String) elementName)) {
0567:                    //if ElementDecl has already being created in the Grammar then remove from table,
0568:                    //this.fElementDeclTab.remove( (String) elementName );
0569:                }
0570:                // then it is forward reference to a element decl, create the elementDecl first.
0571:                else {
0572:                    fCurrentElementIndex = createElementDecl();//create element decl
0573:
0574:                    XMLElementDecl elementDecl = new XMLElementDecl();
0575:                    elementDecl.name.setValues(null, elementName, elementName,
0576:                            null);
0577:
0578:                    elementDecl.scope = -1;
0579:
0580:                    //add(or set) this elementDecl to the local cache
0581:                    this .fElementDeclTab.put(elementName, elementDecl);
0582:
0583:                    //set internal structure
0584:                    setElementDecl(fCurrentElementIndex, elementDecl);
0585:                }
0586:
0587:                //Get Grammar index to grammar array
0588:                int elementIndex = getElementDeclIndex(elementName);
0589:
0590:                //return, when more than one definition is provided for the same attribute of given element type
0591:                //only the first declaration is binding and later declarations are ignored
0592:                if (getAttributeDeclIndex(elementIndex, attributeName) != -1) {
0593:                    return;
0594:                }
0595:
0596:                fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl
0597:
0598:                fSimpleType.clear();
0599:                if (defaultType != null) {
0600:                    if (defaultType.equals("#FIXED")) {
0601:                        fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_FIXED;
0602:                    } else if (defaultType.equals("#IMPLIED")) {
0603:                        fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
0604:                    } else if (defaultType.equals("#REQUIRED")) {
0605:                        fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_REQUIRED;
0606:                    }
0607:                }
0608:                if (DEBUG) {
0609:                    System.out.println("defaultvalue = "
0610:                            + defaultValue.toString());
0611:                }
0612:                fSimpleType.defaultValue = defaultValue != null ? defaultValue
0613:                        .toString() : null;
0614:                fSimpleType.nonNormalizedDefaultValue = nonNormalizedDefaultValue != null ? nonNormalizedDefaultValue
0615:                        .toString()
0616:                        : null;
0617:                fSimpleType.enumeration = enumeration;
0618:
0619:                if (type.equals("CDATA")) {
0620:                    fSimpleType.type = XMLSimpleType.TYPE_CDATA;
0621:                } else if (type.equals("ID")) {
0622:                    fSimpleType.type = XMLSimpleType.TYPE_ID;
0623:                } else if (type.startsWith("IDREF")) {
0624:                    fSimpleType.type = XMLSimpleType.TYPE_IDREF;
0625:                    if (type.indexOf("S") > 0) {
0626:                        fSimpleType.list = true;
0627:                    }
0628:                } else if (type.equals("ENTITIES")) {
0629:                    fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
0630:                    fSimpleType.list = true;
0631:                } else if (type.equals("ENTITY")) {
0632:                    fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
0633:                } else if (type.equals("NMTOKENS")) {
0634:                    fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
0635:                    fSimpleType.list = true;
0636:                } else if (type.equals("NMTOKEN")) {
0637:                    fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
0638:                } else if (type.startsWith("NOTATION")) {
0639:                    fSimpleType.type = XMLSimpleType.TYPE_NOTATION;
0640:                } else if (type.startsWith("ENUMERATION")) {
0641:                    fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
0642:                } else {
0643:                    // REVISIT: Report error message. -Ac
0644:                    System.err.println("!!! unknown attribute type " + type);
0645:                }
0646:                // REVISIT: The datatype should be stored with the attribute value
0647:                //          and not special-cased in the XMLValidator. -Ac
0648:                //fSimpleType.datatypeValidator = fDatatypeValidatorFactory.createDatatypeValidator(type, null, facets, fSimpleType.list);
0649:
0650:                fQName.setValues(null, attributeName, attributeName, null);
0651:                fAttributeDecl.setValues(fQName, fSimpleType, false);
0652:
0653:                setAttributeDecl(elementIndex, fCurrentAttributeIndex,
0654:                        fAttributeDecl);
0655:
0656:                int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT;
0657:                int index = fCurrentAttributeIndex & CHUNK_MASK;
0658:                ensureAttributeDeclCapacity(chunk);
0659:                fAttributeDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1
0660:                        : 0;
0661:
0662:            } // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations)
0663:
0664:            /**
0665:             * An internal entity declaration.
0666:             *
0667:             * @param name The name of the entity. Parameter entity names start with
0668:             *             '%', whereas the name of a general entity is just the
0669:             *             entity name.
0670:             * @param text The value of the entity.
0671:             * @param nonNormalizedText The non-normalized value of the entity. This
0672:             *             value contains the same sequence of characters that was in
0673:             *             the internal entity declaration, without any entity
0674:             *             references expanded.
0675:             * @param augs Additional information that may include infoset
0676:             *                      augmentations.
0677:             * @throws XNIException Thrown by handler to signal an error.
0678:             */
0679:            public void internalEntityDecl(String name, XMLString text,
0680:                    XMLString nonNormalizedText, Augmentations augs)
0681:                    throws XNIException {
0682:
0683:                int entityIndex = getEntityDeclIndex(name);
0684:                if (entityIndex == -1) {
0685:                    entityIndex = createEntityDecl();
0686:                    boolean isPE = name.startsWith("%");
0687:                    boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
0688:                    XMLEntityDecl entityDecl = new XMLEntityDecl();
0689:                    entityDecl.setValues(name, null, null, null, null, text
0690:                            .toString(), isPE, inExternal);
0691:
0692:                    setEntityDecl(entityIndex, entityDecl);
0693:                }
0694:
0695:            } // internalEntityDecl(String,XMLString,XMLString)
0696:
0697:            /**
0698:             * An external entity declaration.
0699:             *
0700:             * @param name     The name of the entity. Parameter entity names start
0701:             *                 with '%', whereas the name of a general entity is just
0702:             *                 the entity name.
0703:             * @param identifier    An object containing all location information
0704:             *                      pertinent to this external entity declaration.
0705:             * @param augs Additional information that may include infoset
0706:             *                      augmentations.
0707:             * @throws XNIException Thrown by handler to signal an error.
0708:             */
0709:            public void externalEntityDecl(String name,
0710:                    XMLResourceIdentifier identifier, Augmentations augs)
0711:                    throws XNIException {
0712:
0713:                int entityIndex = getEntityDeclIndex(name);
0714:                if (entityIndex == -1) {
0715:                    entityIndex = createEntityDecl();
0716:                    boolean isPE = name.startsWith("%");
0717:                    boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
0718:
0719:                    XMLEntityDecl entityDecl = new XMLEntityDecl();
0720:                    entityDecl.setValues(name, identifier.getPublicId(),
0721:                            identifier.getLiteralSystemId(), identifier
0722:                                    .getBaseSystemId(), null, null, isPE,
0723:                            inExternal);
0724:
0725:                    setEntityDecl(entityIndex, entityDecl);
0726:                }
0727:            } // externalEntityDecl(String, XMLResourceIdentifier, Augmentations)
0728:
0729:            /**
0730:             * An unparsed entity declaration.
0731:             *
0732:             * @param name     The name of the entity.
0733:             * @param identifier    An object containing all location information
0734:             *                      pertinent to this entity.
0735:             * @param notation The name of the notation.
0736:             * @param augs Additional information that may include infoset
0737:             *                      augmentations.
0738:             * @throws XNIException Thrown by handler to signal an error.
0739:             */
0740:            public void unparsedEntityDecl(String name,
0741:                    XMLResourceIdentifier identifier, String notation,
0742:                    Augmentations augs) throws XNIException {
0743:
0744:                XMLEntityDecl entityDecl = new XMLEntityDecl();
0745:                boolean isPE = name.startsWith("%");
0746:                boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
0747:
0748:                entityDecl.setValues(name, identifier.getPublicId(), identifier
0749:                        .getLiteralSystemId(), identifier.getBaseSystemId(),
0750:                        notation, null, isPE, inExternal);
0751:                int entityIndex = getEntityDeclIndex(name);
0752:                if (entityIndex == -1) {
0753:                    entityIndex = createEntityDecl();
0754:                    setEntityDecl(entityIndex, entityDecl);
0755:                }
0756:
0757:            } // unparsedEntityDecl(String,StringXMLResourceIdentifier,Augmentations)
0758:
0759:            /**
0760:             * A notation declaration
0761:             *
0762:             * @param name     The name of the notation.
0763:             * @param identifier    An object containing all location information
0764:             *                      pertinent to this notation.
0765:             * @param augs Additional information that may include infoset
0766:             *                      augmentations.
0767:             * @throws XNIException Thrown by handler to signal an error.
0768:             */
0769:            public void notationDecl(String name,
0770:                    XMLResourceIdentifier identifier, Augmentations augs)
0771:                    throws XNIException {
0772:
0773:                XMLNotationDecl notationDecl = new XMLNotationDecl();
0774:                notationDecl.setValues(name, identifier.getPublicId(),
0775:                        identifier.getLiteralSystemId(), identifier
0776:                                .getBaseSystemId());
0777:                int notationIndex = getNotationDeclIndex(name);
0778:                if (notationIndex == -1) {
0779:                    notationIndex = createNotationDecl();
0780:                    setNotationDecl(notationIndex, notationDecl);
0781:                }
0782:
0783:            } // notationDecl(String,XMLResourceIdentifier,Augmentations)
0784:
0785:            /**
0786:             * The end of the DTD.
0787:             *
0788:             * @param augs Additional information that may include infoset
0789:             *                      augmentations.
0790:             * @throws XNIException Thrown by handler to signal an error.
0791:             */
0792:            public void endDTD(Augmentations augs) throws XNIException {
0793:                fIsImmutable = true;
0794:                // make sure our description contains useful stuff...
0795:                if (fGrammarDescription.getRootName() == null) {
0796:                    // we don't know what the root is; so use possibleRoots...
0797:                    int chunk, index = 0;
0798:                    String currName = null;
0799:                    Vector elements = new Vector();
0800:                    for (int i = 0; i < fElementDeclCount; i++) {
0801:                        chunk = i >> CHUNK_SHIFT;
0802:                        index = i & CHUNK_MASK;
0803:                        currName = fElementDeclName[chunk][index].rawname;
0804:                        elements.addElement(currName);
0805:                    }
0806:                    fGrammarDescription.setPossibleRoots(elements);
0807:                }
0808:            } // endDTD()
0809:
0810:            // sets the source of this handler
0811:            public void setDTDSource(XMLDTDSource source) {
0812:                fDTDSource = source;
0813:            } // setDTDSource(XMLDTDSource)
0814:
0815:            // returns the source of this handler
0816:            public XMLDTDSource getDTDSource() {
0817:                return fDTDSource;
0818:            } // getDTDSource():  XMLDTDSource
0819:
0820:            // no-op methods
0821:
0822:            /**
0823:             * Notifies of the presence of a TextDecl line in an entity. If present,
0824:             * this method will be called immediately following the startEntity call.
0825:             * <p>
0826:             * <strong>Note:</strong> This method is only called for external
0827:             * parameter entities referenced in the DTD.
0828:             *
0829:             * @param version  The XML version, or null if not specified.
0830:             * @param encoding The IANA encoding name of the entity.
0831:             *
0832:             * @param augs Additional information that may include infoset
0833:             *                      augmentations.
0834:             * @throws XNIException Thrown by handler to signal an error.
0835:             */
0836:            public void textDecl(String version, String encoding,
0837:                    Augmentations augs) throws XNIException {
0838:            }
0839:
0840:            /**
0841:             * A comment.
0842:             *
0843:             * @param text The text in the comment.
0844:             * @param augs Additional information that may include infoset
0845:             *                      augmentations.
0846:             * @throws XNIException Thrown by application to signal an error.
0847:             */
0848:            public void comment(XMLString text, Augmentations augs)
0849:                    throws XNIException {
0850:            }
0851:
0852:            /**
0853:             * A processing instruction. Processing instructions consist of a
0854:             * target name and, optionally, text data. The data is only meaningful
0855:             * to the application.
0856:             * <p>
0857:             * Typically, a processing instruction's data will contain a series
0858:             * of pseudo-attributes. These pseudo-attributes follow the form of
0859:             * element attributes but are <strong>not</strong> parsed or presented
0860:             * to the application as anything other than text. The application is
0861:             * responsible for parsing the data.
0862:             *
0863:             * @param target The target.
0864:             * @param data   The data or null if none specified.
0865:             * @param augs Additional information that may include infoset
0866:             *                      augmentations.
0867:             * @throws XNIException Thrown by handler to signal an error.
0868:             */
0869:            public void processingInstruction(String target, XMLString data,
0870:                    Augmentations augs) throws XNIException {
0871:            }
0872:
0873:            /**
0874:             * The start of an attribute list.
0875:             *
0876:             * @param elementName The name of the element that this attribute
0877:             *                    list is associated with.
0878:             * @param augs Additional information that may include infoset
0879:             *                      augmentations.
0880:             * @throws XNIException Thrown by handler to signal an error.
0881:             */
0882:            public void startAttlist(String elementName, Augmentations augs)
0883:                    throws XNIException {
0884:            }
0885:
0886:            /**
0887:             * The end of an attribute list.
0888:             * @param augs Additional information that may include infoset
0889:             *                      augmentations.
0890:             * @throws XNIException Thrown by handler to signal an error.
0891:             */
0892:            public void endAttlist(Augmentations augs) throws XNIException {
0893:            }
0894:
0895:            /**
0896:             * The start of a conditional section.
0897:             *
0898:             * @param type The type of the conditional section. This value will
0899:             *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
0900:             * @param augs Additional information that may include infoset
0901:             *                      augmentations.
0902:             * @throws XNIException Thrown by handler to signal an error.
0903:             *
0904:             * @see XMLDTDHandler#CONDITIONAL_INCLUDE
0905:             * @see XMLDTDHandler#CONDITIONAL_IGNORE
0906:             */
0907:            public void startConditional(short type, Augmentations augs)
0908:                    throws XNIException {
0909:            }
0910:
0911:            /**
0912:             * Characters within an IGNORE conditional section.
0913:             *
0914:             * @param text The ignored text.
0915:             * @param augs Additional information that may include infoset
0916:             *                      augmentations.
0917:             */
0918:            public void ignoredCharacters(XMLString text, Augmentations augs)
0919:                    throws XNIException {
0920:            }
0921:
0922:            /**
0923:             * The end of a conditional section.
0924:             * @param augs Additional information that may include infoset
0925:             *                      augmentations.
0926:             * @throws XNIException Thrown by handler to signal an error.
0927:             */
0928:            public void endConditional(Augmentations augs) throws XNIException {
0929:            }
0930:
0931:            //
0932:            // XMLDTDContentModelHandler methods
0933:            //
0934:
0935:            // set content model source
0936:            public void setDTDContentModelSource(XMLDTDContentModelSource source) {
0937:                fDTDContentModelSource = source;
0938:            }
0939:
0940:            // get content model source
0941:            public XMLDTDContentModelSource getDTDContentModelSource() {
0942:                return fDTDContentModelSource;
0943:            }
0944:
0945:            /**
0946:             * The start of a content model. Depending on the type of the content
0947:             * model, specific methods may be called between the call to the
0948:             * startContentModel method and the call to the endContentModel method.
0949:             *
0950:             * @param elementName The name of the element.
0951:             * @param augs Additional information that may include infoset
0952:             *                      augmentations.
0953:             * @throws XNIException Thrown by handler to signal an error.
0954:             */
0955:            public void startContentModel(String elementName, Augmentations augs)
0956:                    throws XNIException {
0957:
0958:                XMLElementDecl elementDecl = (XMLElementDecl) this .fElementDeclTab
0959:                        .get(elementName);
0960:                if (elementDecl != null) {
0961:                    fElementDecl = elementDecl;
0962:                }
0963:                fDepth = 0;
0964:                initializeContentModelStack();
0965:
0966:            } // startContentModel(String)
0967:
0968:            /**
0969:             * A start of either a mixed or children content model. A mixed
0970:             * content model will immediately be followed by a call to the
0971:             * <code>pcdata()</code> method. A children content model will
0972:             * contain additional groups and/or elements.
0973:             *
0974:             * @param augs Additional information that may include infoset
0975:             *                      augmentations.
0976:             * @throws XNIException Thrown by handler to signal an error.
0977:             *
0978:             * @see #any
0979:             * @see #empty
0980:             */
0981:            public void startGroup(Augmentations augs) throws XNIException {
0982:                fDepth++;
0983:                initializeContentModelStack();
0984:                fMixed = false;
0985:            } // startGroup()
0986:
0987:            /**
0988:             * The appearance of "#PCDATA" within a group signifying a
0989:             * mixed content model. This method will be the first called
0990:             * following the content model's <code>startGroup()</code>.
0991:             *
0992:             *@param augs Additional information that may include infoset
0993:             *                      augmentations.
0994:             *
0995:             * @throws XNIException Thrown by handler to signal an error.
0996:             *
0997:             * @see #startGroup
0998:             */
0999:            public void pcdata(Augmentations augs) throws XNIException {
1000:                fMixed = true;
1001:            } // pcdata()
1002:
1003:            /**
1004:             * A referenced element in a mixed or children content model.
1005:             *
1006:             * @param elementName The name of the referenced element.
1007:             * @param augs Additional information that may include infoset
1008:             *                      augmentations.
1009:             *
1010:             * @throws XNIException Thrown by handler to signal an error.
1011:             */
1012:            public void element(String elementName, Augmentations augs)
1013:                    throws XNIException {
1014:                if (fMixed) {
1015:                    if (fNodeIndexStack[fDepth] == -1) {
1016:                        fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName);
1017:                    } else {
1018:                        fNodeIndexStack[fDepth] = addContentSpecNode(
1019:                                XMLContentSpec.CONTENTSPECNODE_CHOICE,
1020:                                fNodeIndexStack[fDepth],
1021:                                addUniqueLeafNode(elementName));
1022:                    }
1023:                } else {
1024:                    fNodeIndexStack[fDepth] = addContentSpecNode(
1025:                            XMLContentSpec.CONTENTSPECNODE_LEAF, elementName);
1026:                }
1027:            } // element(String)
1028:
1029:            /**
1030:             * The separator between choices or sequences of a mixed or children
1031:             * content model.
1032:             *
1033:             * @param separator The type of children separator.
1034:             * @param augs Additional information that may include infoset
1035:             *                      augmentations.
1036:             * @throws XNIException Thrown by handler to signal an error.
1037:             *
1038:             * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE
1039:             * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE
1040:             */
1041:            public void separator(short separator, Augmentations augs)
1042:                    throws XNIException {
1043:
1044:                if (!fMixed) {
1045:                    if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_SEQ
1046:                            && separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE) {
1047:                        if (fPrevNodeIndexStack[fDepth] != -1) {
1048:                            fNodeIndexStack[fDepth] = addContentSpecNode(
1049:                                    fOpStack[fDepth],
1050:                                    fPrevNodeIndexStack[fDepth],
1051:                                    fNodeIndexStack[fDepth]);
1052:                        }
1053:                        fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
1054:                        fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
1055:                    } else if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_CHOICE
1056:                            && separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) {
1057:                        if (fPrevNodeIndexStack[fDepth] != -1) {
1058:                            fNodeIndexStack[fDepth] = addContentSpecNode(
1059:                                    fOpStack[fDepth],
1060:                                    fPrevNodeIndexStack[fDepth],
1061:                                    fNodeIndexStack[fDepth]);
1062:                        }
1063:                        fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
1064:                        fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
1065:                    }
1066:                }
1067:
1068:            } // separator(short)
1069:
1070:            /**
1071:             * The occurrence count for a child in a children content model or
1072:             * for the mixed content model group.
1073:             *
1074:             * @param occurrence The occurrence count for the last element
1075:             *                   or group.
1076:             * @param augs Additional information that may include infoset
1077:             *                      augmentations.
1078:             * @throws XNIException Thrown by handler to signal an error.
1079:             *
1080:             * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE
1081:             * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE
1082:             * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE
1083:             */
1084:            public void occurrence(short occurrence, Augmentations augs)
1085:                    throws XNIException {
1086:
1087:                if (!fMixed) {
1088:                    if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE) {
1089:                        fNodeIndexStack[fDepth] = addContentSpecNode(
1090:                                XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
1091:                                fNodeIndexStack[fDepth], -1);
1092:                    } else if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE) {
1093:                        fNodeIndexStack[fDepth] = addContentSpecNode(
1094:                                XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
1095:                                fNodeIndexStack[fDepth], -1);
1096:                    } else if (occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) {
1097:                        fNodeIndexStack[fDepth] = addContentSpecNode(
1098:                                XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
1099:                                fNodeIndexStack[fDepth], -1);
1100:                    }
1101:                }
1102:
1103:            } // occurrence(short)
1104:
1105:            /**
1106:             * The end of a group for mixed or children content models.
1107:             *
1108:             * @param augs Additional information that may include infoset
1109:             *                      augmentations.
1110:             * @throws XNIException Thrown by handler to signal an error.
1111:             */
1112:            public void endGroup(Augmentations augs) throws XNIException {
1113:
1114:                if (!fMixed) {
1115:                    if (fPrevNodeIndexStack[fDepth] != -1) {
1116:                        fNodeIndexStack[fDepth] = addContentSpecNode(
1117:                                fOpStack[fDepth], fPrevNodeIndexStack[fDepth],
1118:                                fNodeIndexStack[fDepth]);
1119:                    }
1120:                    int nodeIndex = fNodeIndexStack[fDepth--];
1121:                    fNodeIndexStack[fDepth] = nodeIndex;
1122:                }
1123:
1124:            } // endGroup()
1125:
1126:            // no-op methods
1127:
1128:            /**
1129:             * A content model of ANY.
1130:             *
1131:             * @param augs Additional information that may include infoset
1132:             *                      augmentations.
1133:             * @throws XNIException Thrown by handler to signal an error.
1134:             *
1135:             * @see #empty
1136:             * @see #startGroup
1137:             */
1138:            public void any(Augmentations augs) throws XNIException {
1139:            }
1140:
1141:            /**
1142:             * A content model of EMPTY.
1143:             *
1144:             * @param augs Additional information that may include infoset
1145:             *                      augmentations.
1146:             * @throws XNIException Thrown by handler to signal an error.
1147:             *
1148:             * @see #any
1149:             * @see #startGroup
1150:             */
1151:            public void empty(Augmentations augs) throws XNIException {
1152:            }
1153:
1154:            /**
1155:             * The end of a content model.
1156:             * @param augs Additional information that may include infoset
1157:             *                      augmentations.
1158:             *
1159:             * @throws XNIException Thrown by handler to signal an error.
1160:             */
1161:            public void endContentModel(Augmentations augs) throws XNIException {
1162:            }
1163:
1164:            //
1165:            // Grammar methods
1166:            //
1167:
1168:            /** Returns true if this grammar is namespace aware. */
1169:            public boolean isNamespaceAware() {
1170:                return false;
1171:            } // isNamespaceAware():boolean
1172:
1173:            /** Returns the symbol table. */
1174:            public SymbolTable getSymbolTable() {
1175:                return fSymbolTable;
1176:            } // getSymbolTable():SymbolTable
1177:
1178:            /**
1179:             * Returns the index of the first element declaration. This index
1180:             * is then used to query more information about the element declaration.
1181:             *
1182:             * @see #getNextElementDeclIndex
1183:             * @see #getElementDecl
1184:             */
1185:            public int getFirstElementDeclIndex() {
1186:                return fElementDeclCount >= 0 ? 0 : -1;
1187:            } // getFirstElementDeclIndex():int
1188:
1189:            /**
1190:             * Returns the next index of the element declaration following the
1191:             * specified element declaration.
1192:             * 
1193:             * @param elementDeclIndex The element declaration index.
1194:             */
1195:            public int getNextElementDeclIndex(int elementDeclIndex) {
1196:                return elementDeclIndex < fElementDeclCount - 1 ? elementDeclIndex + 1
1197:                        : -1;
1198:            } // getNextElementDeclIndex(int):int
1199:
1200:            /**
1201:             * getElementDeclIndex
1202:             * 
1203:             * @param elementDeclName 
1204:             * 
1205:             * @return index of the elementDeclName in scope
1206:             */
1207:            public int getElementDeclIndex(String elementDeclName) {
1208:                int mapping = fElementIndexMap.get(elementDeclName);
1209:                //System.out.println("getElementDeclIndex("+elementDeclName+") -> "+mapping);
1210:                return mapping;
1211:            } // getElementDeclIndex(String):int
1212:
1213:            /** Returns the element decl index.
1214:             * @param elementDeclQName qualilfied name of the element
1215:             */
1216:            public int getElementDeclIndex(QName elementDeclQName) {
1217:                return getElementDeclIndex(elementDeclQName.rawname);
1218:            } // getElementDeclIndex(QName):int
1219:
1220:            /** make separate function for getting contentSpecType of element.
1221:             * we can avoid setting of the element values.
1222:             */
1223:
1224:            public short getContentSpecType(int elementIndex) {
1225:                if (elementIndex < 0 || elementIndex >= fElementDeclCount) {
1226:                    return -1;
1227:                }
1228:
1229:                int chunk = elementIndex >> CHUNK_SHIFT;
1230:                int index = elementIndex & CHUNK_MASK;
1231:
1232:                if (fElementDeclType[chunk][index] == -1) {
1233:                    return -1;
1234:                } else {
1235:                    return (short) (fElementDeclType[chunk][index] & LIST_MASK);
1236:                }
1237:
1238:            }//getContentSpecType
1239:
1240:            /**
1241:             * getElementDecl
1242:             * 
1243:             * @param elementDeclIndex 
1244:             * @param elementDecl The values of this structure are set by this call.
1245:             * 
1246:             * @return True if find the element, False otherwise. 
1247:             */
1248:            public boolean getElementDecl(int elementDeclIndex,
1249:                    XMLElementDecl elementDecl) {
1250:
1251:                if (elementDeclIndex < 0
1252:                        || elementDeclIndex >= fElementDeclCount) {
1253:                    return false;
1254:                }
1255:
1256:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1257:                int index = elementDeclIndex & CHUNK_MASK;
1258:
1259:                elementDecl.name.setValues(fElementDeclName[chunk][index]);
1260:
1261:                if (fElementDeclType[chunk][index] == -1) {
1262:                    elementDecl.type = -1;
1263:                    elementDecl.simpleType.list = false;
1264:                } else {
1265:                    elementDecl.type = (short) (fElementDeclType[chunk][index] & LIST_MASK);
1266:                    elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
1267:                }
1268:
1269:                /* Validators are null until we add that code */
1270:                if (elementDecl.type == XMLElementDecl.TYPE_CHILDREN
1271:                        || elementDecl.type == XMLElementDecl.TYPE_MIXED) {
1272:                    elementDecl.contentModelValidator = getElementContentModelValidator(elementDeclIndex);
1273:                }
1274:
1275:                elementDecl.simpleType.datatypeValidator = null;
1276:                elementDecl.simpleType.defaultType = -1;
1277:                elementDecl.simpleType.defaultValue = null;
1278:
1279:                return true;
1280:
1281:            } // getElementDecl(int,XMLElementDecl):boolean
1282:
1283:            QName getElementDeclName(int elementDeclIndex) {
1284:                if (elementDeclIndex < 0
1285:                        || elementDeclIndex >= fElementDeclCount) {
1286:                    return null;
1287:                }
1288:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1289:                int index = elementDeclIndex & CHUNK_MASK;
1290:                return fElementDeclName[chunk][index];
1291:            }
1292:
1293:            // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac
1294:
1295:            /**
1296:             * getFirstAttributeDeclIndex
1297:             * 
1298:             * @param elementDeclIndex 
1299:             * 
1300:             * @return index of the first attribute for element declaration elementDeclIndex
1301:             */
1302:            public int getFirstAttributeDeclIndex(int elementDeclIndex) {
1303:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1304:                int index = elementDeclIndex & CHUNK_MASK;
1305:
1306:                return fElementDeclFirstAttributeDeclIndex[chunk][index];
1307:            } // getFirstAttributeDeclIndex
1308:
1309:            /**
1310:             * getNextAttributeDeclIndex
1311:             * 
1312:             * @param attributeDeclIndex 
1313:             * 
1314:             * @return index of the next attribute of the attribute at attributeDeclIndex
1315:             */
1316:            public int getNextAttributeDeclIndex(int attributeDeclIndex) {
1317:                int chunk = attributeDeclIndex >> CHUNK_SHIFT;
1318:                int index = attributeDeclIndex & CHUNK_MASK;
1319:
1320:                return fAttributeDeclNextAttributeDeclIndex[chunk][index];
1321:            } // getNextAttributeDeclIndex
1322:
1323:            /**
1324:             * getAttributeDecl
1325:             * 
1326:             * @param attributeDeclIndex 
1327:             * @param attributeDecl The values of this structure are set by this call.
1328:             * 
1329:             * @return true if getAttributeDecl was able to fill in the value of attributeDecl
1330:             */
1331:            public boolean getAttributeDecl(int attributeDeclIndex,
1332:                    XMLAttributeDecl attributeDecl) {
1333:                if (attributeDeclIndex < 0
1334:                        || attributeDeclIndex >= fAttributeDeclCount) {
1335:                    return false;
1336:                }
1337:                int chunk = attributeDeclIndex >> CHUNK_SHIFT;
1338:                int index = attributeDeclIndex & CHUNK_MASK;
1339:
1340:                attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
1341:
1342:                short attributeType;
1343:                boolean isList;
1344:
1345:                if (fAttributeDeclType[chunk][index] == -1) {
1346:
1347:                    attributeType = -1;
1348:                    isList = false;
1349:                } else {
1350:                    attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK);
1351:                    isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
1352:                }
1353:                attributeDecl.simpleType.setValues(attributeType,
1354:                        fAttributeDeclName[chunk][index].localpart,
1355:                        fAttributeDeclEnumeration[chunk][index], isList,
1356:                        fAttributeDeclDefaultType[chunk][index],
1357:                        fAttributeDeclDefaultValue[chunk][index],
1358:                        fAttributeDeclNonNormalizedDefaultValue[chunk][index],
1359:                        fAttributeDeclDatatypeValidator[chunk][index]);
1360:                return true;
1361:
1362:            } // getAttributeDecl
1363:
1364:            /**
1365:             * Returns whether the given attribute is of type CDATA or not
1366:             *
1367:             * @param elName The element name.
1368:             * @param atName The attribute name.
1369:             *
1370:             * @return true if the attribute is of type CDATA
1371:             */
1372:            public boolean isCDATAAttribute(QName elName, QName atName) {
1373:                int elDeclIdx = getElementDeclIndex(elName);
1374:                if (getAttributeDecl(elDeclIdx, fAttributeDecl)
1375:                        && fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA) {
1376:                    return false;
1377:                }
1378:                return true;
1379:            }
1380:
1381:            /**
1382:             * getEntityDeclIndex
1383:             * 
1384:             * @param entityDeclName 
1385:             * 
1386:             * @return the index of the EntityDecl
1387:             */
1388:            public int getEntityDeclIndex(String entityDeclName) {
1389:                if (entityDeclName == null) {
1390:                    return -1;
1391:                }
1392:
1393:                return fEntityIndexMap.get(entityDeclName);
1394:            } // getEntityDeclIndex
1395:
1396:            /**
1397:             * getEntityDecl
1398:             * 
1399:             * @param entityDeclIndex 
1400:             * @param entityDecl 
1401:             * 
1402:             * @return true if getEntityDecl was able to fill entityDecl with the contents of the entity
1403:             * with index entityDeclIndex
1404:             */
1405:            public boolean getEntityDecl(int entityDeclIndex,
1406:                    XMLEntityDecl entityDecl) {
1407:                if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) {
1408:                    return false;
1409:                }
1410:                int chunk = entityDeclIndex >> CHUNK_SHIFT;
1411:                int index = entityDeclIndex & CHUNK_MASK;
1412:
1413:                entityDecl.setValues(fEntityName[chunk][index],
1414:                        fEntityPublicId[chunk][index],
1415:                        fEntitySystemId[chunk][index],
1416:                        fEntityBaseSystemId[chunk][index],
1417:                        fEntityNotation[chunk][index],
1418:                        fEntityValue[chunk][index],
1419:                        fEntityIsPE[chunk][index] == 0 ? false : true,
1420:                        fEntityInExternal[chunk][index] == 0 ? false : true);
1421:
1422:                return true;
1423:            } // getEntityDecl
1424:
1425:            /**
1426:             * getNotationDeclIndex
1427:             * 
1428:             * @param notationDeclName 
1429:             * 
1430:             * @return the index if found a notation with the name, otherwise -1.
1431:             */
1432:            public int getNotationDeclIndex(String notationDeclName) {
1433:                if (notationDeclName == null) {
1434:                    return -1;
1435:                }
1436:
1437:                return fNotationIndexMap.get(notationDeclName);
1438:            } // getNotationDeclIndex
1439:
1440:            /**
1441:             * getNotationDecl
1442:             * 
1443:             * @param notationDeclIndex 
1444:             * @param notationDecl 
1445:             * 
1446:             * @return return true of getNotationDecl can fill notationDecl with information about 
1447:             * the notation at notationDeclIndex.
1448:             */
1449:            public boolean getNotationDecl(int notationDeclIndex,
1450:                    XMLNotationDecl notationDecl) {
1451:                if (notationDeclIndex < 0
1452:                        || notationDeclIndex >= fNotationCount) {
1453:                    return false;
1454:                }
1455:                int chunk = notationDeclIndex >> CHUNK_SHIFT;
1456:                int index = notationDeclIndex & CHUNK_MASK;
1457:
1458:                notationDecl.setValues(fNotationName[chunk][index],
1459:                        fNotationPublicId[chunk][index],
1460:                        fNotationSystemId[chunk][index],
1461:                        fNotationBaseSystemId[chunk][index]);
1462:
1463:                return true;
1464:
1465:            } // getNotationDecl
1466:
1467:            /**
1468:             * getContentSpec
1469:             * 
1470:             * @param contentSpecIndex 
1471:             * @param contentSpec
1472:             * 
1473:             * @return true if find the requested contentSpec node, false otherwise
1474:             */
1475:            public boolean getContentSpec(int contentSpecIndex,
1476:                    XMLContentSpec contentSpec) {
1477:                if (contentSpecIndex < 0
1478:                        || contentSpecIndex >= fContentSpecCount)
1479:                    return false;
1480:
1481:                int chunk = contentSpecIndex >> CHUNK_SHIFT;
1482:                int index = contentSpecIndex & CHUNK_MASK;
1483:
1484:                contentSpec.type = fContentSpecType[chunk][index];
1485:                contentSpec.value = fContentSpecValue[chunk][index];
1486:                contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
1487:                return true;
1488:            }
1489:
1490:            /**
1491:             * Returns the index to the content spec for the given element 
1492:             * declaration, or <code>-1</code> if the element declaration
1493:             * index was invalid.
1494:             */
1495:            public int getContentSpecIndex(int elementDeclIndex) {
1496:                if (elementDeclIndex < 0
1497:                        || elementDeclIndex >= fElementDeclCount) {
1498:                    return -1;
1499:                }
1500:                final int chunk = elementDeclIndex >> CHUNK_SHIFT;
1501:                final int index = elementDeclIndex & CHUNK_MASK;
1502:                return fElementDeclContentSpecIndex[chunk][index];
1503:            }
1504:
1505:            /**
1506:             * getContentSpecAsString
1507:             *
1508:             * @param elementDeclIndex
1509:             *
1510:             * @return String
1511:             */
1512:            public String getContentSpecAsString(int elementDeclIndex) {
1513:
1514:                if (elementDeclIndex < 0
1515:                        || elementDeclIndex >= fElementDeclCount) {
1516:                    return null;
1517:                }
1518:
1519:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1520:                int index = elementDeclIndex & CHUNK_MASK;
1521:
1522:                int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
1523:
1524:                // lookup content spec node
1525:                XMLContentSpec contentSpec = new XMLContentSpec();
1526:
1527:                if (getContentSpec(contentSpecIndex, contentSpec)) {
1528:
1529:                    // build string
1530:                    StringBuffer str = new StringBuffer();
1531:                    int parentContentSpecType = contentSpec.type & 0x0f;
1532:                    int nextContentSpec;
1533:                    switch (parentContentSpecType) {
1534:                    case XMLContentSpec.CONTENTSPECNODE_LEAF: {
1535:                        str.append('(');
1536:                        if (contentSpec.value == null
1537:                                && contentSpec.otherValue == null) {
1538:                            str.append("#PCDATA");
1539:                        } else {
1540:                            str.append(contentSpec.value);
1541:                        }
1542:                        str.append(')');
1543:                        break;
1544:                    }
1545:                    case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
1546:                        getContentSpec(((int[]) contentSpec.value)[0],
1547:                                contentSpec);
1548:                        nextContentSpec = contentSpec.type;
1549:
1550:                        if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
1551:                            str.append('(');
1552:                            str.append(contentSpec.value);
1553:                            str.append(')');
1554:                        } else if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
1555:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
1556:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
1557:                            str.append('(');
1558:                            appendContentSpec(contentSpec, str, true,
1559:                                    parentContentSpecType);
1560:                            str.append(')');
1561:                        } else {
1562:                            appendContentSpec(contentSpec, str, true,
1563:                                    parentContentSpecType);
1564:                        }
1565:                        str.append('?');
1566:                        break;
1567:                    }
1568:                    case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
1569:                        getContentSpec(((int[]) contentSpec.value)[0],
1570:                                contentSpec);
1571:                        nextContentSpec = contentSpec.type;
1572:
1573:                        if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
1574:                            str.append('(');
1575:                            if (contentSpec.value == null
1576:                                    && contentSpec.otherValue == null) {
1577:                                str.append("#PCDATA");
1578:                            } else if (contentSpec.otherValue != null) {
1579:                                str.append("##any:uri=").append(
1580:                                        contentSpec.otherValue);
1581:                            } else if (contentSpec.value == null) {
1582:                                str.append("##any");
1583:                            } else {
1584:                                appendContentSpec(contentSpec, str, true,
1585:                                        parentContentSpecType);
1586:                            }
1587:                            str.append(')');
1588:                        } else if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
1589:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
1590:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
1591:                            str.append('(');
1592:                            appendContentSpec(contentSpec, str, true,
1593:                                    parentContentSpecType);
1594:                            str.append(')');
1595:                        } else {
1596:                            appendContentSpec(contentSpec, str, true,
1597:                                    parentContentSpecType);
1598:                        }
1599:                        str.append('*');
1600:                        break;
1601:                    }
1602:                    case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
1603:                        getContentSpec(((int[]) contentSpec.value)[0],
1604:                                contentSpec);
1605:                        nextContentSpec = contentSpec.type;
1606:
1607:                        if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
1608:                            str.append('(');
1609:                            if (contentSpec.value == null
1610:                                    && contentSpec.otherValue == null) {
1611:                                str.append("#PCDATA");
1612:                            } else if (contentSpec.otherValue != null) {
1613:                                str.append("##any:uri=").append(
1614:                                        contentSpec.otherValue);
1615:                            } else if (contentSpec.value == null) {
1616:                                str.append("##any");
1617:                            } else {
1618:                                str.append(contentSpec.value);
1619:                            }
1620:                            str.append(')');
1621:                        } else if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
1622:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
1623:                                || nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
1624:                            str.append('(');
1625:                            appendContentSpec(contentSpec, str, true,
1626:                                    parentContentSpecType);
1627:                            str.append(')');
1628:                        } else {
1629:                            appendContentSpec(contentSpec, str, true,
1630:                                    parentContentSpecType);
1631:                        }
1632:                        str.append('+');
1633:                        break;
1634:                    }
1635:                    case XMLContentSpec.CONTENTSPECNODE_CHOICE:
1636:                    case XMLContentSpec.CONTENTSPECNODE_SEQ: {
1637:                        appendContentSpec(contentSpec, str, true,
1638:                                parentContentSpecType);
1639:                        break;
1640:                    }
1641:                    case XMLContentSpec.CONTENTSPECNODE_ANY: {
1642:                        str.append("##any");
1643:                        if (contentSpec.otherValue != null) {
1644:                            str.append(":uri=");
1645:                            str.append(contentSpec.otherValue);
1646:                        }
1647:                        break;
1648:                    }
1649:                    case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
1650:                        str.append("##other:uri=");
1651:                        str.append(contentSpec.otherValue);
1652:                        break;
1653:                    }
1654:                    case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
1655:                        str.append("##local");
1656:                        break;
1657:                    }
1658:                    default: {
1659:                        str.append("???");
1660:                    }
1661:
1662:                    } // switch type
1663:
1664:                    // return string
1665:                    return str.toString();
1666:                }
1667:
1668:                // not found
1669:                return null;
1670:
1671:            } // getContentSpecAsString(int):String
1672:
1673:            // debugging
1674:
1675:            public void printElements() {
1676:                int elementDeclIndex = 0;
1677:                XMLElementDecl elementDecl = new XMLElementDecl();
1678:                while (getElementDecl(elementDeclIndex++, elementDecl)) {
1679:
1680:                    System.out.println("element decl: " + elementDecl.name
1681:                            + ", " + elementDecl.name.rawname);
1682:
1683:                    //                   ", "+ elementDecl.contentModelValidator.toString());
1684:                }
1685:            }
1686:
1687:            public void printAttributes(int elementDeclIndex) {
1688:                int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
1689:                System.out.print(elementDeclIndex);
1690:                System.out.print(" [");
1691:                while (attributeDeclIndex != -1) {
1692:                    System.out.print(' ');
1693:                    System.out.print(attributeDeclIndex);
1694:                    printAttribute(attributeDeclIndex);
1695:                    attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
1696:                    if (attributeDeclIndex != -1) {
1697:                        System.out.print(",");
1698:                    }
1699:                }
1700:                System.out.println(" ]");
1701:            }
1702:
1703:            //
1704:            // Protected methods
1705:            //
1706:
1707:            /**
1708:             * Adds the content spec to the given element declaration.
1709:             */
1710:            protected void addContentSpecToElement(XMLElementDecl elementDecl) {
1711:                if ((fDepth == 0 || (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED))
1712:                        && fNodeIndexStack != null) {
1713:                    if (elementDecl.type == XMLElementDecl.TYPE_MIXED) {
1714:                        int pcdata = addUniqueLeafNode(null);
1715:                        if (fNodeIndexStack[0] == -1) {
1716:                            fNodeIndexStack[0] = pcdata;
1717:                        } else {
1718:                            fNodeIndexStack[0] = addContentSpecNode(
1719:                                    XMLContentSpec.CONTENTSPECNODE_CHOICE,
1720:                                    pcdata, fNodeIndexStack[0]);
1721:                        }
1722:                    }
1723:                    setContentSpecIndex(fCurrentElementIndex,
1724:                            fNodeIndexStack[fDepth]);
1725:                }
1726:            }
1727:
1728:            /**
1729:             * getElementContentModelValidator
1730:             * 
1731:             * @param elementDeclIndex 
1732:             * 
1733:             * @return its ContentModelValidator if any.
1734:             */
1735:            protected ContentModelValidator getElementContentModelValidator(
1736:                    int elementDeclIndex) {
1737:
1738:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1739:                int index = elementDeclIndex & CHUNK_MASK;
1740:
1741:                ContentModelValidator contentModel = fElementDeclContentModelValidator[chunk][index];
1742:
1743:                // If we have one, just return that. Otherwise, gotta create one
1744:                if (contentModel != null) {
1745:                    return contentModel;
1746:                }
1747:
1748:                int contentType = fElementDeclType[chunk][index];
1749:                if (contentType == XMLElementDecl.TYPE_SIMPLE) {
1750:                    return null;
1751:                }
1752:
1753:                // Get the type of content this element has
1754:                int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
1755:
1756:                /***
1757:                if ( contentSpecIndex == -1 )
1758:                    return null;
1759:                /***/
1760:
1761:                XMLContentSpec contentSpec = new XMLContentSpec();
1762:                getContentSpec(contentSpecIndex, contentSpec);
1763:
1764:                // And create the content model according to the spec type
1765:                if (contentType == XMLElementDecl.TYPE_MIXED) {
1766:                    //
1767:                    //  Just create a mixel content model object. This type of
1768:                    //  content model is optimized for mixed content validation.
1769:                    //
1770:                    ChildrenList children = new ChildrenList();
1771:                    contentSpecTree(contentSpecIndex, contentSpec, children);
1772:                    contentModel = new MixedContentModel(children.qname,
1773:                            children.type, 0, children.length, false);
1774:                } else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
1775:                    //  This method will create an optimal model for the complexity
1776:                    //  of the element's defined model. If its simple, it will create
1777:                    //  a SimpleContentModel object. If its a simple list, it will
1778:                    //  create a SimpleListContentModel object. If its complex, it
1779:                    //  will create a DFAContentModel object.
1780:                    //
1781:                    contentModel = createChildModel(contentSpecIndex);
1782:                } else {
1783:                    throw new RuntimeException(
1784:                            "Unknown content type for a element decl "
1785:                                    + "in getElementContentModelValidator() in AbstractDTDGrammar class");
1786:                }
1787:
1788:                // Add the new model to the content model for this element
1789:                fElementDeclContentModelValidator[chunk][index] = contentModel;
1790:
1791:                return contentModel;
1792:
1793:            } // getElementContentModelValidator(int):ContentModelValidator
1794:
1795:            protected int createElementDecl() {
1796:                int chunk = fElementDeclCount >> CHUNK_SHIFT;
1797:                int index = fElementDeclCount & CHUNK_MASK;
1798:                ensureElementDeclCapacity(chunk);
1799:                fElementDeclName[chunk][index] = new QName();
1800:                fElementDeclType[chunk][index] = -1;
1801:                fElementDeclContentModelValidator[chunk][index] = null;
1802:                fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
1803:                fElementDeclLastAttributeDeclIndex[chunk][index] = -1;
1804:                return fElementDeclCount++;
1805:            }
1806:
1807:            protected void setElementDecl(int elementDeclIndex,
1808:                    XMLElementDecl elementDecl) {
1809:                if (elementDeclIndex < 0
1810:                        || elementDeclIndex >= fElementDeclCount) {
1811:                    return;
1812:                }
1813:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1814:                int index = elementDeclIndex & CHUNK_MASK;
1815:
1816:                fElementDeclName[chunk][index].setValues(elementDecl.name);
1817:                fElementDeclType[chunk][index] = elementDecl.type;
1818:
1819:                fElementDeclContentModelValidator[chunk][index] = elementDecl.contentModelValidator;
1820:
1821:                if (elementDecl.simpleType.list == true) {
1822:                    fElementDeclType[chunk][index] |= LIST_FLAG;
1823:                }
1824:
1825:                fElementIndexMap
1826:                        .put(elementDecl.name.rawname, elementDeclIndex);
1827:            }
1828:
1829:            protected void putElementNameMapping(QName name, int scope,
1830:                    int elementDeclIndex) {
1831:            }
1832:
1833:            protected void setFirstAttributeDeclIndex(int elementDeclIndex,
1834:                    int newFirstAttrIndex) {
1835:
1836:                if (elementDeclIndex < 0
1837:                        || elementDeclIndex >= fElementDeclCount) {
1838:                    return;
1839:                }
1840:
1841:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1842:                int index = elementDeclIndex & CHUNK_MASK;
1843:
1844:                fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
1845:            }
1846:
1847:            protected void setContentSpecIndex(int elementDeclIndex,
1848:                    int contentSpecIndex) {
1849:
1850:                if (elementDeclIndex < 0
1851:                        || elementDeclIndex >= fElementDeclCount) {
1852:                    return;
1853:                }
1854:
1855:                int chunk = elementDeclIndex >> CHUNK_SHIFT;
1856:                int index = elementDeclIndex & CHUNK_MASK;
1857:
1858:                fElementDeclContentSpecIndex[chunk][index] = contentSpecIndex;
1859:            }
1860:
1861:            protected int createAttributeDecl() {
1862:                int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
1863:                int index = fAttributeDeclCount & CHUNK_MASK;
1864:
1865:                ensureAttributeDeclCapacity(chunk);
1866:                fAttributeDeclName[chunk][index] = new QName();
1867:                fAttributeDeclType[chunk][index] = -1;
1868:                fAttributeDeclDatatypeValidator[chunk][index] = null;
1869:                fAttributeDeclEnumeration[chunk][index] = null;
1870:                fAttributeDeclDefaultType[chunk][index] = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
1871:                fAttributeDeclDefaultValue[chunk][index] = null;
1872:                fAttributeDeclNonNormalizedDefaultValue[chunk][index] = null;
1873:                fAttributeDeclNextAttributeDeclIndex[chunk][index] = -1;
1874:                return fAttributeDeclCount++;
1875:            }
1876:
1877:            protected void setAttributeDecl(int elementDeclIndex,
1878:                    int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
1879:                int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
1880:                int attrIndex = attributeDeclIndex & CHUNK_MASK;
1881:                fAttributeDeclName[attrChunk][attrIndex]
1882:                        .setValues(attributeDecl.name);
1883:                fAttributeDeclType[attrChunk][attrIndex] = attributeDecl.simpleType.type;
1884:
1885:                if (attributeDecl.simpleType.list) {
1886:                    fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
1887:                }
1888:                fAttributeDeclEnumeration[attrChunk][attrIndex] = attributeDecl.simpleType.enumeration;
1889:                fAttributeDeclDefaultType[attrChunk][attrIndex] = attributeDecl.simpleType.defaultType;
1890:                fAttributeDeclDatatypeValidator[attrChunk][attrIndex] = attributeDecl.simpleType.datatypeValidator;
1891:
1892:                fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.defaultValue;
1893:                fAttributeDeclNonNormalizedDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.nonNormalizedDefaultValue;
1894:
1895:                int elemChunk = elementDeclIndex >> CHUNK_SHIFT;
1896:                int elemIndex = elementDeclIndex & CHUNK_MASK;
1897:                int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
1898:                while (index != -1) {
1899:                    if (index == attributeDeclIndex) {
1900:                        break;
1901:                    }
1902:                    attrChunk = index >> CHUNK_SHIFT;
1903:                    attrIndex = index & CHUNK_MASK;
1904:                    index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
1905:                }
1906:                if (index == -1) {
1907:                    if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
1908:                        fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
1909:                    } else {
1910:                        index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
1911:                        attrChunk = index >> CHUNK_SHIFT;
1912:                        attrIndex = index & CHUNK_MASK;
1913:                        fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
1914:                    }
1915:                    fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
1916:                }
1917:            }
1918:
1919:            protected int createContentSpec() {
1920:                int chunk = fContentSpecCount >> CHUNK_SHIFT;
1921:                int index = fContentSpecCount & CHUNK_MASK;
1922:
1923:                ensureContentSpecCapacity(chunk);
1924:                fContentSpecType[chunk][index] = -1;
1925:                fContentSpecValue[chunk][index] = null;
1926:                fContentSpecOtherValue[chunk][index] = null;
1927:
1928:                return fContentSpecCount++;
1929:            }
1930:
1931:            protected void setContentSpec(int contentSpecIndex,
1932:                    XMLContentSpec contentSpec) {
1933:                int chunk = contentSpecIndex >> CHUNK_SHIFT;
1934:                int index = contentSpecIndex & CHUNK_MASK;
1935:
1936:                fContentSpecType[chunk][index] = contentSpec.type;
1937:                fContentSpecValue[chunk][index] = contentSpec.value;
1938:                fContentSpecOtherValue[chunk][index] = contentSpec.otherValue;
1939:            }
1940:
1941:            protected int createEntityDecl() {
1942:                int chunk = fEntityCount >> CHUNK_SHIFT;
1943:                int index = fEntityCount & CHUNK_MASK;
1944:
1945:                ensureEntityDeclCapacity(chunk);
1946:                fEntityIsPE[chunk][index] = 0;
1947:                fEntityInExternal[chunk][index] = 0;
1948:
1949:                return fEntityCount++;
1950:            }
1951:
1952:            protected void setEntityDecl(int entityDeclIndex,
1953:                    XMLEntityDecl entityDecl) {
1954:                int chunk = entityDeclIndex >> CHUNK_SHIFT;
1955:                int index = entityDeclIndex & CHUNK_MASK;
1956:
1957:                fEntityName[chunk][index] = entityDecl.name;
1958:                fEntityValue[chunk][index] = entityDecl.value;
1959:                fEntityPublicId[chunk][index] = entityDecl.publicId;
1960:                fEntitySystemId[chunk][index] = entityDecl.systemId;
1961:                fEntityBaseSystemId[chunk][index] = entityDecl.baseSystemId;
1962:                fEntityNotation[chunk][index] = entityDecl.notation;
1963:                fEntityIsPE[chunk][index] = entityDecl.isPE ? (byte) 1
1964:                        : (byte) 0;
1965:                fEntityInExternal[chunk][index] = entityDecl.inExternal ? (byte) 1
1966:                        : (byte) 0;
1967:
1968:                fEntityIndexMap.put(entityDecl.name, entityDeclIndex);
1969:            }
1970:
1971:            protected int createNotationDecl() {
1972:                int chunk = fNotationCount >> CHUNK_SHIFT;
1973:                ensureNotationDeclCapacity(chunk);
1974:                return fNotationCount++;
1975:            }
1976:
1977:            protected void setNotationDecl(int notationDeclIndex,
1978:                    XMLNotationDecl notationDecl) {
1979:                int chunk = notationDeclIndex >> CHUNK_SHIFT;
1980:                int index = notationDeclIndex & CHUNK_MASK;
1981:
1982:                fNotationName[chunk][index] = notationDecl.name;
1983:                fNotationPublicId[chunk][index] = notationDecl.publicId;
1984:                fNotationSystemId[chunk][index] = notationDecl.systemId;
1985:                fNotationBaseSystemId[chunk][index] = notationDecl.baseSystemId;
1986:
1987:                fNotationIndexMap.put(notationDecl.name, notationDeclIndex);
1988:            }
1989:
1990:            /**
1991:             * Create an XMLContentSpec for a single non-leaf
1992:             *
1993:             * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
1994:             * @param nodeValue handle to an XMLContentSpec
1995:             * @return handle to the newly create XMLContentSpec
1996:             */
1997:            protected int addContentSpecNode(short nodeType, String nodeValue) {
1998:
1999:                // create content spec node
2000:                int contentSpecIndex = createContentSpec();
2001:
2002:                // set content spec node values
2003:                fContentSpec.setValues(nodeType, nodeValue, null);
2004:                setContentSpec(contentSpecIndex, fContentSpec);
2005:
2006:                // return index
2007:                return contentSpecIndex;
2008:
2009:            } // addContentSpecNode(short,String):int
2010:
2011:            /**
2012:             * create an XMLContentSpec for a leaf
2013:             *
2014:             * @param   elementName  the name (Element) for the node
2015:             * @return handle to the newly create XMLContentSpec
2016:             */
2017:            protected int addUniqueLeafNode(String elementName) {
2018:
2019:                // create content spec node
2020:                int contentSpecIndex = createContentSpec();
2021:
2022:                // set content spec node values
2023:                fContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF,
2024:                        elementName, null);
2025:                setContentSpec(contentSpecIndex, fContentSpec);
2026:
2027:                // return index
2028:                return contentSpecIndex;
2029:
2030:            } // addUniqueLeafNode(String):int
2031:
2032:            /**
2033:             * Create an XMLContentSpec for a two child leaf
2034:             *
2035:             * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
2036:             * @param leftNodeIndex handle to an XMLContentSpec
2037:             * @param rightNodeIndex handle to an XMLContentSpec
2038:             * @return handle to the newly create XMLContentSpec
2039:             */
2040:            protected int addContentSpecNode(short nodeType, int leftNodeIndex,
2041:                    int rightNodeIndex) {
2042:
2043:                // create content spec node
2044:                int contentSpecIndex = createContentSpec();
2045:
2046:                // set content spec node values
2047:                int[] leftIntArray = new int[1];
2048:                int[] rightIntArray = new int[1];
2049:
2050:                leftIntArray[0] = leftNodeIndex;
2051:                rightIntArray[0] = rightNodeIndex;
2052:                fContentSpec.setValues(nodeType, leftIntArray, rightIntArray);
2053:                setContentSpec(contentSpecIndex, fContentSpec);
2054:
2055:                // return index
2056:                return contentSpecIndex;
2057:
2058:            } // addContentSpecNode(short,int,int):int
2059:
2060:            /** Initialize content model stack. */
2061:            protected void initializeContentModelStack() {
2062:
2063:                if (fOpStack == null) {
2064:                    fOpStack = new short[8];
2065:                    fNodeIndexStack = new int[8];
2066:                    fPrevNodeIndexStack = new int[8];
2067:                } else if (fDepth == fOpStack.length) {
2068:                    short[] newStack = new short[fDepth * 2];
2069:                    System.arraycopy(fOpStack, 0, newStack, 0, fDepth);
2070:                    fOpStack = newStack;
2071:                    int[] newIntStack = new int[fDepth * 2];
2072:                    System
2073:                            .arraycopy(fNodeIndexStack, 0, newIntStack, 0,
2074:                                    fDepth);
2075:                    fNodeIndexStack = newIntStack;
2076:                    newIntStack = new int[fDepth * 2];
2077:                    System.arraycopy(fPrevNodeIndexStack, 0, newIntStack, 0,
2078:                            fDepth);
2079:                    fPrevNodeIndexStack = newIntStack;
2080:                }
2081:                fOpStack[fDepth] = -1;
2082:                fNodeIndexStack[fDepth] = -1;
2083:                fPrevNodeIndexStack[fDepth] = -1;
2084:
2085:            } // initializeContentModelStack()
2086:
2087:            boolean isImmutable() {
2088:                return fIsImmutable;
2089:            }
2090:
2091:            //
2092:            // Private methods
2093:            //
2094:
2095:            private void appendContentSpec(XMLContentSpec contentSpec,
2096:                    StringBuffer str, boolean parens, int parentContentSpecType) {
2097:
2098:                int this ContentSpec = contentSpec.type & 0x0f;
2099:                switch (this ContentSpec) {
2100:                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
2101:                    if (contentSpec.value == null
2102:                            && contentSpec.otherValue == null) {
2103:                        str.append("#PCDATA");
2104:                    } else if (contentSpec.value == null
2105:                            && contentSpec.otherValue != null) {
2106:                        str.append("##any:uri=").append(contentSpec.otherValue);
2107:                    } else if (contentSpec.value == null) {
2108:                        str.append("##any");
2109:                    } else {
2110:                        str.append(contentSpec.value);
2111:                    }
2112:                    break;
2113:                }
2114:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
2115:                    if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
2116:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
2117:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
2118:                        getContentSpec(((int[]) contentSpec.value)[0],
2119:                                contentSpec);
2120:                        str.append('(');
2121:                        appendContentSpec(contentSpec, str, true,
2122:                                this ContentSpec);
2123:                        str.append(')');
2124:                    } else {
2125:                        getContentSpec(((int[]) contentSpec.value)[0],
2126:                                contentSpec);
2127:                        appendContentSpec(contentSpec, str, true,
2128:                                this ContentSpec);
2129:                    }
2130:                    str.append('?');
2131:                    break;
2132:                }
2133:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
2134:                    if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
2135:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
2136:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
2137:                        getContentSpec(((int[]) contentSpec.value)[0],
2138:                                contentSpec);
2139:                        str.append('(');
2140:                        appendContentSpec(contentSpec, str, true,
2141:                                this ContentSpec);
2142:                        str.append(')');
2143:                    } else {
2144:                        getContentSpec(((int[]) contentSpec.value)[0],
2145:                                contentSpec);
2146:                        appendContentSpec(contentSpec, str, true,
2147:                                this ContentSpec);
2148:                    }
2149:                    str.append('*');
2150:                    break;
2151:                }
2152:                case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
2153:                    if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE
2154:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
2155:                            || parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) {
2156:
2157:                        str.append('(');
2158:                        getContentSpec(((int[]) contentSpec.value)[0],
2159:                                contentSpec);
2160:                        appendContentSpec(contentSpec, str, true,
2161:                                this ContentSpec);
2162:                        str.append(')');
2163:                    } else {
2164:                        getContentSpec(((int[]) contentSpec.value)[0],
2165:                                contentSpec);
2166:                        appendContentSpec(contentSpec, str, true,
2167:                                this ContentSpec);
2168:                    }
2169:                    str.append('+');
2170:                    break;
2171:                }
2172:                case XMLContentSpec.CONTENTSPECNODE_CHOICE:
2173:                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
2174:                    if (parens) {
2175:                        str.append('(');
2176:                    }
2177:                    int type = contentSpec.type;
2178:                    int otherValue = ((int[]) contentSpec.otherValue)[0];
2179:                    getContentSpec(((int[]) contentSpec.value)[0], contentSpec);
2180:                    appendContentSpec(contentSpec, str,
2181:                            contentSpec.type != type, this ContentSpec);
2182:                    if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
2183:                        str.append('|');
2184:                    } else {
2185:                        str.append(',');
2186:                    }
2187:                    getContentSpec(otherValue, contentSpec);
2188:                    appendContentSpec(contentSpec, str, true, this ContentSpec);
2189:                    if (parens) {
2190:                        str.append(')');
2191:                    }
2192:                    break;
2193:                }
2194:                case XMLContentSpec.CONTENTSPECNODE_ANY: {
2195:                    str.append("##any");
2196:                    if (contentSpec.otherValue != null) {
2197:                        str.append(":uri=");
2198:                        str.append(contentSpec.otherValue);
2199:                    }
2200:                    break;
2201:                }
2202:                case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
2203:                    str.append("##other:uri=");
2204:                    str.append(contentSpec.otherValue);
2205:                    break;
2206:                }
2207:                case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
2208:                    str.append("##local");
2209:                    break;
2210:                }
2211:                default: {
2212:                    str.append("???");
2213:                    break;
2214:                }
2215:
2216:                } // switch type
2217:
2218:            } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
2219:
2220:            // debugging
2221:
2222:            private void printAttribute(int attributeDeclIndex) {
2223:
2224:                XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
2225:                if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
2226:                    System.out.print(" { ");
2227:                    System.out.print(attributeDecl.name.localpart);
2228:                    System.out.print(" }");
2229:                }
2230:
2231:            } // printAttribute(int)
2232:
2233:            // content models
2234:
2235:            /**
2236:             * When the element has a 'CHILDREN' model, this method is called to
2237:             * create the content model object. It looks for some special case simple
2238:             * models and creates SimpleContentModel objects for those. For the rest
2239:             * it creates the standard DFA style model.
2240:             */
2241:            private synchronized ContentModelValidator createChildModel(
2242:                    int contentSpecIndex) {
2243:
2244:                //
2245:                //  Get the content spec node for the element we are working on.
2246:                //  This will tell us what kind of node it is, which tells us what
2247:                //  kind of model we will try to create.
2248:                //
2249:                XMLContentSpec contentSpec = new XMLContentSpec();
2250:                getContentSpec(contentSpecIndex, contentSpec);
2251:
2252:                if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY
2253:                        || (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER
2254:                        || (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
2255:                    // let fall through to build a DFAContentModel
2256:                }
2257:
2258:                else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
2259:                    //
2260:                    //  Check that the left value is not -1, since any content model
2261:                    //  with PCDATA should be MIXED, so we should not have gotten here.
2262:                    //
2263:                    if (contentSpec.value == null
2264:                            && contentSpec.otherValue == null)
2265:                        throw new RuntimeException(
2266:                                "ImplementationMessages.VAL_NPCD");
2267:
2268:                    //
2269:                    //  Its a single leaf, so its an 'a' type of content model, i.e.
2270:                    //  just one instance of one element. That one is definitely a
2271:                    //  simple content model.
2272:                    //
2273:
2274:                    fQName.setValues(null, (String) contentSpec.value,
2275:                            (String) contentSpec.value,
2276:                            (String) contentSpec.otherValue);
2277:                    return new SimpleContentModel(contentSpec.type, fQName,
2278:                            null);
2279:                } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
2280:                        || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
2281:                    //
2282:                    //  Lets see if both of the children are leafs. If so, then it
2283:                    //  it has to be a simple content model
2284:                    //
2285:                    XMLContentSpec contentSpecLeft = new XMLContentSpec();
2286:                    XMLContentSpec contentSpecRight = new XMLContentSpec();
2287:
2288:                    getContentSpec(((int[]) contentSpec.value)[0],
2289:                            contentSpecLeft);
2290:                    getContentSpec(((int[]) contentSpec.otherValue)[0],
2291:                            contentSpecRight);
2292:
2293:                    if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
2294:                            && (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
2295:                        //
2296:                        //  Its a simple choice or sequence, so we can do a simple
2297:                        //  content model for it.
2298:                        //
2299:                        fQName.setValues(null, (String) contentSpecLeft.value,
2300:                                (String) contentSpecLeft.value,
2301:                                (String) contentSpecLeft.otherValue);
2302:                        fQName2.setValues(null,
2303:                                (String) contentSpecRight.value,
2304:                                (String) contentSpecRight.value,
2305:                                (String) contentSpecRight.otherValue);
2306:                        return new SimpleContentModel(contentSpec.type, fQName,
2307:                                fQName2);
2308:                    }
2309:                } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
2310:                        || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
2311:                        || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
2312:                    //
2313:                    //  Its a repetition, so see if its one child is a leaf. If so
2314:                    //  its a repetition of a single element, so we can do a simple
2315:                    //  content model for that.
2316:                    //
2317:                    XMLContentSpec contentSpecLeft = new XMLContentSpec();
2318:                    getContentSpec(((int[]) contentSpec.value)[0],
2319:                            contentSpecLeft);
2320:
2321:                    if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
2322:                        //
2323:                        //  It is, so we can create a simple content model here that
2324:                        //  will check for this repetition. We pass -1 for the unused
2325:                        //  right node.
2326:                        //
2327:                        fQName.setValues(null, (String) contentSpecLeft.value,
2328:                                (String) contentSpecLeft.value,
2329:                                (String) contentSpecLeft.otherValue);
2330:                        return new SimpleContentModel(contentSpec.type, fQName,
2331:                                null);
2332:                    }
2333:                } else {
2334:                    throw new RuntimeException("ImplementationMessages.VAL_CST");
2335:                }
2336:
2337:                //
2338:                //  Its not a simple content model, so here we have to create a DFA
2339:                //  for this element. So we create a DFAContentModel object. He
2340:                //  encapsulates all of the work to create the DFA.
2341:                //
2342:
2343:                fLeafCount = 0;
2344:                //int leafCount = countLeaves(contentSpecIndex);
2345:                fLeafCount = 0;
2346:                CMNode cmn = buildSyntaxTree(contentSpecIndex, contentSpec);
2347:
2348:                // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
2349:                return new DFAContentModel(cmn, fLeafCount, false);
2350:
2351:            } // createChildModel(int):ContentModelValidator
2352:
2353:            private final CMNode buildSyntaxTree(int startNode,
2354:                    XMLContentSpec contentSpec) {
2355:
2356:                // We will build a node at this level for the new tree
2357:                CMNode nodeRet = null;
2358:                getContentSpec(startNode, contentSpec);
2359:                if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) {
2360:                    //nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++);
2361:                    nodeRet = new CMAny(contentSpec.type,
2362:                            (String) contentSpec.otherValue, fLeafCount++);
2363:                } else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
2364:                    nodeRet = new CMAny(contentSpec.type,
2365:                            (String) contentSpec.otherValue, fLeafCount++);
2366:                } else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
2367:                    nodeRet = new CMAny(contentSpec.type, null, fLeafCount++);
2368:                }
2369:                //
2370:                //  If this node is a leaf, then its an easy one. We just add it
2371:                //  to the tree.
2372:                //
2373:                else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
2374:                    //
2375:                    //  Create a new leaf node, and pass it the current leaf count,
2376:                    //  which is its DFA state position. Bump the leaf count after
2377:                    //  storing it. This makes the positions zero based since we
2378:                    //  store first and then increment.
2379:                    //
2380:                    fQName.setValues(null, (String) contentSpec.value,
2381:                            (String) contentSpec.value,
2382:                            (String) contentSpec.otherValue);
2383:                    nodeRet = new CMLeaf(fQName, fLeafCount++);
2384:                } else {
2385:                    //
2386:                    //  Its not a leaf, so we have to recurse its left and maybe right
2387:                    //  nodes. Save both values before we recurse and trash the node.
2388:                    final int leftNode = ((int[]) contentSpec.value)[0];
2389:                    final int rightNode = ((int[]) contentSpec.otherValue)[0];
2390:
2391:                    if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
2392:                            || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
2393:                        //
2394:                        //  Recurse on both children, and return a binary op node
2395:                        //  with the two created sub nodes as its children. The node
2396:                        //  type is the same type as the source.
2397:                        //
2398:
2399:                        nodeRet = new CMBinOp(contentSpec.type,
2400:                                buildSyntaxTree(leftNode, contentSpec),
2401:                                buildSyntaxTree(rightNode, contentSpec));
2402:                    } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) {
2403:                        nodeRet = new CMUniOp(contentSpec.type,
2404:                                buildSyntaxTree(leftNode, contentSpec));
2405:                    } else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
2406:                            || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
2407:                            || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
2408:                        nodeRet = new CMUniOp(contentSpec.type,
2409:                                buildSyntaxTree(leftNode, contentSpec));
2410:                    } else {
2411:                        throw new RuntimeException(
2412:                                "ImplementationMessages.VAL_CST");
2413:                    }
2414:                }
2415:                // And return our new node for this level
2416:                return nodeRet;
2417:            }
2418:
2419:            /**
2420:             * Build a vector of valid QNames from Content Spec
2421:             * table.
2422:             * 
2423:             * @param contentSpecIndex
2424:             *               Content Spec index
2425:             * @param vectorQName
2426:             *               Array of QName
2427:             * @exception RuntimeException
2428:             */
2429:            private void contentSpecTree(int contentSpecIndex,
2430:                    XMLContentSpec contentSpec, ChildrenList children) {
2431:
2432:                // Handle any and leaf nodes
2433:                getContentSpec(contentSpecIndex, contentSpec);
2434:                if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF
2435:                        || (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY
2436:                        || (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL
2437:                        || (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
2438:
2439:                    // resize arrays, if needed
2440:                    if (children.length == children.qname.length) {
2441:                        QName[] newQName = new QName[children.length * 2];
2442:                        System.arraycopy(children.qname, 0, newQName, 0,
2443:                                children.length);
2444:                        children.qname = newQName;
2445:                        int[] newType = new int[children.length * 2];
2446:                        System.arraycopy(children.type, 0, newType, 0,
2447:                                children.length);
2448:                        children.type = newType;
2449:                    }
2450:
2451:                    // save values and return length
2452:                    children.qname[children.length] = new QName(null,
2453:                            (String) contentSpec.value,
2454:                            (String) contentSpec.value,
2455:                            (String) contentSpec.otherValue);
2456:                    children.type[children.length] = contentSpec.type;
2457:                    children.length++;
2458:                    return;
2459:                }
2460:
2461:                //
2462:                //  Its not a leaf, so we have to recurse its left and maybe right
2463:                //  nodes. Save both values before we recurse and trash the node.
2464:                //
2465:                final int leftNode = contentSpec.value != null ? ((int[]) (contentSpec.value))[0]
2466:                        : -1;
2467:                int rightNode = -1;
2468:                if (contentSpec.otherValue != null)
2469:                    rightNode = ((int[]) (contentSpec.otherValue))[0];
2470:                else
2471:                    return;
2472:
2473:                if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE
2474:                        || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
2475:                    contentSpecTree(leftNode, contentSpec, children);
2476:                    contentSpecTree(rightNode, contentSpec, children);
2477:                    return;
2478:                }
2479:
2480:                if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
2481:                        || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
2482:                        || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
2483:                    contentSpecTree(leftNode, contentSpec, children);
2484:                    return;
2485:                }
2486:
2487:                // error
2488:                throw new RuntimeException(
2489:                        "Invalid content spec type seen in contentSpecTree() method of AbstractDTDGrammar class : "
2490:                                + contentSpec.type);
2491:
2492:            } // contentSpecTree(int,XMLContentSpec,ChildrenList)
2493:
2494:            // ensure capacity
2495:
2496:            private void ensureElementDeclCapacity(int chunk) {
2497:                if (chunk >= fElementDeclName.length) {
2498:                    fElementDeclIsExternal = resize(fElementDeclIsExternal,
2499:                            fElementDeclIsExternal.length * 2);
2500:
2501:                    fElementDeclName = resize(fElementDeclName,
2502:                            fElementDeclName.length * 2);
2503:                    fElementDeclType = resize(fElementDeclType,
2504:                            fElementDeclType.length * 2);
2505:                    fElementDeclContentModelValidator = resize(
2506:                            fElementDeclContentModelValidator,
2507:                            fElementDeclContentModelValidator.length * 2);
2508:                    fElementDeclContentSpecIndex = resize(
2509:                            fElementDeclContentSpecIndex,
2510:                            fElementDeclContentSpecIndex.length * 2);
2511:                    fElementDeclFirstAttributeDeclIndex = resize(
2512:                            fElementDeclFirstAttributeDeclIndex,
2513:                            fElementDeclFirstAttributeDeclIndex.length * 2);
2514:                    fElementDeclLastAttributeDeclIndex = resize(
2515:                            fElementDeclLastAttributeDeclIndex,
2516:                            fElementDeclLastAttributeDeclIndex.length * 2);
2517:                } else if (fElementDeclName[chunk] != null) {
2518:                    return;
2519:                }
2520:
2521:                fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
2522:                fElementDeclName[chunk] = new QName[CHUNK_SIZE];
2523:                fElementDeclType[chunk] = new short[CHUNK_SIZE];
2524:                fElementDeclContentModelValidator[chunk] = new ContentModelValidator[CHUNK_SIZE];
2525:                fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
2526:                fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
2527:                fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
2528:                return;
2529:            }
2530:
2531:            private void ensureAttributeDeclCapacity(int chunk) {
2532:
2533:                if (chunk >= fAttributeDeclName.length) {
2534:                    fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal,
2535:                            fAttributeDeclIsExternal.length * 2);
2536:                    fAttributeDeclName = resize(fAttributeDeclName,
2537:                            fAttributeDeclName.length * 2);
2538:                    fAttributeDeclType = resize(fAttributeDeclType,
2539:                            fAttributeDeclType.length * 2);
2540:                    fAttributeDeclEnumeration = resize(
2541:                            fAttributeDeclEnumeration,
2542:                            fAttributeDeclEnumeration.length * 2);
2543:                    fAttributeDeclDefaultType = resize(
2544:                            fAttributeDeclDefaultType,
2545:                            fAttributeDeclDefaultType.length * 2);
2546:                    fAttributeDeclDatatypeValidator = resize(
2547:                            fAttributeDeclDatatypeValidator,
2548:                            fAttributeDeclDatatypeValidator.length * 2);
2549:                    fAttributeDeclDefaultValue = resize(
2550:                            fAttributeDeclDefaultValue,
2551:                            fAttributeDeclDefaultValue.length * 2);
2552:                    fAttributeDeclNonNormalizedDefaultValue = resize(
2553:                            fAttributeDeclNonNormalizedDefaultValue,
2554:                            fAttributeDeclNonNormalizedDefaultValue.length * 2);
2555:                    fAttributeDeclNextAttributeDeclIndex = resize(
2556:                            fAttributeDeclNextAttributeDeclIndex,
2557:                            fAttributeDeclNextAttributeDeclIndex.length * 2);
2558:                } else if (fAttributeDeclName[chunk] != null) {
2559:                    return;
2560:                }
2561:
2562:                fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
2563:                fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
2564:                fAttributeDeclType[chunk] = new short[CHUNK_SIZE];
2565:                fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][];
2566:                fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE];
2567:                fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
2568:                fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
2569:                fAttributeDeclNonNormalizedDefaultValue[chunk] = new String[CHUNK_SIZE];
2570:                fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
2571:                return;
2572:            }
2573:
2574:            private void ensureEntityDeclCapacity(int chunk) {
2575:                if (chunk >= fEntityName.length) {
2576:                    fEntityName = resize(fEntityName, fEntityName.length * 2);
2577:                    fEntityValue = resize(fEntityValue, fEntityValue.length * 2);
2578:                    fEntityPublicId = resize(fEntityPublicId,
2579:                            fEntityPublicId.length * 2);
2580:                    fEntitySystemId = resize(fEntitySystemId,
2581:                            fEntitySystemId.length * 2);
2582:                    fEntityBaseSystemId = resize(fEntityBaseSystemId,
2583:                            fEntityBaseSystemId.length * 2);
2584:                    fEntityNotation = resize(fEntityNotation,
2585:                            fEntityNotation.length * 2);
2586:                    fEntityIsPE = resize(fEntityIsPE, fEntityIsPE.length * 2);
2587:                    fEntityInExternal = resize(fEntityInExternal,
2588:                            fEntityInExternal.length * 2);
2589:                } else if (fEntityName[chunk] != null) {
2590:                    return;
2591:                }
2592:
2593:                fEntityName[chunk] = new String[CHUNK_SIZE];
2594:                fEntityValue[chunk] = new String[CHUNK_SIZE];
2595:                fEntityPublicId[chunk] = new String[CHUNK_SIZE];
2596:                fEntitySystemId[chunk] = new String[CHUNK_SIZE];
2597:                fEntityBaseSystemId[chunk] = new String[CHUNK_SIZE];
2598:                fEntityNotation[chunk] = new String[CHUNK_SIZE];
2599:                fEntityIsPE[chunk] = new byte[CHUNK_SIZE];
2600:                fEntityInExternal[chunk] = new byte[CHUNK_SIZE];
2601:                return;
2602:            }
2603:
2604:            private void ensureNotationDeclCapacity(int chunk) {
2605:                if (chunk >= fNotationName.length) {
2606:                    fNotationName = resize(fNotationName,
2607:                            fNotationName.length * 2);
2608:                    fNotationPublicId = resize(fNotationPublicId,
2609:                            fNotationPublicId.length * 2);
2610:                    fNotationSystemId = resize(fNotationSystemId,
2611:                            fNotationSystemId.length * 2);
2612:                    fNotationBaseSystemId = resize(fNotationBaseSystemId,
2613:                            fNotationBaseSystemId.length * 2);
2614:                } else if (fNotationName[chunk] != null) {
2615:                    return;
2616:                }
2617:
2618:                fNotationName[chunk] = new String[CHUNK_SIZE];
2619:                fNotationPublicId[chunk] = new String[CHUNK_SIZE];
2620:                fNotationSystemId[chunk] = new String[CHUNK_SIZE];
2621:                fNotationBaseSystemId[chunk] = new String[CHUNK_SIZE];
2622:                return;
2623:            }
2624:
2625:            private void ensureContentSpecCapacity(int chunk) {
2626:                if (chunk >= fContentSpecType.length) {
2627:                    fContentSpecType = resize(fContentSpecType,
2628:                            fContentSpecType.length * 2);
2629:                    fContentSpecValue = resize(fContentSpecValue,
2630:                            fContentSpecValue.length * 2);
2631:                    fContentSpecOtherValue = resize(fContentSpecOtherValue,
2632:                            fContentSpecOtherValue.length * 2);
2633:                } else if (fContentSpecType[chunk] != null) {
2634:                    return;
2635:                }
2636:
2637:                fContentSpecType[chunk] = new short[CHUNK_SIZE];
2638:                fContentSpecValue[chunk] = new Object[CHUNK_SIZE];
2639:                fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE];
2640:                return;
2641:            }
2642:
2643:            //
2644:            // Private static methods
2645:            //
2646:
2647:            // resize chunks
2648:
2649:            private static byte[][] resize(byte array[][], int newsize) {
2650:                byte newarray[][] = new byte[newsize][];
2651:                System.arraycopy(array, 0, newarray, 0, array.length);
2652:                return newarray;
2653:            }
2654:
2655:            private static short[][] resize(short array[][], int newsize) {
2656:                short newarray[][] = new short[newsize][];
2657:                System.arraycopy(array, 0, newarray, 0, array.length);
2658:                return newarray;
2659:            }
2660:
2661:            private static int[][] resize(int array[][], int newsize) {
2662:                int newarray[][] = new int[newsize][];
2663:                System.arraycopy(array, 0, newarray, 0, array.length);
2664:                return newarray;
2665:            }
2666:
2667:            private static DatatypeValidator[][] resize(
2668:                    DatatypeValidator array[][], int newsize) {
2669:                DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
2670:                System.arraycopy(array, 0, newarray, 0, array.length);
2671:                return newarray;
2672:            }
2673:
2674:            private static ContentModelValidator[][] resize(
2675:                    ContentModelValidator array[][], int newsize) {
2676:                ContentModelValidator newarray[][] = new ContentModelValidator[newsize][];
2677:                System.arraycopy(array, 0, newarray, 0, array.length);
2678:                return newarray;
2679:            }
2680:
2681:            private static Object[][] resize(Object array[][], int newsize) {
2682:                Object newarray[][] = new Object[newsize][];
2683:                System.arraycopy(array, 0, newarray, 0, array.length);
2684:                return newarray;
2685:            }
2686:
2687:            private static QName[][] resize(QName array[][], int newsize) {
2688:                QName newarray[][] = new QName[newsize][];
2689:                System.arraycopy(array, 0, newarray, 0, array.length);
2690:                return newarray;
2691:            }
2692:
2693:            private static String[][] resize(String array[][], int newsize) {
2694:                String newarray[][] = new String[newsize][];
2695:                System.arraycopy(array, 0, newarray, 0, array.length);
2696:                return newarray;
2697:            }
2698:
2699:            private static String[][][] resize(String array[][][], int newsize) {
2700:                String newarray[][][] = new String[newsize][][];
2701:                System.arraycopy(array, 0, newarray, 0, array.length);
2702:                return newarray;
2703:            }
2704:
2705:            //
2706:            // Classes
2707:            //
2708:
2709:            /**
2710:             * Children list for <code>contentSpecTree</code> method.
2711:             * 
2712:             * @xerces.internal
2713:             *
2714:             * @author Eric Ye, IBM
2715:             */
2716:            private static class ChildrenList {
2717:
2718:                //
2719:                // Data
2720:                //
2721:
2722:                /** Length. */
2723:                public int length = 0;
2724:
2725:                // NOTE: The following set of data is mutually exclusive. It is
2726:                //       written this way because Java doesn't have a native
2727:                //       union data structure. -Ac
2728:
2729:                /** Left and right children names. */
2730:                public QName[] qname = new QName[2];
2731:
2732:                /** Left and right children types. */
2733:                public int[] type = new int[2];
2734:
2735:                //
2736:                // Constructors
2737:                //
2738:
2739:                public ChildrenList() {
2740:                }
2741:
2742:            } // class ChildrenList
2743:
2744:            //
2745:            // Classes
2746:            //
2747:
2748:            /**
2749:             * A simple Hashtable implementation that takes a tuple (String, String)
2750:             * as the key and a int as value.
2751:             * 
2752:             * @xerces.internal
2753:             *
2754:             * @author Eric Ye, IBM
2755:             * @author Andy Clark, IBM
2756:             */
2757:            protected static final class QNameHashtable {
2758:
2759:                //
2760:                // Constants
2761:                //
2762:
2763:                /** Initial bucket size (4). */
2764:                private static final int INITIAL_BUCKET_SIZE = 4;
2765:
2766:                // NOTE: Changed previous hashtable size from 512 to 101 so
2767:                //       that we get a better distribution for hashing. -Ac
2768:                /** Hashtable size (101). */
2769:                private static final int HASHTABLE_SIZE = 101;
2770:
2771:                //
2772:                // Data
2773:                //
2774:                private Object[][] fHashTable = new Object[HASHTABLE_SIZE][];
2775:
2776:                //
2777:                // Public methods
2778:                //
2779:                /** Associates the given value with the specified key tuple. */
2780:                public void put(String key, int value) {
2781:
2782:                    int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
2783:                    Object[] bucket = fHashTable[hash];
2784:
2785:                    if (bucket == null) {
2786:                        bucket = new Object[1 + 2 * INITIAL_BUCKET_SIZE];
2787:                        bucket[0] = new int[] { 1 };
2788:                        bucket[1] = key;
2789:                        bucket[2] = new int[] { value };
2790:                        fHashTable[hash] = bucket;
2791:                    } else {
2792:                        int count = ((int[]) bucket[0])[0];
2793:                        int offset = 1 + 2 * count;
2794:                        if (offset == bucket.length) {
2795:                            int newSize = count + INITIAL_BUCKET_SIZE;
2796:                            Object[] newBucket = new Object[1 + 2 * newSize];
2797:                            System.arraycopy(bucket, 0, newBucket, 0, offset);
2798:                            bucket = newBucket;
2799:                            fHashTable[hash] = bucket;
2800:                        }
2801:                        boolean found = false;
2802:                        int j = 1;
2803:                        for (int i = 0; i < count; i++) {
2804:                            if ((String) bucket[j] == key) {
2805:                                ((int[]) bucket[j + 1])[0] = value;
2806:                                found = true;
2807:                                break;
2808:                            }
2809:                            j += 2;
2810:                        }
2811:                        if (!found) {
2812:                            bucket[offset++] = key;
2813:                            bucket[offset] = new int[] { value };
2814:                            ((int[]) bucket[0])[0] = ++count;
2815:                        }
2816:
2817:                    }
2818:                    //System.out.println("put("+key+" -> "+value+')');
2819:                    //System.out.println("get("+key+") -> "+get(key));
2820:
2821:                } // put(int,String,String,int)
2822:
2823:                /** Returns the value associated with the specified key tuple. */
2824:                public int get(String key) {
2825:                    int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
2826:                    Object[] bucket = fHashTable[hash];
2827:
2828:                    if (bucket == null) {
2829:                        return -1;
2830:                    }
2831:                    int count = ((int[]) bucket[0])[0];
2832:
2833:                    int j = 1;
2834:                    for (int i = 0; i < count; i++) {
2835:                        if ((String) bucket[j] == key) {
2836:                            return ((int[]) bucket[j + 1])[0];
2837:                        }
2838:                        j += 2;
2839:                    }
2840:                    return -1;
2841:
2842:                } // get(int,String,String)
2843:
2844:            } // class QNameHashtable
2845:
2846:            //
2847:            // EntityState methods
2848:            //
2849:            public boolean isEntityDeclared(String name) {
2850:                return (getEntityDeclIndex(name) != -1) ? true : false;
2851:            }
2852:
2853:            public boolean isEntityUnparsed(String name) {
2854:                int entityIndex = getEntityDeclIndex(name);
2855:                if (entityIndex > -1) {
2856:                    int chunk = entityIndex >> CHUNK_SHIFT;
2857:                    int index = entityIndex & CHUNK_MASK;
2858:                    //for unparsed entity notation!=null
2859:                    return (fEntityNotation[chunk][index] != null) ? true
2860:                            : false;
2861:                }
2862:                return false;
2863:            }
2864:        } // class DTDGrammar
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.