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

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


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.xerces.impl.dtd;
0019:
0020:        import org.apache.xerces.impl.Constants;
0021:        import org.apache.xerces.impl.RevalidationHandler;
0022:        import org.apache.xerces.impl.XMLEntityManager;
0023:        import org.apache.xerces.impl.XMLErrorReporter;
0024:        import org.apache.xerces.impl.dtd.models.ContentModelValidator;
0025:        import org.apache.xerces.impl.dv.DTDDVFactory;
0026:        import org.apache.xerces.impl.dv.DatatypeValidator;
0027:        import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
0028:        import org.apache.xerces.impl.msg.XMLMessageFormatter;
0029:        import org.apache.xerces.impl.validation.ValidationManager;
0030:        import org.apache.xerces.impl.validation.ValidationState;
0031:        import org.apache.xerces.util.SymbolTable;
0032:        import org.apache.xerces.util.XMLChar;
0033:        import org.apache.xerces.util.XMLSymbols;
0034:        import org.apache.xerces.xni.Augmentations;
0035:        import org.apache.xerces.xni.NamespaceContext;
0036:        import org.apache.xerces.xni.QName;
0037:        import org.apache.xerces.xni.XMLAttributes;
0038:        import org.apache.xerces.xni.XMLDocumentHandler;
0039:        import org.apache.xerces.xni.XMLLocator;
0040:        import org.apache.xerces.xni.XMLResourceIdentifier;
0041:        import org.apache.xerces.xni.XMLString;
0042:        import org.apache.xerces.xni.XNIException;
0043:        import org.apache.xerces.xni.grammars.Grammar;
0044:        import org.apache.xerces.xni.grammars.XMLGrammarDescription;
0045:        import org.apache.xerces.xni.grammars.XMLGrammarPool;
0046:        import org.apache.xerces.xni.parser.XMLComponent;
0047:        import org.apache.xerces.xni.parser.XMLComponentManager;
0048:        import org.apache.xerces.xni.parser.XMLConfigurationException;
0049:        import org.apache.xerces.xni.parser.XMLDocumentFilter;
0050:        import org.apache.xerces.xni.parser.XMLDocumentSource;
0051:
0052:        /**
0053:         * The DTD validator. The validator implements a document
0054:         * filter: receiving document events from the scanner; validating
0055:         * the content and structure; augmenting the InfoSet, if applicable;
0056:         * and notifying the parser of the information resulting from the
0057:         * validation process.
0058:         * <p> Formerly, this component also handled DTD events and grammar construction.
0059:         * To facilitate the development of a meaningful DTD grammar caching/preparsing
0060:         * framework, this functionality has been moved into the XMLDTDLoader
0061:         * class.  Therefore, this class no longer implements the DTDFilter
0062:         * or DTDContentModelFilter interfaces.
0063:         * <p>
0064:         * This component requires the following features and properties from the
0065:         * component manager that uses it:
0066:         * <ul>
0067:         *  <li>http://xml.org/sax/features/namespaces</li>
0068:         *  <li>http://xml.org/sax/features/validation</li>
0069:         *  <li>http://apache.org/xml/features/validation/dynamic</li>
0070:         *  <li>http://apache.org/xml/properties/internal/symbol-table</li>
0071:         *  <li>http://apache.org/xml/properties/internal/error-reporter</li>
0072:         *  <li>http://apache.org/xml/properties/internal/grammar-pool</li>
0073:         *  <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
0074:         * </ul>
0075:         * 
0076:         * @xerces.internal
0077:         *
0078:         * @author Eric Ye, IBM
0079:         * @author Andy Clark, IBM
0080:         * @author Jeffrey Rodriguez IBM
0081:         * @author Neil Graham, IBM
0082:         *
0083:         * @version $Id: XMLDTDValidator.java 572055 2007-09-02 17:55:43Z mrglavas $
0084:         */
0085:        public class XMLDTDValidator implements  XMLComponent,
0086:                XMLDocumentFilter, XMLDTDValidatorFilter, RevalidationHandler {
0087:
0088:            //
0089:            // Constants
0090:            //
0091:
0092:            /** Symbol: "&lt;&lt;datatypes>>". */
0093:
0094:            /** Top level scope (-1). */
0095:            private static final int TOP_LEVEL_SCOPE = -1;
0096:
0097:            // feature identifiers
0098:
0099:            /** Feature identifier: namespaces. */
0100:            protected static final String NAMESPACES = Constants.SAX_FEATURE_PREFIX
0101:                    + Constants.NAMESPACES_FEATURE;
0102:
0103:            /** Feature identifier: validation. */
0104:            protected static final String VALIDATION = Constants.SAX_FEATURE_PREFIX
0105:                    + Constants.VALIDATION_FEATURE;
0106:
0107:            /** Feature identifier: dynamic validation. */
0108:            protected static final String DYNAMIC_VALIDATION = Constants.XERCES_FEATURE_PREFIX
0109:                    + Constants.DYNAMIC_VALIDATION_FEATURE;
0110:
0111:            /** Feature identifier: balance syntax trees. */
0112:            protected static final String BALANCE_SYNTAX_TREES = Constants.XERCES_FEATURE_PREFIX
0113:                    + Constants.BALANCE_SYNTAX_TREES;
0114:
0115:            /** Feature identifier: warn on duplicate attdef */
0116:            protected static final String WARN_ON_DUPLICATE_ATTDEF = Constants.XERCES_FEATURE_PREFIX
0117:                    + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
0118:
0119:            protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX
0120:                    + Constants.PARSER_SETTINGS;
0121:
0122:            // property identifiers
0123:
0124:            /** Property identifier: symbol table. */
0125:            protected static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX
0126:                    + Constants.SYMBOL_TABLE_PROPERTY;
0127:
0128:            /** Property identifier: error reporter. */
0129:            protected static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX
0130:                    + Constants.ERROR_REPORTER_PROPERTY;
0131:
0132:            /** Property identifier: grammar pool. */
0133:            protected static final String GRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX
0134:                    + Constants.XMLGRAMMAR_POOL_PROPERTY;
0135:
0136:            /** Property identifier: datatype validator factory. */
0137:            protected static final String DATATYPE_VALIDATOR_FACTORY = Constants.XERCES_PROPERTY_PREFIX
0138:                    + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
0139:
0140:            // property identifier:  ValidationManager
0141:            protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0142:                    + Constants.VALIDATION_MANAGER_PROPERTY;
0143:
0144:            // recognized features and properties
0145:
0146:            /** Recognized features. */
0147:            private static final String[] RECOGNIZED_FEATURES = { NAMESPACES,
0148:                    VALIDATION, DYNAMIC_VALIDATION, BALANCE_SYNTAX_TREES };
0149:
0150:            /** Feature defaults. */
0151:            private static final Boolean[] FEATURE_DEFAULTS = { null, null,
0152:                    Boolean.FALSE, Boolean.FALSE, };
0153:
0154:            /** Recognized properties. */
0155:            private static final String[] RECOGNIZED_PROPERTIES = {
0156:                    SYMBOL_TABLE, ERROR_REPORTER, GRAMMAR_POOL,
0157:                    DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER };
0158:
0159:            /** Property defaults. */
0160:            private static final Object[] PROPERTY_DEFAULTS = { null, null,
0161:                    null, null, null, };
0162:
0163:            // debugging
0164:
0165:            /** Compile to true to debug attributes. */
0166:            private static final boolean DEBUG_ATTRIBUTES = false;
0167:
0168:            /** Compile to true to debug element children. */
0169:            private static final boolean DEBUG_ELEMENT_CHILDREN = false;
0170:
0171:            //        
0172:            // Data
0173:            //
0174:
0175:            // updated during reset
0176:            protected ValidationManager fValidationManager = null;
0177:
0178:            // validation state
0179:            protected final ValidationState fValidationState = new ValidationState();
0180:
0181:            // features
0182:
0183:            /** Namespaces. */
0184:            protected boolean fNamespaces;
0185:
0186:            /** Validation. */
0187:            protected boolean fValidation;
0188:
0189:            /** Validation against only DTD */
0190:            protected boolean fDTDValidation;
0191:
0192:            /** 
0193:             * Dynamic validation. This state of this feature is only useful when
0194:             * the validation feature is set to <code>true</code>.
0195:             */
0196:            protected boolean fDynamicValidation;
0197:
0198:            /** Controls whether the DTD grammar produces balanced syntax trees. */
0199:            protected boolean fBalanceSyntaxTrees;
0200:
0201:            /** warn on duplicate attribute definition, this feature works only when validation is true */
0202:            protected boolean fWarnDuplicateAttdef;
0203:
0204:            // properties
0205:
0206:            /** Symbol table. */
0207:            protected SymbolTable fSymbolTable;
0208:
0209:            /** Error reporter. */
0210:            protected XMLErrorReporter fErrorReporter;
0211:
0212:            // the grammar pool
0213:            protected XMLGrammarPool fGrammarPool;
0214:
0215:            /** Grammar bucket. */
0216:            protected DTDGrammarBucket fGrammarBucket;
0217:
0218:            /* location of the document as passed in from startDocument call */
0219:            protected XMLLocator fDocLocation;
0220:
0221:            /** Namespace support. */
0222:            protected NamespaceContext fNamespaceContext = null;
0223:
0224:            /** Datatype validator factory. */
0225:            protected DTDDVFactory fDatatypeValidatorFactory;
0226:
0227:            // handlers
0228:
0229:            /** Document handler. */
0230:            protected XMLDocumentHandler fDocumentHandler;
0231:
0232:            protected XMLDocumentSource fDocumentSource;
0233:            // grammars
0234:
0235:            /** DTD Grammar. */
0236:            protected DTDGrammar fDTDGrammar;
0237:
0238:            // state
0239:
0240:            /** True if seen DOCTYPE declaration. */
0241:            protected boolean fSeenDoctypeDecl = false;
0242:
0243:            /** Perform validation. */
0244:            private boolean fPerformValidation;
0245:
0246:            /** Schema type: None, DTD, Schema */
0247:            private String fSchemaType;
0248:
0249:            // information regarding the current element
0250:
0251:            /** Current element name. */
0252:            private final QName fCurrentElement = new QName();
0253:
0254:            /** Current element index. */
0255:            private int fCurrentElementIndex = -1;
0256:
0257:            /** Current content spec type. */
0258:            private int fCurrentContentSpecType = -1;
0259:
0260:            /** The root element name. */
0261:            private final QName fRootElement = new QName();
0262:
0263:            private boolean fInCDATASection = false;
0264:            // element stack
0265:
0266:            /** Element index stack. */
0267:            private int[] fElementIndexStack = new int[8];
0268:
0269:            /** Content spec type stack. */
0270:            private int[] fContentSpecTypeStack = new int[8];
0271:
0272:            /** Element name stack. */
0273:            private QName[] fElementQNamePartsStack = new QName[8];
0274:
0275:            // children list and offset stack
0276:
0277:            /** 
0278:             * Element children. This data structure is a growing stack that
0279:             * holds the children of elements from the root to the current
0280:             * element depth. This structure never gets "deeper" than the
0281:             * deepest element. Space is re-used once each element is closed.
0282:             * <p>
0283:             * <strong>Note:</strong> This is much more efficient use of memory
0284:             * than creating new arrays for each element depth.
0285:             * <p>
0286:             * <strong>Note:</strong> The use of this data structure is for
0287:             * validation "on the way out". If the validation model changes to
0288:             * "on the way in", then this data structure is not needed.
0289:             */
0290:            private QName[] fElementChildren = new QName[32];
0291:
0292:            /** Element children count. */
0293:            private int fElementChildrenLength = 0;
0294:
0295:            /** 
0296:             * Element children offset stack. This stack refers to offsets
0297:             * into the <code>fElementChildren</code> array.
0298:             * @see #fElementChildren
0299:             */
0300:            private int[] fElementChildrenOffsetStack = new int[32];
0301:
0302:            /** Element depth. */
0303:            private int fElementDepth = -1;
0304:
0305:            // validation states
0306:
0307:            /** True if seen the root element. */
0308:            private boolean fSeenRootElement = false;
0309:
0310:            /** True if inside of element content. */
0311:            private boolean fInElementContent = false;
0312:
0313:            // temporary variables
0314:
0315:            /** Temporary element declaration. */
0316:            private XMLElementDecl fTempElementDecl = new XMLElementDecl();
0317:
0318:            /** Temporary atribute declaration. */
0319:            private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
0320:
0321:            /** Temporary entity declaration. */
0322:            private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
0323:
0324:            /** Temporary qualified name. */
0325:            private QName fTempQName = new QName();
0326:
0327:            /** Temporary string buffers. */
0328:            private StringBuffer fBuffer = new StringBuffer();
0329:
0330:            // symbols: general
0331:
0332:            // attribute validators
0333:
0334:            /** Datatype validator: ID. */
0335:            protected DatatypeValidator fValID;
0336:
0337:            /** Datatype validator: IDREF. */
0338:            protected DatatypeValidator fValIDRef;
0339:
0340:            /** Datatype validator: IDREFS. */
0341:            protected DatatypeValidator fValIDRefs;
0342:
0343:            /** Datatype validator: ENTITY. */
0344:            protected DatatypeValidator fValENTITY;
0345:
0346:            /** Datatype validator: ENTITIES. */
0347:            protected DatatypeValidator fValENTITIES;
0348:
0349:            /** Datatype validator: NMTOKEN. */
0350:            protected DatatypeValidator fValNMTOKEN;
0351:
0352:            /** Datatype validator: NMTOKENS. */
0353:            protected DatatypeValidator fValNMTOKENS;
0354:
0355:            /** Datatype validator: NOTATION. */
0356:            protected DatatypeValidator fValNOTATION;
0357:
0358:            // to check for duplicate ID or ANNOTATION attribute declare in
0359:            // ATTLIST, and misc VCs
0360:
0361:            //
0362:            // Constructors
0363:            //
0364:
0365:            /** Default constructor. */
0366:            public XMLDTDValidator() {
0367:
0368:                // initialize data
0369:                for (int i = 0; i < fElementQNamePartsStack.length; i++) {
0370:                    fElementQNamePartsStack[i] = new QName();
0371:                }
0372:                fGrammarBucket = new DTDGrammarBucket();
0373:
0374:            } // <init>()
0375:
0376:            DTDGrammarBucket getGrammarBucket() {
0377:                return fGrammarBucket;
0378:            } // getGrammarBucket():  DTDGrammarBucket
0379:
0380:            //
0381:            // XMLComponent methods
0382:            //
0383:
0384:            /*
0385:             * Resets the component. The component can query the component manager
0386:             * about any features and properties that affect the operation of the
0387:             * component.
0388:             * 
0389:             * @param componentManager The component manager.
0390:             *
0391:             * @throws SAXException Thrown by component on finitialization error.
0392:             *                      For example, if a feature or property is
0393:             *                      required for the operation of the component, the
0394:             *                      component manager may throw a 
0395:             *                      SAXNotRecognizedException or a
0396:             *                      SAXNotSupportedException.
0397:             */
0398:            public void reset(XMLComponentManager componentManager)
0399:                    throws XMLConfigurationException {
0400:
0401:                // clear grammars
0402:                fDTDGrammar = null;
0403:                fSeenDoctypeDecl = false;
0404:                fInCDATASection = false;
0405:                // initialize state
0406:                fSeenRootElement = false;
0407:                fInElementContent = false;
0408:                fCurrentElementIndex = -1;
0409:                fCurrentContentSpecType = -1;
0410:
0411:                fRootElement.clear();
0412:
0413:                fValidationState.resetIDTables();
0414:
0415:                fGrammarBucket.clear();
0416:                fElementDepth = -1;
0417:                fElementChildrenLength = 0;
0418:
0419:                boolean parser_settings;
0420:                try {
0421:                    parser_settings = componentManager
0422:                            .getFeature(PARSER_SETTINGS);
0423:                } catch (XMLConfigurationException e) {
0424:                    parser_settings = true;
0425:                }
0426:
0427:                if (!parser_settings) {
0428:                    // parser settings have not been changed
0429:                    fValidationManager.addValidationState(fValidationState);
0430:                    return;
0431:                }
0432:
0433:                // sax features
0434:                try {
0435:                    fNamespaces = componentManager.getFeature(NAMESPACES);
0436:                } catch (XMLConfigurationException e) {
0437:                    fNamespaces = true;
0438:                }
0439:                try {
0440:                    fValidation = componentManager.getFeature(VALIDATION);
0441:                } catch (XMLConfigurationException e) {
0442:                    fValidation = false;
0443:                }
0444:                try {
0445:                    fDTDValidation = !(componentManager
0446:                            .getFeature(Constants.XERCES_FEATURE_PREFIX
0447:                                    + Constants.SCHEMA_VALIDATION_FEATURE));
0448:                } catch (XMLConfigurationException e) {
0449:                    // must be in a schema-less configuration!
0450:                    fDTDValidation = true;
0451:                }
0452:
0453:                // Xerces features
0454:                try {
0455:                    fDynamicValidation = componentManager
0456:                            .getFeature(DYNAMIC_VALIDATION);
0457:                } catch (XMLConfigurationException e) {
0458:                    fDynamicValidation = false;
0459:                }
0460:
0461:                try {
0462:                    fBalanceSyntaxTrees = componentManager
0463:                            .getFeature(BALANCE_SYNTAX_TREES);
0464:                } catch (XMLConfigurationException e) {
0465:                    fBalanceSyntaxTrees = false;
0466:                }
0467:
0468:                try {
0469:                    fWarnDuplicateAttdef = componentManager
0470:                            .getFeature(WARN_ON_DUPLICATE_ATTDEF);
0471:                } catch (XMLConfigurationException e) {
0472:                    fWarnDuplicateAttdef = false;
0473:                }
0474:
0475:                try {
0476:                    fSchemaType = (String) componentManager
0477:                            .getProperty(Constants.JAXP_PROPERTY_PREFIX
0478:                                    + Constants.SCHEMA_LANGUAGE);
0479:                } catch (XMLConfigurationException e) {
0480:                    fSchemaType = null;
0481:                }
0482:
0483:                fValidationManager = (ValidationManager) componentManager
0484:                        .getProperty(VALIDATION_MANAGER);
0485:                fValidationManager.addValidationState(fValidationState);
0486:                fValidationState.setUsingNamespaces(fNamespaces);
0487:
0488:                // get needed components
0489:                fErrorReporter = (XMLErrorReporter) componentManager
0490:                        .getProperty(Constants.XERCES_PROPERTY_PREFIX
0491:                                + Constants.ERROR_REPORTER_PROPERTY);
0492:                fSymbolTable = (SymbolTable) componentManager
0493:                        .getProperty(Constants.XERCES_PROPERTY_PREFIX
0494:                                + Constants.SYMBOL_TABLE_PROPERTY);
0495:                try {
0496:                    fGrammarPool = (XMLGrammarPool) componentManager
0497:                            .getProperty(GRAMMAR_POOL);
0498:                } catch (XMLConfigurationException e) {
0499:                    fGrammarPool = null;
0500:                }
0501:
0502:                fDatatypeValidatorFactory = (DTDDVFactory) componentManager
0503:                        .getProperty(Constants.XERCES_PROPERTY_PREFIX
0504:                                + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY);
0505:                init();
0506:
0507:            } // reset(XMLComponentManager)
0508:
0509:            /**
0510:             * Returns a list of feature identifiers that are recognized by
0511:             * this component. This method may return null if no features
0512:             * are recognized by this component.
0513:             */
0514:            public String[] getRecognizedFeatures() {
0515:                return (String[]) (RECOGNIZED_FEATURES.clone());
0516:            } // getRecognizedFeatures():String[]
0517:
0518:            /**
0519:             * Sets the state of a feature. This method is called by the component
0520:             * manager any time after reset when a feature changes state. 
0521:             * <p>
0522:             * <strong>Note:</strong> Components should silently ignore features
0523:             * that do not affect the operation of the component.
0524:             * 
0525:             * @param featureId The feature identifier.
0526:             * @param state     The state of the feature.
0527:             *
0528:             * @throws SAXNotRecognizedException The component should not throw
0529:             *                                   this exception.
0530:             * @throws SAXNotSupportedException The component should not throw
0531:             *                                  this exception.
0532:             */
0533:            public void setFeature(String featureId, boolean state)
0534:                    throws XMLConfigurationException {
0535:            } // setFeature(String,boolean)
0536:
0537:            /**
0538:             * Returns a list of property identifiers that are recognized by
0539:             * this component. This method may return null if no properties
0540:             * are recognized by this component.
0541:             */
0542:            public String[] getRecognizedProperties() {
0543:                return (String[]) (RECOGNIZED_PROPERTIES.clone());
0544:            } // getRecognizedProperties():String[]
0545:
0546:            /**
0547:             * Sets the value of a property. This method is called by the component
0548:             * manager any time after reset when a property changes value. 
0549:             * <p>
0550:             * <strong>Note:</strong> Components should silently ignore properties
0551:             * that do not affect the operation of the component.
0552:             * 
0553:             * @param propertyId The property identifier.
0554:             * @param value      The value of the property.
0555:             *
0556:             * @throws SAXNotRecognizedException The component should not throw
0557:             *                                   this exception.
0558:             * @throws SAXNotSupportedException The component should not throw
0559:             *                                  this exception.
0560:             */
0561:            public void setProperty(String propertyId, Object value)
0562:                    throws XMLConfigurationException {
0563:            } // setProperty(String,Object)
0564:
0565:            /** 
0566:             * Returns the default state for a feature, or null if this
0567:             * component does not want to report a default value for this
0568:             * feature.
0569:             *
0570:             * @param featureId The feature identifier.
0571:             *
0572:             * @since Xerces 2.2.0
0573:             */
0574:            public Boolean getFeatureDefault(String featureId) {
0575:                for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
0576:                    if (RECOGNIZED_FEATURES[i].equals(featureId)) {
0577:                        return FEATURE_DEFAULTS[i];
0578:                    }
0579:                }
0580:                return null;
0581:            } // getFeatureDefault(String):Boolean
0582:
0583:            /** 
0584:             * Returns the default state for a property, or null if this
0585:             * component does not want to report a default value for this
0586:             * property. 
0587:             *
0588:             * @param propertyId The property identifier.
0589:             *
0590:             * @since Xerces 2.2.0
0591:             */
0592:            public Object getPropertyDefault(String propertyId) {
0593:                for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
0594:                    if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
0595:                        return PROPERTY_DEFAULTS[i];
0596:                    }
0597:                }
0598:                return null;
0599:            } // getPropertyDefault(String):Object
0600:
0601:            //
0602:            // XMLDocumentSource methods
0603:            //
0604:
0605:            /** Sets the document handler to receive information about the document. */
0606:            public void setDocumentHandler(XMLDocumentHandler documentHandler) {
0607:                fDocumentHandler = documentHandler;
0608:            } // setDocumentHandler(XMLDocumentHandler)
0609:
0610:            /** Returns the document handler */
0611:            public XMLDocumentHandler getDocumentHandler() {
0612:                return fDocumentHandler;
0613:            } // getDocumentHandler():  XMLDocumentHandler
0614:
0615:            //
0616:            // XMLDocumentHandler methods
0617:            //
0618:
0619:            /** Sets the document source */
0620:            public void setDocumentSource(XMLDocumentSource source) {
0621:                fDocumentSource = source;
0622:            } // setDocumentSource
0623:
0624:            /** Returns the document source */
0625:            public XMLDocumentSource getDocumentSource() {
0626:                return fDocumentSource;
0627:            } // getDocumentSource
0628:
0629:            /**
0630:             * The start of the document.
0631:             *
0632:             * @param locator The system identifier of the entity if the entity
0633:             *                 is external, null otherwise.
0634:             * @param encoding The auto-detected IANA encoding name of the entity
0635:             *                 stream. This value will be null in those situations
0636:             *                 where the entity encoding is not auto-detected (e.g.
0637:             *                 internal entities or a document entity that is
0638:             *                 parsed from a java.io.Reader).
0639:             * @param namespaceContext
0640:             *                 The namespace context in effect at the
0641:             *                 start of this document.
0642:             *                 This object represents the current context.
0643:             *                 Implementors of this class are responsible
0644:             *                 for copying the namespace bindings from the
0645:             *                 the current context (and its parent contexts)
0646:             *                 if that information is important.
0647:             * @param augs   Additional information that may include infoset augmentations
0648:             *
0649:             * @throws XNIException Thrown by handler to signal an error.
0650:             */
0651:            public void startDocument(XMLLocator locator, String encoding,
0652:                    NamespaceContext namespaceContext, Augmentations augs)
0653:                    throws XNIException {
0654:
0655:                // call handlers
0656:                // get initial grammars
0657:                if (fGrammarPool != null) {
0658:                    Grammar[] grammars = fGrammarPool
0659:                            .retrieveInitialGrammarSet(XMLGrammarDescription.XML_DTD);
0660:                    for (int i = 0; i < grammars.length; i++) {
0661:                        fGrammarBucket.putGrammar((DTDGrammar) grammars[i]);
0662:                    }
0663:                }
0664:                fDocLocation = locator;
0665:                fNamespaceContext = namespaceContext;
0666:
0667:                if (fDocumentHandler != null) {
0668:                    fDocumentHandler.startDocument(locator, encoding,
0669:                            namespaceContext, augs);
0670:                }
0671:
0672:            } // startDocument(XMLLocator,String)
0673:
0674:            /**
0675:             * Notifies of the presence of an XMLDecl line in the document. If
0676:             * present, this method will be called immediately following the
0677:             * startDocument call.
0678:             * 
0679:             * @param version    The XML version.
0680:             * @param encoding   The IANA encoding name of the document, or null if
0681:             *                   not specified.
0682:             * @param standalone The standalone value, or null if not specified.     
0683:             * @param augs   Additional information that may include infoset augmentations
0684:             *
0685:             * @throws XNIException Thrown by handler to signal an error.
0686:             */
0687:            public void xmlDecl(String version, String encoding,
0688:                    String standalone, Augmentations augs) throws XNIException {
0689:
0690:                // save standalone state
0691:                fGrammarBucket.setStandalone(standalone != null
0692:                        && standalone.equals("yes"));
0693:
0694:                // call handlers
0695:                if (fDocumentHandler != null) {
0696:                    fDocumentHandler.xmlDecl(version, encoding, standalone,
0697:                            augs);
0698:                }
0699:
0700:            } // xmlDecl(String,String,String)
0701:
0702:            /**
0703:             * Notifies of the presence of the DOCTYPE line in the document.
0704:             * 
0705:             * @param rootElement The name of the root element.
0706:             * @param publicId    The public identifier if an external DTD or null
0707:             *                    if the external DTD is specified using SYSTEM.
0708:             * @param systemId    The system identifier if an external DTD, null
0709:             *                    otherwise.     
0710:             * @param augs   Additional information that may include infoset augmentations
0711:             *
0712:             * @throws XNIException Thrown by handler to signal an error.
0713:             */
0714:            public void doctypeDecl(String rootElement, String publicId,
0715:                    String systemId, Augmentations augs) throws XNIException {
0716:
0717:                // save root element state
0718:                fSeenDoctypeDecl = true;
0719:                fRootElement.setValues(null, rootElement, rootElement, null);
0720:                // find or create grammar:
0721:                String eid = null;
0722:                try {
0723:                    eid = XMLEntityManager.expandSystemId(systemId,
0724:                            fDocLocation.getExpandedSystemId(), false);
0725:                } catch (java.io.IOException e) {
0726:                }
0727:                XMLDTDDescription grammarDesc = new XMLDTDDescription(publicId,
0728:                        systemId, fDocLocation.getExpandedSystemId(), eid,
0729:                        rootElement);
0730:                fDTDGrammar = fGrammarBucket.getGrammar(grammarDesc);
0731:                if (fDTDGrammar == null) {
0732:                    // give grammar pool a chance...
0733:                    //
0734:                    // Do not bother checking the pool if no public or system identifier was provided. 
0735:                    // Since so many different DTDs have roots in common, using only a root name as the 
0736:                    // key may cause an unexpected grammar to be retrieved from the grammar pool. This scenario
0737:                    // would occur when an ExternalSubsetResolver has been queried and the
0738:                    // XMLInputSource returned contains an input stream but no external identifier.
0739:                    // This can never happen when the instance document specified a DOCTYPE. -- mrglavas
0740:                    if (fGrammarPool != null
0741:                            && (systemId != null || publicId != null)) {
0742:                        fDTDGrammar = (DTDGrammar) fGrammarPool
0743:                                .retrieveGrammar(grammarDesc);
0744:                    }
0745:                }
0746:                if (fDTDGrammar == null) {
0747:                    // we'll have to create it...
0748:                    if (!fBalanceSyntaxTrees) {
0749:                        fDTDGrammar = new DTDGrammar(fSymbolTable, grammarDesc);
0750:                    } else {
0751:                        fDTDGrammar = new BalancedDTDGrammar(fSymbolTable,
0752:                                grammarDesc);
0753:                    }
0754:                } else {
0755:                    // we've found a cached one;so let's make sure not to read
0756:                    // any external subset!
0757:                    fValidationManager.setCachedDTD(true);
0758:                }
0759:                fGrammarBucket.setActiveGrammar(fDTDGrammar);
0760:
0761:                // call handlers
0762:                if (fDocumentHandler != null) {
0763:                    fDocumentHandler.doctypeDecl(rootElement, publicId,
0764:                            systemId, augs);
0765:                }
0766:
0767:            } // doctypeDecl(String,String,String, Augmentations)
0768:
0769:            /**
0770:             * The start of an element.
0771:             * 
0772:             * @param element    The name of the element.
0773:             * @param attributes The element attributes.     
0774:             * @param augs   Additional information that may include infoset augmentations
0775:             *
0776:             * @throws XNIException Thrown by handler to signal an error.
0777:             */
0778:            public void startElement(QName element, XMLAttributes attributes,
0779:                    Augmentations augs) throws XNIException {
0780:
0781:                handleStartElement(element, attributes, augs);
0782:                // call handlers
0783:                if (fDocumentHandler != null) {
0784:                    fDocumentHandler.startElement(element, attributes, augs);
0785:
0786:                }
0787:
0788:            } // startElement(QName,XMLAttributes)
0789:
0790:            /**
0791:             * An empty element.
0792:             * 
0793:             * @param element    The name of the element.
0794:             * @param attributes The element attributes.     
0795:             * @param augs   Additional information that may include infoset augmentations
0796:             *
0797:             * @throws XNIException Thrown by handler to signal an error.
0798:             */
0799:            public void emptyElement(QName element, XMLAttributes attributes,
0800:                    Augmentations augs) throws XNIException {
0801:
0802:                boolean removed = handleStartElement(element, attributes, augs);
0803:
0804:                if (fDocumentHandler != null) {
0805:                    fDocumentHandler.emptyElement(element, attributes, augs);
0806:                }
0807:                if (!removed) {
0808:                    handleEndElement(element, augs, true);
0809:                }
0810:
0811:            } // emptyElement(QName,XMLAttributes)
0812:
0813:            /**
0814:             * Character content.
0815:             * 
0816:             * @param text The content.
0817:             *
0818:             * @param augs   Additional information that may include infoset augmentations
0819:             *
0820:             * @throws XNIException Thrown by handler to signal an error.
0821:             */
0822:            public void characters(XMLString text, Augmentations augs)
0823:                    throws XNIException {
0824:
0825:                boolean callNextCharacters = true;
0826:
0827:                // REVISIT: [Q] Is there a more efficient way of doing this?
0828:                //          Perhaps if the scanner told us so we don't have to
0829:                //          look at the characters again. -Ac
0830:                boolean allWhiteSpace = true;
0831:                for (int i = text.offset; i < text.offset + text.length; i++) {
0832:                    if (!isSpace(text.ch[i])) {
0833:                        allWhiteSpace = false;
0834:                        break;
0835:                    }
0836:                }
0837:                // call the ignoreableWhiteSpace callback
0838:                // never call ignorableWhitespace if we are in cdata section
0839:                if (fInElementContent && allWhiteSpace && !fInCDATASection) {
0840:                    if (fDocumentHandler != null) {
0841:                        fDocumentHandler.ignorableWhitespace(text, augs);
0842:                        callNextCharacters = false;
0843:                    }
0844:                }
0845:
0846:                // validate
0847:                if (fPerformValidation) {
0848:                    if (fInElementContent) {
0849:                        if (fGrammarBucket.getStandalone()
0850:                                && fDTDGrammar
0851:                                        .getElementDeclIsExternal(fCurrentElementIndex)) {
0852:                            if (allWhiteSpace) {
0853:                                fErrorReporter
0854:                                        .reportError(
0855:                                                XMLMessageFormatter.XML_DOMAIN,
0856:                                                "MSG_WHITE_SPACE_IN_ELEMENT_CONTENT_WHEN_STANDALONE",
0857:                                                null,
0858:                                                XMLErrorReporter.SEVERITY_ERROR);
0859:                            }
0860:                        }
0861:                        if (!allWhiteSpace) {
0862:                            charDataInContent();
0863:                        }
0864:
0865:                        // For E15.2
0866:                        if (augs != null
0867:                                && augs.getItem(Constants.CHAR_REF_PROBABLE_WS) == Boolean.TRUE) {
0868:                            fErrorReporter
0869:                                    .reportError(
0870:                                            XMLMessageFormatter.XML_DOMAIN,
0871:                                            "MSG_CONTENT_INVALID_SPECIFIED",
0872:                                            new Object[] {
0873:                                                    fCurrentElement.rawname,
0874:                                                    fDTDGrammar
0875:                                                            .getContentSpecAsString(fElementDepth),
0876:                                                    "character reference" },
0877:                                            XMLErrorReporter.SEVERITY_ERROR);
0878:                        }
0879:                    }
0880:
0881:                    if (fCurrentContentSpecType == XMLElementDecl.TYPE_EMPTY) {
0882:                        charDataInContent();
0883:                    }
0884:                }
0885:
0886:                // call handlers
0887:                if (callNextCharacters && fDocumentHandler != null) {
0888:                    fDocumentHandler.characters(text, augs);
0889:                }
0890:
0891:            } // characters(XMLString)
0892:
0893:            /**
0894:             * Ignorable whitespace. For this method to be called, the document
0895:             * source must have some way of determining that the text containing
0896:             * only whitespace characters should be considered ignorable. For
0897:             * example, the validator can determine if a length of whitespace
0898:             * characters in the document are ignorable based on the element
0899:             * content model.
0900:             * 
0901:             * @param text The ignorable whitespace.
0902:             * @param augs   Additional information that may include infoset augmentations
0903:             *
0904:             * @throws XNIException Thrown by handler to signal an error.
0905:             */
0906:            public void ignorableWhitespace(XMLString text, Augmentations augs)
0907:                    throws XNIException {
0908:
0909:                // call handlers
0910:                if (fDocumentHandler != null) {
0911:                    fDocumentHandler.ignorableWhitespace(text, augs);
0912:                }
0913:
0914:            } // ignorableWhitespace(XMLString)
0915:
0916:            /**
0917:             * The end of an element.
0918:             * 
0919:             * @param element The name of the element.
0920:             * @param augs   Additional information that may include infoset augmentations
0921:             *
0922:             * @throws XNIException Thrown by handler to signal an error.
0923:             */
0924:            public void endElement(QName element, Augmentations augs)
0925:                    throws XNIException {
0926:
0927:                handleEndElement(element, augs, false);
0928:
0929:            } // endElement(QName)
0930:
0931:            /** 
0932:             * The start of a CDATA section. 
0933:             * @param augs   Additional information that may include infoset augmentations
0934:             *
0935:             * @throws XNIException Thrown by handler to signal an error.
0936:             */
0937:            public void startCDATA(Augmentations augs) throws XNIException {
0938:
0939:                if (fPerformValidation && fInElementContent) {
0940:                    charDataInContent();
0941:                }
0942:                fInCDATASection = true;
0943:                // call handlers
0944:                if (fDocumentHandler != null) {
0945:                    fDocumentHandler.startCDATA(augs);
0946:                }
0947:
0948:            } // startCDATA()
0949:
0950:            /**
0951:             * The end of a CDATA section. 
0952:             * @param augs   Additional information that may include infoset augmentations
0953:             *
0954:             * @throws XNIException Thrown by handler to signal an error.
0955:             */
0956:            public void endCDATA(Augmentations augs) throws XNIException {
0957:
0958:                fInCDATASection = false;
0959:                // call handlers
0960:                if (fDocumentHandler != null) {
0961:                    fDocumentHandler.endCDATA(augs);
0962:                }
0963:
0964:            } // endCDATA()
0965:
0966:            /**
0967:             * The end of the document.
0968:             * @param augs   Additional information that may include infoset augmentations
0969:             *
0970:             * @throws XNIException Thrown by handler to signal an error.
0971:             */
0972:            public void endDocument(Augmentations augs) throws XNIException {
0973:
0974:                // call handlers
0975:                if (fDocumentHandler != null) {
0976:                    fDocumentHandler.endDocument(augs);
0977:                }
0978:
0979:            } // endDocument()
0980:
0981:            /**
0982:             * A comment.
0983:             * 
0984:             * @param text The text in the comment.
0985:             * @param augs   Additional information that may include infoset augmentations
0986:             *
0987:             * @throws XNIException Thrown by application to signal an error.
0988:             */
0989:            public void comment(XMLString text, Augmentations augs)
0990:                    throws XNIException {
0991:                // fixes E15.1
0992:                if (fPerformValidation && fElementDepth >= 0
0993:                        && fDTDGrammar != null) {
0994:                    fDTDGrammar.getElementDecl(fCurrentElementIndex,
0995:                            fTempElementDecl);
0996:                    if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
0997:                        fErrorReporter.reportError(
0998:                                XMLMessageFormatter.XML_DOMAIN,
0999:                                "MSG_CONTENT_INVALID_SPECIFIED", new Object[] {
1000:                                        fCurrentElement.rawname, "EMPTY",
1001:                                        "comment" },
1002:                                XMLErrorReporter.SEVERITY_ERROR);
1003:                    }
1004:                }
1005:                // call handlers
1006:                if (fDocumentHandler != null) {
1007:                    fDocumentHandler.comment(text, augs);
1008:                }
1009:
1010:            } // comment(XMLString)
1011:
1012:            /**
1013:             * A processing instruction. Processing instructions consist of a
1014:             * target name and, optionally, text data. The data is only meaningful
1015:             * to the application.
1016:             * <p>
1017:             * Typically, a processing instruction's data will contain a series
1018:             * of pseudo-attributes. These pseudo-attributes follow the form of
1019:             * element attributes but are <strong>not</strong> parsed or presented
1020:             * to the application as anything other than text. The application is
1021:             * responsible for parsing the data.
1022:             * 
1023:             * @param target The target.
1024:             * @param data   The data or null if none specified.     
1025:             * @param augs   Additional information that may include infoset augmentations
1026:             *
1027:             * @throws XNIException Thrown by handler to signal an error.
1028:             */
1029:            public void processingInstruction(String target, XMLString data,
1030:                    Augmentations augs) throws XNIException {
1031:
1032:                // fixes E15.1
1033:                if (fPerformValidation && fElementDepth >= 0
1034:                        && fDTDGrammar != null) {
1035:                    fDTDGrammar.getElementDecl(fCurrentElementIndex,
1036:                            fTempElementDecl);
1037:                    if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
1038:                        fErrorReporter.reportError(
1039:                                XMLMessageFormatter.XML_DOMAIN,
1040:                                "MSG_CONTENT_INVALID_SPECIFIED", new Object[] {
1041:                                        fCurrentElement.rawname, "EMPTY",
1042:                                        "processing instruction" },
1043:                                XMLErrorReporter.SEVERITY_ERROR);
1044:                    }
1045:                }
1046:                // call handlers
1047:                if (fDocumentHandler != null) {
1048:                    fDocumentHandler.processingInstruction(target, data, augs);
1049:                }
1050:            } // processingInstruction(String,XMLString)
1051:
1052:            /**
1053:             * This method notifies the start of a general entity.
1054:             * <p>
1055:             * <strong>Note:</strong> This method is not called for entity references
1056:             * appearing as part of attribute values.
1057:             * 
1058:             * @param name     The name of the general entity.
1059:             * @param identifier The resource identifier.
1060:             * @param encoding The auto-detected IANA encoding name of the entity
1061:             *                 stream. This value will be null in those situations
1062:             *                 where the entity encoding is not auto-detected (e.g.
1063:             *                 internal entities or a document entity that is
1064:             *                 parsed from a java.io.Reader).
1065:             * @param augs     Additional information that may include infoset augmentations
1066:             *                 
1067:             * @exception XNIException Thrown by handler to signal an error.
1068:             */
1069:            public void startGeneralEntity(String name,
1070:                    XMLResourceIdentifier identifier, String encoding,
1071:                    Augmentations augs) throws XNIException {
1072:                if (fPerformValidation && fElementDepth >= 0
1073:                        && fDTDGrammar != null) {
1074:                    fDTDGrammar.getElementDecl(fCurrentElementIndex,
1075:                            fTempElementDecl);
1076:                    // fixes E15.1
1077:                    if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
1078:                        fErrorReporter.reportError(
1079:                                XMLMessageFormatter.XML_DOMAIN,
1080:                                "MSG_CONTENT_INVALID_SPECIFIED", new Object[] {
1081:                                        fCurrentElement.rawname, "EMPTY",
1082:                                        "ENTITY" },
1083:                                XMLErrorReporter.SEVERITY_ERROR);
1084:                    }
1085:                    if (fGrammarBucket.getStandalone()) {
1086:                        XMLDTDLoader.checkStandaloneEntityRef(name,
1087:                                fDTDGrammar, fEntityDecl, fErrorReporter);
1088:                    }
1089:                }
1090:                if (fDocumentHandler != null) {
1091:                    fDocumentHandler.startGeneralEntity(name, identifier,
1092:                            encoding, augs);
1093:                }
1094:            }
1095:
1096:            /**
1097:             * This method notifies the end of a general entity.
1098:             * <p>
1099:             * <strong>Note:</strong> This method is not called for entity references
1100:             * appearing as part of attribute values.
1101:             * 
1102:             * @param name   The name of the entity.
1103:             * @param augs   Additional information that may include infoset augmentations
1104:             *               
1105:             * @exception XNIException
1106:             *                   Thrown by handler to signal an error.
1107:             */
1108:            public void endGeneralEntity(String name, Augmentations augs)
1109:                    throws XNIException {
1110:                // call handlers
1111:                if (fDocumentHandler != null) {
1112:                    fDocumentHandler.endGeneralEntity(name, augs);
1113:                }
1114:            } // endEntity(String)
1115:
1116:            /**
1117:             * Notifies of the presence of a TextDecl line in an entity. If present,
1118:             * this method will be called immediately following the startParameterEntity call.
1119:             * <p>
1120:             * <strong>Note:</strong> This method is only called for external
1121:             * parameter entities referenced in the DTD.
1122:             * 
1123:             * @param version  The XML version, or null if not specified.
1124:             * @param encoding The IANA encoding name of the entity.
1125:             * @param augs Additional information that may include infoset
1126:             *                      augmentations.
1127:             *
1128:             * @throws XNIException Thrown by handler to signal an error.
1129:             */
1130:            public void textDecl(String version, String encoding,
1131:                    Augmentations augs) throws XNIException {
1132:
1133:                // call handlers
1134:                if (fDocumentHandler != null) {
1135:                    fDocumentHandler.textDecl(version, encoding, augs);
1136:                }
1137:            }
1138:
1139:            public final boolean hasGrammar() {
1140:
1141:                return (fDTDGrammar != null);
1142:            }
1143:
1144:            public final boolean validate() {
1145:                // Do validation if all of the following are true:
1146:                // 1. The JAXP Schema Language property is not XML Schema
1147:                //    REVISIT: since only DTD and Schema are supported at this time,
1148:                //             such checking is sufficient. but if more schema types
1149:                //             are introduced in the future, we'll need to change it
1150:                //             to something like
1151:                //             (fSchemaType == null || fSchemaType == NS_XML_DTD)
1152:                // 2. One of the following is true (validation features)
1153:                // 2.1 Dynamic validation is off, and validation is on
1154:                // 2.2 Dynamic validation is on, and DOCTYPE was seen
1155:                // 3 Xerces schema validation feature is off, or DOCTYPE was seen.
1156:                return (fSchemaType != Constants.NS_XMLSCHEMA)
1157:                        && (!fDynamicValidation && fValidation || fDynamicValidation
1158:                                && fSeenDoctypeDecl)
1159:                        && (fDTDValidation || fSeenDoctypeDecl);
1160:            }
1161:
1162:            //REVISIT:we can convert into functions.. adding default attribute values.. and one validating.
1163:
1164:            /** Add default attributes and validate. */
1165:            protected void addDTDDefaultAttrsAndValidate(QName elementName,
1166:                    int elementIndex, XMLAttributes attributes)
1167:                    throws XNIException {
1168:
1169:                // is there anything to do?
1170:                if (elementIndex == -1 || fDTDGrammar == null) {
1171:                    return;
1172:                }
1173:
1174:                //
1175:                // Check after all specified attrs are scanned
1176:                // (1) report error for REQUIRED attrs that are missing (V_TAGc)
1177:                // (2) add default attrs (FIXED and NOT_FIXED)
1178:                //
1179:                int attlistIndex = fDTDGrammar
1180:                        .getFirstAttributeDeclIndex(elementIndex);
1181:
1182:                while (attlistIndex != -1) {
1183:
1184:                    fDTDGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
1185:
1186:                    if (DEBUG_ATTRIBUTES) {
1187:                        if (fTempAttDecl != null) {
1188:                            XMLElementDecl elementDecl = new XMLElementDecl();
1189:                            fDTDGrammar.getElementDecl(elementIndex,
1190:                                    elementDecl);
1191:                            System.out.println("element: "
1192:                                    + (elementDecl.name.localpart));
1193:                            System.out.println("attlistIndex " + attlistIndex
1194:                                    + "\n" + "attName : '"
1195:                                    + (fTempAttDecl.name.localpart) + "'\n"
1196:                                    + "attType : "
1197:                                    + fTempAttDecl.simpleType.type + "\n"
1198:                                    + "attDefaultType : "
1199:                                    + fTempAttDecl.simpleType.defaultType
1200:                                    + "\n" + "attDefaultValue : '"
1201:                                    + fTempAttDecl.simpleType.defaultValue
1202:                                    + "'\n" + attributes.getLength() + "\n");
1203:                        }
1204:                    }
1205:                    String attPrefix = fTempAttDecl.name.prefix;
1206:                    String attLocalpart = fTempAttDecl.name.localpart;
1207:                    String attRawName = fTempAttDecl.name.rawname;
1208:                    String attType = getAttributeTypeName(fTempAttDecl);
1209:                    int attDefaultType = fTempAttDecl.simpleType.defaultType;
1210:                    String attValue = null;
1211:
1212:                    if (fTempAttDecl.simpleType.defaultValue != null) {
1213:                        attValue = fTempAttDecl.simpleType.defaultValue;
1214:                    }
1215:
1216:                    boolean specified = false;
1217:                    boolean required = attDefaultType == XMLSimpleType.DEFAULT_TYPE_REQUIRED;
1218:                    boolean cdata = attType == XMLSymbols.fCDATASymbol;
1219:
1220:                    if (!cdata || required || attValue != null) {
1221:                        int attrCount = attributes.getLength();
1222:                        for (int i = 0; i < attrCount; i++) {
1223:                            if (attributes.getQName(i) == attRawName) {
1224:                                specified = true;
1225:                                break;
1226:                            }
1227:                        }
1228:                    }
1229:
1230:                    if (!specified) {
1231:                        if (required) {
1232:                            if (fPerformValidation) {
1233:                                Object[] args = { elementName.localpart,
1234:                                        attRawName };
1235:                                fErrorReporter.reportError(
1236:                                        XMLMessageFormatter.XML_DOMAIN,
1237:                                        "MSG_REQUIRED_ATTRIBUTE_NOT_SPECIFIED",
1238:                                        args, XMLErrorReporter.SEVERITY_ERROR);
1239:                            }
1240:                        } else if (attValue != null) {
1241:                            if (fPerformValidation
1242:                                    && fGrammarBucket.getStandalone()) {
1243:                                if (fDTDGrammar
1244:                                        .getAttributeDeclIsExternal(attlistIndex)) {
1245:
1246:                                    Object[] args = { elementName.localpart,
1247:                                            attRawName };
1248:                                    fErrorReporter
1249:                                            .reportError(
1250:                                                    XMLMessageFormatter.XML_DOMAIN,
1251:                                                    "MSG_DEFAULTED_ATTRIBUTE_NOT_SPECIFIED",
1252:                                                    args,
1253:                                                    XMLErrorReporter.SEVERITY_ERROR);
1254:                                }
1255:                            }
1256:
1257:                            // add namespace information
1258:                            if (fNamespaces) {
1259:                                int index = attRawName.indexOf(':');
1260:                                if (index != -1) {
1261:                                    attPrefix = attRawName.substring(0, index);
1262:                                    attPrefix = fSymbolTable
1263:                                            .addSymbol(attPrefix);
1264:                                    attLocalpart = attRawName
1265:                                            .substring(index + 1);
1266:                                    attLocalpart = fSymbolTable
1267:                                            .addSymbol(attLocalpart);
1268:                                }
1269:                            }
1270:
1271:                            // add attribute
1272:                            fTempQName.setValues(attPrefix, attLocalpart,
1273:                                    attRawName, fTempAttDecl.name.uri);
1274:                            int newAttr = attributes.addAttribute(fTempQName,
1275:                                    attType, attValue);
1276:                        }
1277:                    }
1278:                    // get next att decl in the Grammar for this element
1279:                    attlistIndex = fDTDGrammar
1280:                            .getNextAttributeDeclIndex(attlistIndex);
1281:                }
1282:
1283:                // now iterate through the expanded attributes for
1284:                // 1. if every attribute seen is declared in the DTD
1285:                // 2. check if the VC: default_fixed holds
1286:                // 3. validate every attribute.
1287:                int attrCount = attributes.getLength();
1288:                for (int i = 0; i < attrCount; i++) {
1289:                    String attrRawName = attributes.getQName(i);
1290:                    boolean declared = false;
1291:                    if (fPerformValidation) {
1292:                        if (fGrammarBucket.getStandalone()) {
1293:                            // check VC: Standalone Document Declaration, entities
1294:                            // references appear in the document.
1295:                            // REVISIT: this can be combined to a single check in
1296:                            // startEntity if we add one more argument in
1297:                            // startEnity, inAttrValue
1298:                            String nonNormalizedValue = attributes
1299:                                    .getNonNormalizedValue(i);
1300:                            if (nonNormalizedValue != null) {
1301:                                String entityName = getExternalEntityRefInAttrValue(nonNormalizedValue);
1302:                                if (entityName != null) {
1303:                                    fErrorReporter
1304:                                            .reportError(
1305:                                                    XMLMessageFormatter.XML_DOMAIN,
1306:                                                    "MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE",
1307:                                                    new Object[] { entityName },
1308:                                                    XMLErrorReporter.SEVERITY_ERROR);
1309:                                }
1310:                            }
1311:                        }
1312:                    }
1313:                    int attDefIndex = -1;
1314:                    int position = fDTDGrammar
1315:                            .getFirstAttributeDeclIndex(elementIndex);
1316:                    while (position != -1) {
1317:                        fDTDGrammar.getAttributeDecl(position, fTempAttDecl);
1318:                        if (fTempAttDecl.name.rawname == attrRawName) {
1319:                            // found the match att decl, 
1320:                            attDefIndex = position;
1321:                            declared = true;
1322:                            break;
1323:                        }
1324:                        position = fDTDGrammar
1325:                                .getNextAttributeDeclIndex(position);
1326:                    }
1327:                    if (!declared) {
1328:                        if (fPerformValidation) {
1329:                            // REVISIT - cache the elem/attr tuple so that we only
1330:                            // give this error once for each unique occurrence
1331:                            Object[] args = { elementName.rawname, attrRawName };
1332:
1333:                            fErrorReporter.reportError(
1334:                                    XMLMessageFormatter.XML_DOMAIN,
1335:                                    "MSG_ATTRIBUTE_NOT_DECLARED", args,
1336:                                    XMLErrorReporter.SEVERITY_ERROR);
1337:                        }
1338:                        continue;
1339:                    }
1340:                    // attribute is declared
1341:
1342:                    // fTempAttDecl should have the right value set now, so
1343:                    // the following is not needed
1344:                    // fGrammar.getAttributeDecl(attDefIndex,fTempAttDecl);
1345:
1346:                    String type = getAttributeTypeName(fTempAttDecl);
1347:                    attributes.setType(i, type);
1348:                    attributes.getAugmentations(i).putItem(
1349:                            Constants.ATTRIBUTE_DECLARED, Boolean.TRUE);
1350:
1351:                    boolean changedByNormalization = false;
1352:                    String oldValue = attributes.getValue(i);
1353:                    String attrValue = oldValue;
1354:                    if (attributes.isSpecified(i)
1355:                            && type != XMLSymbols.fCDATASymbol) {
1356:                        changedByNormalization = normalizeAttrValue(attributes,
1357:                                i);
1358:                        attrValue = attributes.getValue(i);
1359:                        if (fPerformValidation
1360:                                && fGrammarBucket.getStandalone()
1361:                                && changedByNormalization
1362:                                && fDTDGrammar
1363:                                        .getAttributeDeclIsExternal(position)) {
1364:                            // check VC: Standalone Document Declaration
1365:                            fErrorReporter
1366:                                    .reportError(
1367:                                            XMLMessageFormatter.XML_DOMAIN,
1368:                                            "MSG_ATTVALUE_CHANGED_DURING_NORMALIZATION_WHEN_STANDALONE",
1369:                                            new Object[] { attrRawName,
1370:                                                    oldValue, attrValue },
1371:                                            XMLErrorReporter.SEVERITY_ERROR);
1372:                        }
1373:                    }
1374:                    if (!fPerformValidation) {
1375:                        continue;
1376:                    }
1377:                    if (fTempAttDecl.simpleType.defaultType == XMLSimpleType.DEFAULT_TYPE_FIXED) {
1378:                        String defaultValue = fTempAttDecl.simpleType.defaultValue;
1379:
1380:                        if (!attrValue.equals(defaultValue)) {
1381:                            Object[] args = { elementName.localpart,
1382:                                    attrRawName, attrValue, defaultValue };
1383:                            fErrorReporter.reportError(
1384:                                    XMLMessageFormatter.XML_DOMAIN,
1385:                                    "MSG_FIXED_ATTVALUE_INVALID", args,
1386:                                    XMLErrorReporter.SEVERITY_ERROR);
1387:                        }
1388:                    }
1389:
1390:                    if (fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ENTITY
1391:                            || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ENUMERATION
1392:                            || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_ID
1393:                            || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_IDREF
1394:                            || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_NMTOKEN
1395:                            || fTempAttDecl.simpleType.type == XMLSimpleType.TYPE_NOTATION) {
1396:                        validateDTDattribute(elementName, attrValue,
1397:                                fTempAttDecl);
1398:                    }
1399:                } // for all attributes
1400:
1401:            } // addDTDDefaultAttrsAndValidate(int,XMLAttrList)
1402:
1403:            /** Checks entities in attribute values for standalone VC. */
1404:            protected String getExternalEntityRefInAttrValue(
1405:                    String nonNormalizedValue) {
1406:                int valLength = nonNormalizedValue.length();
1407:                int ampIndex = nonNormalizedValue.indexOf('&');
1408:                while (ampIndex != -1) {
1409:                    if (ampIndex + 1 < valLength
1410:                            && nonNormalizedValue.charAt(ampIndex + 1) != '#') {
1411:                        int semicolonIndex = nonNormalizedValue.indexOf(';',
1412:                                ampIndex + 1);
1413:                        String entityName = nonNormalizedValue.substring(
1414:                                ampIndex + 1, semicolonIndex);
1415:                        entityName = fSymbolTable.addSymbol(entityName);
1416:                        int entIndex = fDTDGrammar
1417:                                .getEntityDeclIndex(entityName);
1418:                        if (entIndex > -1) {
1419:                            fDTDGrammar.getEntityDecl(entIndex, fEntityDecl);
1420:                            if (fEntityDecl.inExternal
1421:                                    || (entityName = getExternalEntityRefInAttrValue(fEntityDecl.value)) != null) {
1422:                                return entityName;
1423:                            }
1424:                        }
1425:                    }
1426:                    ampIndex = nonNormalizedValue.indexOf('&', ampIndex + 1);
1427:                }
1428:                return null;
1429:            } // isExternalEntityRefInAttrValue(String):String
1430:
1431:            /**
1432:             * Validate attributes in DTD fashion.
1433:             */
1434:            protected void validateDTDattribute(QName element, String attValue,
1435:                    XMLAttributeDecl attributeDecl) throws XNIException {
1436:
1437:                switch (attributeDecl.simpleType.type) {
1438:                case XMLSimpleType.TYPE_ENTITY: {
1439:                    // NOTE: Save this information because invalidStandaloneAttDef
1440:                    boolean isAlistAttribute = attributeDecl.simpleType.list;
1441:
1442:                    try {
1443:                        if (isAlistAttribute) {
1444:                            fValENTITIES.validate(attValue, fValidationState);
1445:                        } else {
1446:                            fValENTITY.validate(attValue, fValidationState);
1447:                        }
1448:                    } catch (InvalidDatatypeValueException ex) {
1449:                        fErrorReporter.reportError(
1450:                                XMLMessageFormatter.XML_DOMAIN, ex.getKey(), ex
1451:                                        .getArgs(),
1452:                                XMLErrorReporter.SEVERITY_ERROR);
1453:
1454:                    }
1455:                    break;
1456:                }
1457:
1458:                case XMLSimpleType.TYPE_NOTATION:
1459:                case XMLSimpleType.TYPE_ENUMERATION: {
1460:                    boolean found = false;
1461:                    String[] enumVals = attributeDecl.simpleType.enumeration;
1462:                    if (enumVals == null) {
1463:                        found = false;
1464:                    } else
1465:                        for (int i = 0; i < enumVals.length; i++) {
1466:                            if (attValue == enumVals[i]
1467:                                    || attValue.equals(enumVals[i])) {
1468:                                found = true;
1469:                                break;
1470:                            }
1471:                        }
1472:
1473:                    if (!found) {
1474:                        StringBuffer enumValueString = new StringBuffer();
1475:                        if (enumVals != null)
1476:                            for (int i = 0; i < enumVals.length; i++) {
1477:                                enumValueString.append(enumVals[i] + " ");
1478:                            }
1479:                        fErrorReporter.reportError(
1480:                                XMLMessageFormatter.XML_DOMAIN,
1481:                                "MSG_ATTRIBUTE_VALUE_NOT_IN_LIST",
1482:                                new Object[] { attributeDecl.name.rawname,
1483:                                        attValue, enumValueString },
1484:                                XMLErrorReporter.SEVERITY_ERROR);
1485:                    }
1486:                    break;
1487:                }
1488:
1489:                case XMLSimpleType.TYPE_ID: {
1490:                    try {
1491:                        fValID.validate(attValue, fValidationState);
1492:                    } catch (InvalidDatatypeValueException ex) {
1493:                        fErrorReporter.reportError(
1494:                                XMLMessageFormatter.XML_DOMAIN, ex.getKey(), ex
1495:                                        .getArgs(),
1496:                                XMLErrorReporter.SEVERITY_ERROR);
1497:                    }
1498:                    break;
1499:                }
1500:
1501:                case XMLSimpleType.TYPE_IDREF: {
1502:                    boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef
1503:
1504:                    try {
1505:                        if (isAlistAttribute) {
1506:                            fValIDRefs.validate(attValue, fValidationState);
1507:                        } else {
1508:                            fValIDRef.validate(attValue, fValidationState);
1509:                        }
1510:                    } catch (InvalidDatatypeValueException ex) {
1511:                        if (isAlistAttribute) {
1512:                            fErrorReporter.reportError(
1513:                                    XMLMessageFormatter.XML_DOMAIN,
1514:                                    "IDREFSInvalid", new Object[] { attValue },
1515:                                    XMLErrorReporter.SEVERITY_ERROR);
1516:                        } else {
1517:                            fErrorReporter.reportError(
1518:                                    XMLMessageFormatter.XML_DOMAIN,
1519:                                    ex.getKey(), ex.getArgs(),
1520:                                    XMLErrorReporter.SEVERITY_ERROR);
1521:                        }
1522:
1523:                    }
1524:                    break;
1525:                }
1526:
1527:                case XMLSimpleType.TYPE_NMTOKEN: {
1528:                    boolean isAlistAttribute = attributeDecl.simpleType.list;//Caveat - Save this information because invalidStandaloneAttDef
1529:                    //changes fTempAttDef
1530:                    try {
1531:                        if (isAlistAttribute) {
1532:                            fValNMTOKENS.validate(attValue, fValidationState);
1533:                        } else {
1534:                            fValNMTOKEN.validate(attValue, fValidationState);
1535:                        }
1536:                    } catch (InvalidDatatypeValueException ex) {
1537:                        if (isAlistAttribute) {
1538:                            fErrorReporter.reportError(
1539:                                    XMLMessageFormatter.XML_DOMAIN,
1540:                                    "NMTOKENSInvalid",
1541:                                    new Object[] { attValue },
1542:                                    XMLErrorReporter.SEVERITY_ERROR);
1543:                        } else {
1544:                            fErrorReporter.reportError(
1545:                                    XMLMessageFormatter.XML_DOMAIN,
1546:                                    "NMTOKENInvalid",
1547:                                    new Object[] { attValue },
1548:                                    XMLErrorReporter.SEVERITY_ERROR);
1549:                        }
1550:                    }
1551:                    break;
1552:                }
1553:
1554:                } // switch
1555:
1556:            } // validateDTDattribute(QName,String,XMLAttributeDecl)
1557:
1558:            /** Returns true if invalid standalone attribute definition. */
1559:            protected boolean invalidStandaloneAttDef(QName element,
1560:                    QName attribute) {
1561:                // REVISIT: This obviously needs to be fixed! -Ac
1562:                boolean state = true;
1563:                /*
1564:                if (fStandaloneReader == -1) {
1565:                  return false;
1566:                }
1567:                // we are normalizing a default att value...  this ok?
1568:                if (element.rawname == -1) {
1569:                  return false;
1570:                }
1571:                return getAttDefIsExternal(element, attribute);
1572:                 */
1573:                return state;
1574:            }
1575:
1576:            //
1577:            // Private methods
1578:            //
1579:
1580:            /**
1581:             * Normalize the attribute value of a non CDATA attributes collapsing
1582:             * sequences of space characters (x20)
1583:             *
1584:             * @param attributes The list of attributes
1585:             * @param index The index of the attribute to normalize
1586:             */
1587:            private boolean normalizeAttrValue(XMLAttributes attributes,
1588:                    int index) {
1589:                // vars
1590:                boolean leadingSpace = true;
1591:                boolean spaceStart = false;
1592:                boolean readingNonSpace = false;
1593:                int count = 0;
1594:                int eaten = 0;
1595:                String attrValue = attributes.getValue(index);
1596:                char[] attValue = new char[attrValue.length()];
1597:
1598:                fBuffer.setLength(0);
1599:                attrValue.getChars(0, attrValue.length(), attValue, 0);
1600:                for (int i = 0; i < attValue.length; i++) {
1601:
1602:                    if (attValue[i] == ' ') {
1603:
1604:                        // now the tricky part
1605:                        if (readingNonSpace) {
1606:                            spaceStart = true;
1607:                            readingNonSpace = false;
1608:                        }
1609:
1610:                        if (spaceStart && !leadingSpace) {
1611:                            spaceStart = false;
1612:                            fBuffer.append(attValue[i]);
1613:                            count++;
1614:                        } else {
1615:                            if (leadingSpace || !spaceStart) {
1616:                                eaten++;
1617:                                /*** BUG #3512 ***
1618:                                int entityCount = attributes.getEntityCount(index);
1619:                                for (int j = 0;  j < entityCount; j++) {
1620:                                    int offset = attributes.getEntityOffset(index, j);
1621:                                    int length = attributes.getEntityLength(index, j);
1622:                                    if (offset <= i-eaten+1) {
1623:                                        if (offset+length >= i-eaten+1) {
1624:                                            if (length > 0)
1625:                                                length--;
1626:                                        }
1627:                                    } 
1628:                                    else {
1629:                                        if (offset > 0)
1630:                                            offset--;
1631:                                    }
1632:                                    attributes.setEntityOffset(index, j, offset);
1633:                                    attributes.setEntityLength(index, j, length);
1634:                                }
1635:                                /***/
1636:                            }
1637:                        }
1638:
1639:                    } else {
1640:                        readingNonSpace = true;
1641:                        spaceStart = false;
1642:                        leadingSpace = false;
1643:                        fBuffer.append(attValue[i]);
1644:                        count++;
1645:                    }
1646:                }
1647:
1648:                // check if the last appended character is a space.
1649:                if (count > 0 && fBuffer.charAt(count - 1) == ' ') {
1650:                    fBuffer.setLength(count - 1);
1651:                    /*** BUG #3512 ***
1652:                    int entityCount = attributes.getEntityCount(index);
1653:                    for (int j=0;  j < entityCount; j++) {
1654:                        int offset = attributes.getEntityOffset(index, j);
1655:                        int length = attributes.getEntityLength(index, j);
1656:                        if (offset < count-1) {
1657:                            if (offset+length == count) {
1658:                                length--;
1659:                            }
1660:                        } 
1661:                        else {
1662:                            offset--;
1663:                        }
1664:                        attributes.setEntityOffset(index, j, offset);
1665:                        attributes.setEntityLength(index, j, length);
1666:                    }
1667:                    /***/
1668:                }
1669:                String newValue = fBuffer.toString();
1670:                attributes.setValue(index, newValue);
1671:                return !attrValue.equals(newValue);
1672:            }
1673:
1674:            /** Root element specified. */
1675:            private final void rootElementSpecified(QName rootElement)
1676:                    throws XNIException {
1677:                if (fPerformValidation) {
1678:                    String root1 = fRootElement.rawname;
1679:                    String root2 = rootElement.rawname;
1680:                    if (root1 == null || !root1.equals(root2)) {
1681:                        fErrorReporter.reportError(
1682:                                XMLMessageFormatter.XML_DOMAIN,
1683:                                "RootElementTypeMustMatchDoctypedecl",
1684:                                new Object[] { root1, root2 },
1685:                                XMLErrorReporter.SEVERITY_ERROR);
1686:                    }
1687:                }
1688:            } // rootElementSpecified(QName)
1689:
1690:            /**
1691:             * Check that the content of an element is valid.
1692:             * <p>
1693:             * This is the method of primary concern to the validator. This method is called
1694:             * upon the scanner reaching the end tag of an element. At that time, the
1695:             * element's children must be structurally validated, so it calls this method.
1696:             * The index of the element being checked (in the decl pool), is provided as
1697:             * well as an array of element name indexes of the children. The validator must
1698:             * confirm that this element can have these children in this order.
1699:             * <p>
1700:             * This can also be called to do 'what if' testing of content models just to see
1701:             * if they would be valid.
1702:             * <p>
1703:             * Note that the element index is an index into the element decl pool, whereas
1704:             * the children indexes are name indexes, i.e. into the string pool.
1705:             * <p>
1706:             * A value of -1 in the children array indicates a PCDATA node. All other
1707:             * indexes will be positive and represent child elements. The count can be
1708:             * zero, since some elements have the EMPTY content model and that must be
1709:             * confirmed.
1710:             *
1711:             * @param elementIndex The index within the <code>ElementDeclPool</code> of this
1712:             *                     element.
1713:             * @param childCount The number of entries in the <code>children</code> array.
1714:             * @param children The children of this element.  
1715:             *
1716:             * @return The value -1 if fully valid, else the 0 based index of the child
1717:             *         that first failed. If the value returned is equal to the number
1718:             *         of children, then additional content is required to reach a valid
1719:             *         ending state.
1720:             *
1721:             * @exception Exception Thrown on error.
1722:             */
1723:            private int checkContent(int elementIndex, QName[] children,
1724:                    int childOffset, int childCount) throws XNIException {
1725:
1726:                fDTDGrammar.getElementDecl(elementIndex, fTempElementDecl);
1727:
1728:                // Get the element name index from the element
1729:                final String elementType = fCurrentElement.rawname;
1730:
1731:                // Get out the content spec for this element
1732:                final int contentType = fCurrentContentSpecType;
1733:
1734:                //
1735:                //  Deal with the possible types of content. We try to optimized here
1736:                //  by dealing specially with content models that don't require the
1737:                //  full DFA treatment.
1738:                //
1739:                if (contentType == XMLElementDecl.TYPE_EMPTY) {
1740:                    //
1741:                    //  If the child count is greater than zero, then this is
1742:                    //  an error right off the bat at index 0.
1743:                    //
1744:                    if (childCount != 0) {
1745:                        return 0;
1746:                    }
1747:                } else if (contentType == XMLElementDecl.TYPE_ANY) {
1748:                    //
1749:                    //  This one is open game so we don't pass any judgement on it
1750:                    //  at all. Its assumed to fine since it can hold anything.
1751:                    //
1752:                } else if (contentType == XMLElementDecl.TYPE_MIXED
1753:                        || contentType == XMLElementDecl.TYPE_CHILDREN) {
1754:                    // Get the content model for this element, faulting it in if needed
1755:                    ContentModelValidator cmElem = null;
1756:                    cmElem = fTempElementDecl.contentModelValidator;
1757:                    int result = cmElem.validate(children, childOffset,
1758:                            childCount);
1759:                    return result;
1760:                } else if (contentType == -1) {
1761:                    //REVISIT
1762:                    /****
1763:                    reportRecoverableXMLError(XMLMessages.MSG_ELEMENT_NOT_DECLARED,
1764:                                              XMLMessages.VC_ELEMENT_VALID,
1765:                                              elementType);
1766:                    /****/
1767:                } else if (contentType == XMLElementDecl.TYPE_SIMPLE) {
1768:
1769:                    //REVISIT
1770:                    // this should never be reached in the case of DTD validation.
1771:
1772:                } else {
1773:                    //REVISIT
1774:                    /****
1775:                    fErrorReporter.reportError(fErrorReporter.getLocator(),
1776:                                               ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN,
1777:                                               ImplementationMessages.VAL_CST,
1778:                                               0,
1779:                                               null,
1780:                                               XMLErrorReporter.ERRORTYPE_FATAL_ERROR);
1781:                    /****/
1782:                }
1783:
1784:                // We succeeded
1785:                return -1;
1786:
1787:            } // checkContent(int,int,QName[]):int
1788:
1789:            /** Returns the content spec type for an element index. */
1790:            private int getContentSpecType(int elementIndex) {
1791:
1792:                int contentSpecType = -1;
1793:                if (elementIndex > -1) {
1794:                    if (fDTDGrammar.getElementDecl(elementIndex,
1795:                            fTempElementDecl)) {
1796:                        contentSpecType = fTempElementDecl.type;
1797:                    }
1798:                }
1799:                return contentSpecType;
1800:            }
1801:
1802:            /** Character data in content. */
1803:            private void charDataInContent() {
1804:
1805:                if (DEBUG_ELEMENT_CHILDREN) {
1806:                    System.out.println("charDataInContent()");
1807:                }
1808:                if (fElementChildren.length <= fElementChildrenLength) {
1809:                    QName[] newarray = new QName[fElementChildren.length * 2];
1810:                    System.arraycopy(fElementChildren, 0, newarray, 0,
1811:                            fElementChildren.length);
1812:                    fElementChildren = newarray;
1813:                }
1814:                QName qname = fElementChildren[fElementChildrenLength];
1815:                if (qname == null) {
1816:                    for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
1817:                        fElementChildren[i] = new QName();
1818:                    }
1819:                    qname = fElementChildren[fElementChildrenLength];
1820:                }
1821:                qname.clear();
1822:                fElementChildrenLength++;
1823:
1824:            } // charDataInCount()
1825:
1826:            /** convert attribute type from ints to strings */
1827:            private String getAttributeTypeName(XMLAttributeDecl attrDecl) {
1828:
1829:                switch (attrDecl.simpleType.type) {
1830:                case XMLSimpleType.TYPE_ENTITY: {
1831:                    return attrDecl.simpleType.list ? XMLSymbols.fENTITIESSymbol
1832:                            : XMLSymbols.fENTITYSymbol;
1833:                }
1834:                case XMLSimpleType.TYPE_ENUMERATION: {
1835:                    StringBuffer buffer = new StringBuffer();
1836:                    buffer.append('(');
1837:                    for (int i = 0; i < attrDecl.simpleType.enumeration.length; i++) {
1838:                        if (i > 0) {
1839:                            buffer.append("|");
1840:                        }
1841:                        buffer.append(attrDecl.simpleType.enumeration[i]);
1842:                    }
1843:                    buffer.append(')');
1844:                    return fSymbolTable.addSymbol(buffer.toString());
1845:                }
1846:                case XMLSimpleType.TYPE_ID: {
1847:                    return XMLSymbols.fIDSymbol;
1848:                }
1849:                case XMLSimpleType.TYPE_IDREF: {
1850:                    return attrDecl.simpleType.list ? XMLSymbols.fIDREFSSymbol
1851:                            : XMLSymbols.fIDREFSymbol;
1852:                }
1853:                case XMLSimpleType.TYPE_NMTOKEN: {
1854:                    return attrDecl.simpleType.list ? XMLSymbols.fNMTOKENSSymbol
1855:                            : XMLSymbols.fNMTOKENSymbol;
1856:                }
1857:                case XMLSimpleType.TYPE_NOTATION: {
1858:                    return XMLSymbols.fNOTATIONSymbol;
1859:                }
1860:                }
1861:                return XMLSymbols.fCDATASymbol;
1862:
1863:            } // getAttributeTypeName(XMLAttributeDecl):String
1864:
1865:            /** initialization */
1866:            protected void init() {
1867:
1868:                // datatype validators
1869:                if (fValidation || fDynamicValidation) {
1870:                    try {
1871:                        //REVISIT: datatypeRegistry + initialization of datatype 
1872:                        //         why do we cast to ListDatatypeValidator?
1873:                        fValID = fDatatypeValidatorFactory
1874:                                .getBuiltInDV(XMLSymbols.fIDSymbol);
1875:                        fValIDRef = fDatatypeValidatorFactory
1876:                                .getBuiltInDV(XMLSymbols.fIDREFSymbol);
1877:                        fValIDRefs = fDatatypeValidatorFactory
1878:                                .getBuiltInDV(XMLSymbols.fIDREFSSymbol);
1879:                        fValENTITY = fDatatypeValidatorFactory
1880:                                .getBuiltInDV(XMLSymbols.fENTITYSymbol);
1881:                        fValENTITIES = fDatatypeValidatorFactory
1882:                                .getBuiltInDV(XMLSymbols.fENTITIESSymbol);
1883:                        fValNMTOKEN = fDatatypeValidatorFactory
1884:                                .getBuiltInDV(XMLSymbols.fNMTOKENSymbol);
1885:                        fValNMTOKENS = fDatatypeValidatorFactory
1886:                                .getBuiltInDV(XMLSymbols.fNMTOKENSSymbol);
1887:                        fValNOTATION = fDatatypeValidatorFactory
1888:                                .getBuiltInDV(XMLSymbols.fNOTATIONSymbol);
1889:
1890:                    } catch (Exception e) {
1891:                        // should never happen
1892:                        e.printStackTrace(System.err);
1893:                    }
1894:
1895:                }
1896:
1897:            } // init()
1898:
1899:            /** ensure element stack capacity */
1900:            private void ensureStackCapacity(int newElementDepth) {
1901:                if (newElementDepth == fElementQNamePartsStack.length) {
1902:
1903:                    QName[] newStackOfQueue = new QName[newElementDepth * 2];
1904:                    System.arraycopy(this .fElementQNamePartsStack, 0,
1905:                            newStackOfQueue, 0, newElementDepth);
1906:                    fElementQNamePartsStack = newStackOfQueue;
1907:
1908:                    QName qname = fElementQNamePartsStack[newElementDepth];
1909:                    if (qname == null) {
1910:                        for (int i = newElementDepth; i < fElementQNamePartsStack.length; i++) {
1911:                            fElementQNamePartsStack[i] = new QName();
1912:                        }
1913:                    }
1914:
1915:                    int[] newStack = new int[newElementDepth * 2];
1916:                    System.arraycopy(fElementIndexStack, 0, newStack, 0,
1917:                            newElementDepth);
1918:                    fElementIndexStack = newStack;
1919:
1920:                    newStack = new int[newElementDepth * 2];
1921:                    System.arraycopy(fContentSpecTypeStack, 0, newStack, 0,
1922:                            newElementDepth);
1923:                    fContentSpecTypeStack = newStack;
1924:
1925:                }
1926:            } // ensureStackCapacity
1927:
1928:            //
1929:            // Protected methods
1930:            //
1931:
1932:            /** Handle element
1933:             * @return true if validator is removed from the pipeline
1934:             */
1935:            protected boolean handleStartElement(QName element,
1936:                    XMLAttributes attributes, Augmentations augs)
1937:                    throws XNIException {
1938:
1939:                // VC: Root Element Type
1940:                // see if the root element's name matches the one in DoctypeDecl 
1941:                if (!fSeenRootElement) {
1942:                    // REVISIT: Here are current assumptions about validation features
1943:                    //          given that XMLSchema validator is in the pipeline
1944:                    //
1945:                    // http://xml.org/sax/features/validation = true
1946:                    // http://apache.org/xml/features/validation/schema = true
1947:                    //
1948:                    // [1] XML instance document only has reference to a DTD 
1949:                    //  Outcome: report validation errors only against dtd.
1950:                    //
1951:                    // [2] XML instance document has only XML Schema grammars:
1952:                    //  Outcome: report validation errors only against schemas (no errors produced from DTD validator)
1953:                    //
1954:                    // [3] XML instance document has DTD and XML schemas:
1955:                    // [a] if schema language is not set outcome - validation errors reported against both grammars: DTD and schemas.
1956:                    // [b] if schema language is set to XML Schema - do not report validation errors
1957:                    //         
1958:                    // if dynamic validation is on
1959:                    //            validate only against grammar we've found (depending on settings
1960:                    //            for schema feature)
1961:                    // 
1962:                    // 
1963:                    fPerformValidation = validate();
1964:                    fSeenRootElement = true;
1965:                    fValidationManager.setEntityState(fDTDGrammar);
1966:                    fValidationManager.setGrammarFound(fSeenDoctypeDecl);
1967:                    rootElementSpecified(element);
1968:                }
1969:                if (fDTDGrammar == null) {
1970:
1971:                    if (!fPerformValidation) {
1972:                        fCurrentElementIndex = -1;
1973:                        fCurrentContentSpecType = -1;
1974:                        fInElementContent = false;
1975:                    }
1976:                    if (fPerformValidation) {
1977:                        fErrorReporter.reportError(
1978:                                XMLMessageFormatter.XML_DOMAIN,
1979:                                "MSG_GRAMMAR_NOT_FOUND",
1980:                                new Object[] { element.rawname },
1981:                                XMLErrorReporter.SEVERITY_ERROR);
1982:                    }
1983:                    // modify pipeline
1984:                    if (fDocumentSource != null) {
1985:                        fDocumentSource.setDocumentHandler(fDocumentHandler);
1986:                        if (fDocumentHandler != null)
1987:                            fDocumentHandler.setDocumentSource(fDocumentSource);
1988:                        return true;
1989:                    }
1990:                } else {
1991:                    //  resolve the element
1992:                    fCurrentElementIndex = fDTDGrammar
1993:                            .getElementDeclIndex(element);
1994:                    //changed here.. new function for getContentSpecType
1995:                    fCurrentContentSpecType = fDTDGrammar
1996:                            .getContentSpecType(fCurrentElementIndex);
1997:                    if (fCurrentContentSpecType == -1 && fPerformValidation) {
1998:                        fErrorReporter.reportError(
1999:                                XMLMessageFormatter.XML_DOMAIN,
2000:                                "MSG_ELEMENT_NOT_DECLARED",
2001:                                new Object[] { element.rawname },
2002:                                XMLErrorReporter.SEVERITY_ERROR);
2003:                    }
2004:
2005:                    //  0. insert default attributes
2006:                    //  1. normalize the attributes
2007:                    //  2. validate the attrivute list.
2008:                    // TO DO: 
2009:                    //changed here.. also pass element name,
2010:                    addDTDDefaultAttrsAndValidate(element,
2011:                            fCurrentElementIndex, attributes);
2012:                }
2013:
2014:                // set element content state
2015:                fInElementContent = fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN;
2016:
2017:                // increment the element depth, add this element's 
2018:                // QName to its enclosing element 's children list
2019:                fElementDepth++;
2020:                if (fPerformValidation) {
2021:                    // push current length onto stack
2022:                    if (fElementChildrenOffsetStack.length <= fElementDepth) {
2023:                        int newarray[] = new int[fElementChildrenOffsetStack.length * 2];
2024:                        System
2025:                                .arraycopy(fElementChildrenOffsetStack, 0,
2026:                                        newarray, 0,
2027:                                        fElementChildrenOffsetStack.length);
2028:                        fElementChildrenOffsetStack = newarray;
2029:                    }
2030:                    fElementChildrenOffsetStack[fElementDepth] = fElementChildrenLength;
2031:
2032:                    // add this element to children
2033:                    if (fElementChildren.length <= fElementChildrenLength) {
2034:                        QName[] newarray = new QName[fElementChildrenLength * 2];
2035:                        System.arraycopy(fElementChildren, 0, newarray, 0,
2036:                                fElementChildren.length);
2037:                        fElementChildren = newarray;
2038:                    }
2039:                    QName qname = fElementChildren[fElementChildrenLength];
2040:                    if (qname == null) {
2041:                        for (int i = fElementChildrenLength; i < fElementChildren.length; i++) {
2042:                            fElementChildren[i] = new QName();
2043:                        }
2044:                        qname = fElementChildren[fElementChildrenLength];
2045:                    }
2046:                    qname.setValues(element);
2047:                    fElementChildrenLength++;
2048:                }
2049:
2050:                // save current element information
2051:                fCurrentElement.setValues(element);
2052:                ensureStackCapacity(fElementDepth);
2053:                fElementQNamePartsStack[fElementDepth]
2054:                        .setValues(fCurrentElement);
2055:                fElementIndexStack[fElementDepth] = fCurrentElementIndex;
2056:                fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
2057:                startNamespaceScope(element, attributes, augs);
2058:                return false;
2059:
2060:            } // handleStartElement(QName,XMLAttributes)
2061:
2062:            protected void startNamespaceScope(QName element,
2063:                    XMLAttributes attributes, Augmentations augs) {
2064:            }
2065:
2066:            /** Handle end element. */
2067:            protected void handleEndElement(QName element, Augmentations augs,
2068:                    boolean isEmpty) throws XNIException {
2069:
2070:                // decrease element depth
2071:                fElementDepth--;
2072:
2073:                // validate
2074:                if (fPerformValidation) {
2075:                    int elementIndex = fCurrentElementIndex;
2076:                    if (elementIndex != -1 && fCurrentContentSpecType != -1) {
2077:                        QName children[] = fElementChildren;
2078:                        int childrenOffset = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
2079:                        int childrenLength = fElementChildrenLength
2080:                                - childrenOffset;
2081:                        int result = checkContent(elementIndex, children,
2082:                                childrenOffset, childrenLength);
2083:
2084:                        if (result != -1) {
2085:                            fDTDGrammar.getElementDecl(elementIndex,
2086:                                    fTempElementDecl);
2087:                            if (fTempElementDecl.type == XMLElementDecl.TYPE_EMPTY) {
2088:                                fErrorReporter.reportError(
2089:                                        XMLMessageFormatter.XML_DOMAIN,
2090:                                        "MSG_CONTENT_INVALID", new Object[] {
2091:                                                element.rawname, "EMPTY" },
2092:                                        XMLErrorReporter.SEVERITY_ERROR);
2093:                            } else {
2094:                                String messageKey = result != childrenLength ? "MSG_CONTENT_INVALID"
2095:                                        : "MSG_CONTENT_INCOMPLETE";
2096:                                fErrorReporter
2097:                                        .reportError(
2098:                                                XMLMessageFormatter.XML_DOMAIN,
2099:                                                messageKey,
2100:                                                new Object[] {
2101:                                                        element.rawname,
2102:                                                        fDTDGrammar
2103:                                                                .getContentSpecAsString(elementIndex) },
2104:                                                XMLErrorReporter.SEVERITY_ERROR);
2105:                            }
2106:                        }
2107:                    }
2108:                    fElementChildrenLength = fElementChildrenOffsetStack[fElementDepth + 1] + 1;
2109:                }
2110:
2111:                endNamespaceScope(fCurrentElement, augs, isEmpty);
2112:
2113:                // now pop this element off the top of the element stack
2114:                if (fElementDepth < -1) {
2115:                    throw new RuntimeException("FWK008 Element stack underflow");
2116:                }
2117:                if (fElementDepth < 0) {
2118:                    fCurrentElement.clear();
2119:                    fCurrentElementIndex = -1;
2120:                    fCurrentContentSpecType = -1;
2121:                    fInElementContent = false;
2122:
2123:                    // TO DO : fix this
2124:                    //
2125:                    // Check after document is fully parsed
2126:                    // (1) check that there was an element with a matching id for every
2127:                    //   IDREF and IDREFS attr (V_IDREF0)
2128:                    //
2129:                    if (fPerformValidation) {
2130:                        String value = fValidationState.checkIDRefID();
2131:                        if (value != null) {
2132:                            fErrorReporter.reportError(
2133:                                    XMLMessageFormatter.XML_DOMAIN,
2134:                                    "MSG_ELEMENT_WITH_ID_REQUIRED",
2135:                                    new Object[] { value },
2136:                                    XMLErrorReporter.SEVERITY_ERROR);
2137:                        }
2138:                    }
2139:                    return;
2140:                }
2141:
2142:                // If Namespace enable then localName != rawName
2143:                fCurrentElement
2144:                        .setValues(fElementQNamePartsStack[fElementDepth]);
2145:
2146:                fCurrentElementIndex = fElementIndexStack[fElementDepth];
2147:                fCurrentContentSpecType = fContentSpecTypeStack[fElementDepth];
2148:                fInElementContent = (fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN);
2149:
2150:            } // handleEndElement(QName,boolean)
2151:
2152:            protected void endNamespaceScope(QName element, Augmentations augs,
2153:                    boolean isEmpty) {
2154:
2155:                // call handlers
2156:                if (fDocumentHandler != null && !isEmpty) {
2157:                    // NOTE: The binding of the element doesn't actually happen
2158:                    //       yet because the namespace binder does that. However,
2159:                    //       if it does it before this point, then the endPrefix-
2160:                    //       Mapping calls get made too soon! As long as the
2161:                    //       rawnames match, we know it'll have a good binding,
2162:                    //       so we can just use the current element. -Ac
2163:                    fDocumentHandler.endElement(fCurrentElement, augs);
2164:                }
2165:            }
2166:
2167:            // returns whether a character is space according to the
2168:            // version of XML this validator supports.
2169:            protected boolean isSpace(int c) {
2170:                return XMLChar.isSpace(c);
2171:            } // isSpace(int):  boolean
2172:
2173:            public boolean characterData(String data, Augmentations augs) {
2174:                characters(new XMLString(data.toCharArray(), 0, data.length()),
2175:                        augs);
2176:                return true;
2177:            }
2178:
2179:        } // class XMLDTDValidator
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.