Source Code Cross Referenced for XMLDocumentScannerImpl.java in  » XML » xerces-2_9_1 » org » apache » xerces » impl » 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 
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;
0019:
0020:        import java.io.CharConversionException;
0021:        import java.io.EOFException;
0022:        import java.io.IOException;
0023:
0024:        import org.apache.xerces.impl.dtd.XMLDTDDescription;
0025:        import org.apache.xerces.impl.io.MalformedByteSequenceException;
0026:        import org.apache.xerces.impl.msg.XMLMessageFormatter;
0027:        import org.apache.xerces.impl.validation.ValidationManager;
0028:        import org.apache.xerces.util.NamespaceSupport;
0029:        import org.apache.xerces.util.XMLChar;
0030:        import org.apache.xerces.util.XMLStringBuffer;
0031:        import org.apache.xerces.xni.Augmentations;
0032:        import org.apache.xerces.xni.NamespaceContext;
0033:        import org.apache.xerces.xni.XMLResourceIdentifier;
0034:        import org.apache.xerces.xni.XMLString;
0035:        import org.apache.xerces.xni.XNIException;
0036:        import org.apache.xerces.xni.parser.XMLComponentManager;
0037:        import org.apache.xerces.xni.parser.XMLConfigurationException;
0038:        import org.apache.xerces.xni.parser.XMLDTDScanner;
0039:        import org.apache.xerces.xni.parser.XMLInputSource;
0040:
0041:        /**
0042:         * This class is responsible for scanning XML document structure
0043:         * and content. The scanner acts as the source for the document
0044:         * information which is communicated to the document handler.
0045:         * <p>
0046:         * This component requires the following features and properties from the
0047:         * component manager that uses it:
0048:         * <ul>
0049:         *  <li>http://xml.org/sax/features/namespaces</li>
0050:         *  <li>http://xml.org/sax/features/validation</li>
0051:         *  <li>http://apache.org/xml/features/nonvalidating/load-external-dtd</li>
0052:         *  <li>http://apache.org/xml/features/scanner/notify-char-refs</li>
0053:         *  <li>http://apache.org/xml/features/scanner/notify-builtin-refs</li>
0054:         *  <li>http://apache.org/xml/properties/internal/symbol-table</li>
0055:         *  <li>http://apache.org/xml/properties/internal/error-reporter</li>
0056:         *  <li>http://apache.org/xml/properties/internal/entity-manager</li>
0057:         *  <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
0058:         * </ul>
0059:         * 
0060:         * @xerces.internal
0061:         *
0062:         * @author Glenn Marcy, IBM
0063:         * @author Andy Clark, IBM
0064:         * @author Arnaud  Le Hors, IBM
0065:         * @author Eric Ye, IBM
0066:         *
0067:         * @version $Id: XMLDocumentScannerImpl.java 572055 2007-09-02 17:55:43Z mrglavas $
0068:         */
0069:        public class XMLDocumentScannerImpl extends
0070:                XMLDocumentFragmentScannerImpl {
0071:
0072:            //
0073:            // Constants
0074:            //
0075:
0076:            // scanner states
0077:
0078:            /** Scanner state: XML declaration. */
0079:            protected static final int SCANNER_STATE_XML_DECL = 0;
0080:
0081:            /** Scanner state: prolog. */
0082:            protected static final int SCANNER_STATE_PROLOG = 5;
0083:
0084:            /** Scanner state: trailing misc. */
0085:            protected static final int SCANNER_STATE_TRAILING_MISC = 12;
0086:
0087:            /** Scanner state: DTD internal declarations. */
0088:            protected static final int SCANNER_STATE_DTD_INTERNAL_DECLS = 17;
0089:
0090:            /** Scanner state: open DTD external subset. */
0091:            protected static final int SCANNER_STATE_DTD_EXTERNAL = 18;
0092:
0093:            /** Scanner state: DTD external declarations. */
0094:            protected static final int SCANNER_STATE_DTD_EXTERNAL_DECLS = 19;
0095:
0096:            // feature identifiers
0097:
0098:            /** Feature identifier: load external DTD. */
0099:            protected static final String LOAD_EXTERNAL_DTD = Constants.XERCES_FEATURE_PREFIX
0100:                    + Constants.LOAD_EXTERNAL_DTD_FEATURE;
0101:
0102:            /** Feature identifier: load external DTD. */
0103:            protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = Constants.XERCES_FEATURE_PREFIX
0104:                    + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
0105:
0106:            // property identifiers
0107:
0108:            /** Property identifier: DTD scanner. */
0109:            protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0110:                    + Constants.DTD_SCANNER_PROPERTY;
0111:
0112:            /** property identifier:  ValidationManager */
0113:            protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0114:                    + Constants.VALIDATION_MANAGER_PROPERTY;
0115:
0116:            /** property identifier:  NamespaceContext */
0117:            protected static final String NAMESPACE_CONTEXT = Constants.XERCES_PROPERTY_PREFIX
0118:                    + Constants.NAMESPACE_CONTEXT_PROPERTY;
0119:
0120:            // recognized features and properties
0121:
0122:            /** Recognized features. */
0123:            private static final String[] RECOGNIZED_FEATURES = {
0124:                    LOAD_EXTERNAL_DTD, DISALLOW_DOCTYPE_DECL_FEATURE, };
0125:
0126:            /** Feature defaults. */
0127:            private static final Boolean[] FEATURE_DEFAULTS = { Boolean.TRUE,
0128:                    Boolean.FALSE, };
0129:
0130:            /** Recognized properties. */
0131:            private static final String[] RECOGNIZED_PROPERTIES = {
0132:                    DTD_SCANNER, VALIDATION_MANAGER, NAMESPACE_CONTEXT, };
0133:
0134:            /** Property defaults. */
0135:            private static final Object[] PROPERTY_DEFAULTS = { null, null,
0136:                    null, };
0137:
0138:            //
0139:            // Data
0140:            //
0141:
0142:            // properties
0143:
0144:            /** DTD scanner. */
0145:            protected XMLDTDScanner fDTDScanner;
0146:            /** Validation manager . */
0147:            protected ValidationManager fValidationManager;
0148:
0149:            // protected data
0150:
0151:            /** Scanning DTD. */
0152:            protected boolean fScanningDTD;
0153:
0154:            // other info
0155:
0156:            /** Doctype name. */
0157:            protected String fDoctypeName;
0158:
0159:            /** Doctype declaration public identifier. */
0160:            protected String fDoctypePublicId;
0161:
0162:            /** Doctype declaration system identifier. */
0163:            protected String fDoctypeSystemId;
0164:
0165:            /** Namespace support. */
0166:            protected NamespaceContext fNamespaceContext = new NamespaceSupport();
0167:
0168:            // features
0169:
0170:            /** Load external DTD. */
0171:            protected boolean fLoadExternalDTD = true;
0172:
0173:            /** Disallow doctype declaration. */
0174:            protected boolean fDisallowDoctype = false;
0175:
0176:            // state
0177:
0178:            /** Seen doctype declaration. */
0179:            protected boolean fSeenDoctypeDecl;
0180:
0181:            // dispatchers
0182:
0183:            /** XML declaration dispatcher. */
0184:            protected final Dispatcher fXMLDeclDispatcher = new XMLDeclDispatcher();
0185:
0186:            /** Prolog dispatcher. */
0187:            protected final Dispatcher fPrologDispatcher = new PrologDispatcher();
0188:
0189:            /** DTD dispatcher. */
0190:            protected final Dispatcher fDTDDispatcher = new DTDDispatcher();
0191:
0192:            /** Trailing miscellaneous section dispatcher. */
0193:            protected final Dispatcher fTrailingMiscDispatcher = new TrailingMiscDispatcher();
0194:
0195:            // temporary variables
0196:
0197:            /** Array of 3 strings. */
0198:            private final String[] fStrings = new String[3];
0199:
0200:            /** String. */
0201:            private final XMLString fString = new XMLString();
0202:
0203:            /** String buffer. */
0204:            private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();
0205:
0206:            /** External subset source. */
0207:            private XMLInputSource fExternalSubsetSource = null;
0208:
0209:            /** A DTD Description. */
0210:            private final XMLDTDDescription fDTDDescription = new XMLDTDDescription(
0211:                    null, null, null, null, null);
0212:
0213:            //
0214:            // Constructors
0215:            //
0216:
0217:            /** Default constructor. */
0218:            public XMLDocumentScannerImpl() {
0219:            } // <init>()
0220:
0221:            //
0222:            // XMLDocumentScanner methods
0223:            //
0224:
0225:            /**
0226:             * Sets the input source.
0227:             *
0228:             * @param inputSource The input source.
0229:             *
0230:             * @throws IOException Thrown on i/o error.
0231:             */
0232:            public void setInputSource(XMLInputSource inputSource)
0233:                    throws IOException {
0234:                fEntityManager.setEntityHandler(this );
0235:                fEntityManager.startDocumentEntity(inputSource);
0236:                //fDocumentSystemId = fEntityManager.expandSystemId(inputSource.getSystemId());
0237:            } // setInputSource(XMLInputSource)
0238:
0239:            //
0240:            // XMLComponent methods
0241:            //
0242:
0243:            /**
0244:             * Resets the component. The component can query the component manager
0245:             * about any features and properties that affect the operation of the
0246:             * component.
0247:             *
0248:             * @param componentManager The component manager.
0249:             *
0250:             * @throws SAXException Thrown by component on initialization error.
0251:             *                      For example, if a feature or property is
0252:             *                      required for the operation of the component, the
0253:             *                      component manager may throw a
0254:             *                      SAXNotRecognizedException or a
0255:             *                      SAXNotSupportedException.
0256:             */
0257:            public void reset(XMLComponentManager componentManager)
0258:                    throws XMLConfigurationException {
0259:
0260:                super .reset(componentManager);
0261:
0262:                // other settings
0263:                fDoctypeName = null;
0264:                fDoctypePublicId = null;
0265:                fDoctypeSystemId = null;
0266:                fSeenDoctypeDecl = false;
0267:                fScanningDTD = false;
0268:                fExternalSubsetSource = null;
0269:
0270:                if (!fParserSettings) {
0271:                    // parser settings have not been changed
0272:                    fNamespaceContext.reset();
0273:                    // setup dispatcher
0274:                    setScannerState(SCANNER_STATE_XML_DECL);
0275:                    setDispatcher(fXMLDeclDispatcher);
0276:                    return;
0277:                }
0278:
0279:                // xerces features
0280:                try {
0281:                    fLoadExternalDTD = componentManager
0282:                            .getFeature(LOAD_EXTERNAL_DTD);
0283:                } catch (XMLConfigurationException e) {
0284:                    fLoadExternalDTD = true;
0285:                }
0286:                try {
0287:                    fDisallowDoctype = componentManager
0288:                            .getFeature(DISALLOW_DOCTYPE_DECL_FEATURE);
0289:                } catch (XMLConfigurationException e) {
0290:                    fDisallowDoctype = false;
0291:                }
0292:
0293:                // xerces properties
0294:                fDTDScanner = (XMLDTDScanner) componentManager
0295:                        .getProperty(DTD_SCANNER);
0296:                try {
0297:                    fValidationManager = (ValidationManager) componentManager
0298:                            .getProperty(VALIDATION_MANAGER);
0299:                } catch (XMLConfigurationException e) {
0300:                    fValidationManager = null;
0301:                }
0302:
0303:                try {
0304:                    fNamespaceContext = (NamespaceContext) componentManager
0305:                            .getProperty(NAMESPACE_CONTEXT);
0306:                } catch (XMLConfigurationException e) {
0307:                }
0308:                if (fNamespaceContext == null) {
0309:                    fNamespaceContext = new NamespaceSupport();
0310:                }
0311:                fNamespaceContext.reset();
0312:
0313:                // setup dispatcher
0314:                setScannerState(SCANNER_STATE_XML_DECL);
0315:                setDispatcher(fXMLDeclDispatcher);
0316:
0317:            } // reset(XMLComponentManager)
0318:
0319:            /**
0320:             * Returns a list of feature identifiers that are recognized by
0321:             * this component. This method may return null if no features
0322:             * are recognized by this component.
0323:             */
0324:            public String[] getRecognizedFeatures() {
0325:                String[] featureIds = super .getRecognizedFeatures();
0326:                int length = featureIds != null ? featureIds.length : 0;
0327:                String[] combinedFeatureIds = new String[length
0328:                        + RECOGNIZED_FEATURES.length];
0329:                if (featureIds != null) {
0330:                    System.arraycopy(featureIds, 0, combinedFeatureIds, 0,
0331:                            featureIds.length);
0332:                }
0333:                System.arraycopy(RECOGNIZED_FEATURES, 0, combinedFeatureIds,
0334:                        length, RECOGNIZED_FEATURES.length);
0335:                return combinedFeatureIds;
0336:            } // getRecognizedFeatures():String[]
0337:
0338:            /**
0339:             * Sets the state of a feature. This method is called by the component
0340:             * manager any time after reset when a feature changes state.
0341:             * <p>
0342:             * <strong>Note:</strong> Components should silently ignore features
0343:             * that do not affect the operation of the component.
0344:             *
0345:             * @param featureId The feature identifier.
0346:             * @param state     The state of the feature.
0347:             *
0348:             * @throws SAXNotRecognizedException The component should not throw
0349:             *                                   this exception.
0350:             * @throws SAXNotSupportedException The component should not throw
0351:             *                                  this exception.
0352:             */
0353:            public void setFeature(String featureId, boolean state)
0354:                    throws XMLConfigurationException {
0355:
0356:                super .setFeature(featureId, state);
0357:
0358:                // Xerces properties
0359:                if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
0360:                    final int suffixLength = featureId.length()
0361:                            - Constants.XERCES_FEATURE_PREFIX.length();
0362:
0363:                    if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE
0364:                            .length()
0365:                            && featureId
0366:                                    .endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
0367:                        fLoadExternalDTD = state;
0368:                        return;
0369:                    } else if (suffixLength == Constants.DISALLOW_DOCTYPE_DECL_FEATURE
0370:                            .length()
0371:                            && featureId
0372:                                    .endsWith(Constants.DISALLOW_DOCTYPE_DECL_FEATURE)) {
0373:                        fDisallowDoctype = state;
0374:                        return;
0375:                    }
0376:                }
0377:
0378:            } // setFeature(String,boolean)
0379:
0380:            /**
0381:             * Returns a list of property identifiers that are recognized by
0382:             * this component. This method may return null if no properties
0383:             * are recognized by this component.
0384:             */
0385:            public String[] getRecognizedProperties() {
0386:                String[] propertyIds = super .getRecognizedProperties();
0387:                int length = propertyIds != null ? propertyIds.length : 0;
0388:                String[] combinedPropertyIds = new String[length
0389:                        + RECOGNIZED_PROPERTIES.length];
0390:                if (propertyIds != null) {
0391:                    System.arraycopy(propertyIds, 0, combinedPropertyIds, 0,
0392:                            propertyIds.length);
0393:                }
0394:                System.arraycopy(RECOGNIZED_PROPERTIES, 0, combinedPropertyIds,
0395:                        length, RECOGNIZED_PROPERTIES.length);
0396:                return combinedPropertyIds;
0397:            } // getRecognizedProperties():String[]
0398:
0399:            /**
0400:             * Sets the value of a property. This method is called by the component
0401:             * manager any time after reset when a property changes value.
0402:             * <p>
0403:             * <strong>Note:</strong> Components should silently ignore properties
0404:             * that do not affect the operation of the component.
0405:             *
0406:             * @param propertyId The property identifier.
0407:             * @param value      The value of the property.
0408:             *
0409:             * @throws SAXNotRecognizedException The component should not throw
0410:             *                                   this exception.
0411:             * @throws SAXNotSupportedException The component should not throw
0412:             *                                  this exception.
0413:             */
0414:            public void setProperty(String propertyId, Object value)
0415:                    throws XMLConfigurationException {
0416:
0417:                super .setProperty(propertyId, value);
0418:
0419:                // Xerces properties
0420:                if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
0421:                    final int suffixLength = propertyId.length()
0422:                            - Constants.XERCES_PROPERTY_PREFIX.length();
0423:
0424:                    if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length()
0425:                            && propertyId
0426:                                    .endsWith(Constants.DTD_SCANNER_PROPERTY)) {
0427:                        fDTDScanner = (XMLDTDScanner) value;
0428:                    }
0429:                    if (suffixLength == Constants.NAMESPACE_CONTEXT_PROPERTY
0430:                            .length()
0431:                            && propertyId
0432:                                    .endsWith(Constants.NAMESPACE_CONTEXT_PROPERTY)) {
0433:                        if (value != null) {
0434:                            fNamespaceContext = (NamespaceContext) value;
0435:                        }
0436:                    }
0437:
0438:                    return;
0439:                }
0440:
0441:            } // setProperty(String,Object)
0442:
0443:            /** 
0444:             * Returns the default state for a feature, or null if this
0445:             * component does not want to report a default value for this
0446:             * feature.
0447:             *
0448:             * @param featureId The feature identifier.
0449:             *
0450:             * @since Xerces 2.2.0
0451:             */
0452:            public Boolean getFeatureDefault(String featureId) {
0453:
0454:                for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
0455:                    if (RECOGNIZED_FEATURES[i].equals(featureId)) {
0456:                        return FEATURE_DEFAULTS[i];
0457:                    }
0458:                }
0459:                return super .getFeatureDefault(featureId);
0460:            } // getFeatureDefault(String):Boolean
0461:
0462:            /** 
0463:             * Returns the default state for a property, or null if this
0464:             * component does not want to report a default value for this
0465:             * property. 
0466:             *
0467:             * @param propertyId The property identifier.
0468:             *
0469:             * @since Xerces 2.2.0
0470:             */
0471:            public Object getPropertyDefault(String propertyId) {
0472:                for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
0473:                    if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
0474:                        return PROPERTY_DEFAULTS[i];
0475:                    }
0476:                }
0477:                return super .getPropertyDefault(propertyId);
0478:            } // getPropertyDefault(String):Object
0479:
0480:            //
0481:            // XMLEntityHandler methods
0482:            //
0483:
0484:            /**
0485:             * This method notifies of the start of an entity. The DTD has the
0486:             * pseudo-name of "[dtd]" parameter entity names start with '%'; and
0487:             * general entities are just specified by their name.
0488:             *
0489:             * @param name     The name of the entity.
0490:             * @param identifier The resource identifier.
0491:             * @param encoding The auto-detected IANA encoding name of the entity
0492:             *                 stream. This value will be null in those situations
0493:             *                 where the entity encoding is not auto-detected (e.g.
0494:             *                 internal entities or a document entity that is
0495:             *                 parsed from a java.io.Reader).
0496:             *
0497:             * @throws XNIException Thrown by handler to signal an error.
0498:             */
0499:            public void startEntity(String name,
0500:                    XMLResourceIdentifier identifier, String encoding,
0501:                    Augmentations augs) throws XNIException {
0502:
0503:                super .startEntity(name, identifier, encoding, augs);
0504:
0505:                // prepare to look for a TextDecl if external general entity
0506:                if (!name.equals("[xml]") && fEntityScanner.isExternal()) {
0507:                    setScannerState(SCANNER_STATE_TEXT_DECL);
0508:                }
0509:
0510:                // call handler
0511:                if (fDocumentHandler != null && name.equals("[xml]")) {
0512:                    fDocumentHandler.startDocument(fEntityScanner, encoding,
0513:                            fNamespaceContext, null);
0514:                }
0515:
0516:            } // startEntity(String,identifier,String)
0517:
0518:            /**
0519:             * This method notifies the end of an entity. The DTD has the pseudo-name
0520:             * of "[dtd]" parameter entity names start with '%'; and general entities
0521:             * are just specified by their name.
0522:             *
0523:             * @param name The name of the entity.
0524:             *
0525:             * @throws XNIException Thrown by handler to signal an error.
0526:             */
0527:            public void endEntity(String name, Augmentations augs)
0528:                    throws XNIException {
0529:
0530:                super .endEntity(name, augs);
0531:
0532:                // call handler
0533:                if (fDocumentHandler != null && name.equals("[xml]")) {
0534:                    fDocumentHandler.endDocument(null);
0535:                }
0536:
0537:            } // endEntity(String)
0538:
0539:            //
0540:            // Protected methods
0541:            //
0542:
0543:            // dispatcher factory methods
0544:
0545:            /** Creates a content dispatcher. */
0546:            protected Dispatcher createContentDispatcher() {
0547:                return new ContentDispatcher();
0548:            } // createContentDispatcher():Dispatcher
0549:
0550:            // scanning methods
0551:
0552:            /** Scans a doctype declaration. */
0553:            protected boolean scanDoctypeDecl() throws IOException,
0554:                    XNIException {
0555:
0556:                // spaces
0557:                if (!fEntityScanner.skipSpaces()) {
0558:                    reportFatalError(
0559:                            "MSG_SPACE_REQUIRED_BEFORE_ROOT_ELEMENT_TYPE_IN_DOCTYPEDECL",
0560:                            null);
0561:                }
0562:
0563:                // root element name
0564:                fDoctypeName = fEntityScanner.scanName();
0565:                if (fDoctypeName == null) {
0566:                    reportFatalError("MSG_ROOT_ELEMENT_TYPE_REQUIRED", null);
0567:                }
0568:
0569:                // external id
0570:                if (fEntityScanner.skipSpaces()) {
0571:                    scanExternalID(fStrings, false);
0572:                    fDoctypeSystemId = fStrings[0];
0573:                    fDoctypePublicId = fStrings[1];
0574:                    fEntityScanner.skipSpaces();
0575:                }
0576:
0577:                fHasExternalDTD = fDoctypeSystemId != null;
0578:
0579:                // Attempt to locate an external subset with an external subset resolver.
0580:                if (!fHasExternalDTD && fExternalSubsetResolver != null) {
0581:                    fDTDDescription.setValues(null, null, fEntityManager
0582:                            .getCurrentResourceIdentifier()
0583:                            .getExpandedSystemId(), null);
0584:                    fDTDDescription.setRootName(fDoctypeName);
0585:                    fExternalSubsetSource = fExternalSubsetResolver
0586:                            .getExternalSubset(fDTDDescription);
0587:                    fHasExternalDTD = fExternalSubsetSource != null;
0588:                }
0589:
0590:                // call handler
0591:                if (fDocumentHandler != null) {
0592:                    // NOTE: I don't like calling the doctypeDecl callback until
0593:                    //       end of the *full* doctype line (including internal
0594:                    //       subset) is parsed correctly but SAX2 requires that
0595:                    //       it knows the root element name and public and system
0596:                    //       identifier for the startDTD call. -Ac
0597:                    if (fExternalSubsetSource == null) {
0598:                        fDocumentHandler.doctypeDecl(fDoctypeName,
0599:                                fDoctypePublicId, fDoctypeSystemId, null);
0600:                    } else {
0601:                        fDocumentHandler.doctypeDecl(fDoctypeName,
0602:                                fExternalSubsetSource.getPublicId(),
0603:                                fExternalSubsetSource.getSystemId(), null);
0604:                    }
0605:                }
0606:
0607:                // is there an internal subset?
0608:                boolean internalSubset = true;
0609:                if (!fEntityScanner.skipChar('[')) {
0610:                    internalSubset = false;
0611:                    fEntityScanner.skipSpaces();
0612:                    if (!fEntityScanner.skipChar('>')) {
0613:                        reportFatalError("DoctypedeclUnterminated",
0614:                                new Object[] { fDoctypeName });
0615:                    }
0616:                    fMarkupDepth--;
0617:                }
0618:
0619:                return internalSubset;
0620:
0621:            } // scanDoctypeDecl():boolean
0622:
0623:            //
0624:            // Private methods
0625:            //
0626:
0627:            /** Returns the scanner state name. */
0628:            protected String getScannerStateName(int state) {
0629:
0630:                switch (state) {
0631:                case SCANNER_STATE_XML_DECL:
0632:                    return "SCANNER_STATE_XML_DECL";
0633:                case SCANNER_STATE_PROLOG:
0634:                    return "SCANNER_STATE_PROLOG";
0635:                case SCANNER_STATE_TRAILING_MISC:
0636:                    return "SCANNER_STATE_TRAILING_MISC";
0637:                case SCANNER_STATE_DTD_INTERNAL_DECLS:
0638:                    return "SCANNER_STATE_DTD_INTERNAL_DECLS";
0639:                case SCANNER_STATE_DTD_EXTERNAL:
0640:                    return "SCANNER_STATE_DTD_EXTERNAL";
0641:                case SCANNER_STATE_DTD_EXTERNAL_DECLS:
0642:                    return "SCANNER_STATE_DTD_EXTERNAL_DECLS";
0643:                }
0644:                return super .getScannerStateName(state);
0645:
0646:            } // getScannerStateName(int):String
0647:
0648:            //
0649:            // Classes
0650:            //
0651:
0652:            /**
0653:             * Dispatcher to handle XMLDecl scanning.
0654:             *
0655:             * @author Andy Clark, IBM
0656:             */
0657:            protected final class XMLDeclDispatcher implements  Dispatcher {
0658:
0659:                //
0660:                // Dispatcher methods
0661:                //
0662:
0663:                /**
0664:                 * Dispatch an XML "event".
0665:                 *
0666:                 * @param complete True if this dispatcher is intended to scan
0667:                 *                 and dispatch as much as possible.
0668:                 *
0669:                 * @return True if there is more to dispatch either from this
0670:                 *          or a another dispatcher.
0671:                 *
0672:                 * @throws IOException  Thrown on i/o error.
0673:                 * @throws XNIException Thrown on parse error.
0674:                 */
0675:                public boolean dispatch(boolean complete) throws IOException,
0676:                        XNIException {
0677:
0678:                    // next dispatcher is prolog regardless of whether there
0679:                    // is an XMLDecl in this document
0680:                    setScannerState(SCANNER_STATE_PROLOG);
0681:                    setDispatcher(fPrologDispatcher);
0682:
0683:                    // scan XMLDecl
0684:                    try {
0685:                        if (fEntityScanner.skipString("<?xml")) {
0686:                            fMarkupDepth++;
0687:                            // NOTE: special case where document starts with a PI
0688:                            //       whose name starts with "xml" (e.g. "xmlfoo")
0689:                            if (XMLChar.isName(fEntityScanner.peekChar())) {
0690:                                fStringBuffer.clear();
0691:                                fStringBuffer.append("xml");
0692:                                if (fNamespaces) {
0693:                                    while (XMLChar.isNCName(fEntityScanner
0694:                                            .peekChar())) {
0695:                                        fStringBuffer
0696:                                                .append((char) fEntityScanner
0697:                                                        .scanChar());
0698:                                    }
0699:                                } else {
0700:                                    while (XMLChar.isName(fEntityScanner
0701:                                            .peekChar())) {
0702:                                        fStringBuffer
0703:                                                .append((char) fEntityScanner
0704:                                                        .scanChar());
0705:                                    }
0706:                                }
0707:                                String target = fSymbolTable.addSymbol(
0708:                                        fStringBuffer.ch, fStringBuffer.offset,
0709:                                        fStringBuffer.length);
0710:                                scanPIData(target, fString);
0711:                            }
0712:
0713:                            // standard XML declaration
0714:                            else {
0715:                                scanXMLDeclOrTextDecl(false);
0716:                            }
0717:                        }
0718:                        fEntityManager.fCurrentEntity.mayReadChunks = true;
0719:
0720:                        // if no XMLDecl, then scan piece of prolog
0721:                        return true;
0722:                    }
0723:                    // encoding errors
0724:                    catch (MalformedByteSequenceException e) {
0725:                        fErrorReporter.reportError(e.getDomain(), e.getKey(), e
0726:                                .getArguments(),
0727:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0728:                        return false;
0729:                    } catch (CharConversionException e) {
0730:                        fErrorReporter.reportError(
0731:                                XMLMessageFormatter.XML_DOMAIN,
0732:                                "CharConversionFailure", null,
0733:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0734:                        return false;
0735:                    }
0736:                    // premature end of file
0737:                    catch (EOFException e) {
0738:                        reportFatalError("PrematureEOF", null);
0739:                        return false;
0740:                        //throw e;
0741:                    }
0742:
0743:                } // dispatch(boolean):boolean
0744:
0745:            } // class XMLDeclDispatcher
0746:
0747:            /**
0748:             * Dispatcher to handle prolog scanning.
0749:             *
0750:             * @author Andy Clark, IBM
0751:             */
0752:            protected final class PrologDispatcher implements  Dispatcher {
0753:
0754:                //
0755:                // Dispatcher methods
0756:                //
0757:
0758:                /**
0759:                 * Dispatch an XML "event".
0760:                 *
0761:                 * @param complete True if this dispatcher is intended to scan
0762:                 *                 and dispatch as much as possible.
0763:                 *
0764:                 * @return True if there is more to dispatch either from this
0765:                 *          or a another dispatcher.
0766:                 *
0767:                 * @throws IOException  Thrown on i/o error.
0768:                 * @throws XNIException Thrown on parse error.
0769:                 */
0770:                public boolean dispatch(boolean complete) throws IOException,
0771:                        XNIException {
0772:
0773:                    try {
0774:                        boolean again;
0775:                        do {
0776:                            again = false;
0777:                            switch (fScannerState) {
0778:                            case SCANNER_STATE_PROLOG: {
0779:                                fEntityScanner.skipSpaces();
0780:                                if (fEntityScanner.skipChar('<')) {
0781:                                    setScannerState(SCANNER_STATE_START_OF_MARKUP);
0782:                                    again = true;
0783:                                } else if (fEntityScanner.skipChar('&')) {
0784:                                    setScannerState(SCANNER_STATE_REFERENCE);
0785:                                    again = true;
0786:                                } else {
0787:                                    setScannerState(SCANNER_STATE_CONTENT);
0788:                                    again = true;
0789:                                }
0790:                                break;
0791:                            }
0792:                            case SCANNER_STATE_START_OF_MARKUP: {
0793:                                fMarkupDepth++;
0794:                                if (fEntityScanner.skipChar('!')) {
0795:                                    if (fEntityScanner.skipChar('-')) {
0796:                                        if (!fEntityScanner.skipChar('-')) {
0797:                                            reportFatalError(
0798:                                                    "InvalidCommentStart", null);
0799:                                        }
0800:                                        setScannerState(SCANNER_STATE_COMMENT);
0801:                                        again = true;
0802:                                    } else if (fEntityScanner
0803:                                            .skipString("DOCTYPE")) {
0804:                                        setScannerState(SCANNER_STATE_DOCTYPE);
0805:                                        again = true;
0806:                                    } else {
0807:                                        reportFatalError(
0808:                                                "MarkupNotRecognizedInProlog",
0809:                                                null);
0810:                                    }
0811:                                } else if (isValidNameStartChar(fEntityScanner
0812:                                        .peekChar())) {
0813:                                    setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0814:                                    setDispatcher(fContentDispatcher);
0815:                                    return true;
0816:                                } else if (fEntityScanner.skipChar('?')) {
0817:                                    setScannerState(SCANNER_STATE_PI);
0818:                                    again = true;
0819:                                } else if (isValidNameStartHighSurrogate(fEntityScanner
0820:                                        .peekChar())) {
0821:                                    setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0822:                                    setDispatcher(fContentDispatcher);
0823:                                    return true;
0824:                                } else {
0825:                                    reportFatalError(
0826:                                            "MarkupNotRecognizedInProlog", null);
0827:                                }
0828:                                break;
0829:                            }
0830:                            case SCANNER_STATE_COMMENT: {
0831:                                scanComment();
0832:                                setScannerState(SCANNER_STATE_PROLOG);
0833:                                break;
0834:                            }
0835:                            case SCANNER_STATE_PI: {
0836:                                scanPI();
0837:                                setScannerState(SCANNER_STATE_PROLOG);
0838:                                break;
0839:                            }
0840:                            case SCANNER_STATE_DOCTYPE: {
0841:                                if (fDisallowDoctype) {
0842:                                    reportFatalError("DoctypeNotAllowed", null);
0843:                                }
0844:                                if (fSeenDoctypeDecl) {
0845:                                    reportFatalError("AlreadySeenDoctype", null);
0846:                                }
0847:                                fSeenDoctypeDecl = true;
0848:
0849:                                // scanDoctypeDecl() sends XNI doctypeDecl event that 
0850:                                // in SAX is converted to startDTD() event.
0851:                                if (scanDoctypeDecl()) {
0852:                                    setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);
0853:                                    setDispatcher(fDTDDispatcher);
0854:                                    return true;
0855:                                }
0856:
0857:                                // handle external subset
0858:                                if (fDoctypeSystemId != null) {
0859:                                    fIsEntityDeclaredVC = !fStandalone;
0860:                                    if (((fValidation || fLoadExternalDTD) && (fValidationManager == null || !fValidationManager
0861:                                            .isCachedDTD()))) {
0862:                                        setScannerState(SCANNER_STATE_DTD_EXTERNAL);
0863:                                        setDispatcher(fDTDDispatcher);
0864:                                        return true;
0865:                                    }
0866:                                } else if (fExternalSubsetSource != null) {
0867:                                    fIsEntityDeclaredVC = !fStandalone;
0868:                                    if (((fValidation || fLoadExternalDTD) && (fValidationManager == null || !fValidationManager
0869:                                            .isCachedDTD()))) {
0870:                                        // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.
0871:                                        fDTDScanner
0872:                                                .setInputSource(fExternalSubsetSource);
0873:                                        fExternalSubsetSource = null;
0874:                                        setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
0875:                                        setDispatcher(fDTDDispatcher);
0876:                                        return true;
0877:                                    }
0878:                                }
0879:
0880:                                // Send endDTD() call if: 
0881:                                // a) systemId is null or if an external subset resolver could not locate an external subset.
0882:                                // b) "load-external-dtd" and validation are false
0883:                                // c) DTD grammar is cached
0884:
0885:                                // in XNI this results in 3 events:  doctypeDecl, startDTD, endDTD
0886:                                // in SAX this results in 2 events: startDTD, endDTD
0887:                                fDTDScanner.setInputSource(null);
0888:                                setScannerState(SCANNER_STATE_PROLOG);
0889:                                break;
0890:                            }
0891:                            case SCANNER_STATE_CONTENT: {
0892:                                reportFatalError("ContentIllegalInProlog", null);
0893:                                fEntityScanner.scanChar();
0894:                            }
0895:                            case SCANNER_STATE_REFERENCE: {
0896:                                reportFatalError("ReferenceIllegalInProlog",
0897:                                        null);
0898:                            }
0899:                            }
0900:                        } while (complete || again);
0901:
0902:                        if (complete) {
0903:                            if (fEntityScanner.scanChar() != '<') {
0904:                                reportFatalError("RootElementRequired", null);
0905:                            }
0906:                            setScannerState(SCANNER_STATE_ROOT_ELEMENT);
0907:                            setDispatcher(fContentDispatcher);
0908:                        }
0909:                    }
0910:                    // encoding errors
0911:                    catch (MalformedByteSequenceException e) {
0912:                        fErrorReporter.reportError(e.getDomain(), e.getKey(), e
0913:                                .getArguments(),
0914:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0915:                        return false;
0916:                    } catch (CharConversionException e) {
0917:                        fErrorReporter.reportError(
0918:                                XMLMessageFormatter.XML_DOMAIN,
0919:                                "CharConversionFailure", null,
0920:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
0921:                        return false;
0922:                    }
0923:                    // premature end of file
0924:                    catch (EOFException e) {
0925:                        reportFatalError("PrematureEOF", null);
0926:                        return false;
0927:                        //throw e;
0928:                    }
0929:
0930:                    return true;
0931:
0932:                } // dispatch(boolean):boolean
0933:
0934:            } // class PrologDispatcher
0935:
0936:            /**
0937:             * Dispatcher to handle the internal and external DTD subsets.
0938:             *
0939:             * @author Andy Clark, IBM
0940:             */
0941:            protected final class DTDDispatcher implements  Dispatcher {
0942:
0943:                //
0944:                // Dispatcher methods
0945:                //
0946:
0947:                /**
0948:                 * Dispatch an XML "event".
0949:                 *
0950:                 * @param complete True if this dispatcher is intended to scan
0951:                 *                 and dispatch as much as possible.
0952:                 *
0953:                 * @return True if there is more to dispatch either from this
0954:                 *          or a another dispatcher.
0955:                 *
0956:                 * @throws IOException  Thrown on i/o error.
0957:                 * @throws XNIException Thrown on parse error.
0958:                 */
0959:                public boolean dispatch(boolean complete) throws IOException,
0960:                        XNIException {
0961:                    fEntityManager.setEntityHandler(null);
0962:                    try {
0963:                        boolean again;
0964:                        do {
0965:                            again = false;
0966:                            switch (fScannerState) {
0967:                            case SCANNER_STATE_DTD_INTERNAL_DECLS: {
0968:                                // REVISIT: Should there be a feature for
0969:                                //          the "complete" parameter?
0970:                                boolean completeDTD = true;
0971:                                boolean readExternalSubset = (fValidation || fLoadExternalDTD)
0972:                                        && (fValidationManager == null || !fValidationManager
0973:                                                .isCachedDTD());
0974:                                boolean moreToScan = fDTDScanner
0975:                                        .scanDTDInternalSubset(completeDTD,
0976:                                                fStandalone, fHasExternalDTD
0977:                                                        && readExternalSubset);
0978:                                if (!moreToScan) {
0979:                                    // end doctype declaration
0980:                                    if (!fEntityScanner.skipChar(']')) {
0981:                                        reportFatalError(
0982:                                                "EXPECTED_SQUARE_BRACKET_TO_CLOSE_INTERNAL_SUBSET",
0983:                                                null);
0984:                                    }
0985:                                    fEntityScanner.skipSpaces();
0986:                                    if (!fEntityScanner.skipChar('>')) {
0987:                                        reportFatalError(
0988:                                                "DoctypedeclUnterminated",
0989:                                                new Object[] { fDoctypeName });
0990:                                    }
0991:                                    fMarkupDepth--;
0992:
0993:                                    // scan external subset next
0994:                                    if (fDoctypeSystemId != null) {
0995:                                        fIsEntityDeclaredVC = !fStandalone;
0996:                                        if (readExternalSubset) {
0997:                                            setScannerState(SCANNER_STATE_DTD_EXTERNAL);
0998:                                            break;
0999:                                        }
1000:                                    } else if (fExternalSubsetSource != null) {
1001:                                        fIsEntityDeclaredVC = !fStandalone;
1002:                                        if (readExternalSubset) {
1003:                                            // This handles the case of a DOCTYPE that only had an internal subset.
1004:                                            fDTDScanner
1005:                                                    .setInputSource(fExternalSubsetSource);
1006:                                            fExternalSubsetSource = null;
1007:                                            setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
1008:                                            break;
1009:                                        }
1010:                                    }
1011:                                    // This document only has an internal subset. If it contains parameter entity
1012:                                    // references and standalone="no" then [Entity Declared] is a validity constraint.
1013:                                    else {
1014:                                        fIsEntityDeclaredVC = fEntityManager
1015:                                                .hasPEReferences()
1016:                                                && !fStandalone;
1017:                                    }
1018:
1019:                                    // break out of this dispatcher.
1020:                                    setScannerState(SCANNER_STATE_PROLOG);
1021:                                    setDispatcher(fPrologDispatcher);
1022:                                    fEntityManager
1023:                                            .setEntityHandler(XMLDocumentScannerImpl.this );
1024:                                    return true;
1025:                                }
1026:                                break;
1027:                            }
1028:                            case SCANNER_STATE_DTD_EXTERNAL: {
1029:                                fDTDDescription.setValues(fDoctypePublicId,
1030:                                        fDoctypeSystemId, null, null);
1031:                                fDTDDescription.setRootName(fDoctypeName);
1032:                                XMLInputSource xmlInputSource = fEntityManager
1033:                                        .resolveEntity(fDTDDescription);
1034:                                fDTDScanner.setInputSource(xmlInputSource);
1035:                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
1036:                                again = true;
1037:                                break;
1038:                            }
1039:                            case SCANNER_STATE_DTD_EXTERNAL_DECLS: {
1040:                                // REVISIT: Should there be a feature for
1041:                                //          the "complete" parameter?
1042:                                boolean completeDTD = true;
1043:                                boolean moreToScan = fDTDScanner
1044:                                        .scanDTDExternalSubset(completeDTD);
1045:                                if (!moreToScan) {
1046:                                    setScannerState(SCANNER_STATE_PROLOG);
1047:                                    setDispatcher(fPrologDispatcher);
1048:                                    fEntityManager
1049:                                            .setEntityHandler(XMLDocumentScannerImpl.this );
1050:                                    return true;
1051:                                }
1052:                                break;
1053:                            }
1054:                            default: {
1055:                                throw new XNIException(
1056:                                        "DTDDispatcher#dispatch: scanner state="
1057:                                                + fScannerState
1058:                                                + " ("
1059:                                                + getScannerStateName(fScannerState)
1060:                                                + ')');
1061:                            }
1062:                            }
1063:                        } while (complete || again);
1064:                    }
1065:                    // encoding errors
1066:                    catch (MalformedByteSequenceException e) {
1067:                        fErrorReporter.reportError(e.getDomain(), e.getKey(), e
1068:                                .getArguments(),
1069:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1070:                        return false;
1071:                    } catch (CharConversionException e) {
1072:                        fErrorReporter.reportError(
1073:                                XMLMessageFormatter.XML_DOMAIN,
1074:                                "CharConversionFailure", null,
1075:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1076:                        return false;
1077:                    }
1078:                    // premature end of file
1079:                    catch (EOFException e) {
1080:                        reportFatalError("PrematureEOF", null);
1081:                        return false;
1082:                        //throw e;
1083:                    }
1084:
1085:                    // cleanup
1086:                    finally {
1087:                        fEntityManager
1088:                                .setEntityHandler(XMLDocumentScannerImpl.this );
1089:                    }
1090:
1091:                    return true;
1092:
1093:                } // dispatch(boolean):boolean
1094:
1095:            } // class DTDDispatcher
1096:
1097:            /**
1098:             * Dispatcher to handle content scanning.
1099:             *
1100:             * @author Andy Clark, IBM
1101:             * @author Eric Ye, IBM
1102:             */
1103:            protected class ContentDispatcher extends FragmentContentDispatcher {
1104:
1105:                //
1106:                // Protected methods
1107:                //
1108:
1109:                // hooks
1110:
1111:                // NOTE: These hook methods are added so that the full document
1112:                //       scanner can share the majority of code with this class.
1113:
1114:                /**
1115:                 * Scan for DOCTYPE hook. This method is a hook for subclasses
1116:                 * to add code to handle scanning for a the "DOCTYPE" string
1117:                 * after the string "<!" has been scanned.
1118:                 *
1119:                 * @return True if the "DOCTYPE" was scanned; false if "DOCTYPE"
1120:                 *          was not scanned.
1121:                 */
1122:                protected boolean scanForDoctypeHook() throws IOException,
1123:                        XNIException {
1124:
1125:                    if (fEntityScanner.skipString("DOCTYPE")) {
1126:                        setScannerState(SCANNER_STATE_DOCTYPE);
1127:                        return true;
1128:                    }
1129:                    return false;
1130:
1131:                } // scanForDoctypeHook():boolean
1132:
1133:                /**
1134:                 * Element depth iz zero. This methos is a hook for subclasses
1135:                 * to add code to handle when the element depth hits zero. When
1136:                 * scanning a document fragment, an element depth of zero is
1137:                 * normal. However, when scanning a full XML document, the
1138:                 * scanner must handle the trailing miscellanous section of
1139:                 * the document after the end of the document's root element.
1140:                 *
1141:                 * @return True if the caller should stop and return true which
1142:                 *          allows the scanner to switch to a new scanning
1143:                 *          dispatcher. A return value of false indicates that
1144:                 *          the content dispatcher should continue as normal.
1145:                 */
1146:                protected boolean elementDepthIsZeroHook() throws IOException,
1147:                        XNIException {
1148:
1149:                    setScannerState(SCANNER_STATE_TRAILING_MISC);
1150:                    setDispatcher(fTrailingMiscDispatcher);
1151:                    return true;
1152:
1153:                } // elementDepthIsZeroHook():boolean
1154:
1155:                /**
1156:                 * Scan for root element hook. This method is a hook for
1157:                 * subclasses to add code that handles scanning for the root
1158:                 * element. When scanning a document fragment, there is no
1159:                 * "root" element. However, when scanning a full XML document,
1160:                 * the scanner must handle the root element specially.
1161:                 *
1162:                 * @return True if the caller should stop and return true which
1163:                 *          allows the scanner to switch to a new scanning
1164:                 *          dispatcher. A return value of false indicates that
1165:                 *          the content dispatcher should continue as normal.
1166:                 */
1167:                protected boolean scanRootElementHook() throws IOException,
1168:                        XNIException {
1169:
1170:                    if (fExternalSubsetResolver != null && !fSeenDoctypeDecl
1171:                            && !fDisallowDoctype
1172:                            && (fValidation || fLoadExternalDTD)) {
1173:                        scanStartElementName();
1174:                        resolveExternalSubsetAndRead();
1175:                        if (scanStartElementAfterName()) {
1176:                            setScannerState(SCANNER_STATE_TRAILING_MISC);
1177:                            setDispatcher(fTrailingMiscDispatcher);
1178:                            return true;
1179:                        }
1180:                    } else if (scanStartElement()) {
1181:                        setScannerState(SCANNER_STATE_TRAILING_MISC);
1182:                        setDispatcher(fTrailingMiscDispatcher);
1183:                        return true;
1184:                    }
1185:                    return false;
1186:
1187:                } // scanRootElementHook():boolean
1188:
1189:                /**
1190:                 * End of file hook. This method is a hook for subclasses to
1191:                 * add code that handles the end of file. The end of file in
1192:                 * a document fragment is OK if the markup depth is zero.
1193:                 * However, when scanning a full XML document, an end of file
1194:                 * is always premature.
1195:                 */
1196:                protected void endOfFileHook(EOFException e)
1197:                        throws IOException, XNIException {
1198:
1199:                    reportFatalError("PrematureEOF", null);
1200:                    // in case continue-after-fatal-error set, should not do this...
1201:                    //throw e;
1202:
1203:                } // endOfFileHook()
1204:
1205:                /**
1206:                 * <p>Attempt to locate an external subset for a document that does not otherwise
1207:                 * have one. If an external subset is located, then it is scanned.</p>
1208:                 */
1209:                protected void resolveExternalSubsetAndRead()
1210:                        throws IOException, XNIException {
1211:
1212:                    fDTDDescription.setValues(null, null, fEntityManager
1213:                            .getCurrentResourceIdentifier()
1214:                            .getExpandedSystemId(), null);
1215:                    fDTDDescription.setRootName(fElementQName.rawname);
1216:                    XMLInputSource src = fExternalSubsetResolver
1217:                            .getExternalSubset(fDTDDescription);
1218:
1219:                    if (src != null) {
1220:                        fDoctypeName = fElementQName.rawname;
1221:                        fDoctypePublicId = src.getPublicId();
1222:                        fDoctypeSystemId = src.getSystemId();
1223:                        // call document handler
1224:                        if (fDocumentHandler != null) {
1225:                            // This inserts a doctypeDecl event into the stream though no 
1226:                            // DOCTYPE existed in the instance document.
1227:                            fDocumentHandler.doctypeDecl(fDoctypeName,
1228:                                    fDoctypePublicId, fDoctypeSystemId, null);
1229:                        }
1230:                        try {
1231:                            if (fValidationManager == null
1232:                                    || !fValidationManager.isCachedDTD()) {
1233:                                fDTDScanner.setInputSource(src);
1234:                                while (fDTDScanner.scanDTDExternalSubset(true))
1235:                                    ;
1236:                            } else {
1237:                                // This sends startDTD and endDTD calls down the pipeline.
1238:                                fDTDScanner.setInputSource(null);
1239:                            }
1240:                        } finally {
1241:                            fEntityManager
1242:                                    .setEntityHandler(XMLDocumentScannerImpl.this );
1243:                        }
1244:                    }
1245:                } // resolveExternalSubsetAndRead()
1246:
1247:            } // class ContentDispatcher
1248:
1249:            /**
1250:             * Dispatcher to handle trailing miscellaneous section scanning.
1251:             *
1252:             * @author Andy Clark, IBM
1253:             * @author Eric Ye, IBM
1254:             */
1255:            protected final class TrailingMiscDispatcher implements  Dispatcher {
1256:
1257:                //
1258:                // Dispatcher methods
1259:                //
1260:
1261:                /**
1262:                 * Dispatch an XML "event".
1263:                 *
1264:                 * @param complete True if this dispatcher is intended to scan
1265:                 *                 and dispatch as much as possible.
1266:                 *
1267:                 * @return True if there is more to dispatch either from this
1268:                 *          or a another dispatcher.
1269:                 *
1270:                 * @throws IOException  Thrown on i/o error.
1271:                 * @throws XNIException Thrown on parse error.
1272:                 */
1273:                public boolean dispatch(boolean complete) throws IOException,
1274:                        XNIException {
1275:
1276:                    try {
1277:                        boolean again;
1278:                        do {
1279:                            again = false;
1280:                            switch (fScannerState) {
1281:                            case SCANNER_STATE_TRAILING_MISC: {
1282:                                fEntityScanner.skipSpaces();
1283:                                if (fEntityScanner.skipChar('<')) {
1284:                                    setScannerState(SCANNER_STATE_START_OF_MARKUP);
1285:                                    again = true;
1286:                                } else {
1287:                                    setScannerState(SCANNER_STATE_CONTENT);
1288:                                    again = true;
1289:                                }
1290:                                break;
1291:                            }
1292:                            case SCANNER_STATE_START_OF_MARKUP: {
1293:                                fMarkupDepth++;
1294:                                if (fEntityScanner.skipChar('?')) {
1295:                                    setScannerState(SCANNER_STATE_PI);
1296:                                    again = true;
1297:                                } else if (fEntityScanner.skipChar('!')) {
1298:                                    setScannerState(SCANNER_STATE_COMMENT);
1299:                                    again = true;
1300:                                } else if (fEntityScanner.skipChar('/')) {
1301:                                    reportFatalError(
1302:                                            "MarkupNotRecognizedInMisc", null);
1303:                                    again = true;
1304:                                } else if (isValidNameStartChar(fEntityScanner
1305:                                        .peekChar())) {
1306:                                    reportFatalError(
1307:                                            "MarkupNotRecognizedInMisc", null);
1308:                                    scanStartElement();
1309:                                    setScannerState(SCANNER_STATE_CONTENT);
1310:                                } else if (isValidNameStartHighSurrogate(fEntityScanner
1311:                                        .peekChar())) {
1312:                                    reportFatalError(
1313:                                            "MarkupNotRecognizedInMisc", null);
1314:                                    scanStartElement();
1315:                                    setScannerState(SCANNER_STATE_CONTENT);
1316:                                } else {
1317:                                    reportFatalError(
1318:                                            "MarkupNotRecognizedInMisc", null);
1319:                                }
1320:                                break;
1321:                            }
1322:                            case SCANNER_STATE_PI: {
1323:                                scanPI();
1324:                                setScannerState(SCANNER_STATE_TRAILING_MISC);
1325:                                break;
1326:                            }
1327:                            case SCANNER_STATE_COMMENT: {
1328:                                if (!fEntityScanner.skipString("--")) {
1329:                                    reportFatalError("InvalidCommentStart",
1330:                                            null);
1331:                                }
1332:                                scanComment();
1333:                                setScannerState(SCANNER_STATE_TRAILING_MISC);
1334:                                break;
1335:                            }
1336:                            case SCANNER_STATE_CONTENT: {
1337:                                int ch = fEntityScanner.peekChar();
1338:                                if (ch == -1) {
1339:                                    setScannerState(SCANNER_STATE_TERMINATED);
1340:                                    return false;
1341:                                }
1342:                                reportFatalError(
1343:                                        "ContentIllegalInTrailingMisc", null);
1344:                                fEntityScanner.scanChar();
1345:                                setScannerState(SCANNER_STATE_TRAILING_MISC);
1346:                                break;
1347:                            }
1348:                            case SCANNER_STATE_REFERENCE: {
1349:                                reportFatalError(
1350:                                        "ReferenceIllegalInTrailingMisc", null);
1351:                                setScannerState(SCANNER_STATE_TRAILING_MISC);
1352:                                break;
1353:                            }
1354:                            case SCANNER_STATE_TERMINATED: {
1355:                                return false;
1356:                            }
1357:                            }
1358:                        } while (complete || again);
1359:                    }
1360:                    // encoding errors
1361:                    catch (MalformedByteSequenceException e) {
1362:                        fErrorReporter.reportError(e.getDomain(), e.getKey(), e
1363:                                .getArguments(),
1364:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1365:                        return false;
1366:                    } catch (CharConversionException e) {
1367:                        fErrorReporter.reportError(
1368:                                XMLMessageFormatter.XML_DOMAIN,
1369:                                "CharConversionFailure", null,
1370:                                XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
1371:                        return false;
1372:                    } catch (EOFException e) {
1373:                        // NOTE: This is the only place we're allowed to reach
1374:                        //       the real end of the document stream. Unless the
1375:                        //       end of file was reached prematurely.
1376:                        if (fMarkupDepth != 0) {
1377:                            reportFatalError("PrematureEOF", null);
1378:                            return false;
1379:                            //throw e;
1380:                        }
1381:
1382:                        setScannerState(SCANNER_STATE_TERMINATED);
1383:                        return false;
1384:                    }
1385:
1386:                    return true;
1387:
1388:                } // dispatch(boolean):boolean
1389:
1390:            } // class TrailingMiscDispatcher
1391:
1392:        } // class XMLDocumentScannerImpl
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.