Source Code Cross Referenced for XMLDTDScanner.java in  » Web-Server » Rimfaxe-Web-Server » org » apache » xerces » framework » 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 » Web Server » Rimfaxe Web Server » org.apache.xerces.framework 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The Apache Software License, Version 1.1
0003:         *
0004:         *
0005:         * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights 
0006:         * reserved.
0007:         *
0008:         * Redistribution and use in source and binary forms, with or without
0009:         * modification, are permitted provided that the following conditions
0010:         * are met:
0011:         *
0012:         * 1. Redistributions of source code must retain the above copyright
0013:         *    notice, this list of conditions and the following disclaimer. 
0014:         *
0015:         * 2. Redistributions in binary form must reproduce the above copyright
0016:         *    notice, this list of conditions and the following disclaimer in
0017:         *    the documentation and/or other materials provided with the
0018:         *    distribution.
0019:         *
0020:         * 3. The end-user documentation included with the redistribution,
0021:         *    if any, must include the following acknowledgment:  
0022:         *       "This product includes software developed by the
0023:         *        Apache Software Foundation (http://www.apache.org/)."
0024:         *    Alternately, this acknowledgment may appear in the software itself,
0025:         *    if and wherever such third-party acknowledgments normally appear.
0026:         *
0027:         * 4. The names "Xerces" and "Apache Software Foundation" must
0028:         *    not be used to endorse or promote products derived from this
0029:         *    software without prior written permission. For written 
0030:         *    permission, please contact apache@apache.org.
0031:         *
0032:         * 5. Products derived from this software may not be called "Apache",
0033:         *    nor may "Apache" appear in their name, without prior written
0034:         *    permission of the Apache Software Foundation.
0035:         *
0036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0040:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047:         * SUCH DAMAGE.
0048:         * ====================================================================
0049:         *
0050:         * This software consists of voluntary contributions made by many
0051:         * individuals on behalf of the Apache Software Foundation and was
0052:         * originally based on software copyright (c) 1999, International
0053:         * Business Machines, Inc., http://www.apache.org.  For more
0054:         * information on the Apache Software Foundation, please see
0055:         * <http://www.apache.org/>.
0056:         */
0057:
0058:        package org.apache.xerces.framework;
0059:
0060:        import org.apache.xerces.readers.XMLEntityHandler;
0061:        import org.apache.xerces.readers.DefaultEntityHandler;
0062:        import org.apache.xerces.utils.QName;
0063:        import org.apache.xerces.utils.StringPool;
0064:        import org.apache.xerces.utils.XMLCharacterProperties;
0065:        import org.apache.xerces.utils.XMLMessages;
0066:        import org.apache.xerces.validators.common.Grammar;
0067:        import org.apache.xerces.validators.common.GrammarResolver;
0068:        import org.apache.xerces.validators.common.XMLAttributeDecl;
0069:        import org.apache.xerces.validators.common.XMLElementDecl;
0070:        import org.apache.xerces.validators.dtd.DTDGrammar;
0071:
0072:        import org.xml.sax.Locator;
0073:        import org.xml.sax.SAXParseException;
0074:
0075:        import java.util.StringTokenizer;
0076:
0077:        /**
0078:         * Default implementation of an XML DTD scanner.
0079:         * <p>
0080:         * Clients who wish to scan a DTD should implement
0081:         * XMLDTDScanner.EventHandler to provide the desired behavior
0082:         * when various DTD components are encountered.
0083:         * <p>
0084:         * To process the DTD, the client application should follow the 
0085:         * following sequence:
0086:         * <ol>
0087:         *  <li>call scanDocTypeDecl() to scan the DOCTYPE declaration
0088:         *  <li>call getReadingExternalEntity() to determine if scanDocTypeDecl found an
0089:         *      external subset
0090:         * <li>if scanning an external subset, call scanDecls(true) to process the external subset
0091:         * </ol>
0092:         *
0093:         * @see XMLDTDScanner.EventHandler
0094:         * @version $Id: XMLDTDScanner.java,v 1.19 2001/04/26 17:45:50 lmartin Exp $
0095:         */
0096:        public final class XMLDTDScanner {
0097:            //
0098:            // Constants
0099:            //
0100:            //
0101:            // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
0102:            //
0103:            private static final char[] version_string = { 'v', 'e', 'r', 's',
0104:                    'i', 'o', 'n' };
0105:            //
0106:            // [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
0107:            //
0108:            private static final char[] element_string = { 'E', 'L', 'E', 'M',
0109:                    'E', 'N', 'T' };
0110:            //
0111:            // [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
0112:            //
0113:            private static final char[] empty_string = { 'E', 'M', 'P', 'T',
0114:                    'Y' };
0115:            private static final char[] any_string = { 'A', 'N', 'Y' };
0116:            //
0117:            // [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*'
0118:            //                | '(' S? '#PCDATA' S? ')'
0119:            //
0120:            private static final char[] pcdata_string = { '#', 'P', 'C', 'D',
0121:                    'A', 'T', 'A' };
0122:            //
0123:            // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
0124:            //
0125:            private static final char[] attlist_string = { 'A', 'T', 'T', 'L',
0126:                    'I', 'S', 'T' };
0127:            //
0128:            // [55] StringType ::= 'CDATA'
0129:            //
0130:            private static final char[] cdata_string = { 'C', 'D', 'A', 'T',
0131:                    'A' };
0132:            //
0133:            // [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES'
0134:            //                        | 'NMTOKEN' | 'NMTOKENS'
0135:            //
0136:            // Note: We search for common substrings always trying to move forward
0137:            //
0138:            //  'ID'      - Common prefix of ID, IDREF and IDREFS
0139:            //  'REF'     - Common substring of IDREF and IDREFS after matching ID prefix
0140:            //  'ENTIT'   - Common prefix of ENTITY and ENTITIES
0141:            //  'IES'     - Suffix of ENTITIES
0142:            //  'NMTOKEN' - Common prefix of NMTOKEN and NMTOKENS
0143:            //
0144:            private static final char[] id_string = { 'I', 'D' };
0145:            private static final char[] ref_string = { 'R', 'E', 'F' };
0146:            private static final char[] entit_string = { 'E', 'N', 'T', 'I',
0147:                    'T' };
0148:            private static final char[] ies_string = { 'I', 'E', 'S' };
0149:            private static final char[] nmtoken_string = { 'N', 'M', 'T', 'O',
0150:                    'K', 'E', 'N' };
0151:            //
0152:            // [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
0153:            // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
0154:            //
0155:            private static final char[] notation_string = { 'N', 'O', 'T', 'A',
0156:                    'T', 'I', 'O', 'N' };
0157:            //
0158:            // [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
0159:            //
0160:            private static final char[] required_string = { '#', 'R', 'E', 'Q',
0161:                    'U', 'I', 'R', 'E', 'D' };
0162:            private static final char[] implied_string = { '#', 'I', 'M', 'P',
0163:                    'L', 'I', 'E', 'D' };
0164:            private static final char[] fixed_string = { '#', 'F', 'I', 'X',
0165:                    'E', 'D' };
0166:            //
0167:            // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
0168:            //
0169:            private static final char[] include_string = { 'I', 'N', 'C', 'L',
0170:                    'U', 'D', 'E' };
0171:            //
0172:            // [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
0173:            //
0174:            private static final char[] ignore_string = { 'I', 'G', 'N', 'O',
0175:                    'R', 'E' };
0176:            //
0177:            // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
0178:            // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
0179:            //
0180:            private static final char[] entity_string = { 'E', 'N', 'T', 'I',
0181:                    'T', 'Y' };
0182:            //
0183:            // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
0184:            //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
0185:            // [83] PublicID ::= 'PUBLIC' S PubidLiteral
0186:            //
0187:            private static final char[] system_string = { 'S', 'Y', 'S', 'T',
0188:                    'E', 'M' };
0189:            private static final char[] public_string = { 'P', 'U', 'B', 'L',
0190:                    'I', 'C' };
0191:            //
0192:            // [76] NDataDecl ::= S 'NDATA' S Name
0193:            //
0194:            private static final char[] ndata_string = { 'N', 'D', 'A', 'T',
0195:                    'A' };
0196:            //
0197:            // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
0198:            //
0199:            private static final char[] encoding_string = { 'e', 'n', 'c', 'o',
0200:                    'd', 'i', 'n', 'g' };
0201:            //
0202:            // Instance Variables
0203:            //
0204:            private DTDGrammar fDTDGrammar = null;
0205:            private GrammarResolver fGrammarResolver = null;
0206:            private boolean fNamespacesEnabled = false;
0207:            private boolean fValidationEnabled = false;
0208:            private boolean fLoadExternalDTD = true;
0209:            private XMLElementDecl fTempElementDecl = new XMLElementDecl();
0210:            private XMLAttributeDecl fTempAttributeDecl = new XMLAttributeDecl();
0211:            private QName fElementQName = new QName();
0212:            private QName fAttributeQName = new QName();
0213:            private QName fElementRefQName = new QName();
0214:            private EventHandler fEventHandler = null;
0215:            private XMLDocumentHandler.DTDHandler fDTDHandler = null;
0216:            private StringPool fStringPool = null;
0217:            private XMLErrorReporter fErrorReporter = null;
0218:            private XMLEntityHandler fEntityHandler = null;
0219:            private XMLEntityHandler.EntityReader fEntityReader = null;
0220:            private XMLEntityHandler.CharBuffer fLiteralData = null;
0221:            private int fReaderId = -1;
0222:            private int fSystemLiteral = -1;
0223:            private int fPubidLiteral = -1;
0224:            private int[] fOpStack = null;
0225:            private int[] fNodeIndexStack = null;
0226:            private int[] fPrevNodeIndexStack = null;
0227:            private int fScannerState = SCANNER_STATE_INVALID;
0228:            private int fIncludeSectDepth = 0;
0229:            private int fDoctypeReader = -1;
0230:            private int fExternalSubsetReader = -1;
0231:            private int fDefaultAttValueReader = -1;
0232:            private int fDefaultAttValueElementType = -1;
0233:            private int fDefaultAttValueAttrName = -1;
0234:            private int fDefaultAttValueOffset = -1;
0235:            private int fDefaultAttValueMark = -1;
0236:            private int fEntityValueReader = -1;
0237:            private int fEntityValueMark = -1;
0238:            private int fXMLSymbol = -1;
0239:            private int fXMLNamespace = -1;
0240:            private int fXMLSpace = -1;
0241:            private int fDefault = -1;
0242:            private int fPreserve = -1;
0243:            private int fScannerMarkupDepth = 0;
0244:            private int fScannerParenDepth = 0;
0245:
0246:            //
0247:            // Constructors
0248:            //
0249:            public XMLDTDScanner(StringPool stringPool,
0250:                    XMLErrorReporter errorReporter,
0251:                    XMLEntityHandler entityHandler,
0252:                    XMLEntityHandler.CharBuffer literalData) {
0253:                fStringPool = stringPool;
0254:                fErrorReporter = errorReporter;
0255:                fEntityHandler = entityHandler;
0256:                fLiteralData = literalData;
0257:                init();
0258:            }
0259:
0260:            /**
0261:             * Set the event handler
0262:             *
0263:             * @param eventHandler The place to send our callbacks.
0264:             */
0265:            public void setEventHandler(XMLDTDScanner.EventHandler eventHandler) {
0266:                fEventHandler = eventHandler;
0267:            }
0268:
0269:            /** Set the DTD handler. */
0270:            public void setDTDHandler(XMLDocumentHandler.DTDHandler dtdHandler) {
0271:                fDTDHandler = dtdHandler;
0272:            }
0273:
0274:            /** Sets the grammar resolver. */
0275:            public void setGrammarResolver(GrammarResolver resolver) {
0276:                fGrammarResolver = resolver;
0277:            }
0278:
0279:            /** set fNamespacesEnabled  **/
0280:            public void setNamespacesEnabled(boolean enabled) {
0281:                fNamespacesEnabled = enabled;
0282:            }
0283:
0284:            /** set fValidationEnabled  **/
0285:            public void setValidationEnabled(boolean enabled) {
0286:                fValidationEnabled = enabled;
0287:            }
0288:
0289:            /** Sets whether the parser loads the external DTD. */
0290:            public void setLoadExternalDTD(boolean enabled) {
0291:                fLoadExternalDTD = enabled;
0292:            }
0293:
0294:            /**
0295:             * Is the XMLDTDScanner reading from an external entity?
0296:             *
0297:             * This will be true, in particular if there was an external subset
0298:             *
0299:             * @return true if the XMLDTDScanner is reading from an external entity.
0300:             */
0301:            public boolean getReadingExternalEntity() {
0302:                return fReaderId != fDoctypeReader;
0303:            }
0304:
0305:            /**
0306:             * Is the scanner reading a ContentSpec?
0307:             * 
0308:             * @return true if the scanner is reading a ContentSpec
0309:             */
0310:            public boolean getReadingContentSpec() {
0311:                return getScannerState() == SCANNER_STATE_CONTENTSPEC;
0312:            }
0313:
0314:            /**
0315:             * Report the markup nesting depth.  This allows a client to
0316:             * perform validation checks for correct markup nesting.  This keeps
0317:             * scanning and validation separate.
0318:             *
0319:             * @return the markup nesting depth
0320:             */
0321:            public int markupDepth() {
0322:                return fScannerMarkupDepth;
0323:            }
0324:
0325:            private int increaseMarkupDepth() {
0326:                return fScannerMarkupDepth++;
0327:            }
0328:
0329:            private int decreaseMarkupDepth() {
0330:                return fScannerMarkupDepth--;
0331:            }
0332:
0333:            /**
0334:             * Report the parenthesis nesting depth.  This allows a client to
0335:             * perform validation checks for correct parenthesis balancing.  This keeps 
0336:             * scanning and validation separate.
0337:             *
0338:             * @return the parenthesis depth
0339:             */
0340:            public int parenDepth() {
0341:                return fScannerParenDepth;
0342:            }
0343:
0344:            private void setParenDepth(int parenDepth) {
0345:                fScannerParenDepth = parenDepth;
0346:            }
0347:
0348:            private void increaseParenDepth() {
0349:                fScannerParenDepth++;
0350:            }
0351:
0352:            private void decreaseParenDepth() {
0353:                fScannerParenDepth--;
0354:            }
0355:
0356:            //
0357:            //
0358:            //
0359:            /**
0360:             * Allow XMLDTDScanner to be reused.  This method is called from an
0361:             * XMLParser reset method, which passes the StringPool to be used
0362:             * by the reset DTD scanner instance.
0363:             *
0364:             * @param stringPool the string pool to be used by XMLDTDScanner.  
0365:             */
0366:            public void reset(StringPool stringPool,
0367:                    XMLEntityHandler.CharBuffer literalData) throws Exception {
0368:                fStringPool = stringPool;
0369:                fLiteralData = literalData;
0370:                fEntityReader = null;
0371:                fReaderId = -1;
0372:                fSystemLiteral = -1;
0373:                fPubidLiteral = -1;
0374:                fOpStack = null;
0375:                fNodeIndexStack = null;
0376:                fPrevNodeIndexStack = null;
0377:                fScannerState = SCANNER_STATE_INVALID;
0378:                fIncludeSectDepth = 0;
0379:                fDoctypeReader = -1;
0380:                fExternalSubsetReader = -1;
0381:                fDefaultAttValueReader = -1;
0382:                fDefaultAttValueElementType = -1;
0383:                fDefaultAttValueAttrName = -1;
0384:                fDefaultAttValueOffset = -1;
0385:                fDefaultAttValueMark = -1;
0386:                fEntityValueReader = -1;
0387:                fEntityValueMark = -1;
0388:                fScannerMarkupDepth = 0;
0389:                fScannerParenDepth = 0;
0390:                init();
0391:            }
0392:
0393:            private void init() {
0394:                fXMLSymbol = fStringPool.addSymbol("xml");
0395:                fXMLNamespace = fStringPool
0396:                        .addSymbol("http://www.w3.org/XML/1998/namespace");
0397:
0398:                fXMLSpace = fStringPool.addSymbol("xml:space");
0399:                fDefault = fStringPool.addSymbol("default");
0400:                fPreserve = fStringPool.addSymbol("preserve");
0401:            }
0402:
0403:            //
0404:            // Interfaces
0405:            //
0406:
0407:            /**
0408:             * This interface must be implemented by the users of the XMLDTDScanner class.
0409:             * These methods form the abstraction between the implementation semantics and the
0410:             * more generic task of scanning the DTD-specific XML grammar.
0411:             */
0412:            public interface EventHandler {
0413:
0414:                /** Start of DTD. */
0415:                public void callStartDTD() throws Exception;
0416:
0417:                /** End of DTD. */
0418:                public void callEndDTD() throws Exception;
0419:
0420:                /**
0421:                 * Signal the Text declaration of an external entity.
0422:                 *
0423:                 * @param version the handle in the string pool for the version number
0424:                 * @param encoding the handle in the string pool for the encoding
0425:                 * @exception java.lang.Exception
0426:                 */
0427:                public void callTextDecl(int version, int encoding)
0428:                        throws Exception;
0429:
0430:                /**
0431:                 * Called when the doctype decl is scanned
0432:                 *
0433:                 * @param rootElementType handle of the rootElement
0434:                 * @param publicId StringPool handle of the public id
0435:                 * @param systemId StringPool handle of the system id
0436:                 * @exception java.lang.Exception
0437:                 */
0438:                public void doctypeDecl(QName rootElement, int publicId,
0439:                        int systemId) throws Exception;
0440:
0441:                /**
0442:                 * Called when the DTDScanner starts reading from the external subset
0443:                 *
0444:                 * @param publicId StringPool handle of the public id
0445:                 * @param systemId StringPool handle of the system id
0446:                 * @exception java.lang.Exception
0447:                 */
0448:                public void startReadingFromExternalSubset(int publicId,
0449:                        int systemId) throws Exception;
0450:
0451:                /**
0452:                 * Called when the DTDScanner stop reading from the external subset
0453:                 *
0454:                 * @exception java.lang.Exception
0455:                 */
0456:                public void stopReadingFromExternalSubset() throws Exception;
0457:
0458:                /**
0459:                 * Add an element declaration (forward reference)
0460:                 *
0461:                 * @param handle to the name of the element being declared
0462:                 * @return handle to the element whose declaration was added
0463:                 * @exception java.lang.Exception
0464:                 */
0465:                public int addElementDecl(QName elementDecl) throws Exception;
0466:
0467:                /**
0468:                 * Add an element declaration
0469:                 *
0470:                 * @param handle to the name of the element being declared
0471:                 * @param contentSpecType handle to the type name of the content spec
0472:                 * @param ContentSpec handle to the content spec node for the contentSpecType
0473:                 * @return handle to the element declaration that was added 
0474:                 * @exception java.lang.Exception
0475:                 */
0476:                public int addElementDecl(QName elementDecl,
0477:                        int contentSpecType, int contentSpec, boolean isExternal)
0478:                        throws Exception;
0479:
0480:                /**
0481:                 * Add an attribute definition
0482:                 *
0483:                 * @param handle to the element whose attribute is being declared
0484:                 * @param attName StringPool handle to the attribute name being declared
0485:                 * @param attType type of the attribute
0486:                 * @param enumeration StringPool handle of the attribute's enumeration list (if any)
0487:                 * @param attDefaultType an integer value denoting the DefaultDecl value
0488:                 * @param attDefaultValue StringPool handle of this attribute's default value
0489:                 * @return handle to the attribute definition
0490:                 * @exception java.lang.Exception
0491:                 */
0492:                public int addAttDef(QName elementDecl, QName attributeDecl,
0493:                        int attType, boolean attList, int enumeration,
0494:                        int attDefaultType, int attDefaultValue,
0495:                        boolean isExternal) throws Exception;
0496:
0497:                /**
0498:                 * create an XMLContentSpec for a leaf
0499:                 *
0500:                 * @param nameIndex StringPool handle to the name (Element) for the node
0501:                 * @return handle to the newly create XMLContentSpec
0502:                 * @exception java.lang.Exception
0503:                 */
0504:                public int addUniqueLeafNode(int nameIndex) throws Exception;
0505:
0506:                /**
0507:                 * Create an XMLContentSpec for a single non-leaf
0508:                 * 
0509:                 * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
0510:                 * @param nodeValue handle to an XMLContentSpec
0511:                 * @return handle to the newly create XMLContentSpec
0512:                 * @exception java.lang.Exception
0513:                 */
0514:                public int addContentSpecNode(int nodeType, int nodeValue)
0515:                        throws Exception;
0516:
0517:                /**
0518:                 * Create an XMLContentSpec for a two child leaf
0519:                 *
0520:                 * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
0521:                 * @param leftNodeIndex handle to an XMLContentSpec
0522:                 * @param rightNodeIndex handle to an XMLContentSpec
0523:                 * @return handle to the newly create XMLContentSpec
0524:                 * @exception java.lang.Exception
0525:                 */
0526:                public int addContentSpecNode(int nodeType, int leftNodeIndex,
0527:                        int rightNodeIndex) throws Exception;
0528:
0529:                /**
0530:                 * Create a string representation of an XMLContentSpec tree
0531:                 * 
0532:                 * @param handle to an XMLContentSpec
0533:                 * @return String representation of the content spec tree
0534:                 * @exception java.lang.Exception
0535:                 */
0536:                public String getContentSpecNodeAsString(int nodeIndex)
0537:                        throws Exception;
0538:
0539:                /**
0540:                 * Start the scope of an entity declaration.
0541:                 *
0542:                 * @return <code>true</code> on success; otherwise
0543:                 *         <code>false</code> if the entity declaration is recursive.
0544:                 * @exception java.lang.Exception
0545:                 */
0546:                public boolean startEntityDecl(boolean isPE, int entityName)
0547:                        throws Exception;
0548:
0549:                /**
0550:                 * End the scope of an entity declaration.
0551:                 * @exception java.lang.Exception
0552:                 */
0553:                public void endEntityDecl() throws Exception;
0554:
0555:                /**
0556:                 * Add a declaration for an internal parameter entity
0557:                 *
0558:                 * @param name StringPool handle of the parameter entity name
0559:                 * @param value StringPool handle of the parameter entity value
0560:                 * @return handle to the parameter entity declaration
0561:                 * @exception java.lang.Exception
0562:                 */
0563:                public int addInternalPEDecl(int name, int value)
0564:                        throws Exception;
0565:
0566:                /**
0567:                 * Add a declaration for an external parameter entity
0568:                 *
0569:                 * @param name StringPool handle of the parameter entity name
0570:                 * @param publicId StringPool handle of the publicId
0571:                 * @param systemId StringPool handle of the systemId
0572:                 * @return handle to the parameter entity declaration
0573:                 * @exception java.lang.Exception
0574:                 */
0575:                public int addExternalPEDecl(int name, int publicId,
0576:                        int systemId) throws Exception;
0577:
0578:                /**
0579:                 * Add a declaration for an internal entity
0580:                 *
0581:                 * @param name StringPool handle of the entity name
0582:                 * @param value StringPool handle of the entity value
0583:                 * @return handle to the entity declaration
0584:                 * @exception java.lang.Exception
0585:                 */
0586:                public int addInternalEntityDecl(int name, int value)
0587:                        throws Exception;
0588:
0589:                /**
0590:                 * Add a declaration for an entity
0591:                 *
0592:                 * @param name StringPool handle of the entity name
0593:                 * @param publicId StringPool handle of the publicId
0594:                 * @param systemId StringPool handle of the systemId
0595:                 * @return handle to the entity declaration
0596:                 * @exception java.lang.Exception
0597:                 */
0598:                public int addExternalEntityDecl(int name, int publicId,
0599:                        int systemId) throws Exception;
0600:
0601:                /**
0602:                 * Add a declaration for an unparsed entity
0603:                 *
0604:                 * @param name StringPool handle of the entity name
0605:                 * @param publicId StringPool handle of the publicId
0606:                 * @param systemId StringPool handle of the systemId
0607:                 * @param notationName StringPool handle of the notationName
0608:                 * @return handle to the entity declaration
0609:                 * @exception java.lang.Exception
0610:                 */
0611:                public int addUnparsedEntityDecl(int name, int publicId,
0612:                        int systemId, int notationName) throws Exception;
0613:
0614:                /**
0615:                 * Called when the scanner start scanning an enumeration
0616:                 * @return StringPool handle to a string list that will hold the enumeration names
0617:                 * @exception java.lang.Exception
0618:                 */
0619:                public int startEnumeration() throws Exception;
0620:
0621:                /**
0622:                 * Add a name to an enumeration
0623:                 * @param enumIndex StringPool handle to the string list for the enumeration
0624:                 * @param elementType handle to the element that owns the attribute with the enumeration
0625:                 * @param attrName StringPool handle to the name of the attribut with the enumeration
0626:                 * @param nameIndex StringPool handle to the name to be added to the enumeration
0627:                 * @param isNotationType true if the enumeration is an enumeration of NOTATION names
0628:                 * @exception java.lang.Exception
0629:                 */
0630:                public void addNameToEnumeration(int enumIndex,
0631:                        int elementType, int attrName, int nameIndex,
0632:                        boolean isNotationType) throws Exception;
0633:
0634:                /**
0635:                 * Finish processing an enumeration
0636:                 *
0637:                 * @param enumIndex handle to the string list which holds the enumeration to be finshed.
0638:                 * @exception java.lang.Exception
0639:                 */
0640:                public void endEnumeration(int enumIndex) throws Exception;
0641:
0642:                /**
0643:                 * Add a declaration for a notation
0644:                 *
0645:                 * @param notationName
0646:                 * @param publicId
0647:                 * @param systemId
0648:                 * @return handle to the notation declaration
0649:                 * @exception java.lang.Exception
0650:                 */
0651:                public int addNotationDecl(int notationName, int publicId,
0652:                        int systemId) throws Exception;
0653:
0654:                /**
0655:                 * Called when a comment has been scanned
0656:                 *
0657:                 * @param data StringPool handle of the comment text
0658:                 * @exception java.lang.Exception
0659:                 */
0660:                public void callComment(int data) throws Exception;
0661:
0662:                /**
0663:                 * Called when a processing instruction has been scanned
0664:                 * @param piTarget StringPool handle of the PI target
0665:                 * @param piData StringPool handle of the PI data
0666:                 * @exception java.lang.Exception
0667:                 */
0668:                public void callProcessingInstruction(int piTarget, int piData)
0669:                        throws Exception;
0670:
0671:                /**
0672:                 * Supports DOM Level 2 internalSubset additions.
0673:                 * Called when the internal subset is completely scanned.
0674:                 */
0675:                public void internalSubset(int internalSubset) throws Exception;
0676:            }
0677:
0678:            //
0679:            //
0680:            //
0681:
0682:            /** Report a recoverable xml error. */
0683:            protected void reportRecoverableXMLError(int majorCode,
0684:                    int minorCode, int stringIndex1) throws Exception {
0685:
0686:                Object[] args = { fStringPool.toString(stringIndex1) };
0687:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0688:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0689:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
0690:
0691:            } // reportRecoverableXMLError(int,int,int)
0692:
0693:            /** Report a recoverable xml error. */
0694:            protected void reportRecoverableXMLError(int majorCode,
0695:                    int minorCode, String string1) throws Exception {
0696:
0697:                Object[] args = { string1 };
0698:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0699:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0700:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
0701:
0702:            } // reportRecoverableXMLError(int,int,String)
0703:
0704:            /** Report a recoverable xml error. */
0705:            protected void reportRecoverableXMLError(int majorCode,
0706:                    int minorCode, String string1, String string2)
0707:                    throws Exception {
0708:
0709:                Object[] args = { string1, string2 };
0710:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0711:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0712:                        XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
0713:
0714:            } // reportRecoverableXMLError(int,int,String,String)
0715:
0716:            private void reportFatalXMLError(int majorCode, int minorCode)
0717:                    throws Exception {
0718:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0719:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, null,
0720:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0721:            }
0722:
0723:            private void reportFatalXMLError(int majorCode, int minorCode,
0724:                    int stringIndex1) throws Exception {
0725:                Object[] args = { fStringPool.toString(stringIndex1) };
0726:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0727:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0728:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0729:            }
0730:
0731:            private void reportFatalXMLError(int majorCode, int minorCode,
0732:                    String string1) throws Exception {
0733:                Object[] args = { string1 };
0734:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0735:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0736:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0737:            }
0738:
0739:            private void reportFatalXMLError(int majorCode, int minorCode,
0740:                    int stringIndex1, int stringIndex2) throws Exception {
0741:                Object[] args = { fStringPool.toString(stringIndex1),
0742:                        fStringPool.toString(stringIndex2) };
0743:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0744:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0745:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0746:            }
0747:
0748:            private void reportFatalXMLError(int majorCode, int minorCode,
0749:                    String string1, String string2) throws Exception {
0750:                Object[] args = { string1, string2 };
0751:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0752:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0753:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0754:            }
0755:
0756:            private void reportFatalXMLError(int majorCode, int minorCode,
0757:                    String string1, String string2, String string3)
0758:                    throws Exception {
0759:                Object[] args = { string1, string2, string3 };
0760:                fErrorReporter.reportError(fErrorReporter.getLocator(),
0761:                        XMLMessages.XML_DOMAIN, majorCode, minorCode, args,
0762:                        XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
0763:            }
0764:
0765:            private void abortMarkup(int majorCode, int minorCode)
0766:                    throws Exception {
0767:                reportFatalXMLError(majorCode, minorCode);
0768:                skipPastEndOfCurrentMarkup();
0769:            }
0770:
0771:            private void abortMarkup(int majorCode, int minorCode,
0772:                    int stringIndex1) throws Exception {
0773:                reportFatalXMLError(majorCode, minorCode, stringIndex1);
0774:                skipPastEndOfCurrentMarkup();
0775:            }
0776:
0777:            private void abortMarkup(int majorCode, int minorCode,
0778:                    String string1) throws Exception {
0779:                reportFatalXMLError(majorCode, minorCode, string1);
0780:                skipPastEndOfCurrentMarkup();
0781:            }
0782:
0783:            private void abortMarkup(int majorCode, int minorCode,
0784:                    int stringIndex1, int stringIndex2) throws Exception {
0785:                reportFatalXMLError(majorCode, minorCode, stringIndex1,
0786:                        stringIndex2);
0787:                skipPastEndOfCurrentMarkup();
0788:            }
0789:
0790:            private void skipPastEndOfCurrentMarkup() throws Exception {
0791:                fEntityReader.skipToChar('>');
0792:                if (fEntityReader.lookingAtChar('>', true))
0793:                    decreaseMarkupDepth();
0794:            }
0795:
0796:            //
0797:            //
0798:            //
0799:            static private final int SCANNER_STATE_INVALID = -1;
0800:            static private final int SCANNER_STATE_END_OF_INPUT = 0;
0801:            static private final int SCANNER_STATE_DOCTYPEDECL = 50;
0802:            static private final int SCANNER_STATE_MARKUP_DECL = 51;
0803:            static private final int SCANNER_STATE_TEXTDECL = 53;
0804:            static private final int SCANNER_STATE_COMMENT = 54;
0805:            static private final int SCANNER_STATE_PI = 55;
0806:            static private final int SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE = 56;
0807:            static private final int SCANNER_STATE_CONTENTSPEC = 57;
0808:            static private final int SCANNER_STATE_ENTITY_VALUE = 58;
0809:            static private final int SCANNER_STATE_SYSTEMLITERAL = 59;
0810:            static private final int SCANNER_STATE_PUBIDLITERAL = 60;
0811:
0812:            private int setScannerState(int scannerState) {
0813:                int prevState = fScannerState;
0814:                fScannerState = scannerState;
0815:                return prevState;
0816:            }
0817:
0818:            private int getScannerState() {
0819:                return fScannerState;
0820:            }
0821:
0822:            private void restoreScannerState(int scannerState) {
0823:                if (fScannerState != SCANNER_STATE_END_OF_INPUT)
0824:                    fScannerState = scannerState;
0825:            }
0826:
0827:            /**
0828:             * Change readers
0829:             *
0830:             * @param nextReader the new reader that the scanner will use
0831:             * @param nextReaderId id of the reader to change to
0832:             * @exception throws java.lang.Exception
0833:             */
0834:            public void readerChange(XMLEntityHandler.EntityReader nextReader,
0835:                    int nextReaderId) throws Exception {
0836:                fEntityReader = nextReader;
0837:                fReaderId = nextReaderId;
0838:                if (fScannerState == SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE) {
0839:                    fDefaultAttValueOffset = fEntityReader.currentOffset();
0840:                    fDefaultAttValueMark = fDefaultAttValueOffset;
0841:                } else if (fScannerState == SCANNER_STATE_ENTITY_VALUE) {
0842:                    fEntityValueMark = fEntityReader.currentOffset();
0843:                }
0844:            }
0845:
0846:            /**
0847:             * Handle the end of input
0848:             *
0849:             * @param entityName the handle in the string pool of the name of the entity which has reached end of input
0850:             * @param moreToFollow if true, there is still input left to process in other readers
0851:             * @exception java.lang.Exception
0852:             */
0853:            public void endOfInput(int entityNameIndex, boolean moreToFollow)
0854:                    throws Exception {
0855:                if (fValidationEnabled) {
0856:                    int readerDepth = fEntityHandler.getReaderDepth();
0857:                    if (getReadingContentSpec()) {
0858:                        int parenDepth = parenDepth();
0859:                        if (readerDepth != parenDepth) {
0860:                            reportRecoverableXMLError(
0861:                                    XMLMessages.MSG_IMPROPER_GROUP_NESTING,
0862:                                    XMLMessages.VC_PROPER_GROUP_PE_NESTING,
0863:                                    entityNameIndex);
0864:                        }
0865:                    } else {
0866:                        int markupDepth = markupDepth();
0867:                        if (readerDepth != markupDepth) {
0868:                            reportRecoverableXMLError(
0869:                                    XMLMessages.MSG_IMPROPER_DECLARATION_NESTING,
0870:                                    XMLMessages.VC_PROPER_DECLARATION_PE_NESTING,
0871:                                    entityNameIndex);
0872:                        }
0873:                    }
0874:                }
0875:                //REVISIT, why are we doing this?
0876:                moreToFollow = fReaderId != fExternalSubsetReader;
0877:
0878:                //      System.out.println("current Scanner state " + getScannerState() +","+ fScannerState + moreToFollow);
0879:                switch (fScannerState) {
0880:                case SCANNER_STATE_INVALID:
0881:                    throw new RuntimeException(
0882:                            "FWK004 XMLDTDScanner.endOfInput: cannot happen: 2"
0883:                                    + "\n2");
0884:                case SCANNER_STATE_END_OF_INPUT:
0885:                    break;
0886:                case SCANNER_STATE_MARKUP_DECL:
0887:                    if (!moreToFollow && fIncludeSectDepth > 0) {
0888:                        reportFatalXMLError(
0889:                                XMLMessages.MSG_INCLUDESECT_UNTERMINATED,
0890:                                XMLMessages.P62_UNTERMINATED);
0891:                    }
0892:                    break;
0893:                case SCANNER_STATE_DOCTYPEDECL:
0894:                    throw new RuntimeException(
0895:                            "FWK004 XMLDTDScanner.endOfInput: cannot happen: 2.5"
0896:                                    + "\n2.5");
0897:                    //            break;
0898:                case SCANNER_STATE_TEXTDECL:
0899:                    // REVISIT            reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
0900:                    break;
0901:                case SCANNER_STATE_SYSTEMLITERAL:
0902:                    if (!moreToFollow) {
0903:                        reportFatalXMLError(
0904:                                XMLMessages.MSG_SYSTEMID_UNTERMINATED,
0905:                                XMLMessages.P11_UNTERMINATED);
0906:                    } else {
0907:                        // REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
0908:                    }
0909:                    break;
0910:                case SCANNER_STATE_PUBIDLITERAL:
0911:                    if (!moreToFollow) {
0912:                        reportFatalXMLError(
0913:                                XMLMessages.MSG_PUBLICID_UNTERMINATED,
0914:                                XMLMessages.P12_UNTERMINATED);
0915:                    } else {
0916:                        // REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
0917:                    }
0918:                    break;
0919:                case SCANNER_STATE_COMMENT:
0920:                    if (!moreToFollow && !getReadingExternalEntity()) {
0921:                        reportFatalXMLError(
0922:                                XMLMessages.MSG_COMMENT_UNTERMINATED,
0923:                                XMLMessages.P15_UNTERMINATED);
0924:                    } else {
0925:                        //
0926:                        // REVISIT - HACK !!!  code changed to pass incorrect OASIS test 'invalid--001'
0927:                        //  Uncomment the next line to conform to the spec...
0928:                        //
0929:                        //reportFatalXMLError(XMLMessages.MSG_COMMENT_NOT_IN_ONE_ENTITY,
0930:                        //                    XMLMessages.P78_NOT_WELLFORMED);
0931:                    }
0932:                    break;
0933:                case SCANNER_STATE_PI:
0934:                    if (!moreToFollow) {
0935:                        reportFatalXMLError(XMLMessages.MSG_PI_UNTERMINATED,
0936:                                XMLMessages.P16_UNTERMINATED);
0937:                    } else {
0938:                        reportFatalXMLError(
0939:                                XMLMessages.MSG_PI_NOT_IN_ONE_ENTITY,
0940:                                XMLMessages.P78_NOT_WELLFORMED);
0941:                    }
0942:                    break;
0943:                case SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE:
0944:                    if (!moreToFollow) {
0945:                        reportFatalXMLError(
0946:                                XMLMessages.MSG_ATTRIBUTE_VALUE_UNTERMINATED,
0947:                                XMLMessages.P10_UNTERMINATED,
0948:                                fDefaultAttValueElementType,
0949:                                fDefaultAttValueAttrName);
0950:                    } else if (fReaderId == fDefaultAttValueReader) {
0951:                        // REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
0952:                    } else {
0953:                        fEntityReader.append(fLiteralData,
0954:                                fDefaultAttValueMark, fDefaultAttValueOffset
0955:                                        - fDefaultAttValueMark);
0956:                    }
0957:                    break;
0958:                case SCANNER_STATE_CONTENTSPEC:
0959:                    break;
0960:                case SCANNER_STATE_ENTITY_VALUE:
0961:                    if (fReaderId == fEntityValueReader) {
0962:                        // REVISIT                reportFatalXMLError(XMLMessages.MSG_ATTVAL0);
0963:                    } else {
0964:                        fEntityReader.append(fLiteralData, fEntityValueMark,
0965:                                fEntityReader.currentOffset()
0966:                                        - fEntityValueMark);
0967:                    }
0968:                    break;
0969:                default:
0970:                    throw new RuntimeException(
0971:                            "FWK004 XMLDTDScanner.endOfInput: cannot happen: 3"
0972:                                    + "\n3");
0973:                }
0974:                if (!moreToFollow) {
0975:                    setScannerState(SCANNER_STATE_END_OF_INPUT);
0976:                }
0977:            }
0978:
0979:            //
0980:            // [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
0981:            //
0982:            private int scanCharRef() throws Exception {
0983:                int valueOffset = fEntityReader.currentOffset();
0984:                boolean hex = fEntityReader.lookingAtChar('x', true);
0985:                int num = fEntityReader.scanCharRef(hex);
0986:                if (num < 0) {
0987:                    switch (num) {
0988:                    case XMLEntityHandler.CHARREF_RESULT_SEMICOLON_REQUIRED:
0989:                        reportFatalXMLError(
0990:                                XMLMessages.MSG_SEMICOLON_REQUIRED_IN_CHARREF,
0991:                                XMLMessages.P66_SEMICOLON_REQUIRED);
0992:                        return -1;
0993:                    case XMLEntityHandler.CHARREF_RESULT_INVALID_CHAR:
0994:                        int majorCode = hex ? XMLMessages.MSG_HEXDIGIT_REQUIRED_IN_CHARREF
0995:                                : XMLMessages.MSG_DIGIT_REQUIRED_IN_CHARREF;
0996:                        int minorCode = hex ? XMLMessages.P66_HEXDIGIT_REQUIRED
0997:                                : XMLMessages.P66_DIGIT_REQUIRED;
0998:                        reportFatalXMLError(majorCode, minorCode);
0999:                        return -1;
1000:                    case XMLEntityHandler.CHARREF_RESULT_OUT_OF_RANGE:
1001:                        num = 0x110000; // this will cause the right error to be reported below...
1002:                        break;
1003:                    }
1004:                }
1005:                //
1006:                //  [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF]        // any Unicode character, excluding the
1007:                //               | [#xE000-#xFFFD] | [#x10000-#x10FFFF] // surrogate blocks, FFFE, and FFFF.
1008:                //
1009:                if (num < 0x20) {
1010:                    if (num == 0x09 || num == 0x0A || num == 0x0D) {
1011:                        return num;
1012:                    }
1013:                } else if (num <= 0xD7FF
1014:                        || (num >= 0xE000 && (num <= 0xFFFD || (num >= 0x10000 && num <= 0x10FFFF)))) {
1015:                    return num;
1016:                }
1017:                int valueLength = fEntityReader.currentOffset() - valueOffset;
1018:                reportFatalXMLError(XMLMessages.MSG_INVALID_CHARREF,
1019:                        XMLMessages.WFC_LEGAL_CHARACTER, fEntityReader
1020:                                .addString(valueOffset, valueLength));
1021:                return -1;
1022:            }
1023:
1024:            //
1025:            // From the standard:
1026:            //
1027:            // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
1028:            //
1029:            // Called after scanning past '<!--'
1030:            //
1031:            private void scanComment() throws Exception {
1032:                int commentOffset = fEntityReader.currentOffset();
1033:                boolean sawDashDash = false;
1034:                int previousState = setScannerState(SCANNER_STATE_COMMENT);
1035:                while (fScannerState == SCANNER_STATE_COMMENT) {
1036:                    if (fEntityReader.lookingAtChar('-', false)) {
1037:                        int nextEndOffset = fEntityReader.currentOffset();
1038:                        int endOffset = 0;
1039:                        fEntityReader.lookingAtChar('-', true);
1040:                        int offset = fEntityReader.currentOffset();
1041:                        int count = 1;
1042:                        while (fEntityReader.lookingAtChar('-', true)) {
1043:                            count++;
1044:                            endOffset = nextEndOffset;
1045:                            nextEndOffset = offset;
1046:                            offset = fEntityReader.currentOffset();
1047:                        }
1048:                        if (count > 1) {
1049:                            if (fEntityReader.lookingAtChar('>', true)) {
1050:                                if (!sawDashDash && count > 2) {
1051:                                    reportFatalXMLError(
1052:                                            XMLMessages.MSG_DASH_DASH_IN_COMMENT,
1053:                                            XMLMessages.P15_DASH_DASH);
1054:                                    sawDashDash = true;
1055:                                }
1056:                                decreaseMarkupDepth();
1057:                                int comment = fEntityReader.addString(
1058:                                        commentOffset, endOffset
1059:                                                - commentOffset);
1060:                                fDTDGrammar.callComment(comment);
1061:                                if (fDTDHandler != null) {
1062:                                    fDTDHandler.comment(comment);
1063:                                }
1064:                                restoreScannerState(previousState);
1065:                                return;
1066:                            } else if (!sawDashDash) {
1067:                                reportFatalXMLError(
1068:                                        XMLMessages.MSG_DASH_DASH_IN_COMMENT,
1069:                                        XMLMessages.P15_DASH_DASH);
1070:                                sawDashDash = true;
1071:                            }
1072:                        }
1073:                    } else {
1074:                        if (!fEntityReader.lookingAtValidChar(true)) {
1075:                            int invChar = fEntityReader.scanInvalidChar();
1076:                            if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
1077:                                if (invChar >= 0) {
1078:                                    reportFatalXMLError(
1079:                                            XMLMessages.MSG_INVALID_CHAR_IN_COMMENT,
1080:                                            XMLMessages.P15_INVALID_CHARACTER,
1081:                                            Integer.toHexString(invChar));
1082:                                }
1083:                            }
1084:                        }
1085:                    }
1086:                }
1087:                restoreScannerState(previousState);
1088:            }
1089:
1090:            //
1091:            // From the standard:
1092:            //
1093:            // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
1094:            // [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
1095:            //
1096:            private void scanPI(int piTarget) throws Exception {
1097:                String piTargetString = fStringPool.toString(piTarget);
1098:                if (piTargetString.length() == 3
1099:                        && (piTargetString.charAt(0) == 'X' || piTargetString
1100:                                .charAt(0) == 'x')
1101:                        && (piTargetString.charAt(1) == 'M' || piTargetString
1102:                                .charAt(1) == 'm')
1103:                        && (piTargetString.charAt(2) == 'L' || piTargetString
1104:                                .charAt(2) == 'l')) {
1105:                    abortMarkup(XMLMessages.MSG_RESERVED_PITARGET,
1106:                            XMLMessages.P17_RESERVED_PITARGET);
1107:                    return;
1108:                }
1109:                int prevState = setScannerState(SCANNER_STATE_PI);
1110:                int piDataOffset = -1;
1111:                int piDataLength = 0;
1112:                if (!fEntityReader.lookingAtSpace(true)) {
1113:                    if (!fEntityReader.lookingAtChar('?', true)
1114:                            || !fEntityReader.lookingAtChar('>', true)) {
1115:                        if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
1116:                            abortMarkup(XMLMessages.MSG_SPACE_REQUIRED_IN_PI,
1117:                                    XMLMessages.P16_WHITESPACE_REQUIRED);
1118:                            restoreScannerState(prevState);
1119:                        }
1120:                        return;
1121:                    }
1122:                    decreaseMarkupDepth();
1123:                    restoreScannerState(prevState);
1124:                } else {
1125:                    fEntityReader.skipPastSpaces();
1126:                    piDataOffset = fEntityReader.currentOffset();
1127:                    while (fScannerState == SCANNER_STATE_PI) {
1128:                        while (fEntityReader.lookingAtChar('?', false)) {
1129:                            int offset = fEntityReader.currentOffset();
1130:                            fEntityReader.lookingAtChar('?', true);
1131:                            if (fEntityReader.lookingAtChar('>', true)) {
1132:                                piDataLength = offset - piDataOffset;
1133:                                decreaseMarkupDepth();
1134:                                restoreScannerState(prevState);
1135:                                break;
1136:                            }
1137:                        }
1138:                        if (fScannerState != SCANNER_STATE_PI)
1139:                            break;
1140:                        if (!fEntityReader.lookingAtValidChar(true)) {
1141:                            int invChar = fEntityReader.scanInvalidChar();
1142:                            if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
1143:                                if (invChar >= 0) {
1144:                                    reportFatalXMLError(
1145:                                            XMLMessages.MSG_INVALID_CHAR_IN_PI,
1146:                                            XMLMessages.P16_INVALID_CHARACTER,
1147:                                            Integer.toHexString(invChar));
1148:                                }
1149:                                skipPastEndOfCurrentMarkup();
1150:                                restoreScannerState(prevState);
1151:                            }
1152:                            return;
1153:                        }
1154:                    }
1155:                }
1156:                int piData = piDataLength == 0 ? StringPool.EMPTY_STRING
1157:                        : fEntityReader.addString(piDataOffset, piDataLength);
1158:                fDTDGrammar.callProcessingInstruction(piTarget, piData);
1159:                if (fDTDHandler != null) {
1160:                    fDTDHandler.processingInstruction(piTarget, piData);
1161:                }
1162:            }
1163:
1164:            //
1165:            // From the standard:
1166:            //
1167:            // [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S?
1168:            //                      ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
1169:            // [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl
1170:            //                     | NotationDecl | PI | Comment
1171:            //
1172:            // Called after scanning '<!DOCTYPE'
1173:            //
1174:            /**
1175:             * This routine is called after the &lt;!DOCTYPE portion of a DOCTYPE
1176:             * line has been called.  scanDocTypeDecl goes onto scan the rest of the DOCTYPE
1177:             * decl.  If an internal DTD subset exists, it is scanned. If an external DTD
1178:             * subset exists, scanDocTypeDecl sets up the state necessary to process it.
1179:             *
1180:             * @return true if successful
1181:             * @exception java.lang.Exception
1182:             */
1183:            public boolean scanDoctypeDecl() throws Exception {
1184:                //System.out.println("XMLDTDScanner#scanDoctypeDecl()");
1185:
1186:                fDTDGrammar = new DTDGrammar(fStringPool);
1187:                fDTDGrammar.callStartDTD();
1188:                increaseMarkupDepth();
1189:                fEntityReader = fEntityHandler.getEntityReader();
1190:                fReaderId = fEntityHandler.getReaderId();
1191:                fDoctypeReader = fReaderId;
1192:                setScannerState(SCANNER_STATE_DOCTYPEDECL);
1193:                if (!fEntityReader.lookingAtSpace(true)) {
1194:                    abortMarkup(
1195:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL,
1196:                            XMLMessages.P28_SPACE_REQUIRED);
1197:                    return false;
1198:                }
1199:                fEntityReader.skipPastSpaces();
1200:                scanElementType(fEntityReader, ' ', fElementQName);
1201:                if (fElementQName.rawname == -1) {
1202:                    abortMarkup(XMLMessages.MSG_ROOT_ELEMENT_TYPE_REQUIRED,
1203:                            XMLMessages.P28_ROOT_ELEMENT_TYPE_REQUIRED);
1204:                    return false;
1205:                }
1206:                boolean lbrkt;
1207:                boolean scanExternalSubset = false;
1208:                int publicId = -1;
1209:                int systemId = -1;
1210:                if (fEntityReader.lookingAtSpace(true)) {
1211:                    fEntityReader.skipPastSpaces();
1212:                    if (!(lbrkt = fEntityReader.lookingAtChar('[', true))
1213:                            && !fEntityReader.lookingAtChar('>', false)) {
1214:                        if (!scanExternalID(false)) {
1215:                            skipPastEndOfCurrentMarkup();
1216:                            return false;
1217:                        }
1218:                        if (fValidationEnabled || fLoadExternalDTD) {
1219:                            scanExternalSubset = true;
1220:                        }
1221:                        publicId = fPubidLiteral;
1222:                        systemId = fSystemLiteral;
1223:                        fEntityReader.skipPastSpaces();
1224:                        lbrkt = fEntityReader.lookingAtChar('[', true);
1225:                    }
1226:                } else
1227:                    lbrkt = fEntityReader.lookingAtChar('[', true);
1228:                fDTDGrammar.doctypeDecl(fElementQName, publicId, systemId);
1229:                if (fDTDHandler != null) {
1230:                    fDTDHandler.startDTD(fElementQName, publicId, systemId);
1231:                }
1232:                if (lbrkt) {
1233:                    scanDecls(false);
1234:                    fEntityReader.skipPastSpaces();
1235:                }
1236:                if (!fEntityReader.lookingAtChar('>', true)) {
1237:                    if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
1238:                        abortMarkup(XMLMessages.MSG_DOCTYPEDECL_UNTERMINATED,
1239:                                XMLMessages.P28_UNTERMINATED,
1240:                                fElementQName.rawname);
1241:                    }
1242:                    return false;
1243:                }
1244:
1245:                decreaseMarkupDepth();
1246:
1247:                //System.out.println("  scanExternalSubset: "+scanExternalSubset);
1248:                if (scanExternalSubset) {
1249:                    ((DefaultEntityHandler) fEntityHandler)
1250:                            .startReadingFromExternalSubset(fStringPool
1251:                                    .toString(publicId), fStringPool
1252:                                    .toString(systemId), markupDepth());
1253:                    fDTDGrammar.startReadingFromExternalSubset(publicId,
1254:                            systemId);
1255:                } else {
1256:                    fDTDGrammar.callEndDTD();
1257:                    if (fDTDHandler != null) {
1258:                        fDTDHandler.endDTD();
1259:                    }
1260:                }
1261:
1262:                fGrammarResolver.putGrammar("", fDTDGrammar);
1263:
1264:                return true;
1265:            }
1266:
1267:            //
1268:            // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
1269:            //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
1270:            // [83] PublicID ::= 'PUBLIC' S PubidLiteral
1271:            //
1272:            private boolean scanExternalID(boolean scanPublicID)
1273:                    throws Exception {
1274:                fSystemLiteral = -1;
1275:                fPubidLiteral = -1;
1276:                int offset = fEntityReader.currentOffset();
1277:                if (fEntityReader.skippedString(system_string)) {
1278:                    if (!fEntityReader.lookingAtSpace(true)) {
1279:                        reportFatalXMLError(
1280:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_SYSTEMLITERAL_IN_EXTERNALID,
1281:                                XMLMessages.P75_SPACE_REQUIRED);
1282:                        return false;
1283:                    }
1284:                    fEntityReader.skipPastSpaces();
1285:                    if (getReadingExternalEntity() == true) { //Are we in external subset?
1286:                        checkForPEReference(false);//If so Check for PE Ref
1287:                    }
1288:                    return scanSystemLiteral();
1289:                }
1290:                if (fEntityReader.skippedString(public_string)) {
1291:                    if (!fEntityReader.lookingAtSpace(true)) {
1292:                        reportFatalXMLError(
1293:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_PUBIDLITERAL_IN_EXTERNALID,
1294:                                XMLMessages.P75_SPACE_REQUIRED);
1295:                        return false;
1296:                    }
1297:                    fEntityReader.skipPastSpaces();
1298:                    if (!scanPubidLiteral())
1299:                        return false;
1300:                    if (scanPublicID) {
1301:                        //
1302:                        // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
1303:                        //
1304:                        if (!fEntityReader.lookingAtSpace(true))
1305:                            return true; // no S, not an ExternalID
1306:                        fEntityReader.skipPastSpaces();
1307:                        if (fEntityReader.lookingAtChar('>', false)) // matches end of NotationDecl
1308:                            return true;
1309:                    } else {
1310:                        if (!fEntityReader.lookingAtSpace(true)) {
1311:                            reportFatalXMLError(
1312:                                    XMLMessages.MSG_SPACE_REQUIRED_AFTER_PUBIDLITERAL_IN_EXTERNALID,
1313:                                    XMLMessages.P75_SPACE_REQUIRED);
1314:                            return false;
1315:                        }
1316:                        fEntityReader.skipPastSpaces();
1317:                    }
1318:                    return scanSystemLiteral();
1319:                }
1320:                reportFatalXMLError(XMLMessages.MSG_EXTERNALID_REQUIRED,
1321:                        XMLMessages.P75_INVALID);
1322:                return false;
1323:            }
1324:
1325:            //
1326:            // [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
1327:            //
1328:            // REVISIT - need to look into uri escape mechanism for non-ascii characters.
1329:            //
1330:            private boolean scanSystemLiteral() throws Exception {
1331:                boolean single;
1332:                if (!(single = fEntityReader.lookingAtChar('\'', true))
1333:                        && !fEntityReader.lookingAtChar('\"', true)) {
1334:                    reportFatalXMLError(
1335:                            XMLMessages.MSG_QUOTE_REQUIRED_IN_SYSTEMID,
1336:                            XMLMessages.P11_QUOTE_REQUIRED);
1337:                    return false;
1338:                }
1339:                int prevState = setScannerState(SCANNER_STATE_SYSTEMLITERAL);
1340:                int offset = fEntityReader.currentOffset();
1341:                char qchar = single ? '\'' : '\"';
1342:                boolean dataok = true;
1343:                boolean fragment = false;
1344:                while (!fEntityReader.lookingAtChar(qchar, false)) {
1345:                    //ericye
1346:                    //System.out.println("XMLDTDScanner#scanDoctypeDecl() 3333333, "+fReaderId+", " + fScannerState+", " +fExternalSubsetReader);
1347:                    if (fEntityReader.lookingAtChar('#', true)) {
1348:                        fragment = true;
1349:                    } else if (!fEntityReader.lookingAtValidChar(true)) {
1350:                        //System.out.println("XMLDTDScanner#scanDoctypeDecl() 555555 scan state: " + fScannerState);
1351:                        dataok = false;
1352:                        int invChar = fEntityReader.scanInvalidChar();
1353:                        if (fScannerState == SCANNER_STATE_END_OF_INPUT)
1354:                            return false;
1355:                        if (invChar >= 0) {
1356:                            reportFatalXMLError(
1357:                                    XMLMessages.MSG_INVALID_CHAR_IN_SYSTEMID,
1358:                                    XMLMessages.P11_INVALID_CHARACTER, Integer
1359:                                            .toHexString(invChar));
1360:                        }
1361:                    }
1362:                }
1363:                if (dataok) {
1364:                    fSystemLiteral = fEntityReader.addString(offset,
1365:                            fEntityReader.currentOffset() - offset);
1366:                    if (fragment) {
1367:                        // NOTE: RECOVERABLE ERROR
1368:                        Object[] args = { fStringPool.toString(fSystemLiteral) };
1369:                        fErrorReporter.reportError(fErrorReporter.getLocator(),
1370:                                XMLMessages.XML_DOMAIN,
1371:                                XMLMessages.MSG_URI_FRAGMENT_IN_SYSTEMID,
1372:                                XMLMessages.P11_URI_FRAGMENT, args,
1373:                                XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1374:                    }
1375:                }
1376:                fEntityReader.lookingAtChar(qchar, true);
1377:                restoreScannerState(prevState);
1378:                return dataok;
1379:            }
1380:
1381:            //
1382:            // [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
1383:            // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
1384:            //
1385:            private boolean scanPubidLiteral() throws Exception {
1386:                boolean single;
1387:                if (!(single = fEntityReader.lookingAtChar('\'', true))
1388:                        && !fEntityReader.lookingAtChar('\"', true)) {
1389:                    reportFatalXMLError(
1390:                            XMLMessages.MSG_QUOTE_REQUIRED_IN_PUBLICID,
1391:                            XMLMessages.P12_QUOTE_REQUIRED);
1392:                    return false;
1393:                }
1394:                char qchar = single ? '\'' : '\"';
1395:                int prevState = setScannerState(SCANNER_STATE_PUBIDLITERAL);
1396:                boolean dataok = true;
1397:                while (true) {
1398:                    if (fEntityReader.lookingAtChar((char) 0x09, true)) {
1399:                        dataok = false;
1400:                        reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
1401:                                XMLMessages.P12_INVALID_CHARACTER, "9");
1402:                    }
1403:                    if (!fEntityReader.lookingAtSpace(true))
1404:                        break;
1405:                }
1406:                int offset = fEntityReader.currentOffset();
1407:                int dataOffset = fLiteralData.length();
1408:                int toCopy = offset;
1409:                while (true) {
1410:                    if (fEntityReader.lookingAtChar(qchar, true)) {
1411:                        if (dataok && offset - toCopy > 0)
1412:                            fEntityReader.append(fLiteralData, toCopy, offset
1413:                                    - toCopy);
1414:                        break;
1415:                    }
1416:                    if (fEntityReader.lookingAtChar((char) 0x09, true)) {
1417:                        dataok = false;
1418:                        reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
1419:                                XMLMessages.P12_INVALID_CHARACTER, "9");
1420:                        continue;
1421:                    }
1422:                    if (fEntityReader.lookingAtSpace(true)) {
1423:                        if (dataok && offset - toCopy > 0)
1424:                            fEntityReader.append(fLiteralData, toCopy, offset
1425:                                    - toCopy);
1426:                        while (true) {
1427:                            if (fEntityReader.lookingAtChar((char) 0x09, true)) {
1428:                                dataok = false;
1429:                                reportFatalXMLError(
1430:                                        XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
1431:                                        XMLMessages.P12_INVALID_CHARACTER, "9");
1432:                                break;
1433:                            } else if (!fEntityReader.lookingAtSpace(true)) {
1434:                                break;
1435:                            }
1436:                        }
1437:                        if (fEntityReader.lookingAtChar(qchar, true))
1438:                            break;
1439:                        if (dataok) {
1440:                            fLiteralData.append(' ');
1441:                            offset = fEntityReader.currentOffset();
1442:                            toCopy = offset;
1443:                        }
1444:                        continue;
1445:                    }
1446:                    if (!fEntityReader.lookingAtValidChar(true)) {
1447:                        int invChar = fEntityReader.scanInvalidChar();
1448:                        if (fScannerState == SCANNER_STATE_END_OF_INPUT)
1449:                            return false;
1450:                        dataok = false;
1451:                        if (invChar >= 0) {
1452:                            reportFatalXMLError(
1453:                                    XMLMessages.MSG_INVALID_CHAR_IN_PUBLICID,
1454:                                    XMLMessages.P12_INVALID_CHARACTER, Integer
1455:                                            .toHexString(invChar));
1456:                        }
1457:                    }
1458:                    if (dataok)
1459:                        offset = fEntityReader.currentOffset();
1460:                }
1461:                if (dataok) {
1462:                    int dataLength = fLiteralData.length() - dataOffset;
1463:                    fPubidLiteral = fLiteralData.addString(dataOffset,
1464:                            dataLength);
1465:                    String publicId = fStringPool.toString(fPubidLiteral);
1466:                    int invCharIndex = validPublicId(publicId);
1467:                    if (invCharIndex >= 0) {
1468:                        reportFatalXMLError(XMLMessages.MSG_PUBIDCHAR_ILLEGAL,
1469:                                XMLMessages.P12_INVALID_CHARACTER, Integer
1470:                                        .toHexString(publicId
1471:                                                .charAt(invCharIndex)));
1472:                        return false;
1473:                    }
1474:                }
1475:                restoreScannerState(prevState);
1476:                return dataok;
1477:            }
1478:
1479:            //
1480:            // [??] intSubsetDecl = '[' (markupdecl | PEReference | S)* ']'
1481:            //
1482:            // [31] extSubsetDecl ::= ( markupdecl | conditionalSect | PEReference | S )*
1483:            // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
1484:            //
1485:            // [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl
1486:            //                     | NotationDecl | PI | Comment
1487:            //
1488:            // [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
1489:            //
1490:            // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
1491:            //
1492:            // [70] EntityDecl ::= GEDecl | PEDecl
1493:            // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
1494:            // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
1495:            //
1496:            // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
1497:            //
1498:            // [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
1499:            //
1500:            // [15] Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
1501:            //
1502:            // [61] conditionalSect ::= includeSect | ignoreSect
1503:            // [62] includeSect ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
1504:            // [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
1505:            // [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
1506:            // [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
1507:            //
1508:            /**
1509:             * Scan markup declarations
1510:             *
1511:             * @param extSubset true if the scanner is scanning an external subset, false
1512:             *                  if it is scanning an internal subset
1513:             * @exception java.lang.Exception
1514:             */
1515:            public void scanDecls(boolean extSubset) throws Exception {
1516:                int subsetOffset = fEntityReader.currentOffset();
1517:                if (extSubset)
1518:                    fExternalSubsetReader = fReaderId;
1519:                fIncludeSectDepth = 0;
1520:                boolean parseTextDecl = extSubset;
1521:                int prevState = setScannerState(SCANNER_STATE_MARKUP_DECL);
1522:                while (fScannerState == SCANNER_STATE_MARKUP_DECL) {
1523:
1524:                    boolean newParseTextDecl = false;
1525:                    if (fEntityReader.lookingAtChar(']', false)
1526:                            && !getReadingExternalEntity()) {
1527:                        int subsetLength = fEntityReader.currentOffset()
1528:                                - subsetOffset;
1529:                        int internalSubset = fEntityReader.addString(
1530:                                subsetOffset, subsetLength);
1531:                        fDTDGrammar.internalSubset(internalSubset);
1532:                        if (fDTDHandler != null) {
1533:                            fDTDHandler.internalSubset(internalSubset);
1534:                        }
1535:                        fEntityReader.lookingAtChar(']', true);
1536:                        restoreScannerState(prevState);
1537:                        return;
1538:                    }
1539:                    if (fEntityReader.lookingAtChar('<', true)) {
1540:                        int olddepth = markupDepth();
1541:                        increaseMarkupDepth();
1542:                        if (fEntityReader.lookingAtChar('!', true)) {
1543:                            if (fEntityReader.lookingAtChar('-', true)) {
1544:                                if (fEntityReader.lookingAtChar('-', true)) {
1545:                                    scanComment();
1546:                                } else {
1547:                                    abortMarkup(
1548:                                            XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1549:                                            XMLMessages.P29_NOT_RECOGNIZED);
1550:                                }
1551:                            } else if (fEntityReader.lookingAtChar('[', true)
1552:                                    && getReadingExternalEntity()) {
1553:                                checkForPEReference(false);
1554:                                if (fEntityReader.skippedString(include_string)) {
1555:                                    checkForPEReference(false);
1556:                                    if (!fEntityReader.lookingAtChar('[', true)) {
1557:                                        abortMarkup(
1558:                                                XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1559:                                                XMLMessages.P29_NOT_RECOGNIZED);
1560:                                    } else {
1561:                                        fIncludeSectDepth++;
1562:                                    }
1563:                                } else if (fEntityReader
1564:                                        .skippedString(ignore_string)) {
1565:                                    checkForPEReference(false);
1566:                                    if (!fEntityReader.lookingAtChar('[', true)) {
1567:                                        abortMarkup(
1568:                                                XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1569:                                                XMLMessages.P29_NOT_RECOGNIZED);
1570:                                    } else
1571:                                        scanIgnoreSectContents();
1572:                                } else {
1573:                                    abortMarkup(
1574:                                            XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1575:                                            XMLMessages.P29_NOT_RECOGNIZED);
1576:                                }
1577:                            } else if (fEntityReader
1578:                                    .skippedString(element_string)) {
1579:                                scanElementDecl();
1580:                            } else if (fEntityReader
1581:                                    .skippedString(attlist_string))
1582:                                scanAttlistDecl();
1583:                            else if (fEntityReader.skippedString(entity_string))
1584:                                scanEntityDecl();
1585:                            else if (fEntityReader
1586:                                    .skippedString(notation_string))
1587:                                scanNotationDecl();
1588:                            else {
1589:                                abortMarkup(
1590:                                        XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1591:                                        XMLMessages.P29_NOT_RECOGNIZED);
1592:                            }
1593:                        } else if (fEntityReader.lookingAtChar('?', true)) {
1594:                            int piTarget = fEntityReader.scanName(' ');
1595:                            if (piTarget == -1) {
1596:                                abortMarkup(XMLMessages.MSG_PITARGET_REQUIRED,
1597:                                        XMLMessages.P16_REQUIRED);
1598:                            } else if ("xml".equals(fStringPool
1599:                                    .toString(piTarget))) {
1600:                                if (fEntityReader.lookingAtSpace(true)) {
1601:                                    if (parseTextDecl) { // a TextDecl looks like a PI with the target 'xml'
1602:                                        scanTextDecl();
1603:                                    } else {
1604:                                        abortMarkup(
1605:                                                XMLMessages.MSG_TEXTDECL_MUST_BE_FIRST,
1606:                                                XMLMessages.P30_TEXTDECL_MUST_BE_FIRST);
1607:                                    }
1608:                                } else { // a PI target matching 'xml'
1609:                                    abortMarkup(
1610:                                            XMLMessages.MSG_RESERVED_PITARGET,
1611:                                            XMLMessages.P17_RESERVED_PITARGET);
1612:                                }
1613:                            } else
1614:                                // PI
1615:                                scanPI(piTarget);
1616:                        } else {
1617:                            abortMarkup(
1618:                                    XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1619:                                    XMLMessages.P29_NOT_RECOGNIZED);
1620:                        }
1621:                    } else if (fEntityReader.lookingAtSpace(true)) {
1622:                        fEntityReader.skipPastSpaces();
1623:                    } else if (fEntityReader.lookingAtChar('%', true)) {
1624:                        //
1625:                        // [69] PEReference ::= '%' Name ';'
1626:                        //
1627:                        int nameOffset = fEntityReader.currentOffset();
1628:                        fEntityReader.skipPastName(';');
1629:                        int nameLength = fEntityReader.currentOffset()
1630:                                - nameOffset;
1631:                        if (nameLength == 0) {
1632:                            reportFatalXMLError(
1633:                                    XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
1634:                                    XMLMessages.P69_NAME_REQUIRED);
1635:                        } else if (!fEntityReader.lookingAtChar(';', true)) {
1636:                            reportFatalXMLError(
1637:                                    XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
1638:                                    XMLMessages.P69_SEMICOLON_REQUIRED,
1639:                                    fEntityReader.addString(nameOffset,
1640:                                            nameLength));
1641:                        } else {
1642:                            int peNameIndex = fEntityReader.addSymbol(
1643:                                    nameOffset, nameLength);
1644:                            newParseTextDecl = fEntityHandler
1645:                                    .startReadingFromEntity(
1646:                                            peNameIndex,
1647:                                            markupDepth(),
1648:                                            XMLEntityHandler.ENTITYREF_IN_DTD_AS_MARKUP);
1649:                        }
1650:                    } else if (fIncludeSectDepth > 0
1651:                            && fEntityReader.lookingAtChar(']', true)) {
1652:                        if (!fEntityReader.lookingAtChar(']', true)
1653:                                || !fEntityReader.lookingAtChar('>', true)) {
1654:                            abortMarkup(
1655:                                    XMLMessages.MSG_INCLUDESECT_UNTERMINATED,
1656:                                    XMLMessages.P62_UNTERMINATED);
1657:                        } else
1658:                            decreaseMarkupDepth();
1659:                        fIncludeSectDepth--;
1660:                    } else {
1661:                        if (!fEntityReader.lookingAtValidChar(false)) {
1662:                            int invChar = fEntityReader.scanInvalidChar();
1663:                            if (fScannerState == SCANNER_STATE_END_OF_INPUT)
1664:                                break;
1665:                            if (invChar >= 0) {
1666:                                if (!extSubset) {
1667:                                    reportFatalXMLError(
1668:                                            XMLMessages.MSG_INVALID_CHAR_IN_INTERNAL_SUBSET,
1669:                                            XMLMessages.P28_INVALID_CHARACTER,
1670:                                            Integer.toHexString(invChar));
1671:                                } else {
1672:                                    reportFatalXMLError(
1673:                                            XMLMessages.MSG_INVALID_CHAR_IN_EXTERNAL_SUBSET,
1674:                                            XMLMessages.P30_INVALID_CHARACTER,
1675:                                            Integer.toHexString(invChar));
1676:                                }
1677:                            }
1678:                        } else {
1679:                            reportFatalXMLError(
1680:                                    XMLMessages.MSG_MARKUP_NOT_RECOGNIZED_IN_DTD,
1681:                                    XMLMessages.P29_NOT_RECOGNIZED);
1682:                            fEntityReader.lookingAtValidChar(true);
1683:                        }
1684:                    }
1685:                    parseTextDecl = newParseTextDecl;
1686:                }
1687:                if (extSubset) {
1688:
1689:                    ((DefaultEntityHandler) fEntityHandler)
1690:                            .stopReadingFromExternalSubset();
1691:
1692:                    fDTDGrammar.stopReadingFromExternalSubset();
1693:                    fDTDGrammar.callEndDTD();
1694:                    if (fDTDHandler != null) {
1695:                        fDTDHandler.endDTD();
1696:                    }
1697:                    // REVISIT: What should the namspace URI of a DTD be?
1698:                    fGrammarResolver.putGrammar("", fDTDGrammar);
1699:                }
1700:            }
1701:
1702:            //
1703:            // [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
1704:            // [65] Ignore ::= Char* - (Char* ('<![' | ']]>') Char*)
1705:            //
1706:            private void scanIgnoreSectContents() throws Exception {
1707:                int initialDepth = ++fIncludeSectDepth;
1708:                while (true) {
1709:                    if (fEntityReader.lookingAtChar('<', true)) {
1710:                        //
1711:                        // These tests are split so that we handle cases like
1712:                        // '<<![' and '<!<![' which we might otherwise miss.
1713:                        //
1714:                        if (fEntityReader.lookingAtChar('!', true)
1715:                                && fEntityReader.lookingAtChar('[', true))
1716:                            fIncludeSectDepth++;
1717:                    } else if (fEntityReader.lookingAtChar(']', true)) {
1718:                        //
1719:                        // The same thing goes for ']<![' and '<]]>', etc.
1720:                        //
1721:                        if (fEntityReader.lookingAtChar(']', true)) {
1722:                            while (fEntityReader.lookingAtChar(']', true)) {
1723:                                /* empty loop body */
1724:                            }
1725:                            if (fEntityReader.lookingAtChar('>', true)) {
1726:                                if (fIncludeSectDepth-- == initialDepth) {
1727:                                    decreaseMarkupDepth();
1728:                                    return;
1729:                                }
1730:                            }
1731:                        }
1732:                    } else if (!fEntityReader.lookingAtValidChar(true)) {
1733:                        int invChar = fEntityReader.scanInvalidChar();
1734:                        if (fScannerState == SCANNER_STATE_END_OF_INPUT)
1735:                            return;
1736:                        if (invChar >= 0) {
1737:                            reportFatalXMLError(
1738:                                    XMLMessages.MSG_INVALID_CHAR_IN_IGNORESECT,
1739:                                    XMLMessages.P65_INVALID_CHARACTER, Integer
1740:                                            .toHexString(invChar));
1741:                        }
1742:                    }
1743:                }
1744:            }
1745:
1746:            //
1747:            // From the standard:
1748:            //
1749:            // [77] TextDecl ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
1750:            // [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
1751:            // [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' |  "'" EncName "'" )
1752:            // [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
1753:            //
1754:            private void scanTextDecl() throws Exception {
1755:                int version = -1;
1756:                int encoding = -1;
1757:                final int TEXTDECL_START = 0;
1758:                final int TEXTDECL_VERSION = 1;
1759:                final int TEXTDECL_ENCODING = 2;
1760:                final int TEXTDECL_FINISHED = 3;
1761:                int prevState = setScannerState(SCANNER_STATE_TEXTDECL);
1762:                int state = TEXTDECL_START;
1763:                do {
1764:                    fEntityReader.skipPastSpaces();
1765:                    int offset = fEntityReader.currentOffset();
1766:                    if (state == TEXTDECL_START
1767:                            && fEntityReader.skippedString(version_string)) {
1768:                        state = TEXTDECL_VERSION;
1769:                    } else if (fEntityReader.skippedString(encoding_string)) {
1770:                        state = TEXTDECL_ENCODING;
1771:                    } else {
1772:                        abortMarkup(XMLMessages.MSG_ENCODINGDECL_REQUIRED,
1773:                                XMLMessages.P77_ENCODINGDECL_REQUIRED);
1774:                        restoreScannerState(prevState);
1775:                        return;
1776:                    }
1777:                    int length = fEntityReader.currentOffset() - offset;
1778:                    fEntityReader.skipPastSpaces();
1779:                    if (!fEntityReader.lookingAtChar('=', true)) {
1780:                        int minorCode = state == TEXTDECL_VERSION ? XMLMessages.P24_EQ_REQUIRED
1781:                                : XMLMessages.P80_EQ_REQUIRED;
1782:                        abortMarkup(XMLMessages.MSG_EQ_REQUIRED_IN_TEXTDECL,
1783:                                minorCode, fEntityReader.addString(offset,
1784:                                        length));
1785:                        restoreScannerState(prevState);
1786:                        return;
1787:                    }
1788:                    fEntityReader.skipPastSpaces();
1789:                    int result = fEntityReader.scanStringLiteral();
1790:                    switch (result) {
1791:                    case XMLEntityHandler.STRINGLIT_RESULT_QUOTE_REQUIRED: {
1792:                        int minorCode = state == TEXTDECL_VERSION ? XMLMessages.P24_QUOTE_REQUIRED
1793:                                : XMLMessages.P80_QUOTE_REQUIRED;
1794:                        abortMarkup(XMLMessages.MSG_QUOTE_REQUIRED_IN_TEXTDECL,
1795:                                minorCode, fEntityReader.addString(offset,
1796:                                        length));
1797:                        restoreScannerState(prevState);
1798:                        return;
1799:                    }
1800:                    case XMLEntityHandler.STRINGLIT_RESULT_INVALID_CHAR:
1801:                        int invChar = fEntityReader.scanInvalidChar();
1802:                        if (fScannerState != SCANNER_STATE_END_OF_INPUT) {
1803:                            if (invChar >= 0) {
1804:                                int minorCode = state == TEXTDECL_VERSION ? XMLMessages.P26_INVALID_CHARACTER
1805:                                        : XMLMessages.P81_INVALID_CHARACTER;
1806:                                reportFatalXMLError(
1807:                                        XMLMessages.MSG_INVALID_CHAR_IN_TEXTDECL,
1808:                                        minorCode, Integer.toHexString(invChar));
1809:                            }
1810:                            skipPastEndOfCurrentMarkup();
1811:                            restoreScannerState(prevState);
1812:                        }
1813:                        return;
1814:                    default:
1815:                        break;
1816:                    }
1817:                    switch (state) {
1818:                    case TEXTDECL_VERSION:
1819:                        //
1820:                        // version="..."
1821:                        //
1822:                        version = result;
1823:                        String versionString = fStringPool.toString(version);
1824:                        if (!"1.0".equals(versionString)) {
1825:                            if (!validVersionNum(versionString)) {
1826:                                abortMarkup(
1827:                                        XMLMessages.MSG_VERSIONINFO_INVALID,
1828:                                        XMLMessages.P26_INVALID_VALUE,
1829:                                        versionString);
1830:                                restoreScannerState(prevState);
1831:                                return;
1832:                            }
1833:                            // NOTE: RECOVERABLE ERROR
1834:                            Object[] args = { versionString };
1835:                            fErrorReporter
1836:                                    .reportError(
1837:                                            fErrorReporter.getLocator(),
1838:                                            XMLMessages.XML_DOMAIN,
1839:                                            XMLMessages.MSG_VERSION_NOT_SUPPORTED,
1840:                                            XMLMessages.P26_NOT_SUPPORTED,
1841:                                            args,
1842:                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
1843:                            // REVISIT - hope it is a compatible version...
1844:                            // skipPastEndOfCurrentMarkup();
1845:                            // return;
1846:                        }
1847:                        if (!fEntityReader.lookingAtSpace(true)) {
1848:                            abortMarkup(
1849:                                    XMLMessages.MSG_SPACE_REQUIRED_IN_TEXTDECL,
1850:                                    XMLMessages.P80_WHITESPACE_REQUIRED);
1851:                            restoreScannerState(prevState);
1852:                            return;
1853:                        }
1854:                        break;
1855:                    case TEXTDECL_ENCODING:
1856:                        //
1857:                        // encoding = "..."
1858:                        //
1859:                        encoding = result;
1860:                        String encodingString = fStringPool.toString(encoding);
1861:                        if (!validEncName(encodingString)) {
1862:                            abortMarkup(XMLMessages.MSG_ENCODINGDECL_INVALID,
1863:                                    XMLMessages.P81_INVALID_VALUE,
1864:                                    encodingString);
1865:                            restoreScannerState(prevState);
1866:                            return;
1867:                        }
1868:                        fEntityReader.skipPastSpaces();
1869:                        state = TEXTDECL_FINISHED;
1870:                        break;
1871:                    }
1872:                } while (state != TEXTDECL_FINISHED);
1873:                if (!fEntityReader.lookingAtChar('?', true)
1874:                        || !fEntityReader.lookingAtChar('>', true)) {
1875:                    abortMarkup(XMLMessages.MSG_TEXTDECL_UNTERMINATED,
1876:                            XMLMessages.P77_UNTERMINATED);
1877:                    restoreScannerState(prevState);
1878:                    return;
1879:                }
1880:                decreaseMarkupDepth();
1881:                fDTDGrammar.callTextDecl(version, encoding);
1882:                if (fDTDHandler != null) {
1883:                    fDTDHandler.textDecl(version, encoding);
1884:                }
1885:                restoreScannerState(prevState);
1886:            }
1887:
1888:            private QName fElementDeclQName = new QName();
1889:
1890:            /**
1891:             * Scans an element declaration.
1892:             * <pre>
1893:             * [45] elementdecl ::= '&lt;!ELEMENT' S Name S contentspec S? '&gt;'
1894:             * </pre>
1895:             */
1896:            private void scanElementDecl() throws Exception {
1897:
1898:                if (!checkForPEReference(true)) {
1899:                    abortMarkup(
1900:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ELEMENTDECL,
1901:                            XMLMessages.P45_SPACE_REQUIRED);
1902:                    return;
1903:                }
1904:                checkForElementTypeWithPEReference(fEntityReader, ' ',
1905:                        fElementQName);
1906:                if (fElementQName.rawname == -1) {
1907:                    abortMarkup(
1908:                            XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ELEMENTDECL,
1909:                            XMLMessages.P45_ELEMENT_TYPE_REQUIRED);
1910:                    return;
1911:                }
1912:                if (fDTDHandler != null) {
1913:                    fElementDeclQName.setValues(fElementQName);
1914:                }
1915:                if (!checkForPEReference(true)) {
1916:                    abortMarkup(
1917:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_CONTENTSPEC_IN_ELEMENTDECL,
1918:                            XMLMessages.P45_SPACE_REQUIRED,
1919:                            fElementQName.rawname);
1920:                    return;
1921:                }
1922:                int contentSpecType = -1;
1923:                int contentSpec = -1;
1924:                if (fEntityReader.skippedString(empty_string)) {
1925:                    contentSpecType = XMLElementDecl.TYPE_EMPTY;
1926:                } else if (fEntityReader.skippedString(any_string)) {
1927:                    contentSpecType = XMLElementDecl.TYPE_ANY;
1928:                } else if (!fEntityReader.lookingAtChar('(', true)) {
1929:                    abortMarkup(
1930:                            XMLMessages.MSG_CONTENTSPEC_REQUIRED_IN_ELEMENTDECL,
1931:                            XMLMessages.P45_CONTENTSPEC_REQUIRED,
1932:                            fElementQName.rawname);
1933:                    return;
1934:                } else {
1935:                    int contentSpecReader = fReaderId;
1936:                    int contentSpecReaderDepth = fEntityHandler
1937:                            .getReaderDepth();
1938:                    int prevState = setScannerState(SCANNER_STATE_CONTENTSPEC);
1939:                    int oldDepth = parenDepth();
1940:                    fEntityHandler.setReaderDepth(oldDepth);
1941:                    increaseParenDepth();
1942:                    checkForPEReference(false);
1943:                    boolean skippedPCDATA = fEntityReader
1944:                            .skippedString(pcdata_string);
1945:                    if (skippedPCDATA) {
1946:                        contentSpecType = XMLElementDecl.TYPE_MIXED_SIMPLE;
1947:                        // REVISIT: Validation. Should we pass in QName?
1948:                        contentSpec = scanMixed(fElementQName);
1949:                    } else {
1950:                        contentSpecType = XMLElementDecl.TYPE_CHILDREN;
1951:                        // REVISIT: Validation. Should we pass in QName?
1952:                        contentSpec = scanChildren(fElementQName);
1953:                    }
1954:                    boolean success = contentSpec != -1;
1955:                    restoreScannerState(prevState);
1956:                    fEntityHandler.setReaderDepth(contentSpecReaderDepth);
1957:                    if (!success) {
1958:                        setParenDepth(oldDepth);
1959:                        skipPastEndOfCurrentMarkup();
1960:                        return;
1961:                    } else {
1962:                        if (parenDepth() != oldDepth) // REVISIT - should not be needed
1963:                            // System.out.println("nesting depth mismatch");
1964:                            ;
1965:                    }
1966:                }
1967:                checkForPEReference(false);
1968:                if (!fEntityReader.lookingAtChar('>', true)) {
1969:                    abortMarkup(XMLMessages.MSG_ELEMENTDECL_UNTERMINATED,
1970:                            XMLMessages.P45_UNTERMINATED, fElementQName.rawname);
1971:                    return;
1972:                }
1973:                decreaseMarkupDepth();
1974:                int elementIndex = fDTDGrammar.getElementDeclIndex(
1975:                        fElementQName, -1);
1976:                boolean elementDeclIsExternal = getReadingExternalEntity();
1977:                if (elementIndex == -1) {
1978:                    elementIndex = fDTDGrammar
1979:                            .addElementDecl(fElementQName, contentSpecType,
1980:                                    contentSpec, elementDeclIsExternal);
1981:                    //System.out.println("XMLDTDScanner#scanElementDecl->DTDGrammar#addElementDecl: "+elementIndex+" ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.localpart)+')');
1982:                } else {
1983:                    //now check if we already add this element Decl by foward reference
1984:                    fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
1985:                    if (fTempElementDecl.type == -1) {
1986:                        fTempElementDecl.type = contentSpecType;
1987:                        fTempElementDecl.contentSpecIndex = contentSpec;
1988:                        fDTDGrammar.setElementDeclDTD(elementIndex,
1989:                                fTempElementDecl);
1990:                        fDTDGrammar.setElementDeclIsExternal(elementIndex,
1991:                                elementDeclIsExternal);
1992:                    } else {
1993:                        //REVISIT, valiate VC duplicate element type. 
1994:                        if (fValidationEnabled)
1995:                        //&& 
1996:                        // (elemenetDeclIsExternal==fDTDGrammar.getElementDeclIsExternal(elementIndex)
1997:                        {
1998:
1999:                            reportRecoverableXMLError(
2000:                                    XMLMessages.MSG_ELEMENT_ALREADY_DECLARED,
2001:                                    XMLMessages.VC_UNIQUE_ELEMENT_TYPE_DECLARATION,
2002:                                    fStringPool.toString(fElementQName.rawname));
2003:                        }
2004:                    }
2005:                }
2006:                if (fDTDHandler != null) {
2007:                    fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
2008:                    fDTDHandler.elementDecl(fElementDeclQName, contentSpecType,
2009:                            contentSpec, fDTDGrammar);
2010:                }
2011:
2012:            } // scanElementDecl()
2013:
2014:            /**
2015:             * Scans mixed content model. Called after scanning past '(' S? '#PCDATA'
2016:             * <pre>
2017:             * [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'
2018:             * </pre>
2019:             */
2020:            private int scanMixed(QName element) throws Exception {
2021:
2022:                int valueIndex = -1; // -1 is special value for #PCDATA
2023:                int prevNodeIndex = -1;
2024:                boolean starRequired = false;
2025:                int[] valueSeen = new int[32];
2026:                int valueCount = 0;
2027:                boolean dupAttrType = false;
2028:                int nodeIndex = -1;
2029:
2030:                while (true) {
2031:                    if (fValidationEnabled) {
2032:                        for (int i = 0; i < valueCount; i++) {
2033:                            if (valueSeen[i] == valueIndex) {
2034:                                dupAttrType = true;
2035:                                break;
2036:                            }
2037:                        }
2038:                    }
2039:                    if (dupAttrType && fValidationEnabled) {
2040:                        reportRecoverableXMLError(
2041:                                XMLMessages.MSG_DUPLICATE_TYPE_IN_MIXED_CONTENT,
2042:                                XMLMessages.VC_NO_DUPLICATE_TYPES, valueIndex);
2043:                        dupAttrType = false;
2044:
2045:                    } else {
2046:                        try {
2047:                            valueSeen[valueCount] = valueIndex;
2048:                        } catch (ArrayIndexOutOfBoundsException ae) {
2049:                            int[] newArray = new int[valueSeen.length * 2];
2050:                            System.arraycopy(valueSeen, 0, newArray, 0,
2051:                                    valueSeen.length);
2052:                            valueSeen = newArray;
2053:                            valueSeen[valueCount] = valueIndex;
2054:                        }
2055:                        valueCount++;
2056:
2057:                        nodeIndex = fDTDGrammar.addUniqueLeafNode(valueIndex);
2058:                    }
2059:
2060:                    checkForPEReference(false);
2061:                    if (!fEntityReader.lookingAtChar('|', true)) {
2062:                        if (!fEntityReader.lookingAtChar(')', true)) {
2063:                            reportFatalXMLError(
2064:                                    XMLMessages.MSG_CLOSE_PAREN_REQUIRED_IN_MIXED,
2065:                                    XMLMessages.P51_CLOSE_PAREN_REQUIRED,
2066:                                    element.rawname);
2067:                            return -1;
2068:                        }
2069:                        decreaseParenDepth();
2070:                        if (nodeIndex == -1) {
2071:                            nodeIndex = prevNodeIndex;
2072:                        } else if (prevNodeIndex != -1) {
2073:                            nodeIndex = fDTDGrammar.addContentSpecNode(
2074:                                    XMLContentSpec.CONTENTSPECNODE_CHOICE,
2075:                                    prevNodeIndex, nodeIndex);
2076:                        }
2077:                        if (fEntityReader.lookingAtChar('*', true)) {
2078:                            nodeIndex = fDTDGrammar
2079:                                    .addContentSpecNode(
2080:                                            XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
2081:                                            nodeIndex);
2082:                        } else if (starRequired) {
2083:                            reportFatalXMLError(
2084:                                    XMLMessages.MSG_MIXED_CONTENT_UNTERMINATED,
2085:                                    XMLMessages.P51_UNTERMINATED,
2086:                                    fStringPool.toString(element.rawname),
2087:                                    fDTDGrammar
2088:                                            .getContentSpecNodeAsString(nodeIndex));
2089:                            return -1;
2090:                        }
2091:                        return nodeIndex;
2092:                    }
2093:                    if (nodeIndex != -1) {
2094:                        if (prevNodeIndex != -1) {
2095:                            nodeIndex = fDTDGrammar.addContentSpecNode(
2096:                                    XMLContentSpec.CONTENTSPECNODE_CHOICE,
2097:                                    prevNodeIndex, nodeIndex);
2098:                        }
2099:                        prevNodeIndex = nodeIndex;
2100:                    }
2101:                    starRequired = true;
2102:                    checkForPEReference(false);
2103:                    checkForElementTypeWithPEReference(fEntityReader, ')',
2104:                            fElementRefQName);
2105:                    valueIndex = fElementRefQName.rawname;
2106:                    if (valueIndex == -1) {
2107:                        reportFatalXMLError(
2108:                                XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_MIXED_CONTENT,
2109:                                XMLMessages.P51_ELEMENT_TYPE_REQUIRED,
2110:                                element.rawname);
2111:                        return -1;
2112:                    }
2113:                }
2114:
2115:            } // scanMixed(QName):int
2116:
2117:            /**
2118:             * Scans a children content model.
2119:             * <pre>
2120:             * [47] children ::= (choice | seq) ('?' | '*' | '+')?
2121:             * [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
2122:             * [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
2123:             * [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
2124:             * </pre>
2125:             */
2126:            private int scanChildren(QName element) throws Exception {
2127:
2128:                int depth = 1;
2129:                initializeContentModelStack(depth);
2130:                while (true) {
2131:                    if (fEntityReader.lookingAtChar('(', true)) {
2132:                        increaseParenDepth();
2133:                        checkForPEReference(false);
2134:                        depth++;
2135:                        initializeContentModelStack(depth);
2136:                        continue;
2137:                    }
2138:                    checkForElementTypeWithPEReference(fEntityReader, ')',
2139:                            fElementRefQName);
2140:                    int valueIndex = fElementRefQName.rawname;
2141:                    if (valueIndex == -1) {
2142:                        reportFatalXMLError(
2143:                                XMLMessages.MSG_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED_IN_CHILDREN,
2144:                                XMLMessages.P47_OPEN_PAREN_OR_ELEMENT_TYPE_REQUIRED,
2145:                                element.rawname);
2146:                        return -1;
2147:                    }
2148:                    fNodeIndexStack[depth] = fDTDGrammar.addContentSpecNode(
2149:                            XMLContentSpec.CONTENTSPECNODE_LEAF, valueIndex);
2150:                    if (fEntityReader.lookingAtChar('?', true)) {
2151:                        fNodeIndexStack[depth] = fDTDGrammar
2152:                                .addContentSpecNode(
2153:                                        XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
2154:                                        fNodeIndexStack[depth]);
2155:                    } else if (fEntityReader.lookingAtChar('*', true)) {
2156:                        fNodeIndexStack[depth] = fDTDGrammar
2157:                                .addContentSpecNode(
2158:                                        XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
2159:                                        fNodeIndexStack[depth]);
2160:                    } else if (fEntityReader.lookingAtChar('+', true)) {
2161:                        fNodeIndexStack[depth] = fDTDGrammar
2162:                                .addContentSpecNode(
2163:                                        XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
2164:                                        fNodeIndexStack[depth]);
2165:                    }
2166:                    while (true) {
2167:                        checkForPEReference(false);
2168:                        if (fOpStack[depth] != XMLContentSpec.CONTENTSPECNODE_SEQ
2169:                                && fEntityReader.lookingAtChar('|', true)) {
2170:                            if (fPrevNodeIndexStack[depth] != -1) {
2171:                                fNodeIndexStack[depth] = fDTDGrammar
2172:                                        .addContentSpecNode(fOpStack[depth],
2173:                                                fPrevNodeIndexStack[depth],
2174:                                                fNodeIndexStack[depth]);
2175:                            }
2176:                            fPrevNodeIndexStack[depth] = fNodeIndexStack[depth];
2177:                            fOpStack[depth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
2178:                            break;
2179:                        } else if (fOpStack[depth] != XMLContentSpec.CONTENTSPECNODE_CHOICE
2180:                                && fEntityReader.lookingAtChar(',', true)) {
2181:                            if (fPrevNodeIndexStack[depth] != -1) {
2182:                                fNodeIndexStack[depth] = fDTDGrammar
2183:                                        .addContentSpecNode(fOpStack[depth],
2184:                                                fPrevNodeIndexStack[depth],
2185:                                                fNodeIndexStack[depth]);
2186:                            }
2187:                            fPrevNodeIndexStack[depth] = fNodeIndexStack[depth];
2188:                            fOpStack[depth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
2189:                            break;
2190:                        } else {
2191:                            if (!fEntityReader.lookingAtChar(')', true)) {
2192:                                reportFatalXMLError(
2193:                                        XMLMessages.MSG_CLOSE_PAREN_REQUIRED_IN_CHILDREN,
2194:                                        XMLMessages.P47_CLOSE_PAREN_REQUIRED,
2195:                                        element.rawname);
2196:                            }
2197:                            decreaseParenDepth();
2198:                            if (fPrevNodeIndexStack[depth] != -1) {
2199:                                fNodeIndexStack[depth] = fDTDGrammar
2200:                                        .addContentSpecNode(fOpStack[depth],
2201:                                                fPrevNodeIndexStack[depth],
2202:                                                fNodeIndexStack[depth]);
2203:                            }
2204:                            int nodeIndex = fNodeIndexStack[depth--];
2205:                            fNodeIndexStack[depth] = nodeIndex;
2206:                            if (fEntityReader.lookingAtChar('?', true)) {
2207:                                fNodeIndexStack[depth] = fDTDGrammar
2208:                                        .addContentSpecNode(
2209:                                                XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE,
2210:                                                fNodeIndexStack[depth]);
2211:                            } else if (fEntityReader.lookingAtChar('*', true)) {
2212:                                fNodeIndexStack[depth] = fDTDGrammar
2213:                                        .addContentSpecNode(
2214:                                                XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE,
2215:                                                fNodeIndexStack[depth]);
2216:                            } else if (fEntityReader.lookingAtChar('+', true)) {
2217:                                fNodeIndexStack[depth] = fDTDGrammar
2218:                                        .addContentSpecNode(
2219:                                                XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE,
2220:                                                fNodeIndexStack[depth]);
2221:                            }
2222:                            if (depth == 0) {
2223:                                return fNodeIndexStack[0];
2224:                            }
2225:                        }
2226:                    }
2227:                    checkForPEReference(false);
2228:                }
2229:
2230:            } // scanChildren(QName):int
2231:
2232:            //
2233:            // [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
2234:            // [53] AttDef ::= S Name S AttType S DefaultDecl
2235:            // [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue)
2236:            //
2237:            private void scanAttlistDecl() throws Exception {
2238:                if (!checkForPEReference(true)) {
2239:                    abortMarkup(
2240:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ELEMENT_TYPE_IN_ATTLISTDECL,
2241:                            XMLMessages.P52_SPACE_REQUIRED);
2242:                    return;
2243:                }
2244:                checkForElementTypeWithPEReference(fEntityReader, ' ',
2245:                        fElementQName);
2246:                int elementTypeIndex = fElementQName.rawname;
2247:                if (elementTypeIndex == -1) {
2248:                    abortMarkup(
2249:                            XMLMessages.MSG_ELEMENT_TYPE_REQUIRED_IN_ATTLISTDECL,
2250:                            XMLMessages.P52_ELEMENT_TYPE_REQUIRED);
2251:                    return;
2252:                }
2253:                int elementIndex = fDTDGrammar.getElementDeclIndex(
2254:                        fElementQName, -1);
2255:                if (elementIndex == -1) {
2256:                    elementIndex = fDTDGrammar.addElementDecl(fElementQName);
2257:                    //System.out.println("XMLDTDScanner#scanAttListDecl->DTDGrammar#addElementDecl: "+elementIndex+" ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.localpart)+')');
2258:                }
2259:                boolean sawSpace = checkForPEReference(true);
2260:                if (fEntityReader.lookingAtChar('>', true)) {
2261:                    decreaseMarkupDepth();
2262:                    return;
2263:                }
2264:                // REVISIT - review this code...
2265:                if (!sawSpace) {
2266:                    if (fEntityReader.lookingAtSpace(true)) {
2267:                        fEntityReader.skipPastSpaces();
2268:                    } else
2269:                        reportFatalXMLError(
2270:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF,
2271:                                XMLMessages.P53_SPACE_REQUIRED);
2272:                } else {
2273:                    if (fEntityReader.lookingAtSpace(true)) {
2274:                        fEntityReader.skipPastSpaces();
2275:                    }
2276:                }
2277:                if (fEntityReader.lookingAtChar('>', true)) {
2278:                    decreaseMarkupDepth();
2279:                    return;
2280:                }
2281:                while (true) {
2282:                    checkForAttributeNameWithPEReference(fEntityReader, ' ',
2283:                            fAttributeQName);
2284:                    int attDefName = fAttributeQName.rawname;
2285:                    if (attDefName == -1) {
2286:                        abortMarkup(
2287:                                XMLMessages.MSG_ATTRIBUTE_NAME_REQUIRED_IN_ATTDEF,
2288:                                XMLMessages.P53_NAME_REQUIRED,
2289:                                fElementQName.rawname);
2290:                        return;
2291:                    }
2292:                    if (!checkForPEReference(true)) {
2293:                        abortMarkup(
2294:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTTYPE_IN_ATTDEF,
2295:                                XMLMessages.P53_SPACE_REQUIRED);
2296:                        return;
2297:                    }
2298:                    int attDefType = -1;
2299:                    boolean attDefList = false;
2300:                    int attDefEnumeration = -1;
2301:                    if (fEntityReader.skippedString(cdata_string)) {
2302:                        attDefType = XMLAttributeDecl.TYPE_CDATA;
2303:                    } else if (fEntityReader.skippedString(id_string)) {
2304:                        if (!fEntityReader.skippedString(ref_string)) {
2305:                            attDefType = XMLAttributeDecl.TYPE_ID;
2306:                        } else if (!fEntityReader.lookingAtChar('S', true)) {
2307:                            attDefType = XMLAttributeDecl.TYPE_IDREF;
2308:                        } else {
2309:                            attDefType = XMLAttributeDecl.TYPE_IDREF;
2310:                            attDefList = true;
2311:                        }
2312:                    } else if (fEntityReader.skippedString(entit_string)) {
2313:                        if (fEntityReader.lookingAtChar('Y', true)) {
2314:                            attDefType = XMLAttributeDecl.TYPE_ENTITY;
2315:                        } else if (fEntityReader.skippedString(ies_string)) {
2316:                            attDefType = XMLAttributeDecl.TYPE_ENTITY;
2317:                            attDefList = true;
2318:                        } else {
2319:                            abortMarkup(
2320:                                    XMLMessages.MSG_ATTTYPE_REQUIRED_IN_ATTDEF,
2321:                                    XMLMessages.P53_ATTTYPE_REQUIRED,
2322:                                    elementTypeIndex, attDefName);
2323:                            return;
2324:                        }
2325:                    } else if (fEntityReader.skippedString(nmtoken_string)) {
2326:                        if (fEntityReader.lookingAtChar('S', true)) {
2327:                            attDefType = XMLAttributeDecl.TYPE_NMTOKEN;
2328:                            attDefList = true;
2329:                        } else {
2330:                            attDefType = XMLAttributeDecl.TYPE_NMTOKEN;
2331:                        }
2332:                    } else if (fEntityReader.skippedString(notation_string)) {
2333:                        if (!checkForPEReference(true)) {
2334:                            abortMarkup(
2335:                                    XMLMessages.MSG_SPACE_REQUIRED_AFTER_NOTATION_IN_NOTATIONTYPE,
2336:                                    XMLMessages.P58_SPACE_REQUIRED,
2337:                                    elementTypeIndex, attDefName);
2338:                            return;
2339:                        }
2340:                        if (!fEntityReader.lookingAtChar('(', true)) {
2341:                            abortMarkup(
2342:                                    XMLMessages.MSG_OPEN_PAREN_REQUIRED_IN_NOTATIONTYPE,
2343:                                    XMLMessages.P58_OPEN_PAREN_REQUIRED,
2344:                                    elementTypeIndex, attDefName);
2345:                            return;
2346:                        }
2347:                        increaseParenDepth();
2348:                        attDefType = XMLAttributeDecl.TYPE_NOTATION;
2349:                        attDefEnumeration = scanEnumeration(elementTypeIndex,
2350:                                attDefName, true);
2351:                        if (attDefEnumeration == -1) {
2352:                            skipPastEndOfCurrentMarkup();
2353:                            return;
2354:                        }
2355:                    } else if (fEntityReader.lookingAtChar('(', true)) {
2356:                        increaseParenDepth();
2357:                        attDefType = XMLAttributeDecl.TYPE_ENUMERATION;
2358:                        attDefEnumeration = scanEnumeration(elementTypeIndex,
2359:                                attDefName, false);
2360:                        if (attDefEnumeration == -1) {
2361:                            skipPastEndOfCurrentMarkup();
2362:                            return;
2363:                        }
2364:                    } else {
2365:                        abortMarkup(XMLMessages.MSG_ATTTYPE_REQUIRED_IN_ATTDEF,
2366:                                XMLMessages.P53_ATTTYPE_REQUIRED,
2367:                                elementTypeIndex, attDefName);
2368:                        return;
2369:                    }
2370:                    if (!checkForPEReference(true)) {
2371:                        abortMarkup(
2372:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_DEFAULTDECL_IN_ATTDEF,
2373:                                XMLMessages.P53_SPACE_REQUIRED,
2374:                                elementTypeIndex, attDefName);
2375:                        return;
2376:                    }
2377:                    int attDefDefaultType = -1;
2378:                    int attDefDefaultValue = -1;
2379:                    if (fEntityReader.skippedString(required_string)) {
2380:                        attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_REQUIRED;
2381:                    } else if (fEntityReader.skippedString(implied_string)) {
2382:                        attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_IMPLIED;
2383:                    } else {
2384:                        if (fEntityReader.skippedString(fixed_string)) {
2385:                            if (!checkForPEReference(true)) {
2386:                                abortMarkup(
2387:                                        XMLMessages.MSG_SPACE_REQUIRED_AFTER_FIXED_IN_DEFAULTDECL,
2388:                                        XMLMessages.P60_SPACE_REQUIRED,
2389:                                        elementTypeIndex, attDefName);
2390:                                return;
2391:                            }
2392:                            attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_FIXED;
2393:                        } else
2394:                            attDefDefaultType = XMLAttributeDecl.DEFAULT_TYPE_DEFAULT;
2395:
2396:                        //fElementQName.setValues(-1, elementTypeIndex, elementTypeIndex);
2397:
2398:                        // if attribute name has a prefix "xml", bind it to the XML Namespace.
2399:                        // since this is the only pre-defined namespace.
2400:                        /***
2401:                        if (fAttributeQName.prefix == fXMLSymbol) {
2402:                            fAttributeQName.uri = fXMLNamespace;
2403:                        }
2404:                        else 
2405:                            fAttributeQName.setValues(-1, attDefName, attDefName);
2406:                         ****/
2407:
2408:                        attDefDefaultValue = scanDefaultAttValue(fElementQName,
2409:                                fAttributeQName, attDefType, attDefEnumeration);
2410:
2411:                        //normalize and check VC: Attribute Default Legal
2412:                        if (attDefDefaultValue != -1
2413:                                && attDefType != XMLAttributeDecl.TYPE_CDATA) {
2414:                            attDefDefaultValue = normalizeDefaultAttValue(
2415:                                    fAttributeQName, attDefDefaultValue,
2416:                                    attDefType, attDefEnumeration, attDefList);
2417:                        }
2418:
2419:                        if (attDefDefaultValue == -1) {
2420:                            skipPastEndOfCurrentMarkup();
2421:                            return;
2422:                        }
2423:                    }
2424:                    if (attDefName == fXMLSpace) {
2425:                        boolean ok = false;
2426:                        if (attDefType == XMLAttributeDecl.TYPE_ENUMERATION) {
2427:                            int index = attDefEnumeration;
2428:                            if (index != -1) {
2429:                                ok = (fStringPool.stringListLength(index) == 1 && (fStringPool
2430:                                        .stringInList(index, fDefault) || fStringPool
2431:                                        .stringInList(index, fPreserve)))
2432:                                        || (fStringPool.stringListLength(index) == 2
2433:                                                && fStringPool.stringInList(
2434:                                                        index, fDefault) && fStringPool
2435:                                                .stringInList(index, fPreserve));
2436:                            }
2437:                        }
2438:                        if (!ok) {
2439:                            reportFatalXMLError(
2440:                                    XMLMessages.MSG_XML_SPACE_DECLARATION_ILLEGAL,
2441:                                    XMLMessages.S2_10_DECLARATION_ILLEGAL,
2442:                                    elementTypeIndex);
2443:                        }
2444:                    }
2445:                    sawSpace = checkForPEReference(true);
2446:
2447:                    // if attribute name has a prefix "xml", bind it to the XML Namespace.
2448:                    // since this is the only pre-defined namespace.
2449:                    if (fAttributeQName.prefix == fXMLSymbol) {
2450:                        fAttributeQName.uri = fXMLNamespace;
2451:                    }
2452:
2453:                    if (fEntityReader.lookingAtChar('>', true)) {
2454:                        int attDefIndex = addAttDef(fElementQName,
2455:                                fAttributeQName, attDefType, attDefList,
2456:                                attDefEnumeration, attDefDefaultType,
2457:                                attDefDefaultValue, getReadingExternalEntity());
2458:                        //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
2459:                        //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
2460:                        //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
2461:                        decreaseMarkupDepth();
2462:                        return;
2463:                    }
2464:                    // REVISIT - review this code...
2465:                    if (!sawSpace) {
2466:                        if (fEntityReader.lookingAtSpace(true)) {
2467:                            fEntityReader.skipPastSpaces();
2468:                        } else
2469:                            reportFatalXMLError(
2470:                                    XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ATTRIBUTE_NAME_IN_ATTDEF,
2471:                                    XMLMessages.P53_SPACE_REQUIRED);
2472:                    } else {
2473:                        if (fEntityReader.lookingAtSpace(true)) {
2474:                            fEntityReader.skipPastSpaces();
2475:                        }
2476:                    }
2477:                    if (fEntityReader.lookingAtChar('>', true)) {
2478:                        int attDefIndex = addAttDef(fElementQName,
2479:                                fAttributeQName, attDefType, attDefList,
2480:                                attDefEnumeration, attDefDefaultType,
2481:                                attDefDefaultValue, getReadingExternalEntity());
2482:                        //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
2483:                        //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
2484:                        //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
2485:                        decreaseMarkupDepth();
2486:                        return;
2487:                    }
2488:                    int attDefIndex = addAttDef(fElementQName, fAttributeQName,
2489:                            attDefType, attDefList, attDefEnumeration,
2490:                            attDefDefaultType, attDefDefaultValue,
2491:                            getReadingExternalEntity());
2492:                    //System.out.println("XMLDTDScanner#scanAttlistDecl->DTDGrammar#addAttDef: "+attDefIndex+
2493:                    //                   " ("+fElementQName.localpart+","+fStringPool.toString(fElementQName.rawname)+')'+
2494:                    //                   " ("+fAttributeQName.localpart+","+fStringPool.toString(fAttributeQName.rawname)+')');
2495:                }
2496:            }
2497:
2498:            private int addAttDef(QName element, QName attribute,
2499:                    int attDefType, boolean attDefList, int attDefEnumeration,
2500:                    int attDefDefaultType, int attDefDefaultValue,
2501:                    boolean isExternal) throws Exception {
2502:
2503:                if (fDTDHandler != null) {
2504:                    String enumString = attDefEnumeration != -1 ? fStringPool
2505:                            .stringListAsString(attDefEnumeration) : null;
2506:                    fDTDHandler.attlistDecl(element, attribute, attDefType,
2507:                            attDefList, enumString, attDefDefaultType,
2508:                            attDefDefaultValue);
2509:                }
2510:                int elementIndex = fDTDGrammar.getElementDeclIndex(element, -1);
2511:                if (elementIndex == -1) {
2512:                    // REPORT Internal error here
2513:                } else {
2514:                    int attlistIndex = fDTDGrammar
2515:                            .getFirstAttributeDeclIndex(elementIndex);
2516:                    int dupID = -1;
2517:                    int dupNotation = -1;
2518:                    while (attlistIndex != -1) {
2519:                        fDTDGrammar.getAttributeDecl(attlistIndex,
2520:                                fTempAttributeDecl);
2521:
2522:                        // REVISIT: Validation. Attributes are also tuples.
2523:                        if (fStringPool.equalNames(
2524:                                fTempAttributeDecl.name.rawname,
2525:                                attribute.rawname)) {
2526:                            /******
2527:                            if (fWarningOnDuplicateAttDef) {
2528:                                Object[] args = { fStringPool.toString(fElementType[elemChunk][elemIndex]),
2529:                                                  fStringPool.toString(attributeDecl.rawname) };
2530:                                fErrorReporter.reportError(fErrorReporter.getLocator(),
2531:                                                           XMLMessages.XML_DOMAIN,
2532:                                                           XMLMessages.MSG_DUPLICATE_ATTDEF,
2533:                                                           XMLMessages.P53_DUPLICATE,
2534:                                                           args,
2535:                                                           XMLErrorReporter.ERRORTYPE_WARNING);
2536:                            }
2537:                             ******/
2538:                            return -1;
2539:                        }
2540:
2541:                        if (fValidationEnabled) {
2542:                            if (attDefType == XMLAttributeDecl.TYPE_ID
2543:                                    && fTempAttributeDecl.type == XMLAttributeDecl.TYPE_ID) {
2544:                                dupID = fTempAttributeDecl.name.rawname;
2545:                            }
2546:                            if (attDefType == XMLAttributeDecl.TYPE_NOTATION
2547:                                    && fTempAttributeDecl.type == XMLAttributeDecl.TYPE_NOTATION) {
2548:                                dupNotation = fTempAttributeDecl.name.rawname;
2549:                            }
2550:                        }
2551:                        attlistIndex = fDTDGrammar
2552:                                .getNextAttributeDeclIndex(attlistIndex);
2553:                    }
2554:                    if (fValidationEnabled) {
2555:                        if (dupID != -1) {
2556:                            Object[] args = {
2557:                                    fStringPool.toString(element.rawname),
2558:                                    fStringPool.toString(dupID),
2559:                                    fStringPool.toString(attribute.rawname) };
2560:                            fErrorReporter
2561:                                    .reportError(
2562:                                            fErrorReporter.getLocator(),
2563:                                            XMLMessages.XML_DOMAIN,
2564:                                            XMLMessages.MSG_MORE_THAN_ONE_ID_ATTRIBUTE,
2565:                                            XMLMessages.VC_ONE_ID_PER_ELEMENT_TYPE,
2566:                                            args,
2567:                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2568:                            return -1;
2569:                        }
2570:                        if (dupNotation != -1) {
2571:                            Object[] args = {
2572:                                    fStringPool.toString(element.rawname),
2573:                                    fStringPool.toString(dupNotation),
2574:                                    fStringPool.toString(attribute.rawname) };
2575:                            fErrorReporter
2576:                                    .reportError(
2577:                                            fErrorReporter.getLocator(),
2578:                                            XMLMessages.XML_DOMAIN,
2579:                                            XMLMessages.MSG_MORE_THAN_ONE_NOTATION_ATTRIBUTE,
2580:                                            XMLMessages.VC_ONE_NOTATION_PER_ELEMENT_TYPE,
2581:                                            args,
2582:                                            XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR);
2583:                            return -1;
2584:                        }
2585:                    }
2586:                }
2587:                return fDTDGrammar.addAttDef(element, attribute, attDefType,
2588:                        attDefList, attDefEnumeration, attDefDefaultType,
2589:                        attDefDefaultValue, isExternal);
2590:
2591:            }
2592:
2593:            //
2594:            // [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
2595:            // [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
2596:            //
2597:            private int scanEnumeration(int elementType, int attrName,
2598:                    boolean isNotationType) throws Exception {
2599:                int enumIndex = fDTDGrammar.startEnumeration();
2600:                while (true) {
2601:                    checkForPEReference(false);
2602:                    int nameIndex = isNotationType ? checkForNameWithPEReference(
2603:                            fEntityReader, ')')
2604:                            : checkForNmtokenWithPEReference(fEntityReader, ')');
2605:                    if (nameIndex == -1) {
2606:                        if (isNotationType) {
2607:                            reportFatalXMLError(
2608:                                    XMLMessages.MSG_NAME_REQUIRED_IN_NOTATIONTYPE,
2609:                                    XMLMessages.P58_NAME_REQUIRED, elementType,
2610:                                    attrName);
2611:                        } else {
2612:                            reportFatalXMLError(
2613:                                    XMLMessages.MSG_NMTOKEN_REQUIRED_IN_ENUMERATION,
2614:                                    XMLMessages.P59_NMTOKEN_REQUIRED,
2615:                                    elementType, attrName);
2616:                        }
2617:                        fDTDGrammar.endEnumeration(enumIndex);
2618:                        return -1;
2619:                    }
2620:                    fDTDGrammar.addNameToEnumeration(enumIndex, elementType,
2621:                            attrName, nameIndex, isNotationType);
2622:                    /*****/
2623:                    if (isNotationType
2624:                            && !((DefaultEntityHandler) fEntityHandler)
2625:                                    .isNotationDeclared(nameIndex)) {
2626:                        Object[] args = { fStringPool.toString(elementType),
2627:                                fStringPool.toString(attrName),
2628:                                fStringPool.toString(nameIndex) };
2629:                        ((DefaultEntityHandler) fEntityHandler)
2630:                                .addRequiredNotation(
2631:                                        nameIndex,
2632:                                        fErrorReporter.getLocator(),
2633:                                        XMLMessages.MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE,
2634:                                        XMLMessages.VC_NOTATION_DECLARED, args);
2635:                    }
2636:                    /*****/
2637:                    checkForPEReference(false);
2638:                    if (!fEntityReader.lookingAtChar('|', true)) {
2639:                        fDTDGrammar.endEnumeration(enumIndex);
2640:                        if (!fEntityReader.lookingAtChar(')', true)) {
2641:                            if (isNotationType) {
2642:                                reportFatalXMLError(
2643:                                        XMLMessages.MSG_NOTATIONTYPE_UNTERMINATED,
2644:                                        XMLMessages.P58_UNTERMINATED,
2645:                                        elementType, attrName);
2646:                            } else {
2647:                                reportFatalXMLError(
2648:                                        XMLMessages.MSG_ENUMERATION_UNTERMINATED,
2649:                                        XMLMessages.P59_UNTERMINATED,
2650:                                        elementType, attrName);
2651:                            }
2652:                            return -1;
2653:                        }
2654:                        decreaseParenDepth();
2655:                        return enumIndex;
2656:                    }
2657:                }
2658:            }
2659:
2660:            //
2661:            // [10] AttValue ::= '"' ([^<&"] | Reference)* '"'
2662:            //                   | "'" ([^<&'] | Reference)* "'"
2663:            //
2664:            /**
2665:             * Scan the default value in an attribute declaration
2666:             *
2667:             * @param elementType handle to the element that owns the attribute
2668:             * @param attrName handle in the string pool for the attribute name
2669:             * @return handle in the string pool for the default attribute value
2670:             * @exception java.lang.Exception
2671:             */
2672:            public int scanDefaultAttValue(QName element, QName attribute)
2673:                    throws Exception {
2674:                boolean single;
2675:                if (!(single = fEntityReader.lookingAtChar('\'', true))
2676:                        && !fEntityReader.lookingAtChar('\"', true)) {
2677:                    reportFatalXMLError(
2678:                            XMLMessages.MSG_QUOTE_REQUIRED_IN_ATTVALUE,
2679:                            XMLMessages.P10_QUOTE_REQUIRED, element.rawname,
2680:                            attribute.rawname);
2681:                    return -1;
2682:                }
2683:                int previousState = setScannerState(SCANNER_STATE_DEFAULT_ATTRIBUTE_VALUE);
2684:                char qchar = single ? '\'' : '\"';
2685:                fDefaultAttValueReader = fReaderId;
2686:                fDefaultAttValueElementType = element.rawname;
2687:                fDefaultAttValueAttrName = attribute.rawname;
2688:                boolean setMark = true;
2689:                int dataOffset = fLiteralData.length();
2690:                while (true) {
2691:                    fDefaultAttValueOffset = fEntityReader.currentOffset();
2692:                    if (setMark) {
2693:                        fDefaultAttValueMark = fDefaultAttValueOffset;
2694:                        setMark = false;
2695:                    }
2696:                    if (fEntityReader.lookingAtChar(qchar, true)) {
2697:                        if (fReaderId == fDefaultAttValueReader)
2698:                            break;
2699:                        continue;
2700:                    }
2701:                    if (fEntityReader.lookingAtChar(' ', true)) {
2702:                        continue;
2703:                    }
2704:                    boolean skippedCR;
2705:                    if ((skippedCR = fEntityReader.lookingAtChar((char) 0x0D,
2706:                            true))
2707:                            || fEntityReader.lookingAtSpace(true)) {
2708:                        if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
2709:                            fEntityReader.append(fLiteralData,
2710:                                    fDefaultAttValueMark,
2711:                                    fDefaultAttValueOffset
2712:                                            - fDefaultAttValueMark);
2713:                        setMark = true;
2714:                        fLiteralData.append(' ');
2715:                        if (skippedCR)
2716:                            fEntityReader.lookingAtChar((char) 0x0A, true);
2717:                        continue;
2718:                    }
2719:                    if (fEntityReader.lookingAtChar('&', true)) {
2720:                        if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
2721:                            fEntityReader.append(fLiteralData,
2722:                                    fDefaultAttValueMark,
2723:                                    fDefaultAttValueOffset
2724:                                            - fDefaultAttValueMark);
2725:                        setMark = true;
2726:                        //
2727:                        // Check for character reference first.
2728:                        //
2729:                        if (fEntityReader.lookingAtChar('#', true)) {
2730:                            int ch = scanCharRef();
2731:                            if (ch != -1) {
2732:                                if (ch < 0x10000)
2733:                                    fLiteralData.append((char) ch);
2734:                                else {
2735:                                    fLiteralData
2736:                                            .append((char) (((ch - 0x00010000) >> 10) + 0xd800));
2737:                                    fLiteralData
2738:                                            .append((char) (((ch - 0x00010000) & 0x3ff) + 0xdc00));
2739:                                }
2740:                            }
2741:                        } else {
2742:                            //
2743:                            // Entity reference
2744:                            //
2745:                            int nameOffset = fEntityReader.currentOffset();
2746:                            fEntityReader.skipPastName(';');
2747:                            int nameLength = fEntityReader.currentOffset()
2748:                                    - nameOffset;
2749:                            if (nameLength == 0) {
2750:                                reportFatalXMLError(
2751:                                        XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
2752:                                        XMLMessages.P68_NAME_REQUIRED);
2753:                            } else if (!fEntityReader.lookingAtChar(';', true)) {
2754:                                reportFatalXMLError(
2755:                                        XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
2756:                                        XMLMessages.P68_SEMICOLON_REQUIRED,
2757:                                        fEntityReader.addString(nameOffset,
2758:                                                nameLength));
2759:                            } else {
2760:                                int entityNameIndex = fEntityReader.addSymbol(
2761:                                        nameOffset, nameLength);
2762:                                fEntityHandler
2763:                                        .startReadingFromEntity(
2764:                                                entityNameIndex,
2765:                                                markupDepth(),
2766:                                                XMLEntityHandler.ENTITYREF_IN_DEFAULTATTVALUE);
2767:                            }
2768:                        }
2769:                        continue;
2770:                    }
2771:                    if (fEntityReader.lookingAtChar('<', true)) {
2772:                        if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
2773:                            fEntityReader.append(fLiteralData,
2774:                                    fDefaultAttValueMark,
2775:                                    fDefaultAttValueOffset
2776:                                            - fDefaultAttValueMark);
2777:                        setMark = true;
2778:                        reportFatalXMLError(
2779:                                XMLMessages.MSG_LESSTHAN_IN_ATTVALUE,
2780:                                XMLMessages.WFC_NO_LESSTHAN_IN_ATTVALUE,
2781:                                element.rawname, attribute.rawname);
2782:                        continue;
2783:                    }
2784:                    if (!fEntityReader.lookingAtValidChar(true)) {
2785:                        if (fDefaultAttValueOffset - fDefaultAttValueMark > 0)
2786:                            fEntityReader.append(fLiteralData,
2787:                                    fDefaultAttValueMark,
2788:                                    fDefaultAttValueOffset
2789:                                            - fDefaultAttValueMark);
2790:                        setMark = true;
2791:                        int invChar = fEntityReader.scanInvalidChar();
2792:                        if (fScannerState == SCANNER_STATE_END_OF_INPUT)
2793:                            return -1;
2794:                        if (invChar >= 0) {
2795:                            reportFatalXMLError(
2796:                                    XMLMessages.MSG_INVALID_CHAR_IN_ATTVALUE,
2797:                                    XMLMessages.P10_INVALID_CHARACTER,
2798:                                    fStringPool.toString(element.rawname),
2799:                                    fStringPool.toString(attribute.rawname),
2800:                                    Integer.toHexString(invChar));
2801:                        }
2802:                        continue;
2803:                    }
2804:                }
2805:                restoreScannerState(previousState);
2806:                int dataLength = fLiteralData.length() - dataOffset;
2807:                if (dataLength == 0) {
2808:                    return fEntityReader.addString(fDefaultAttValueMark,
2809:                            fDefaultAttValueOffset - fDefaultAttValueMark);
2810:                }
2811:                if (fDefaultAttValueOffset - fDefaultAttValueMark > 0) {
2812:                    fEntityReader.append(fLiteralData, fDefaultAttValueMark,
2813:                            fDefaultAttValueOffset - fDefaultAttValueMark);
2814:                    dataLength = fLiteralData.length() - dataOffset;
2815:                }
2816:                return fLiteralData.addString(dataOffset, dataLength);
2817:            }
2818:
2819:            //
2820:            // [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
2821:            //
2822:            private void scanNotationDecl() throws Exception {
2823:                if (!checkForPEReference(true)) {
2824:                    abortMarkup(
2825:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_NOTATIONDECL,
2826:                            XMLMessages.P82_SPACE_REQUIRED);
2827:                    return;
2828:                }
2829:                int notationName = checkForNameWithPEReference(fEntityReader,
2830:                        ' ');
2831:                if (notationName == -1) {
2832:                    abortMarkup(
2833:                            XMLMessages.MSG_NOTATION_NAME_REQUIRED_IN_NOTATIONDECL,
2834:                            XMLMessages.P82_NAME_REQUIRED);
2835:                    return;
2836:                }
2837:                if (!checkForPEReference(true)) {
2838:                    abortMarkup(
2839:                            XMLMessages.MSG_SPACE_REQUIRED_AFTER_NOTATION_NAME_IN_NOTATIONDECL,
2840:                            XMLMessages.P82_SPACE_REQUIRED, notationName);
2841:                    return;
2842:                }
2843:                if (!scanExternalID(true)) {
2844:                    skipPastEndOfCurrentMarkup();
2845:                    return;
2846:                }
2847:                checkForPEReference(false);
2848:                if (!fEntityReader.lookingAtChar('>', true)) {
2849:                    abortMarkup(XMLMessages.MSG_NOTATIONDECL_UNTERMINATED,
2850:                            XMLMessages.P82_UNTERMINATED, notationName);
2851:                    return;
2852:                }
2853:                decreaseMarkupDepth();
2854:                /****
2855:                System.out.println(fStringPool.toString(notationName)+","
2856:                                   +fStringPool.toString(fPubidLiteral) + ","
2857:                                   +fStringPool.toString(fSystemLiteral) + ","
2858:                                   +getReadingExternalEntity());
2859:                /****/
2860:
2861:                int notationIndex = ((DefaultEntityHandler) fEntityHandler)
2862:                        .addNotationDecl(notationName, fPubidLiteral,
2863:                                fSystemLiteral, getReadingExternalEntity());
2864:                fDTDGrammar.addNotationDecl(notationName, fPubidLiteral,
2865:                        fSystemLiteral);
2866:                if (fDTDHandler != null) {
2867:                    fDTDHandler.notationDecl(notationName, fPubidLiteral,
2868:                            fSystemLiteral);
2869:                }
2870:            }
2871:
2872:            //
2873:            // [70] EntityDecl ::= GEDecl | PEDecl
2874:            // [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
2875:            // [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
2876:            // [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
2877:            // [74] PEDef ::= EntityValue | ExternalID
2878:            // [75] ExternalID ::= 'SYSTEM' S SystemLiteral
2879:            //                     | 'PUBLIC' S PubidLiteral S SystemLiteral
2880:            // [76] NDataDecl ::= S 'NDATA' S Name
2881:            //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
2882:            //                      | "'" ([^%&'] | PEReference | Reference)* "'"
2883:            //
2884:            // Called after scanning 'ENTITY'
2885:            //
2886:            private void scanEntityDecl() throws Exception {
2887:                boolean isPEDecl = false;
2888:                boolean sawPERef = false;
2889:                if (fEntityReader.lookingAtSpace(true)) {
2890:                    fEntityReader.skipPastSpaces();
2891:                    if (!fEntityReader.lookingAtChar('%', true)) {
2892:                        isPEDecl = false; // <!ENTITY x "x">
2893:                    } else if (fEntityReader.lookingAtSpace(true)) {
2894:                        checkForPEReference(false); // <!ENTITY % x "x">
2895:                        isPEDecl = true;
2896:                    } else if (!getReadingExternalEntity()) {
2897:                        reportFatalXMLError(
2898:                                XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_PEDECL,
2899:                                XMLMessages.P72_SPACE);
2900:                        isPEDecl = true;
2901:                    } else if (fEntityReader.lookingAtChar('%', false)) {
2902:                        checkForPEReference(false); // <!ENTITY %%x; "x"> is legal
2903:                        isPEDecl = true;
2904:                    } else {
2905:                        sawPERef = true;
2906:                    }
2907:                } else if (!getReadingExternalEntity()
2908:                        || !fEntityReader.lookingAtChar('%', true)) {
2909:                    // <!ENTITY[^ ]...> or <!ENTITY[^ %]...>
2910:                    reportFatalXMLError(
2911:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_ENTITY_NAME_IN_ENTITYDECL,
2912:                            XMLMessages.P70_SPACE);
2913:                    isPEDecl = false;
2914:                } else if (fEntityReader.lookingAtSpace(false)) {
2915:                    // <!ENTITY% ...>
2916:                    reportFatalXMLError(
2917:                            XMLMessages.MSG_SPACE_REQUIRED_BEFORE_PERCENT_IN_PEDECL,
2918:                            XMLMessages.P72_SPACE);
2919:                    isPEDecl = false;
2920:                } else {
2921:                    sawPERef = true;
2922:                }
2923:                if (sawPERef) {
2924:                    while (true) {
2925:                        int nameOffset = fEntityReader.currentOffset();
2926:                        fEntityReader.skipPastName(';');
2927:                        int nameLength = fEntityReader.currentOffset()
2928:                                - nameOffset;
2929:                        if (nameLength == 0) {
2930:                            reportFatalXMLError(
2931:                                    XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
2932:                                    XMLMessages.P69_NAME_REQUIRED);
2933:                        } else if (!fEntityReader.lookingAtChar(';', true)) {
2934:                            reportFatalXMLError(
2935:                                    XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
2936:                                    XMLMessages.P69_SEMICOLON_REQUIRED,
2937:                                    fEntityReader.addString(nameOffset,
2938:                                            nameLength));
2939:                        } else {
2940:                            int peNameIndex = fEntityReader.addSymbol(
2941:                                    nameOffset, nameLength);
2942:                            int readerDepth = (fScannerState == SCANNER_STATE_CONTENTSPEC) ? parenDepth()
2943:                                    : markupDepth();
2944:                            fEntityHandler
2945:                                    .startReadingFromEntity(
2946:                                            peNameIndex,
2947:                                            readerDepth,
2948:                                            XMLEntityHandler.ENTITYREF_IN_DTD_WITHIN_MARKUP);
2949:                        }
2950:                        fEntityReader.skipPastSpaces();
2951:                        if (!fEntityReader.lookingAtChar('%', true))
2952:                            break;
2953:                        if (!isPEDecl) {
2954:                            if (fEntityReader.lookingAtSpace(true)) {
2955:                                checkForPEReference(false);
2956:                                isPEDecl = true;
2957:                                break;
2958:                            }
2959:                            isPEDecl = fEntityReader.lookingAtChar('%', true);
2960:                        }
2961:                    }
2962:                }
2963:                int entityName = checkForNameWithPEReference(fEntityReader, ' ');
2964:                if (entityName == -1) {
2965:                    abortMarkup(
2966:                            XMLMessages.MSG_ENTITY_NAME_REQUIRED_IN_ENTITYDECL,
2967:                            XMLMessages.P70_REQUIRED_NAME);
2968:                    return;
2969:                }
2970:                if (!fDTDGrammar.startEntityDecl(isPEDecl, entityName)) {
2971:                    skipPastEndOfCurrentMarkup();
2972:                    return;
2973:                }
2974:                if (!checkForPEReference(true)) {
2975:                    abortMarkup(
2976:                            XMLMessages.MSG_SPACE_REQUIRED_AFTER_ENTITY_NAME_IN_ENTITYDECL,
2977:                            XMLMessages.P70_REQUIRED_SPACE, entityName);
2978:                    fDTDGrammar.endEntityDecl();
2979:                    return;
2980:                }
2981:                if (isPEDecl) {
2982:                    boolean single;
2983:                    if ((single = fEntityReader.lookingAtChar('\'', true))
2984:                            || fEntityReader.lookingAtChar('\"', true)) {
2985:                        int value = scanEntityValue(single);
2986:                        if (value == -1) {
2987:                            skipPastEndOfCurrentMarkup();
2988:                            fDTDGrammar.endEntityDecl();
2989:                            return;
2990:                        }
2991:                        checkForPEReference(false);
2992:                        if (!fEntityReader.lookingAtChar('>', true)) {
2993:                            abortMarkup(
2994:                                    XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
2995:                                    XMLMessages.P72_UNTERMINATED, entityName);
2996:                            fDTDGrammar.endEntityDecl();
2997:                            return;
2998:                        }
2999:                        decreaseMarkupDepth();
3000:                        fDTDGrammar.endEntityDecl();
3001:
3002:                        // a hack by Eric
3003:                        //REVISIT
3004:                        fDTDGrammar.addInternalPEDecl(entityName, value);
3005:                        if (fDTDHandler != null) {
3006:                            fDTDHandler.internalPEDecl(entityName, value);
3007:                        }
3008:                        int entityIndex = ((DefaultEntityHandler) fEntityHandler)
3009:                                .addInternalPEDecl(entityName, value,
3010:                                        getReadingExternalEntity());
3011:
3012:                    } else {
3013:                        if (!scanExternalID(false)) {
3014:                            skipPastEndOfCurrentMarkup();
3015:                            fDTDGrammar.endEntityDecl();
3016:                            return;
3017:                        }
3018:                        checkForPEReference(false);
3019:                        if (!fEntityReader.lookingAtChar('>', true)) {
3020:                            abortMarkup(
3021:                                    XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
3022:                                    XMLMessages.P72_UNTERMINATED, entityName);
3023:                            fDTDGrammar.endEntityDecl();
3024:                            return;
3025:                        }
3026:                        decreaseMarkupDepth();
3027:                        fDTDGrammar.endEntityDecl();
3028:
3029:                        //a hack by Eric
3030:                        //REVISIT
3031:                        fDTDGrammar.addExternalPEDecl(entityName,
3032:                                fPubidLiteral, fSystemLiteral);
3033:                        if (fDTDHandler != null) {
3034:                            fDTDHandler.externalPEDecl(entityName,
3035:                                    fPubidLiteral, fSystemLiteral);
3036:                        }
3037:                        int entityIndex = ((DefaultEntityHandler) fEntityHandler)
3038:                                .addExternalPEDecl(entityName, fPubidLiteral,
3039:                                        fSystemLiteral,
3040:                                        getReadingExternalEntity());
3041:                    }
3042:                } else {
3043:                    boolean single;
3044:                    if ((single = fEntityReader.lookingAtChar('\'', true))
3045:                            || fEntityReader.lookingAtChar('\"', true)) {
3046:                        int value = scanEntityValue(single);
3047:                        if (value == -1) {
3048:                            skipPastEndOfCurrentMarkup();
3049:                            fDTDGrammar.endEntityDecl();
3050:                            return;
3051:                        }
3052:                        checkForPEReference(false);
3053:                        if (!fEntityReader.lookingAtChar('>', true)) {
3054:                            abortMarkup(
3055:                                    XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
3056:                                    XMLMessages.P71_UNTERMINATED, entityName);
3057:                            fDTDGrammar.endEntityDecl();
3058:                            return;
3059:                        }
3060:                        decreaseMarkupDepth();
3061:                        fDTDGrammar.endEntityDecl();
3062:
3063:                        //a hack by Eric
3064:                        //REVISIT
3065:                        fDTDGrammar.addInternalEntityDecl(entityName, value);
3066:                        if (fDTDHandler != null) {
3067:                            fDTDHandler.internalEntityDecl(entityName, value);
3068:                        }
3069:                        int entityIndex = ((DefaultEntityHandler) fEntityHandler)
3070:                                .addInternalEntityDecl(entityName, value,
3071:                                        getReadingExternalEntity());
3072:                    } else {
3073:                        if (!scanExternalID(false)) {
3074:                            skipPastEndOfCurrentMarkup();
3075:                            fDTDGrammar.endEntityDecl();
3076:                            return;
3077:                        }
3078:                        boolean unparsed = false;
3079:                        if (fEntityReader.lookingAtSpace(true)) {
3080:                            fEntityReader.skipPastSpaces();
3081:                            unparsed = fEntityReader
3082:                                    .skippedString(ndata_string);
3083:                        }
3084:                        if (!unparsed) {
3085:                            checkForPEReference(false);
3086:                            if (!fEntityReader.lookingAtChar('>', true)) {
3087:                                abortMarkup(
3088:                                        XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
3089:                                        XMLMessages.P72_UNTERMINATED,
3090:                                        entityName);
3091:                                fDTDGrammar.endEntityDecl();
3092:                                return;
3093:                            }
3094:                            decreaseMarkupDepth();
3095:                            fDTDGrammar.endEntityDecl();
3096:
3097:                            //a hack by Eric
3098:                            //REVISIT
3099:                            fDTDGrammar.addExternalEntityDecl(entityName,
3100:                                    fPubidLiteral, fSystemLiteral);
3101:                            if (fDTDHandler != null) {
3102:                                fDTDHandler.externalEntityDecl(entityName,
3103:                                        fPubidLiteral, fSystemLiteral);
3104:                            }
3105:                            int entityIndex = ((DefaultEntityHandler) fEntityHandler)
3106:                                    .addExternalEntityDecl(entityName,
3107:                                            fPubidLiteral, fSystemLiteral,
3108:                                            getReadingExternalEntity());
3109:
3110:                        } else {
3111:                            if (!fEntityReader.lookingAtSpace(true)) {
3112:                                abortMarkup(
3113:                                        XMLMessages.MSG_SPACE_REQUIRED_BEFORE_NOTATION_NAME_IN_UNPARSED_ENTITYDECL,
3114:                                        XMLMessages.P76_SPACE_REQUIRED,
3115:                                        entityName);
3116:                                fDTDGrammar.endEntityDecl();
3117:                                return;
3118:                            }
3119:                            fEntityReader.skipPastSpaces();
3120:                            int ndataOffset = fEntityReader.currentOffset();
3121:                            fEntityReader.skipPastName('>');
3122:                            int ndataLength = fEntityReader.currentOffset()
3123:                                    - ndataOffset;
3124:                            if (ndataLength == 0) {
3125:                                abortMarkup(
3126:                                        XMLMessages.MSG_NOTATION_NAME_REQUIRED_FOR_UNPARSED_ENTITYDECL,
3127:                                        XMLMessages.P76_REQUIRED, entityName);
3128:                                fDTDGrammar.endEntityDecl();
3129:                                return;
3130:                            }
3131:                            int notationName = fEntityReader.addSymbol(
3132:                                    ndataOffset, ndataLength);
3133:                            checkForPEReference(false);
3134:                            if (!fEntityReader.lookingAtChar('>', true)) {
3135:                                abortMarkup(
3136:                                        XMLMessages.MSG_ENTITYDECL_UNTERMINATED,
3137:                                        XMLMessages.P72_UNTERMINATED,
3138:                                        entityName);
3139:                                fDTDGrammar.endEntityDecl();
3140:                                return;
3141:                            }
3142:                            decreaseMarkupDepth();
3143:                            fDTDGrammar.endEntityDecl();
3144:
3145:                            //a hack by Eric
3146:                            //REVISIT
3147:                            fDTDGrammar
3148:                                    .addUnparsedEntityDecl(entityName,
3149:                                            fPubidLiteral, fSystemLiteral,
3150:                                            notationName);
3151:                            if (fDTDHandler != null) {
3152:                                fDTDHandler.unparsedEntityDecl(entityName,
3153:                                        fPubidLiteral, fSystemLiteral,
3154:                                        notationName);
3155:                            }
3156:                            /****
3157:                            System.out.println("----addUnparsedEntity--- "+ fStringPool.toString(entityName)+","
3158:                                               +fStringPool.toString(notationName)+","
3159:                                               +fStringPool.toString(fPubidLiteral) + ","
3160:                                               +fStringPool.toString(fSystemLiteral) + ","
3161:                                               +getReadingExternalEntity());
3162:                            /****/
3163:                            int entityIndex = ((DefaultEntityHandler) fEntityHandler)
3164:                                    .addUnparsedEntityDecl(entityName,
3165:                                            fPubidLiteral, fSystemLiteral,
3166:                                            notationName,
3167:                                            getReadingExternalEntity());
3168:                        }
3169:                    }
3170:                }
3171:            }
3172:
3173:            //
3174:            //  [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"'
3175:            //                      | "'" ([^%&'] | PEReference | Reference)* "'"
3176:            //
3177:            private int scanEntityValue(boolean single) throws Exception {
3178:                char qchar = single ? '\'' : '\"';
3179:                fEntityValueMark = fEntityReader.currentOffset();
3180:                int entityValue = fEntityReader.scanEntityValue(qchar, true);
3181:                if (entityValue < 0)
3182:                    entityValue = scanComplexEntityValue(qchar, entityValue);
3183:                return entityValue;
3184:            }
3185:
3186:            private int scanComplexEntityValue(char qchar, int result)
3187:                    throws Exception {
3188:                int previousState = setScannerState(SCANNER_STATE_ENTITY_VALUE);
3189:                fEntityValueReader = fReaderId;
3190:                int dataOffset = fLiteralData.length();
3191:                while (true) {
3192:                    switch (result) {
3193:                    case XMLEntityHandler.ENTITYVALUE_RESULT_FINISHED: {
3194:                        int offset = fEntityReader.currentOffset();
3195:                        fEntityReader.lookingAtChar(qchar, true);
3196:                        restoreScannerState(previousState);
3197:                        int dataLength = fLiteralData.length() - dataOffset;
3198:                        if (dataLength == 0) {
3199:                            return fEntityReader.addString(fEntityValueMark,
3200:                                    offset - fEntityValueMark);
3201:                        }
3202:                        if (offset - fEntityValueMark > 0) {
3203:                            fEntityReader
3204:                                    .append(fLiteralData, fEntityValueMark,
3205:                                            offset - fEntityValueMark);
3206:                            dataLength = fLiteralData.length() - dataOffset;
3207:                        }
3208:                        return fLiteralData.addString(dataOffset, dataLength);
3209:                    }
3210:                    case XMLEntityHandler.ENTITYVALUE_RESULT_REFERENCE: {
3211:                        int offset = fEntityReader.currentOffset();
3212:                        if (offset - fEntityValueMark > 0)
3213:                            fEntityReader
3214:                                    .append(fLiteralData, fEntityValueMark,
3215:                                            offset - fEntityValueMark);
3216:                        fEntityReader.lookingAtChar('&', true);
3217:                        //
3218:                        // Check for character reference first.
3219:                        //
3220:                        if (fEntityReader.lookingAtChar('#', true)) {
3221:                            int ch = scanCharRef();
3222:                            if (ch != -1) {
3223:                                if (ch < 0x10000)
3224:                                    fLiteralData.append((char) ch);
3225:                                else {
3226:                                    fLiteralData
3227:                                            .append((char) (((ch - 0x00010000) >> 10) + 0xd800));
3228:                                    fLiteralData
3229:                                            .append((char) (((ch - 0x00010000) & 0x3ff) + 0xdc00));
3230:                                }
3231:                            }
3232:                            fEntityValueMark = fEntityReader.currentOffset();
3233:                        } else {
3234:                            //
3235:                            // Entity reference
3236:                            //
3237:                            int nameOffset = fEntityReader.currentOffset();
3238:                            fEntityReader.skipPastName(';');
3239:                            int nameLength = fEntityReader.currentOffset()
3240:                                    - nameOffset;
3241:                            if (nameLength == 0) {
3242:                                reportFatalXMLError(
3243:                                        XMLMessages.MSG_NAME_REQUIRED_IN_REFERENCE,
3244:                                        XMLMessages.P68_NAME_REQUIRED);
3245:                                fEntityValueMark = fEntityReader
3246:                                        .currentOffset();
3247:                            } else if (!fEntityReader.lookingAtChar(';', true)) {
3248:                                reportFatalXMLError(
3249:                                        XMLMessages.MSG_SEMICOLON_REQUIRED_IN_REFERENCE,
3250:                                        XMLMessages.P68_SEMICOLON_REQUIRED,
3251:                                        fEntityReader.addString(nameOffset,
3252:                                                nameLength));
3253:                                fEntityValueMark = fEntityReader
3254:                                        .currentOffset();
3255:                            } else {
3256:                                //
3257:                                // 4.4.7 Bypassed
3258:                                //
3259:                                // When a general entity reference appears in the EntityValue in an
3260:                                // entity declaration, it is bypassed and left as is.
3261:                                //
3262:                                fEntityValueMark = offset;
3263:                            }
3264:                        }
3265:                        break;
3266:                    }
3267:                    case XMLEntityHandler.ENTITYVALUE_RESULT_PEREF: {
3268:                        int offset = fEntityReader.currentOffset();
3269:                        if (offset - fEntityValueMark > 0)
3270:                            fEntityReader
3271:                                    .append(fLiteralData, fEntityValueMark,
3272:                                            offset - fEntityValueMark);
3273:                        fEntityReader.lookingAtChar('%', true);
3274:                        int nameOffset = fEntityReader.currentOffset();
3275:                        fEntityReader.skipPastName(';');
3276:                        int nameLength = fEntityReader.currentOffset()
3277:                                - nameOffset;
3278:                        if (nameLength == 0) {
3279:                            reportFatalXMLError(
3280:                                    XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
3281:                                    XMLMessages.P69_NAME_REQUIRED);
3282:                        } else if (!fEntityReader.lookingAtChar(';', true)) {
3283:                            reportFatalXMLError(
3284:                                    XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
3285:                                    XMLMessages.P69_SEMICOLON_REQUIRED,
3286:                                    fEntityReader.addString(nameOffset,
3287:                                            nameLength));
3288:                        } else if (!getReadingExternalEntity()) {
3289:                            reportFatalXMLError(
3290:                                    XMLMessages.MSG_PEREFERENCE_WITHIN_MARKUP,
3291:                                    XMLMessages.WFC_PES_IN_INTERNAL_SUBSET,
3292:                                    fEntityReader.addString(nameOffset,
3293:                                            nameLength));
3294:                        } else {
3295:                            int peNameIndex = fEntityReader.addSymbol(
3296:                                    nameOffset, nameLength);
3297:                            fEntityHandler.startReadingFromEntity(peNameIndex,
3298:                                    markupDepth(),
3299:                                    XMLEntityHandler.ENTITYREF_IN_ENTITYVALUE);
3300:                        }
3301:                        fEntityValueMark = fEntityReader.currentOffset();
3302:                        break;
3303:                    }
3304:                    case XMLEntityHandler.ENTITYVALUE_RESULT_INVALID_CHAR: {
3305:                        int offset = fEntityReader.currentOffset();
3306:                        if (offset - fEntityValueMark > 0)
3307:                            fEntityReader
3308:                                    .append(fLiteralData, fEntityValueMark,
3309:                                            offset - fEntityValueMark);
3310:                        int invChar = fEntityReader.scanInvalidChar();
3311:                        if (fScannerState == SCANNER_STATE_END_OF_INPUT)
3312:                            return -1;
3313:                        if (invChar >= 0) {
3314:                            reportFatalXMLError(
3315:                                    XMLMessages.MSG_INVALID_CHAR_IN_ENTITYVALUE,
3316:                                    XMLMessages.P9_INVALID_CHARACTER, Integer
3317:                                            .toHexString(invChar));
3318:                        }
3319:                        fEntityValueMark = fEntityReader.currentOffset();
3320:                        break;
3321:                    }
3322:                    case XMLEntityHandler.ENTITYVALUE_RESULT_END_OF_INPUT:
3323:                        // all the work is done by the previous reader, just invoke the next one now.
3324:                        break;
3325:                    default:
3326:                        break;
3327:                    }
3328:                    result = fEntityReader
3329:                            .scanEntityValue(
3330:                                    fReaderId == fEntityValueReader ? qchar
3331:                                            : -1, false);
3332:                }
3333:            }
3334:
3335:            //
3336:            //
3337:            //
3338:            private boolean checkForPEReference(boolean spaceRequired)
3339:                    throws Exception {
3340:                boolean sawSpace = true;
3341:                if (spaceRequired)
3342:                    sawSpace = fEntityReader.lookingAtSpace(true);
3343:                fEntityReader.skipPastSpaces();
3344:                if (!getReadingExternalEntity())
3345:                    return sawSpace;
3346:                if (!fEntityReader.lookingAtChar('%', true))
3347:                    return sawSpace;
3348:                while (true) {
3349:                    int nameOffset = fEntityReader.currentOffset();
3350:                    fEntityReader.skipPastName(';');
3351:                    int nameLength = fEntityReader.currentOffset() - nameOffset;
3352:                    if (nameLength == 0) {
3353:                        reportFatalXMLError(
3354:                                XMLMessages.MSG_NAME_REQUIRED_IN_PEREFERENCE,
3355:                                XMLMessages.P69_NAME_REQUIRED);
3356:                    } else if (!fEntityReader.lookingAtChar(';', true)) {
3357:                        reportFatalXMLError(
3358:                                XMLMessages.MSG_SEMICOLON_REQUIRED_IN_PEREFERENCE,
3359:                                XMLMessages.P69_SEMICOLON_REQUIRED,
3360:                                fEntityReader.addString(nameOffset, nameLength));
3361:                    } else {
3362:                        int peNameIndex = fEntityReader.addSymbol(nameOffset,
3363:                                nameLength);
3364:                        int readerDepth = (fScannerState == SCANNER_STATE_CONTENTSPEC) ? parenDepth()
3365:                                : markupDepth();
3366:                        fEntityHandler
3367:                                .startReadingFromEntity(
3368:                                        peNameIndex,
3369:                                        readerDepth,
3370:                                        XMLEntityHandler.ENTITYREF_IN_DTD_WITHIN_MARKUP);
3371:                    }
3372:                    fEntityReader.skipPastSpaces();
3373:                    if (!fEntityReader.lookingAtChar('%', true))
3374:                        return true;
3375:                }
3376:            }
3377:
3378:            //
3379:            // content model stack
3380:            //
3381:            private void initializeContentModelStack(int depth) {
3382:                if (fOpStack == null) {
3383:                    fOpStack = new int[8];
3384:                    fNodeIndexStack = new int[8];
3385:                    fPrevNodeIndexStack = new int[8];
3386:                } else if (depth == fOpStack.length) {
3387:                    int[] newStack = new int[depth * 2];
3388:                    System.arraycopy(fOpStack, 0, newStack, 0, depth);
3389:                    fOpStack = newStack;
3390:                    newStack = new int[depth * 2];
3391:                    System.arraycopy(fNodeIndexStack, 0, newStack, 0, depth);
3392:                    fNodeIndexStack = newStack;
3393:                    newStack = new int[depth * 2];
3394:                    System
3395:                            .arraycopy(fPrevNodeIndexStack, 0, newStack, 0,
3396:                                    depth);
3397:                    fPrevNodeIndexStack = newStack;
3398:                }
3399:                fOpStack[depth] = -1;
3400:                fNodeIndexStack[depth] = -1;
3401:                fPrevNodeIndexStack[depth] = -1;
3402:            }
3403:
3404:            private boolean validVersionNum(String version) {
3405:                return XMLCharacterProperties.validVersionNum(version);
3406:            }
3407:
3408:            private boolean validEncName(String encoding) {
3409:                return XMLCharacterProperties.validEncName(encoding);
3410:            }
3411:
3412:            private int validPublicId(String publicId) {
3413:                return XMLCharacterProperties.validPublicId(publicId);
3414:            }
3415:
3416:            private void scanElementType(
3417:                    XMLEntityHandler.EntityReader entityReader, char fastchar,
3418:                    QName element) throws Exception {
3419:
3420:                if (!fNamespacesEnabled) {
3421:                    element.clear();
3422:                    element.localpart = entityReader.scanName(fastchar);
3423:                    element.rawname = element.localpart;
3424:                    return;
3425:                }
3426:                entityReader.scanQName(fastchar, element);
3427:                if (entityReader.lookingAtChar(':', false)) {
3428:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
3429:                            XMLMessages.XML_DOMAIN,
3430:                            XMLMessages.MSG_TWO_COLONS_IN_QNAME,
3431:                            XMLMessages.P5_INVALID_CHARACTER, null,
3432:                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3433:                    entityReader.skipPastNmtoken(' ');
3434:                }
3435:
3436:            } // scanElementType(XMLEntityHandler.EntityReader,char,QName)
3437:
3438:            public void checkForElementTypeWithPEReference(
3439:                    XMLEntityHandler.EntityReader entityReader, char fastchar,
3440:                    QName element) throws Exception {
3441:
3442:                if (!fNamespacesEnabled) {
3443:                    element.clear();
3444:                    element.localpart = entityReader.scanName(fastchar);
3445:                    element.rawname = element.localpart;
3446:                    return;
3447:                }
3448:                entityReader.scanQName(fastchar, element);
3449:                if (entityReader.lookingAtChar(':', false)) {
3450:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
3451:                            XMLMessages.XML_DOMAIN,
3452:                            XMLMessages.MSG_TWO_COLONS_IN_QNAME,
3453:                            XMLMessages.P5_INVALID_CHARACTER, null,
3454:                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3455:                    entityReader.skipPastNmtoken(' ');
3456:                }
3457:
3458:            } // checkForElementTypeWithPEReference(XMLEntityHandler.EntityReader,char,QName)
3459:
3460:            public void checkForAttributeNameWithPEReference(
3461:                    XMLEntityHandler.EntityReader entityReader, char fastchar,
3462:                    QName attribute) throws Exception {
3463:
3464:                if (!fNamespacesEnabled) {
3465:                    attribute.clear();
3466:                    attribute.localpart = entityReader.scanName(fastchar);
3467:                    attribute.rawname = attribute.localpart;
3468:                    return;
3469:                }
3470:
3471:                entityReader.scanQName(fastchar, attribute);
3472:                if (entityReader.lookingAtChar(':', false)) {
3473:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
3474:                            XMLMessages.XML_DOMAIN,
3475:                            XMLMessages.MSG_TWO_COLONS_IN_QNAME,
3476:                            XMLMessages.P5_INVALID_CHARACTER, null,
3477:                            XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
3478:                    entityReader.skipPastNmtoken(' ');
3479:                }
3480:
3481:            } // checkForAttributeNameWithPEReference(XMLEntityHandler.EntityReader,char,QName)
3482:
3483:            public int checkForNameWithPEReference(
3484:                    XMLEntityHandler.EntityReader entityReader, char fastcheck)
3485:                    throws Exception {
3486:                //
3487:                // REVISIT - what does this have to do with PE references?
3488:                //
3489:                int valueIndex = entityReader.scanName(fastcheck);
3490:                return valueIndex;
3491:            }
3492:
3493:            public int checkForNmtokenWithPEReference(
3494:                    XMLEntityHandler.EntityReader entityReader, char fastcheck)
3495:                    throws Exception {
3496:                //
3497:                // REVISIT - what does this have to do with PE references?
3498:                //
3499:                int nameOffset = entityReader.currentOffset();
3500:                entityReader.skipPastNmtoken(fastcheck);
3501:                int nameLength = entityReader.currentOffset() - nameOffset;
3502:                if (nameLength == 0)
3503:                    return -1;
3504:                int valueIndex = entityReader.addSymbol(nameOffset, nameLength);
3505:                return valueIndex;
3506:            }
3507:
3508:            public int scanDefaultAttValue(QName element, QName attribute,
3509:                    int attType, int enumeration) throws Exception {
3510:                /***/
3511:                if (fValidationEnabled && attType == XMLAttributeDecl.TYPE_ID) {
3512:                    reportRecoverableXMLError(
3513:                            XMLMessages.MSG_ID_DEFAULT_TYPE_INVALID,
3514:                            XMLMessages.VC_ID_ATTRIBUTE_DEFAULT, fStringPool
3515:                                    .toString(attribute.rawname));
3516:                }
3517:                /***/
3518:                int defaultAttValue = scanDefaultAttValue(element, attribute);
3519:                if (defaultAttValue == -1)
3520:                    return -1;
3521:                // REVISIT
3522:                /***
3523:                if (attType != fCDATASymbol) {
3524:                    // REVISIT: Validation. Should we pass in the element or is this
3525:                    //          default attribute value normalization?
3526:                    defaultAttValue = fValidator.normalizeAttValue(null, attribute, defaultAttValue, attType, enumeration);
3527:                }
3528:                /***/
3529:                return defaultAttValue;
3530:            }
3531:
3532:            public int normalizeDefaultAttValue(QName attribute,
3533:                    int defaultAttValue, int attType, int enumeration,
3534:                    boolean list) throws Exception {
3535:                //
3536:                // Normalize attribute based upon attribute type...
3537:                //
3538:                String attValue = fStringPool.toString(defaultAttValue);
3539:
3540:                if (list) {
3541:                    StringTokenizer tokenizer = new StringTokenizer(attValue);
3542:                    StringBuffer sb = new StringBuffer(attValue.length());
3543:                    boolean ok = true;
3544:                    if (tokenizer.hasMoreTokens()) {
3545:                        while (true) {
3546:                            String nmtoken = tokenizer.nextToken();
3547:                            if (attType == XMLAttributeDecl.TYPE_NMTOKEN) {
3548:                                if (fValidationEnabled
3549:                                        && !XMLCharacterProperties
3550:                                                .validNmtoken(nmtoken)) {
3551:                                    ok = false;
3552:                                }
3553:                            } else if (attType == XMLAttributeDecl.TYPE_IDREF
3554:                                    || attType == XMLAttributeDecl.TYPE_ENTITY) {
3555:                                if (fValidationEnabled
3556:                                        && !XMLCharacterProperties
3557:                                                .validName(nmtoken)) {
3558:                                    ok = false;
3559:                                }
3560:                                // REVISIT: a Hack!!! THis is to pass SUN test /invalid/attr11.xml and attr12.xml
3561:                                // not consistent with XML1.0 spec VC: Attribute Default Legal
3562:                                if (fValidationEnabled
3563:                                        && attType == XMLAttributeDecl.TYPE_ENTITY)
3564:                                    if (!((DefaultEntityHandler) fEntityHandler)
3565:                                            .isUnparsedEntity(defaultAttValue)) {
3566:                                        reportRecoverableXMLError(
3567:                                                XMLMessages.MSG_ENTITY_INVALID,
3568:                                                XMLMessages.VC_ENTITY_NAME,
3569:                                                fStringPool
3570:                                                        .toString(attribute.rawname),
3571:                                                nmtoken);
3572:                                    }
3573:
3574:                            }
3575:                            sb.append(nmtoken);
3576:                            if (!tokenizer.hasMoreTokens()) {
3577:                                break;
3578:                            }
3579:                            sb.append(' ');
3580:                        }
3581:                    }
3582:                    String newAttValue = sb.toString();
3583:                    if (fValidationEnabled
3584:                            && (!ok || newAttValue.length() == 0)) {
3585:                        reportRecoverableXMLError(
3586:                                XMLMessages.MSG_ATT_DEFAULT_INVALID,
3587:                                XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
3588:                                fStringPool.toString(attribute.rawname),
3589:                                newAttValue);
3590:                    }
3591:                    if (!newAttValue.equals(attValue)) {
3592:                        defaultAttValue = fStringPool.addString(newAttValue);
3593:                    }
3594:                    return defaultAttValue;
3595:                } else {
3596:                    String newAttValue = attValue.trim();
3597:
3598:                    if (fValidationEnabled) {
3599:                        // REVISIT - can we release the old string?
3600:                        if (newAttValue != attValue) {
3601:                            defaultAttValue = fStringPool
3602:                                    .addSymbol(newAttValue);
3603:                        } else {
3604:                            defaultAttValue = fStringPool
3605:                                    .addSymbol(defaultAttValue);
3606:                        }
3607:                        if (attType == XMLAttributeDecl.TYPE_ENTITY
3608:                                || attType == XMLAttributeDecl.TYPE_ID
3609:                                || attType == XMLAttributeDecl.TYPE_IDREF
3610:                                || attType == XMLAttributeDecl.TYPE_NOTATION) {
3611:
3612:                            // REVISIT: A Hack!!! THis is to pass SUN test /invalid/attr11.xml and attr12.xml
3613:                            // not consistent with XML1.0 spec VC: Attribute Default Legal
3614:                            if (attType == XMLAttributeDecl.TYPE_ENTITY)
3615:                                if (!((DefaultEntityHandler) fEntityHandler)
3616:                                        .isUnparsedEntity(defaultAttValue)) {
3617:                                    reportRecoverableXMLError(
3618:                                            XMLMessages.MSG_ENTITY_INVALID,
3619:                                            XMLMessages.VC_ENTITY_NAME,
3620:                                            fStringPool
3621:                                                    .toString(attribute.rawname),
3622:                                            newAttValue);
3623:                                }
3624:
3625:                            if (!XMLCharacterProperties.validName(newAttValue)) {
3626:                                reportRecoverableXMLError(
3627:                                        XMLMessages.MSG_ATT_DEFAULT_INVALID,
3628:                                        XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
3629:                                        fStringPool.toString(attribute.rawname),
3630:                                        newAttValue);
3631:                            }
3632:
3633:                        } else if (attType == XMLAttributeDecl.TYPE_NMTOKEN
3634:                                || attType == XMLAttributeDecl.TYPE_ENUMERATION) {
3635:
3636:                            if (!XMLCharacterProperties
3637:                                    .validNmtoken(newAttValue)) {
3638:                                reportRecoverableXMLError(
3639:                                        XMLMessages.MSG_ATT_DEFAULT_INVALID,
3640:                                        XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
3641:                                        fStringPool.toString(attribute.rawname),
3642:                                        newAttValue);
3643:                            }
3644:                        }
3645:
3646:                        if (attType == XMLAttributeDecl.TYPE_NOTATION
3647:                                || attType == XMLAttributeDecl.TYPE_ENUMERATION) {
3648:
3649:                            if (!fStringPool.stringInList(enumeration,
3650:                                    defaultAttValue)) {
3651:                                reportRecoverableXMLError(
3652:                                        XMLMessages.MSG_ATT_DEFAULT_INVALID,
3653:                                        XMLMessages.VC_ATTRIBUTE_DEFAULT_LEGAL,
3654:                                        fStringPool.toString(attribute.rawname),
3655:                                        newAttValue);
3656:                            }
3657:                        }
3658:
3659:                    } else if (newAttValue != attValue) {
3660:                        // REVISIT - can we release the old string?
3661:                        defaultAttValue = fStringPool.addSymbol(newAttValue);
3662:                    }
3663:                }
3664:
3665:                return defaultAttValue;
3666:            }
3667:            /***
3668:            public boolean scanDoctypeDecl(boolean standalone) throws Exception {
3669:                fStandaloneReader = standalone ? fEntityHandler.getReaderId() : -1;
3670:                fDeclsAreExternal = false;
3671:                if (!fDTDScanner.scanDoctypeDecl()) {
3672:                    return false;
3673:                }
3674:                if (fDTDScanner.getReadingExternalEntity()) {
3675:                    fDTDScanner.scanDecls(true);
3676:                }
3677:                fDTDHandler.endDTD();
3678:                return true;
3679:            }
3680:            /***/
3681:
3682:        } // class XMLDTDScanner
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.