Source Code Cross Referenced for AbstractDOMParser.java in  » XML » xerces-2_9_1 » org » apache » xerces » parsers » 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.parsers 
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.parsers;
0019:
0020:        import java.util.Locale;
0021:        import java.util.Stack;
0022:
0023:        import org.apache.xerces.dom.AttrImpl;
0024:        import org.apache.xerces.dom.CoreDocumentImpl;
0025:        import org.apache.xerces.dom.DOMErrorImpl;
0026:        import org.apache.xerces.dom.DOMMessageFormatter;
0027:        import org.apache.xerces.dom.DeferredDocumentImpl;
0028:        import org.apache.xerces.dom.DocumentImpl;
0029:        import org.apache.xerces.dom.DocumentTypeImpl;
0030:        import org.apache.xerces.dom.ElementDefinitionImpl;
0031:        import org.apache.xerces.dom.ElementImpl;
0032:        import org.apache.xerces.dom.ElementNSImpl;
0033:        import org.apache.xerces.dom.EntityImpl;
0034:        import org.apache.xerces.dom.EntityReferenceImpl;
0035:        import org.apache.xerces.dom.NodeImpl;
0036:        import org.apache.xerces.dom.NotationImpl;
0037:        import org.apache.xerces.dom.PSVIAttrNSImpl;
0038:        import org.apache.xerces.dom.PSVIDocumentImpl;
0039:        import org.apache.xerces.dom.PSVIElementNSImpl;
0040:        import org.apache.xerces.dom.TextImpl;
0041:        import org.apache.xerces.impl.Constants;
0042:        import org.apache.xerces.impl.dv.XSSimpleType;
0043:        import org.apache.xerces.util.DOMErrorHandlerWrapper;
0044:        import org.apache.xerces.xni.Augmentations;
0045:        import org.apache.xerces.xni.NamespaceContext;
0046:        import org.apache.xerces.xni.QName;
0047:        import org.apache.xerces.xni.XMLAttributes;
0048:        import org.apache.xerces.xni.XMLLocator;
0049:        import org.apache.xerces.xni.XMLResourceIdentifier;
0050:        import org.apache.xerces.xni.XMLString;
0051:        import org.apache.xerces.xni.XNIException;
0052:        import org.apache.xerces.xni.parser.XMLParserConfiguration;
0053:        import org.apache.xerces.xs.AttributePSVI;
0054:        import org.apache.xerces.xs.ElementPSVI;
0055:        import org.apache.xerces.xs.XSTypeDefinition;
0056:        import org.w3c.dom.Attr;
0057:        import org.w3c.dom.CDATASection;
0058:        import org.w3c.dom.Comment;
0059:        import org.w3c.dom.Document;
0060:        import org.w3c.dom.DocumentType;
0061:        import org.w3c.dom.DOMError;
0062:        import org.w3c.dom.Element;
0063:        import org.w3c.dom.EntityReference;
0064:        import org.w3c.dom.NamedNodeMap;
0065:        import org.w3c.dom.Node;
0066:        import org.w3c.dom.NodeList;
0067:        import org.w3c.dom.ProcessingInstruction;
0068:        import org.w3c.dom.Text;
0069:        import org.w3c.dom.ls.LSParserFilter;
0070:        import org.w3c.dom.traversal.NodeFilter;
0071:        import org.xml.sax.SAXException;
0072:
0073:        /**
0074:         * This is the base class of all DOM parsers. It implements the XNI
0075:         * callback methods to create the DOM tree. After a successful parse of
0076:         * an XML document, the DOM Document object can be queried using the
0077:         * <code>getDocument</code> method. The actual pipeline is defined in
0078:         * parser configuration.
0079:         *
0080:         * @author Arnaud Le Hors, IBM
0081:         * @author Andy Clark, IBM
0082:         * @author Elena Litani, IBM
0083:         *
0084:         * @version $Id: AbstractDOMParser.java 568412 2007-08-22 04:40:44Z mrglavas $
0085:         */
0086:        public class AbstractDOMParser extends AbstractXMLDocumentParser {
0087:
0088:            //
0089:            // Constants
0090:            //
0091:
0092:            // feature ids
0093:
0094:            /** Feature id: namespace. */
0095:            protected static final String NAMESPACES = Constants.SAX_FEATURE_PREFIX
0096:                    + Constants.NAMESPACES_FEATURE;
0097:
0098:            /** Feature id: create entity ref nodes. */
0099:            protected static final String CREATE_ENTITY_REF_NODES = Constants.XERCES_FEATURE_PREFIX
0100:                    + Constants.CREATE_ENTITY_REF_NODES_FEATURE;
0101:
0102:            /** Feature id: include comments. */
0103:            protected static final String INCLUDE_COMMENTS_FEATURE = Constants.XERCES_FEATURE_PREFIX
0104:                    + Constants.INCLUDE_COMMENTS_FEATURE;
0105:
0106:            /** Feature id: create cdata nodes. */
0107:            protected static final String CREATE_CDATA_NODES_FEATURE = Constants.XERCES_FEATURE_PREFIX
0108:                    + Constants.CREATE_CDATA_NODES_FEATURE;
0109:
0110:            /** Feature id: include ignorable whitespace. */
0111:            protected static final String INCLUDE_IGNORABLE_WHITESPACE = Constants.XERCES_FEATURE_PREFIX
0112:                    + Constants.INCLUDE_IGNORABLE_WHITESPACE;
0113:
0114:            /** Feature id: defer node expansion. */
0115:            protected static final String DEFER_NODE_EXPANSION = Constants.XERCES_FEATURE_PREFIX
0116:                    + Constants.DEFER_NODE_EXPANSION_FEATURE;
0117:
0118:            /** Recognized features. */
0119:            private static final String[] RECOGNIZED_FEATURES = { NAMESPACES,
0120:                    CREATE_ENTITY_REF_NODES, INCLUDE_COMMENTS_FEATURE,
0121:                    CREATE_CDATA_NODES_FEATURE, INCLUDE_IGNORABLE_WHITESPACE,
0122:                    DEFER_NODE_EXPANSION };
0123:
0124:            // property ids
0125:
0126:            /** Property id: document class name. */
0127:            protected static final String DOCUMENT_CLASS_NAME = Constants.XERCES_PROPERTY_PREFIX
0128:                    + Constants.DOCUMENT_CLASS_NAME_PROPERTY;
0129:
0130:            protected static final String CURRENT_ELEMENT_NODE = Constants.XERCES_PROPERTY_PREFIX
0131:                    + Constants.CURRENT_ELEMENT_NODE_PROPERTY;
0132:
0133:            // protected static final String GRAMMAR_POOL =
0134:            // Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
0135:
0136:            /** Recognized properties. */
0137:            private static final String[] RECOGNIZED_PROPERTIES = {
0138:                    DOCUMENT_CLASS_NAME, CURRENT_ELEMENT_NODE, };
0139:
0140:            // other
0141:
0142:            /** Default document class name. */
0143:            protected static final String DEFAULT_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.DocumentImpl";
0144:
0145:            protected static final String CORE_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.CoreDocumentImpl";
0146:
0147:            protected static final String PSVI_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.PSVIDocumentImpl";
0148:
0149:            /**
0150:             * If the user stops the process, this exception will be thrown.
0151:             */
0152:            protected static final RuntimeException ABORT = new RuntimeException() {
0153:                private static final long serialVersionUID = 1687848994976808490L;
0154:
0155:                public Throwable fillInStackTrace() {
0156:                    return this ;
0157:                }
0158:            };
0159:
0160:            // debugging
0161:
0162:            private static final boolean DEBUG_EVENTS = false;
0163:            private static final boolean DEBUG_BASEURI = false;
0164:
0165:            //
0166:            // Data
0167:            //
0168:
0169:            /** DOM L3 error handler */
0170:            protected DOMErrorHandlerWrapper fErrorHandler = null;
0171:
0172:            /** True if inside DTD. */
0173:            protected boolean fInDTD;
0174:
0175:            // features
0176:
0177:            /** Create entity reference nodes. */
0178:            protected boolean fCreateEntityRefNodes;
0179:
0180:            /** Include ignorable whitespace. */
0181:            protected boolean fIncludeIgnorableWhitespace;
0182:
0183:            /** Include Comments. */
0184:            protected boolean fIncludeComments;
0185:
0186:            /** Create cdata nodes. */
0187:            protected boolean fCreateCDATANodes;
0188:
0189:            // dom information
0190:
0191:            /** The document. */
0192:            protected Document fDocument;
0193:
0194:            /** The default Xerces document implementation, if used. */
0195:            protected CoreDocumentImpl fDocumentImpl;
0196:
0197:            /** Whether to store PSVI information in DOM tree. */
0198:            protected boolean fStorePSVI;
0199:
0200:            /** The document class name to use. */
0201:            protected String fDocumentClassName;
0202:
0203:            /** The document type node. */
0204:            protected DocumentType fDocumentType;
0205:
0206:            /** Current node. */
0207:            protected Node fCurrentNode;
0208:            protected CDATASection fCurrentCDATASection;
0209:            protected EntityImpl fCurrentEntityDecl;
0210:            protected int fDeferredEntityDecl;
0211:
0212:            /** Character buffer */
0213:            protected final StringBuffer fStringBuffer = new StringBuffer(50);
0214:
0215:            // internal subset
0216:
0217:            /** Internal subset buffer. */
0218:            protected StringBuffer fInternalSubset;
0219:
0220:            // deferred expansion data
0221:
0222:            protected boolean fDeferNodeExpansion;
0223:            protected boolean fNamespaceAware;
0224:            protected DeferredDocumentImpl fDeferredDocumentImpl;
0225:            protected int fDocumentIndex;
0226:            protected int fDocumentTypeIndex;
0227:            protected int fCurrentNodeIndex;
0228:            protected int fCurrentCDATASectionIndex;
0229:
0230:            // state
0231:
0232:            /** True if inside DTD external subset. */
0233:            protected boolean fInDTDExternalSubset;
0234:
0235:            /** Root element name */
0236:            protected QName fRoot = new QName();
0237:
0238:            /** True if inside CDATA section. */
0239:            protected boolean fInCDATASection;
0240:
0241:            /** True if saw the first chunk of characters*/
0242:            protected boolean fFirstChunk = false;
0243:
0244:            /** LSParserFilter: specifies that element with given QNAME and all its children
0245:             * must be rejected */
0246:            protected boolean fFilterReject = false;
0247:
0248:            // data
0249:
0250:            /** Base uri stack*/
0251:            protected Stack fBaseURIStack = new Stack();
0252:
0253:            /** LSParserFilter: the QNAME of rejected element*/
0254:            protected final QName fRejectedElement = new QName();
0255:
0256:            /** LSParserFilter: store qnames of skipped elements*/
0257:            protected Stack fSkippedElemStack = null;
0258:
0259:            /** LSParserFilter: true if inside entity reference */
0260:            protected boolean fInEntityRef = false;
0261:
0262:            /** Attribute QName. */
0263:            private QName fAttrQName = new QName();
0264:
0265:            /** Document locator. */
0266:            private XMLLocator fLocator;
0267:
0268:            // handlers
0269:
0270:            protected LSParserFilter fDOMFilter = null;
0271:
0272:            //
0273:            // Constructors
0274:            //
0275:
0276:            /** Default constructor. */
0277:            protected AbstractDOMParser(XMLParserConfiguration config) {
0278:
0279:                super (config);
0280:
0281:                // add recognized features
0282:                fConfiguration.addRecognizedFeatures(RECOGNIZED_FEATURES);
0283:
0284:                // set default values
0285:                fConfiguration.setFeature(CREATE_ENTITY_REF_NODES, true);
0286:                fConfiguration.setFeature(INCLUDE_IGNORABLE_WHITESPACE, true);
0287:                fConfiguration.setFeature(DEFER_NODE_EXPANSION, true);
0288:                fConfiguration.setFeature(INCLUDE_COMMENTS_FEATURE, true);
0289:                fConfiguration.setFeature(CREATE_CDATA_NODES_FEATURE, true);
0290:
0291:                // add recognized properties
0292:                fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
0293:
0294:                // set default values
0295:                fConfiguration.setProperty(DOCUMENT_CLASS_NAME,
0296:                        DEFAULT_DOCUMENT_CLASS_NAME);
0297:
0298:            } // <init>(XMLParserConfiguration)
0299:
0300:            /**
0301:             * This method retreives the name of current document class.
0302:             */
0303:            protected String getDocumentClassName() {
0304:                return fDocumentClassName;
0305:            }
0306:
0307:            /**
0308:             * This method allows the programmer to decide which document
0309:             * factory to use when constructing the DOM tree. However, doing
0310:             * so will lose the functionality of the default factory. Also,
0311:             * a document class other than the default will lose the ability
0312:             * to defer node expansion on the DOM tree produced.
0313:             *
0314:             * @param documentClassName The fully qualified class name of the
0315:             *                      document factory to use when constructing
0316:             *                      the DOM tree.
0317:             *
0318:             * @see #getDocumentClassName
0319:             * @see #DEFAULT_DOCUMENT_CLASS_NAME
0320:             */
0321:            protected void setDocumentClassName(String documentClassName) {
0322:
0323:                // normalize class name
0324:                if (documentClassName == null) {
0325:                    documentClassName = DEFAULT_DOCUMENT_CLASS_NAME;
0326:                }
0327:
0328:                if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)
0329:                        && !documentClassName.equals(PSVI_DOCUMENT_CLASS_NAME)) {
0330:                    // verify that this class exists and is of the right type
0331:                    try {
0332:                        Class _class = ObjectFactory.findProviderClass(
0333:                                documentClassName, ObjectFactory
0334:                                        .findClassLoader(), true);
0335:                        //if (!_class.isAssignableFrom(Document.class)) {
0336:                        if (!Document.class.isAssignableFrom(_class)) {
0337:                            throw new IllegalArgumentException(
0338:                                    DOMMessageFormatter.formatMessage(
0339:                                            DOMMessageFormatter.DOM_DOMAIN,
0340:                                            "InvalidDocumentClassName",
0341:                                            new Object[] { documentClassName }));
0342:                        }
0343:                    } catch (ClassNotFoundException e) {
0344:                        throw new IllegalArgumentException(DOMMessageFormatter
0345:                                .formatMessage(DOMMessageFormatter.DOM_DOMAIN,
0346:                                        "MissingDocumentClassName",
0347:                                        new Object[] { documentClassName }));
0348:                    }
0349:                }
0350:
0351:                // set document class name
0352:                fDocumentClassName = documentClassName;
0353:                if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)) {
0354:                    fDeferNodeExpansion = false;
0355:                }
0356:
0357:            } // setDocumentClassName(String)
0358:
0359:            //
0360:            // Public methods
0361:            //
0362:
0363:            /** Returns the DOM document object. */
0364:            public Document getDocument() {
0365:                return fDocument;
0366:            } // getDocument():Document
0367:
0368:            /** 
0369:             * Drops all references to the last DOM which was built by this parser.
0370:             */
0371:            public final void dropDocumentReferences() {
0372:                fDocument = null;
0373:                fDocumentImpl = null;
0374:                fDeferredDocumentImpl = null;
0375:                fDocumentType = null;
0376:                fCurrentNode = null;
0377:                fCurrentCDATASection = null;
0378:                fCurrentEntityDecl = null;
0379:            } // dropDocumentReferences()
0380:
0381:            //
0382:            // XMLDocumentParser methods
0383:            //
0384:
0385:            /**
0386:             * Resets the parser state.
0387:             *
0388:             * @throws SAXException Thrown on initialization error.
0389:             */
0390:            public void reset() throws XNIException {
0391:                super .reset();
0392:
0393:                // get feature state
0394:                fCreateEntityRefNodes = fConfiguration
0395:                        .getFeature(CREATE_ENTITY_REF_NODES);
0396:
0397:                fIncludeIgnorableWhitespace = fConfiguration
0398:                        .getFeature(INCLUDE_IGNORABLE_WHITESPACE);
0399:
0400:                fDeferNodeExpansion = fConfiguration
0401:                        .getFeature(DEFER_NODE_EXPANSION);
0402:
0403:                fNamespaceAware = fConfiguration.getFeature(NAMESPACES);
0404:
0405:                fIncludeComments = fConfiguration
0406:                        .getFeature(INCLUDE_COMMENTS_FEATURE);
0407:
0408:                fCreateCDATANodes = fConfiguration
0409:                        .getFeature(CREATE_CDATA_NODES_FEATURE);
0410:
0411:                // get property
0412:                setDocumentClassName((String) fConfiguration
0413:                        .getProperty(DOCUMENT_CLASS_NAME));
0414:
0415:                // reset dom information
0416:                fDocument = null;
0417:                fDocumentImpl = null;
0418:                fStorePSVI = false;
0419:                fDocumentType = null;
0420:                fDocumentTypeIndex = -1;
0421:                fDeferredDocumentImpl = null;
0422:                fCurrentNode = null;
0423:
0424:                // reset string buffer
0425:                fStringBuffer.setLength(0);
0426:
0427:                // reset state information
0428:                fRoot.clear();
0429:                fInDTD = false;
0430:                fInDTDExternalSubset = false;
0431:                fInCDATASection = false;
0432:                fFirstChunk = false;
0433:                fCurrentCDATASection = null;
0434:                fCurrentCDATASectionIndex = -1;
0435:
0436:                fBaseURIStack.removeAllElements();
0437:
0438:            } // reset()
0439:
0440:            /**
0441:             * Set the locale to use for messages.
0442:             *
0443:             * @param locale The locale object to use for localization of messages.
0444:             *
0445:             */
0446:            public void setLocale(Locale locale) {
0447:                fConfiguration.setLocale(locale);
0448:
0449:            } // setLocale(Locale)
0450:
0451:            //
0452:            // XMLDocumentHandler methods
0453:            //
0454:
0455:            /**
0456:             * This method notifies the start of a general entity.
0457:             * <p>
0458:             * <strong>Note:</strong> This method is not called for entity references
0459:             * appearing as part of attribute values.
0460:             *
0461:             * @param name     The name of the general entity.
0462:             * @param identifier The resource identifier.
0463:             * @param encoding The auto-detected IANA encoding name of the entity
0464:             *                 stream. This value will be null in those situations
0465:             *                 where the entity encoding is not auto-detected (e.g.
0466:             *                 internal entities or a document entity that is
0467:             *                 parsed from a java.io.Reader).
0468:             * @param augs     Additional information that may include infoset augmentations
0469:             *
0470:             * @exception XNIException Thrown by handler to signal an error.
0471:             */
0472:            public void startGeneralEntity(String name,
0473:                    XMLResourceIdentifier identifier, String encoding,
0474:                    Augmentations augs) throws XNIException {
0475:                if (DEBUG_EVENTS) {
0476:                    System.out.println("==>startGeneralEntity (" + name + ")");
0477:                    if (DEBUG_BASEURI) {
0478:                        System.out.println("   expandedSystemId( **baseURI): "
0479:                                + identifier.getExpandedSystemId());
0480:                        System.out.println("   baseURI:"
0481:                                + identifier.getBaseSystemId());
0482:                    }
0483:                }
0484:
0485:                // Always create entity reference nodes to be able to recreate
0486:                // entity as a part of doctype
0487:                if (!fDeferNodeExpansion) {
0488:                    if (fFilterReject) {
0489:                        return;
0490:                    }
0491:                    setCharacterData(true);
0492:                    EntityReference er = fDocument.createEntityReference(name);
0493:                    if (fDocumentImpl != null) {
0494:                        // REVISIT: baseURI/actualEncoding
0495:                        //         remove dependency on our implementation when DOM L3 is REC
0496:                        //
0497:
0498:                        EntityReferenceImpl erImpl = (EntityReferenceImpl) er;
0499:
0500:                        // set base uri
0501:                        erImpl.setBaseURI(identifier.getExpandedSystemId());
0502:                        if (fDocumentType != null) {
0503:                            // set actual encoding
0504:                            NamedNodeMap entities = fDocumentType.getEntities();
0505:                            fCurrentEntityDecl = (EntityImpl) entities
0506:                                    .getNamedItem(name);
0507:                            if (fCurrentEntityDecl != null) {
0508:                                fCurrentEntityDecl.setInputEncoding(encoding);
0509:                            }
0510:
0511:                        }
0512:                        // we don't need synchronization now, because entity ref will be
0513:                        // expanded anyway. Synch only needed when user creates entityRef node
0514:                        erImpl.needsSyncChildren(false);
0515:                    }
0516:                    fInEntityRef = true;
0517:                    fCurrentNode.appendChild(er);
0518:                    fCurrentNode = er;
0519:                } else {
0520:
0521:                    int er = fDeferredDocumentImpl
0522:                            .createDeferredEntityReference(name, identifier
0523:                                    .getExpandedSystemId());
0524:                    if (fDocumentTypeIndex != -1) {
0525:                        // find corresponding Entity decl
0526:                        int node = fDeferredDocumentImpl.getLastChild(
0527:                                fDocumentTypeIndex, false);
0528:                        while (node != -1) {
0529:                            short nodeType = fDeferredDocumentImpl.getNodeType(
0530:                                    node, false);
0531:                            if (nodeType == Node.ENTITY_NODE) {
0532:                                String nodeName = fDeferredDocumentImpl
0533:                                        .getNodeName(node, false);
0534:                                if (nodeName.equals(name)) {
0535:                                    fDeferredEntityDecl = node;
0536:                                    fDeferredDocumentImpl.setInputEncoding(
0537:                                            node, encoding);
0538:                                    break;
0539:                                }
0540:                            }
0541:                            node = fDeferredDocumentImpl.getRealPrevSibling(
0542:                                    node, false);
0543:                        }
0544:                    }
0545:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, er);
0546:                    fCurrentNodeIndex = er;
0547:                }
0548:
0549:            } // startGeneralEntity(String,XMLResourceIdentifier, Augmentations)
0550:
0551:            /**
0552:             * Notifies of the presence of a TextDecl line in an entity. If present,
0553:             * this method will be called immediately following the startEntity call.
0554:             * <p>
0555:             * <strong>Note:</strong> This method will never be called for the
0556:             * document entity; it is only called for external general entities
0557:             * referenced in document content.
0558:             * <p>
0559:             * <strong>Note:</strong> This method is not called for entity references
0560:             * appearing as part of attribute values.
0561:             *
0562:             * @param version  The XML version, or null if not specified.
0563:             * @param encoding The IANA encoding name of the entity.
0564:             * @param augs       Additional information that may include infoset augmentations
0565:             *
0566:             * @throws XNIException Thrown by handler to signal an error.
0567:             */
0568:            public void textDecl(String version, String encoding,
0569:                    Augmentations augs) throws XNIException {
0570:                if (fInDTD) {
0571:                    return;
0572:                }
0573:                if (!fDeferNodeExpansion) {
0574:                    if (fCurrentEntityDecl != null && !fFilterReject) {
0575:                        fCurrentEntityDecl.setXmlEncoding(encoding);
0576:                        if (version != null)
0577:                            fCurrentEntityDecl.setXmlVersion(version);
0578:                    }
0579:                } else {
0580:                    if (fDeferredEntityDecl != -1) {
0581:                        fDeferredDocumentImpl.setEntityInfo(
0582:                                fDeferredEntityDecl, version, encoding);
0583:                    }
0584:                }
0585:            } // textDecl(String,String)
0586:
0587:            /**
0588:             * A comment.
0589:             *
0590:             * @param text The text in the comment.
0591:             * @param augs       Additional information that may include infoset augmentations
0592:             *
0593:             * @throws XNIException Thrown by application to signal an error.
0594:             */
0595:            public void comment(XMLString text, Augmentations augs)
0596:                    throws XNIException {
0597:                if (fInDTD) {
0598:                    if (fInternalSubset != null && !fInDTDExternalSubset) {
0599:                        fInternalSubset.append("<!--");
0600:                        if (text.length > 0) {
0601:                            fInternalSubset.append(text.ch, text.offset,
0602:                                    text.length);
0603:                        }
0604:                        fInternalSubset.append("-->");
0605:                    }
0606:                    return;
0607:                }
0608:                if (!fIncludeComments || fFilterReject) {
0609:                    return;
0610:                }
0611:                if (!fDeferNodeExpansion) {
0612:                    Comment comment = fDocument.createComment(text.toString());
0613:
0614:                    setCharacterData(false);
0615:                    fCurrentNode.appendChild(comment);
0616:                    if (fDOMFilter != null
0617:                            && !fInEntityRef
0618:                            && (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_COMMENT) != 0) {
0619:                        short code = fDOMFilter.acceptNode(comment);
0620:                        switch (code) {
0621:                        case LSParserFilter.FILTER_INTERRUPT: {
0622:                            throw ABORT;
0623:                        }
0624:                        case LSParserFilter.FILTER_REJECT: {
0625:                            // REVISIT: the constant FILTER_REJECT should be changed when new
0626:                            // DOM LS specs gets published
0627:
0628:                            // fall through to SKIP since comment has no children.
0629:                        }
0630:                        case LSParserFilter.FILTER_SKIP: {
0631:                            // REVISIT: the constant FILTER_SKIP should be changed when new
0632:                            // DOM LS specs gets published
0633:                            fCurrentNode.removeChild(comment);
0634:                            // make sure we don't loose chars if next event is characters()
0635:                            fFirstChunk = true;
0636:                            return;
0637:                        }
0638:
0639:                        default: {
0640:                            // accept node
0641:                        }
0642:                        }
0643:                    }
0644:
0645:                } else {
0646:                    int comment = fDeferredDocumentImpl
0647:                            .createDeferredComment(text.toString());
0648:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
0649:                            comment);
0650:                }
0651:
0652:            } // comment(XMLString)
0653:
0654:            /**
0655:             * A processing instruction. Processing instructions consist of a
0656:             * target name and, optionally, text data. The data is only meaningful
0657:             * to the application.
0658:             * <p>
0659:             * Typically, a processing instruction's data will contain a series
0660:             * of pseudo-attributes. These pseudo-attributes follow the form of
0661:             * element attributes but are <strong>not</strong> parsed or presented
0662:             * to the application as anything other than text. The application is
0663:             * responsible for parsing the data.
0664:             *
0665:             * @param target The target.
0666:             * @param data   The data or null if none specified.
0667:             * @param augs       Additional information that may include infoset augmentations
0668:             *
0669:             * @throws XNIException Thrown by handler to signal an error.
0670:             */
0671:            public void processingInstruction(String target, XMLString data,
0672:                    Augmentations augs) throws XNIException {
0673:
0674:                if (fInDTD) {
0675:                    if (fInternalSubset != null && !fInDTDExternalSubset) {
0676:                        fInternalSubset.append("<?");
0677:                        fInternalSubset.append(target);
0678:                        if (data.length > 0) {
0679:                            fInternalSubset.append(' ').append(data.ch,
0680:                                    data.offset, data.length);
0681:                        }
0682:                        fInternalSubset.append("?>");
0683:                    }
0684:                    return;
0685:                }
0686:
0687:                if (DEBUG_EVENTS) {
0688:                    System.out.println("==>processingInstruction (" + target
0689:                            + ")");
0690:                }
0691:                if (!fDeferNodeExpansion) {
0692:                    if (fFilterReject) {
0693:                        return;
0694:                    }
0695:                    ProcessingInstruction pi = fDocument
0696:                            .createProcessingInstruction(target, data
0697:                                    .toString());
0698:
0699:                    setCharacterData(false);
0700:                    fCurrentNode.appendChild(pi);
0701:                    if (fDOMFilter != null
0702:                            && !fInEntityRef
0703:                            && (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_PROCESSING_INSTRUCTION) != 0) {
0704:                        short code = fDOMFilter.acceptNode(pi);
0705:                        switch (code) {
0706:                        case LSParserFilter.FILTER_INTERRUPT: {
0707:                            throw ABORT;
0708:                        }
0709:                        case LSParserFilter.FILTER_REJECT: {
0710:                            // fall through to SKIP since PI has no children.
0711:                        }
0712:                        case LSParserFilter.FILTER_SKIP: {
0713:                            fCurrentNode.removeChild(pi);
0714:                            // fFirstChunk must be set to true so that data
0715:                            // won't be lost in the case where the child before PI is
0716:                            // a text node and the next event is characters.
0717:                            fFirstChunk = true;
0718:                            return;
0719:                        }
0720:                        default: {
0721:                        }
0722:                        }
0723:                    }
0724:                } else {
0725:                    int pi = fDeferredDocumentImpl
0726:                            .createDeferredProcessingInstruction(target, data
0727:                                    .toString());
0728:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, pi);
0729:                }
0730:
0731:            } // processingInstruction(String,XMLString)
0732:
0733:            /**
0734:             * The start of the document.
0735:             *
0736:             * @param locator The system identifier of the entity if the entity
0737:             *                 is external, null otherwise.
0738:             * @param encoding The auto-detected IANA encoding name of the entity
0739:             *                 stream. This value will be null in those situations
0740:             *                 where the entity encoding is not auto-detected (e.g.
0741:             *                 internal entities or a document entity that is
0742:             *                 parsed from a java.io.Reader).
0743:             * @param namespaceContext
0744:             *                 The namespace context in effect at the
0745:             *                 start of this document.
0746:             *                 This object represents the current context.
0747:             *                 Implementors of this class are responsible
0748:             *                 for copying the namespace bindings from the
0749:             *                 the current context (and its parent contexts)
0750:             *                 if that information is important.
0751:             * @param augs     Additional information that may include infoset augmentations
0752:             *
0753:             * @throws XNIException Thrown by handler to signal an error.
0754:             */
0755:            public void startDocument(XMLLocator locator, String encoding,
0756:                    NamespaceContext namespaceContext, Augmentations augs)
0757:                    throws XNIException {
0758:
0759:                fLocator = locator;
0760:                if (!fDeferNodeExpansion) {
0761:                    if (fDocumentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)) {
0762:                        fDocument = new DocumentImpl();
0763:                        fDocumentImpl = (CoreDocumentImpl) fDocument;
0764:                        // REVISIT: when DOM Level 3 is REC rely on Document.support
0765:                        //          instead of specific class
0766:                        // set DOM error checking off
0767:                        fDocumentImpl.setStrictErrorChecking(false);
0768:                        // set actual encoding
0769:                        fDocumentImpl.setInputEncoding(encoding);
0770:                        // set documentURI
0771:                        fDocumentImpl.setDocumentURI(locator
0772:                                .getExpandedSystemId());
0773:                    } else if (fDocumentClassName
0774:                            .equals(PSVI_DOCUMENT_CLASS_NAME)) {
0775:                        fDocument = new PSVIDocumentImpl();
0776:                        fDocumentImpl = (CoreDocumentImpl) fDocument;
0777:                        fStorePSVI = true;
0778:                        // REVISIT: when DOM Level 3 is REC rely on Document.support
0779:                        //          instead of specific class
0780:                        // set DOM error checking off
0781:                        fDocumentImpl.setStrictErrorChecking(false);
0782:                        // set actual encoding
0783:                        fDocumentImpl.setInputEncoding(encoding);
0784:                        // set documentURI
0785:                        fDocumentImpl.setDocumentURI(locator
0786:                                .getExpandedSystemId());
0787:                    } else {
0788:                        // use specified document class
0789:                        try {
0790:                            ClassLoader cl = ObjectFactory.findClassLoader();
0791:                            Class documentClass = ObjectFactory
0792:                                    .findProviderClass(fDocumentClassName, cl,
0793:                                            true);
0794:                            fDocument = (Document) documentClass.newInstance();
0795:
0796:                            // if subclass of our own class that's cool too
0797:                            Class defaultDocClass = ObjectFactory
0798:                                    .findProviderClass(
0799:                                            CORE_DOCUMENT_CLASS_NAME, cl, true);
0800:                            if (defaultDocClass.isAssignableFrom(documentClass)) {
0801:                                fDocumentImpl = (CoreDocumentImpl) fDocument;
0802:
0803:                                Class psviDocClass = ObjectFactory
0804:                                        .findProviderClass(
0805:                                                PSVI_DOCUMENT_CLASS_NAME, cl,
0806:                                                true);
0807:                                if (psviDocClass
0808:                                        .isAssignableFrom(documentClass)) {
0809:                                    fStorePSVI = true;
0810:                                }
0811:
0812:                                // REVISIT: when DOM Level 3 is REC rely on
0813:                                //          Document.support instead of specific class
0814:                                // set DOM error checking off
0815:                                fDocumentImpl.setStrictErrorChecking(false);
0816:                                // set actual encoding
0817:                                fDocumentImpl.setInputEncoding(encoding);
0818:                                // set documentURI
0819:                                if (locator != null) {
0820:                                    fDocumentImpl.setDocumentURI(locator
0821:                                            .getExpandedSystemId());
0822:                                }
0823:                            }
0824:                        } catch (ClassNotFoundException e) {
0825:                            // won't happen we already checked that earlier
0826:                        } catch (Exception e) {
0827:                            throw new RuntimeException(
0828:                                    DOMMessageFormatter
0829:                                            .formatMessage(
0830:                                                    DOMMessageFormatter.DOM_DOMAIN,
0831:                                                    "CannotCreateDocumentClass",
0832:                                                    new Object[] { fDocumentClassName }));
0833:                        }
0834:                    }
0835:                    fCurrentNode = fDocument;
0836:                } else {
0837:                    fDeferredDocumentImpl = new DeferredDocumentImpl(
0838:                            fNamespaceAware);
0839:                    fDocument = fDeferredDocumentImpl;
0840:                    fDocumentIndex = fDeferredDocumentImpl
0841:                            .createDeferredDocument();
0842:                    // REVISIT: strict error checking is not implemented in deferred dom.
0843:                    //          Document.support instead of specific class
0844:
0845:                    // set actual encoding
0846:                    fDeferredDocumentImpl.setInputEncoding(encoding);
0847:                    // set documentURI
0848:                    fDeferredDocumentImpl.setDocumentURI(locator
0849:                            .getExpandedSystemId());
0850:                    fCurrentNodeIndex = fDocumentIndex;
0851:
0852:                }
0853:
0854:            } // startDocument(String,String)
0855:
0856:            /**
0857:             * Notifies of the presence of an XMLDecl line in the document. If
0858:             * present, this method will be called immediately following the
0859:             * startDocument call.
0860:             *
0861:             * @param version    The XML version.
0862:             * @param encoding   The IANA encoding name of the document, or null if
0863:             *                   not specified.
0864:             * @param standalone The standalone value, or null if not specified.
0865:             * @param augs       Additional information that may include infoset augmentations
0866:             *
0867:             * @throws XNIException Thrown by handler to signal an error.
0868:             */
0869:            public void xmlDecl(String version, String encoding,
0870:                    String standalone, Augmentations augs) throws XNIException {
0871:                if (!fDeferNodeExpansion) {
0872:                    // REVISIT: when DOM Level 3 is REC rely on Document.support
0873:                    //          instead of specific class
0874:                    if (fDocumentImpl != null) {
0875:                        if (version != null)
0876:                            fDocumentImpl.setXmlVersion(version);
0877:                        fDocumentImpl.setXmlEncoding(encoding);
0878:                        fDocumentImpl
0879:                                .setXmlStandalone("yes".equals(standalone));
0880:                    }
0881:                } else {
0882:                    if (version != null)
0883:                        fDeferredDocumentImpl.setXmlVersion(version);
0884:                    fDeferredDocumentImpl.setXmlEncoding(encoding);
0885:                    fDeferredDocumentImpl.setXmlStandalone("yes"
0886:                            .equals(standalone));
0887:                }
0888:            } // xmlDecl(String,String,String)
0889:
0890:            /**
0891:             * Notifies of the presence of the DOCTYPE line in the document.
0892:             *
0893:             * @param rootElement The name of the root element.
0894:             * @param publicId    The public identifier if an external DTD or null
0895:             *                    if the external DTD is specified using SYSTEM.
0896:             * @param systemId    The system identifier if an external DTD, null
0897:             *                    otherwise.
0898:             * @param augs     Additional information that may include infoset augmentations
0899:             *
0900:             * @throws XNIException Thrown by handler to signal an error.
0901:             */
0902:            public void doctypeDecl(String rootElement, String publicId,
0903:                    String systemId, Augmentations augs) throws XNIException {
0904:
0905:                if (!fDeferNodeExpansion) {
0906:                    if (fDocumentImpl != null) {
0907:                        fDocumentType = fDocumentImpl.createDocumentType(
0908:                                rootElement, publicId, systemId);
0909:                        fCurrentNode.appendChild(fDocumentType);
0910:                    }
0911:                } else {
0912:                    fDocumentTypeIndex = fDeferredDocumentImpl
0913:                            .createDeferredDocumentType(rootElement, publicId,
0914:                                    systemId);
0915:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
0916:                            fDocumentTypeIndex);
0917:                }
0918:
0919:            } // doctypeDecl(String,String,String)
0920:
0921:            /**
0922:             * The start of an element. If the document specifies the start element
0923:             * by using an empty tag, then the startElement method will immediately
0924:             * be followed by the endElement method, with no intervening methods.
0925:             *
0926:             * @param element    The name of the element.
0927:             * @param attributes The element attributes.
0928:             * @param augs     Additional information that may include infoset augmentations
0929:             *
0930:             * @throws XNIException Thrown by handler to signal an error.
0931:             */
0932:            public void startElement(QName element, XMLAttributes attributes,
0933:                    Augmentations augs) throws XNIException {
0934:                if (DEBUG_EVENTS) {
0935:                    System.out.println("==>startElement (" + element.rawname
0936:                            + ")");
0937:                }
0938:                if (!fDeferNodeExpansion) {
0939:                    if (fFilterReject) {
0940:                        return;
0941:                    }
0942:                    Element el = createElementNode(element);
0943:                    int attrCount = attributes.getLength();
0944:                    boolean seenSchemaDefault = false;
0945:                    for (int i = 0; i < attrCount; i++) {
0946:                        attributes.getName(i, fAttrQName);
0947:                        Attr attr = createAttrNode(fAttrQName);
0948:
0949:                        String attrValue = attributes.getValue(i);
0950:
0951:                        AttributePSVI attrPSVI = (AttributePSVI) attributes
0952:                                .getAugmentations(i).getItem(
0953:                                        Constants.ATTRIBUTE_PSVI);
0954:                        if (fStorePSVI && attrPSVI != null) {
0955:                            ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
0956:                        }
0957:
0958:                        attr.setValue(attrValue);
0959:                        boolean specified = attributes.isSpecified(i);
0960:                        // Take special care of schema defaulted attributes. Calling the 
0961:                        // non-namespace aware setAttributeNode() method could overwrite
0962:                        // another attribute with the same local name.
0963:                        if (!specified
0964:                                && (seenSchemaDefault || (fAttrQName.uri != null && fAttrQName.prefix == null))) {
0965:                            el.setAttributeNodeNS(attr);
0966:                            seenSchemaDefault = true;
0967:                        } else {
0968:                            el.setAttributeNode(attr);
0969:                        }
0970:                        // NOTE: The specified value MUST be set after you set
0971:                        //       the node value because that turns the "specified"
0972:                        //       flag to "true" which may overwrite a "false"
0973:                        //       value from the attribute list. -Ac
0974:                        if (fDocumentImpl != null) {
0975:                            AttrImpl attrImpl = (AttrImpl) attr;
0976:                            Object type = null;
0977:                            boolean id = false;
0978:
0979:                            // REVISIT: currently it is possible that someone turns off
0980:                            // namespaces and turns on xml schema validation
0981:                            // To avoid classcast exception in AttrImpl check for namespaces
0982:                            // however the correct solution should probably disallow setting
0983:                            // namespaces to false when schema processing is turned on.
0984:                            if (attrPSVI != null && fNamespaceAware) {
0985:                                // XML Schema
0986:                                type = attrPSVI.getMemberTypeDefinition();
0987:                                if (type == null) {
0988:                                    type = attrPSVI.getTypeDefinition();
0989:                                    if (type != null) {
0990:                                        id = ((XSSimpleType) type).isIDType();
0991:                                        attrImpl.setType(type);
0992:                                    }
0993:                                } else {
0994:                                    id = ((XSSimpleType) type).isIDType();
0995:                                    attrImpl.setType(type);
0996:                                }
0997:                            } else {
0998:                                // DTD
0999:                                boolean isDeclared = Boolean.TRUE
1000:                                        .equals(attributes
1001:                                                .getAugmentations(i)
1002:                                                .getItem(
1003:                                                        Constants.ATTRIBUTE_DECLARED));
1004:                                // For DOM Level 3 TypeInfo, the type name must
1005:                                // be null if this attribute has not been declared
1006:                                // in the DTD.
1007:                                if (isDeclared) {
1008:                                    type = attributes.getType(i);
1009:                                    id = "ID".equals(type);
1010:                                }
1011:                                attrImpl.setType(type);
1012:                            }
1013:
1014:                            if (id) {
1015:                                ((ElementImpl) el).setIdAttributeNode(attr,
1016:                                        true);
1017:                            }
1018:
1019:                            attrImpl.setSpecified(specified);
1020:                            // REVISIT: Handle entities in attribute value.
1021:                        }
1022:                    }
1023:                    setCharacterData(false);
1024:
1025:                    if (augs != null) {
1026:                        ElementPSVI elementPSVI = (ElementPSVI) augs
1027:                                .getItem(Constants.ELEMENT_PSVI);
1028:                        if (elementPSVI != null && fNamespaceAware) {
1029:                            XSTypeDefinition type = elementPSVI
1030:                                    .getMemberTypeDefinition();
1031:                            if (type == null) {
1032:                                type = elementPSVI.getTypeDefinition();
1033:                            }
1034:                            ((ElementNSImpl) el).setType(type);
1035:                        }
1036:                    }
1037:
1038:                    // filter nodes
1039:                    if (fDOMFilter != null && !fInEntityRef) {
1040:                        if (fRoot.rawname == null) {
1041:                            // fill value of the root element
1042:                            fRoot.setValues(element);
1043:                        } else {
1044:                            short code = fDOMFilter.startElement(el);
1045:                            switch (code) {
1046:                            case LSParserFilter.FILTER_INTERRUPT: {
1047:                                throw ABORT;
1048:                            }
1049:                            case LSParserFilter.FILTER_REJECT: {
1050:                                fFilterReject = true;
1051:                                fRejectedElement.setValues(element);
1052:                                return;
1053:                            }
1054:                            case LSParserFilter.FILTER_SKIP: {
1055:                                fSkippedElemStack.push(element.clone());
1056:                                return;
1057:                            }
1058:                            default: {
1059:                            }
1060:                            }
1061:                        }
1062:                    }
1063:                    fCurrentNode.appendChild(el);
1064:                    fCurrentNode = el;
1065:                } else {
1066:                    int el = fDeferredDocumentImpl.createDeferredElement(
1067:                            fNamespaceAware ? element.uri : null,
1068:                            element.rawname);
1069:                    Object type = null;
1070:                    int attrCount = attributes.getLength();
1071:                    // Need to loop in reverse order so that the attributes
1072:                    // are processed in document order when the DOM is expanded.
1073:                    for (int i = attrCount - 1; i >= 0; --i) {
1074:
1075:                        // set type information
1076:                        AttributePSVI attrPSVI = (AttributePSVI) attributes
1077:                                .getAugmentations(i).getItem(
1078:                                        Constants.ATTRIBUTE_PSVI);
1079:                        boolean id = false;
1080:
1081:                        // REVISIT: currently it is possible that someone turns off
1082:                        // namespaces and turns on xml schema validation
1083:                        // To avoid classcast exception in AttrImpl check for namespaces
1084:                        // however the correct solution should probably disallow setting
1085:                        // namespaces to false when schema processing is turned on.
1086:                        if (attrPSVI != null && fNamespaceAware) {
1087:                            // XML Schema
1088:                            type = attrPSVI.getMemberTypeDefinition();
1089:                            if (type == null) {
1090:                                type = attrPSVI.getTypeDefinition();
1091:                                if (type != null) {
1092:                                    id = ((XSSimpleType) type).isIDType();
1093:                                }
1094:                            } else {
1095:                                id = ((XSSimpleType) type).isIDType();
1096:                            }
1097:                        } else {
1098:                            // DTD
1099:                            boolean isDeclared = Boolean.TRUE.equals(attributes
1100:                                    .getAugmentations(i).getItem(
1101:                                            Constants.ATTRIBUTE_DECLARED));
1102:                            // For DOM Level 3 TypeInfo, the type name must
1103:                            // be null if this attribute has not been declared
1104:                            // in the DTD.
1105:                            if (isDeclared) {
1106:                                type = attributes.getType(i);
1107:                                id = "ID".equals(type);
1108:                            }
1109:                        }
1110:
1111:                        // create attribute
1112:                        fDeferredDocumentImpl.setDeferredAttribute(el,
1113:                                attributes.getQName(i), attributes.getURI(i),
1114:                                attributes.getValue(i), attributes
1115:                                        .isSpecified(i), id, type);
1116:                    }
1117:
1118:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, el);
1119:                    fCurrentNodeIndex = el;
1120:                }
1121:            } // startElement(QName,XMLAttributes)
1122:
1123:            /**
1124:             * An empty element.
1125:             *
1126:             * @param element    The name of the element.
1127:             * @param attributes The element attributes.
1128:             * @param augs   Additional information that may include infoset augmentations
1129:             *
1130:             * @throws XNIException Thrown by handler to signal an error.
1131:             */
1132:            public void emptyElement(QName element, XMLAttributes attributes,
1133:                    Augmentations augs) throws XNIException {
1134:
1135:                startElement(element, attributes, augs);
1136:                endElement(element, augs);
1137:
1138:            } // emptyElement(QName,XMLAttributes)
1139:
1140:            /**
1141:             * Character content.
1142:             *
1143:             * @param text The content.
1144:             * @param augs     Additional information that may include infoset augmentations
1145:             *
1146:             * @throws XNIException Thrown by handler to signal an error.
1147:             */
1148:            public void characters(XMLString text, Augmentations augs)
1149:                    throws XNIException {
1150:
1151:                if (DEBUG_EVENTS) {
1152:                    System.out.println("==>characters(): " + text.toString());
1153:                }
1154:
1155:                if (!fDeferNodeExpansion) {
1156:
1157:                    if (fFilterReject) {
1158:                        return;
1159:                    }
1160:                    if (fInCDATASection && fCreateCDATANodes) {
1161:                        if (fCurrentCDATASection == null) {
1162:                            fCurrentCDATASection = fDocument
1163:                                    .createCDATASection(text.toString());
1164:                            fCurrentNode.appendChild(fCurrentCDATASection);
1165:                            fCurrentNode = fCurrentCDATASection;
1166:                        } else {
1167:                            fCurrentCDATASection.appendData(text.toString());
1168:                        }
1169:                    } else if (!fInDTD) {
1170:                        // if type is union (XML Schema) it is possible that we receive
1171:                        // character call with empty data
1172:                        if (text.length == 0) {
1173:                            return;
1174:                        }
1175:
1176:                        Node child = fCurrentNode.getLastChild();
1177:                        if (child != null
1178:                                && child.getNodeType() == Node.TEXT_NODE) {
1179:                            // collect all the data into the string buffer.
1180:                            if (fFirstChunk) {
1181:                                if (fDocumentImpl != null) {
1182:                                    fStringBuffer.append(((TextImpl) child)
1183:                                            .removeData());
1184:                                } else {
1185:                                    fStringBuffer.append(((Text) child)
1186:                                            .getData());
1187:                                    ((Text) child).setNodeValue(null);
1188:                                }
1189:                                fFirstChunk = false;
1190:                            }
1191:                            if (text.length > 0) {
1192:                                fStringBuffer.append(text.ch, text.offset,
1193:                                        text.length);
1194:                            }
1195:                        } else {
1196:                            fFirstChunk = true;
1197:                            Text textNode = fDocument.createTextNode(text
1198:                                    .toString());
1199:                            fCurrentNode.appendChild(textNode);
1200:                        }
1201:
1202:                    }
1203:                } else {
1204:                    // The Text and CDATASection normalization is taken care of within
1205:                    // the DOM in the deferred case.
1206:                    if (fInCDATASection && fCreateCDATANodes) {
1207:                        if (fCurrentCDATASectionIndex == -1) {
1208:                            int cs = fDeferredDocumentImpl
1209:                                    .createDeferredCDATASection(text.toString());
1210:
1211:                            fDeferredDocumentImpl.appendChild(
1212:                                    fCurrentNodeIndex, cs);
1213:                            fCurrentCDATASectionIndex = cs;
1214:                            fCurrentNodeIndex = cs;
1215:                        } else {
1216:                            int txt = fDeferredDocumentImpl
1217:                                    .createDeferredTextNode(text.toString(),
1218:                                            false);
1219:                            fDeferredDocumentImpl.appendChild(
1220:                                    fCurrentNodeIndex, txt);
1221:                        }
1222:                    } else if (!fInDTD) {
1223:                        // if type is union (XML Schema) it is possible that we receive
1224:                        // character call with empty data
1225:                        if (text.length == 0) {
1226:                            return;
1227:                        }
1228:
1229:                        String value = text.toString();
1230:                        int txt = fDeferredDocumentImpl.createDeferredTextNode(
1231:                                value, false);
1232:                        fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
1233:                                txt);
1234:
1235:                    }
1236:                }
1237:            } // characters(XMLString)
1238:
1239:            /**
1240:             * Ignorable whitespace. For this method to be called, the document
1241:             * source must have some way of determining that the text containing
1242:             * only whitespace characters should be considered ignorable. For
1243:             * example, the validator can determine if a length of whitespace
1244:             * characters in the document are ignorable based on the element
1245:             * content model.
1246:             *
1247:             * @param text The ignorable whitespace.
1248:             * @param augs     Additional information that may include infoset augmentations
1249:             *
1250:             * @throws XNIException Thrown by handler to signal an error.
1251:             */
1252:            public void ignorableWhitespace(XMLString text, Augmentations augs)
1253:                    throws XNIException {
1254:
1255:                if (!fIncludeIgnorableWhitespace || fFilterReject) {
1256:                    return;
1257:                }
1258:                if (!fDeferNodeExpansion) {
1259:                    Node child = fCurrentNode.getLastChild();
1260:                    if (child != null && child.getNodeType() == Node.TEXT_NODE) {
1261:                        Text textNode = (Text) child;
1262:                        textNode.appendData(text.toString());
1263:                    } else {
1264:                        Text textNode = fDocument.createTextNode(text
1265:                                .toString());
1266:                        if (fDocumentImpl != null) {
1267:                            TextImpl textNodeImpl = (TextImpl) textNode;
1268:                            textNodeImpl.setIgnorableWhitespace(true);
1269:                        }
1270:                        fCurrentNode.appendChild(textNode);
1271:                    }
1272:                } else {
1273:                    // The Text normalization is taken care of within the DOM in the
1274:                    // deferred case.
1275:                    int txt = fDeferredDocumentImpl.createDeferredTextNode(text
1276:                            .toString(), true);
1277:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, txt);
1278:                }
1279:
1280:            } // ignorableWhitespace(XMLString)
1281:
1282:            /**
1283:             * The end of an element.
1284:             *
1285:             * @param element The name of the element.
1286:             * @param augs     Additional information that may include infoset augmentations
1287:             *
1288:             * @throws XNIException Thrown by handler to signal an error.
1289:             */
1290:            public void endElement(QName element, Augmentations augs)
1291:                    throws XNIException {
1292:                if (DEBUG_EVENTS) {
1293:                    System.out.println("==>endElement (" + element.rawname
1294:                            + ")");
1295:                }
1296:                if (!fDeferNodeExpansion) {
1297:
1298:                    // REVISIT: Should this happen after we call the filter?
1299:                    if (augs != null && fDocumentImpl != null
1300:                            && (fNamespaceAware || fStorePSVI)) {
1301:                        ElementPSVI elementPSVI = (ElementPSVI) augs
1302:                                .getItem(Constants.ELEMENT_PSVI);
1303:                        if (elementPSVI != null) {
1304:                            // Updating TypeInfo. If the declared type is a union the
1305:                            // [member type definition] will only be available at the
1306:                            // end of an element.
1307:                            if (fNamespaceAware) {
1308:                                XSTypeDefinition type = elementPSVI
1309:                                        .getMemberTypeDefinition();
1310:                                if (type == null) {
1311:                                    type = elementPSVI.getTypeDefinition();
1312:                                }
1313:                                ((ElementNSImpl) fCurrentNode).setType(type);
1314:                            }
1315:                            if (fStorePSVI) {
1316:                                ((PSVIElementNSImpl) fCurrentNode)
1317:                                        .setPSVI(elementPSVI);
1318:                            }
1319:                        }
1320:                    }
1321:
1322:                    if (fDOMFilter != null) {
1323:                        if (fFilterReject) {
1324:                            if (element.equals(fRejectedElement)) {
1325:                                fFilterReject = false;
1326:                            }
1327:                            return;
1328:                        }
1329:                        if (!fSkippedElemStack.isEmpty()) {
1330:                            if (fSkippedElemStack.peek().equals(element)) {
1331:                                fSkippedElemStack.pop();
1332:                                return;
1333:                            }
1334:                        }
1335:                        setCharacterData(false);
1336:                        if (!fRoot.equals(element)
1337:                                && !fInEntityRef
1338:                                && (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_ELEMENT) != 0) {
1339:                            short code = fDOMFilter.acceptNode(fCurrentNode);
1340:                            switch (code) {
1341:                            case LSParserFilter.FILTER_INTERRUPT: {
1342:                                throw ABORT;
1343:                            }
1344:                            case LSParserFilter.FILTER_REJECT: {
1345:                                Node parent = fCurrentNode.getParentNode();
1346:                                parent.removeChild(fCurrentNode);
1347:                                fCurrentNode = parent;
1348:                                return;
1349:                            }
1350:                            case LSParserFilter.FILTER_SKIP: {
1351:                                // make sure that if any char data is available
1352:                                // the fFirstChunk is true, so that if the next event
1353:                                // is characters(), and the last node is text, we will copy
1354:                                // the value already in the text node to fStringBuffer
1355:                                // (not to loose it).
1356:                                fFirstChunk = true;
1357:
1358:                                // replace children
1359:                                Node parent = fCurrentNode.getParentNode();
1360:                                NodeList ls = fCurrentNode.getChildNodes();
1361:                                int length = ls.getLength();
1362:
1363:                                for (int i = 0; i < length; i++) {
1364:                                    parent.appendChild(ls.item(0));
1365:                                }
1366:                                parent.removeChild(fCurrentNode);
1367:                                fCurrentNode = parent;
1368:
1369:                                return;
1370:                            }
1371:
1372:                            default: {
1373:                            }
1374:                            }
1375:                        }
1376:                        fCurrentNode = fCurrentNode.getParentNode();
1377:
1378:                    } // end-if DOMFilter
1379:                    else {
1380:                        setCharacterData(false);
1381:                        fCurrentNode = fCurrentNode.getParentNode();
1382:                    }
1383:
1384:                } else {
1385:                    if (augs != null) {
1386:                        ElementPSVI elementPSVI = (ElementPSVI) augs
1387:                                .getItem(Constants.ELEMENT_PSVI);
1388:                        if (elementPSVI != null) {
1389:                            // Setting TypeInfo. If the declared type is a union the
1390:                            // [member type definition] will only be available at the
1391:                            // end of an element.
1392:                            XSTypeDefinition type = elementPSVI
1393:                                    .getMemberTypeDefinition();
1394:                            if (type == null) {
1395:                                type = elementPSVI.getTypeDefinition();
1396:                            }
1397:                            fDeferredDocumentImpl.setTypeInfo(
1398:                                    fCurrentNodeIndex, type);
1399:                        }
1400:                    }
1401:                    fCurrentNodeIndex = fDeferredDocumentImpl.getParentNode(
1402:                            fCurrentNodeIndex, false);
1403:                }
1404:
1405:            } // endElement(QName)
1406:
1407:            /**
1408:             * The start of a CDATA section.
1409:             * @param augs     Additional information that may include infoset augmentations
1410:             *
1411:             * @throws XNIException Thrown by handler to signal an error.
1412:             */
1413:            public void startCDATA(Augmentations augs) throws XNIException {
1414:
1415:                fInCDATASection = true;
1416:                if (!fDeferNodeExpansion) {
1417:                    if (fFilterReject) {
1418:                        return;
1419:                    }
1420:                    if (fCreateCDATANodes) {
1421:                        setCharacterData(false);
1422:                    }
1423:                }
1424:            } // startCDATA()
1425:
1426:            /**
1427:             * The end of a CDATA section.
1428:             * @param augs     Additional information that may include infoset augmentations
1429:             *
1430:             * @throws XNIException Thrown by handler to signal an error.
1431:             */
1432:            public void endCDATA(Augmentations augs) throws XNIException {
1433:
1434:                fInCDATASection = false;
1435:                if (!fDeferNodeExpansion) {
1436:
1437:                    if (fFilterReject) {
1438:                        return;
1439:                    }
1440:
1441:                    if (fCurrentCDATASection != null) {
1442:
1443:                        if (fDOMFilter != null
1444:                                && !fInEntityRef
1445:                                && (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_CDATA_SECTION) != 0) {
1446:                            short code = fDOMFilter
1447:                                    .acceptNode(fCurrentCDATASection);
1448:                            switch (code) {
1449:                            case LSParserFilter.FILTER_INTERRUPT: {
1450:                                throw ABORT;
1451:                            }
1452:                            case LSParserFilter.FILTER_REJECT: {
1453:                                // fall through to SKIP since CDATA section has no children.
1454:                            }
1455:                            case LSParserFilter.FILTER_SKIP: {
1456:                                Node parent = fCurrentNode.getParentNode();
1457:                                parent.removeChild(fCurrentCDATASection);
1458:                                fCurrentNode = parent;
1459:                                return;
1460:                            }
1461:
1462:                            default: {
1463:                                // accept node
1464:                            }
1465:                            }
1466:                        }
1467:
1468:                        fCurrentNode = fCurrentNode.getParentNode();
1469:                        fCurrentCDATASection = null;
1470:                    }
1471:                } else {
1472:                    if (fCurrentCDATASectionIndex != -1) {
1473:                        fCurrentNodeIndex = fDeferredDocumentImpl
1474:                                .getParentNode(fCurrentNodeIndex, false);
1475:                        fCurrentCDATASectionIndex = -1;
1476:                    }
1477:                }
1478:
1479:            } // endCDATA()
1480:
1481:            /**
1482:             * The end of the document.
1483:             * @param augs     Additional information that may include infoset augmentations
1484:             *
1485:             * @throws XNIException Thrown by handler to signal an error.
1486:             */
1487:            public void endDocument(Augmentations augs) throws XNIException {
1488:
1489:                if (!fDeferNodeExpansion) {
1490:                    // REVISIT: when DOM Level 3 is REC rely on Document.support
1491:                    //          instead of specific class
1492:                    // set the actual encoding and set DOM error checking back on
1493:                    if (fDocumentImpl != null) {
1494:                        if (fLocator != null) {
1495:                            fDocumentImpl.setInputEncoding(fLocator
1496:                                    .getEncoding());
1497:                        }
1498:                        fDocumentImpl.setStrictErrorChecking(true);
1499:                    }
1500:                    fCurrentNode = null;
1501:                } else {
1502:                    // set the actual encoding
1503:                    if (fLocator != null) {
1504:                        fDeferredDocumentImpl.setInputEncoding(fLocator
1505:                                .getEncoding());
1506:                    }
1507:                    fCurrentNodeIndex = -1;
1508:                }
1509:
1510:            } // endDocument()
1511:
1512:            /**
1513:             * This method notifies the end of a general entity.
1514:             * <p>
1515:             * <strong>Note:</strong> This method is not called for entity references
1516:             * appearing as part of attribute values.
1517:             *
1518:             * @param name   The name of the entity.
1519:             * @param augs   Additional information that may include infoset augmentations
1520:             *
1521:             * @exception XNIException
1522:             *                   Thrown by handler to signal an error.
1523:             */
1524:            public void endGeneralEntity(String name, Augmentations augs)
1525:                    throws XNIException {
1526:                if (DEBUG_EVENTS) {
1527:                    System.out.println("==>endGeneralEntity: (" + name + ")");
1528:                }
1529:                if (!fDeferNodeExpansion) {
1530:
1531:                    if (fFilterReject) {
1532:                        return;
1533:                    }
1534:                    setCharacterData(true);
1535:
1536:                    if (fDocumentType != null) {
1537:                        // get current entity declaration
1538:                        NamedNodeMap entities = fDocumentType.getEntities();
1539:                        fCurrentEntityDecl = (EntityImpl) entities
1540:                                .getNamedItem(name);
1541:                        if (fCurrentEntityDecl != null) {
1542:                            if (fCurrentEntityDecl != null
1543:                                    && fCurrentEntityDecl.getFirstChild() == null) {
1544:                                fCurrentEntityDecl.setReadOnly(false, true);
1545:                                Node child = fCurrentNode.getFirstChild();
1546:                                while (child != null) {
1547:                                    Node copy = child.cloneNode(true);
1548:                                    fCurrentEntityDecl.appendChild(copy);
1549:                                    child = child.getNextSibling();
1550:                                }
1551:                                fCurrentEntityDecl.setReadOnly(true, true);
1552:
1553:                                //entities.setNamedItem(fCurrentEntityDecl);
1554:                            }
1555:                            fCurrentEntityDecl = null;
1556:                        }
1557:
1558:                    }
1559:                    fInEntityRef = false;
1560:                    boolean removeEntityRef = false;
1561:                    if (fCreateEntityRefNodes) {
1562:                        if (fDocumentImpl != null) {
1563:                            // Make entity ref node read only
1564:                            ((NodeImpl) fCurrentNode).setReadOnly(true, true);
1565:                        }
1566:
1567:                        if (fDOMFilter != null
1568:                                && (fDOMFilter.getWhatToShow() & NodeFilter.SHOW_ENTITY_REFERENCE) != 0) {
1569:                            short code = fDOMFilter.acceptNode(fCurrentNode);
1570:                            switch (code) {
1571:                            case LSParserFilter.FILTER_INTERRUPT: {
1572:                                throw ABORT;
1573:                            }
1574:                            case LSParserFilter.FILTER_REJECT: {
1575:                                Node parent = fCurrentNode.getParentNode();
1576:                                parent.removeChild(fCurrentNode);
1577:                                fCurrentNode = parent;
1578:                                return;
1579:
1580:                            }
1581:                            case LSParserFilter.FILTER_SKIP: {
1582:                                // make sure we don't loose chars if next event is characters()
1583:                                fFirstChunk = true;
1584:                                removeEntityRef = true;
1585:                                break;
1586:                            }
1587:
1588:                            default: {
1589:                                fCurrentNode = fCurrentNode.getParentNode();
1590:                            }
1591:                            }
1592:                        } else {
1593:                            fCurrentNode = fCurrentNode.getParentNode();
1594:                        }
1595:                    }
1596:
1597:                    if (!fCreateEntityRefNodes || removeEntityRef) {
1598:                        // move entity reference children to the list of
1599:                        // siblings of its parent and remove entity reference
1600:                        NodeList children = fCurrentNode.getChildNodes();
1601:                        Node parent = fCurrentNode.getParentNode();
1602:                        int length = children.getLength();
1603:                        if (length > 0) {
1604:
1605:                            // get previous sibling of the entity reference
1606:                            Node node = fCurrentNode.getPreviousSibling();
1607:                            // normalize text nodes
1608:                            Node child = children.item(0);
1609:                            if (node != null
1610:                                    && node.getNodeType() == Node.TEXT_NODE
1611:                                    && child.getNodeType() == Node.TEXT_NODE) {
1612:                                ((Text) node).appendData(child.getNodeValue());
1613:                                fCurrentNode.removeChild(child);
1614:
1615:                            } else {
1616:                                node = parent.insertBefore(child, fCurrentNode);
1617:                                handleBaseURI(node);
1618:                            }
1619:
1620:                            for (int i = 1; i < length; i++) {
1621:                                node = parent.insertBefore(children.item(0),
1622:                                        fCurrentNode);
1623:                                handleBaseURI(node);
1624:                            }
1625:                        } // length > 0
1626:                        parent.removeChild(fCurrentNode);
1627:                        fCurrentNode = parent;
1628:                    }
1629:                } else {
1630:
1631:                    if (fDocumentTypeIndex != -1) {
1632:                        // find corresponding Entity decl
1633:                        int node = fDeferredDocumentImpl.getLastChild(
1634:                                fDocumentTypeIndex, false);
1635:                        while (node != -1) {
1636:                            short nodeType = fDeferredDocumentImpl.getNodeType(
1637:                                    node, false);
1638:                            if (nodeType == Node.ENTITY_NODE) {
1639:                                String nodeName = fDeferredDocumentImpl
1640:                                        .getNodeName(node, false);
1641:                                if (nodeName.equals(name)) {
1642:                                    fDeferredEntityDecl = node;
1643:                                    break;
1644:                                }
1645:                            }
1646:                            node = fDeferredDocumentImpl.getRealPrevSibling(
1647:                                    node, false);
1648:                        }
1649:                    }
1650:
1651:                    if (fDeferredEntityDecl != -1
1652:                            && fDeferredDocumentImpl.getLastChild(
1653:                                    fDeferredEntityDecl, false) == -1) {
1654:                        // entity definition exists and it does not have any children
1655:                        int prevIndex = -1;
1656:                        int childIndex = fDeferredDocumentImpl.getLastChild(
1657:                                fCurrentNodeIndex, false);
1658:                        while (childIndex != -1) {
1659:                            int cloneIndex = fDeferredDocumentImpl.cloneNode(
1660:                                    childIndex, true);
1661:                            fDeferredDocumentImpl.insertBefore(
1662:                                    fDeferredEntityDecl, cloneIndex, prevIndex);
1663:                            prevIndex = cloneIndex;
1664:                            childIndex = fDeferredDocumentImpl
1665:                                    .getRealPrevSibling(childIndex, false);
1666:                        }
1667:                    }
1668:                    if (fCreateEntityRefNodes) {
1669:                        fCurrentNodeIndex = fDeferredDocumentImpl
1670:                                .getParentNode(fCurrentNodeIndex, false);
1671:                    } else { //!fCreateEntityRefNodes
1672:                        // move children of entity ref before the entity ref.
1673:                        // remove entity ref.
1674:
1675:                        // holds a child of entity ref
1676:                        int childIndex = fDeferredDocumentImpl.getLastChild(
1677:                                fCurrentNodeIndex, false);
1678:                        int parentIndex = fDeferredDocumentImpl.getParentNode(
1679:                                fCurrentNodeIndex, false);
1680:
1681:                        int prevIndex = fCurrentNodeIndex;
1682:                        int lastChild = childIndex;
1683:                        int sibling = -1;
1684:                        while (childIndex != -1) {
1685:                            handleBaseURI(childIndex);
1686:                            sibling = fDeferredDocumentImpl.getRealPrevSibling(
1687:                                    childIndex, false);
1688:                            fDeferredDocumentImpl.insertBefore(parentIndex,
1689:                                    childIndex, prevIndex);
1690:                            prevIndex = childIndex;
1691:                            childIndex = sibling;
1692:                        }
1693:                        if (lastChild != -1)
1694:                            fDeferredDocumentImpl.setAsLastChild(parentIndex,
1695:                                    lastChild);
1696:                        else {
1697:                            sibling = fDeferredDocumentImpl.getRealPrevSibling(
1698:                                    prevIndex, false);
1699:                            fDeferredDocumentImpl.setAsLastChild(parentIndex,
1700:                                    sibling);
1701:                        }
1702:                        fCurrentNodeIndex = parentIndex;
1703:                    }
1704:                    fDeferredEntityDecl = -1;
1705:                }
1706:
1707:            } // endGeneralEntity(String, Augmentations)
1708:
1709:            /**
1710:             * Record baseURI information for the Element (by adding xml:base attribute)
1711:             * or for the ProcessingInstruction (by setting a baseURI field)
1712:             * Non deferred DOM.
1713:             *
1714:             * @param node
1715:             */
1716:            protected final void handleBaseURI(Node node) {
1717:                if (fDocumentImpl != null) {
1718:                    // REVISIT: remove dependency on our implementation when
1719:                    //          DOM L3 becomes REC
1720:
1721:                    String baseURI = null;
1722:                    short nodeType = node.getNodeType();
1723:
1724:                    if (nodeType == Node.ELEMENT_NODE) {
1725:                        // if an element already has xml:base attribute
1726:                        // do nothing
1727:                        if (fNamespaceAware) {
1728:                            if (((Element) node).getAttributeNodeNS(
1729:                                    "http://www.w3.org/XML/1998/namespace",
1730:                                    "base") != null) {
1731:                                return;
1732:                            }
1733:                        } else if (((Element) node)
1734:                                .getAttributeNode("xml:base") != null) {
1735:                            return;
1736:                        }
1737:                        // retrive the baseURI from the entity reference
1738:                        baseURI = ((EntityReferenceImpl) fCurrentNode)
1739:                                .getBaseURI();
1740:                        if (baseURI != null
1741:                                && !baseURI.equals(fDocumentImpl
1742:                                        .getDocumentURI())) {
1743:                            if (fNamespaceAware) {
1744:                                ((Element) node).setAttributeNS(
1745:                                        "http://www.w3.org/XML/1998/namespace",
1746:                                        "base", baseURI);
1747:                            } else {
1748:                                ((Element) node).setAttribute("xml:base",
1749:                                        baseURI);
1750:                            }
1751:                        }
1752:                    } else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
1753:
1754:                        baseURI = ((EntityReferenceImpl) fCurrentNode)
1755:                                .getBaseURI();
1756:                        if (baseURI != null && fErrorHandler != null) {
1757:                            DOMErrorImpl error = new DOMErrorImpl();
1758:                            error.fType = "pi-base-uri-not-preserved";
1759:                            error.fRelatedData = baseURI;
1760:                            error.fSeverity = DOMError.SEVERITY_WARNING;
1761:                            fErrorHandler.getErrorHandler().handleError(error);
1762:                        }
1763:                    }
1764:                }
1765:            }
1766:
1767:            /**
1768:             *
1769:             * Record baseURI information for the Element (by adding xml:base attribute)
1770:             * or for the ProcessingInstruction (by setting a baseURI field)
1771:             * Deferred DOM.
1772:             *
1773:             * @param node
1774:             */
1775:            protected final void handleBaseURI(int node) {
1776:                short nodeType = fDeferredDocumentImpl.getNodeType(node, false);
1777:
1778:                if (nodeType == Node.ELEMENT_NODE) {
1779:                    String baseURI = fDeferredDocumentImpl.getNodeValueString(
1780:                            fCurrentNodeIndex, false);
1781:                    if (baseURI == null) {
1782:                        baseURI = fDeferredDocumentImpl
1783:                                .getDeferredEntityBaseURI(fDeferredEntityDecl);
1784:                    }
1785:                    if (baseURI != null
1786:                            && !baseURI.equals(fDeferredDocumentImpl
1787:                                    .getDocumentURI())) {
1788:                        fDeferredDocumentImpl.setDeferredAttribute(node,
1789:                                "xml:base",
1790:                                "http://www.w3.org/XML/1998/namespace",
1791:                                baseURI, true);
1792:                    }
1793:                } else if (nodeType == Node.PROCESSING_INSTRUCTION_NODE) {
1794:
1795:                    // retrieve baseURI from the entity reference
1796:                    String baseURI = fDeferredDocumentImpl.getNodeValueString(
1797:                            fCurrentNodeIndex, false);
1798:
1799:                    if (baseURI == null) {
1800:                        // try baseURI of the entity declaration
1801:                        baseURI = fDeferredDocumentImpl
1802:                                .getDeferredEntityBaseURI(fDeferredEntityDecl);
1803:                    }
1804:
1805:                    if (baseURI != null && fErrorHandler != null) {
1806:                        DOMErrorImpl error = new DOMErrorImpl();
1807:                        error.fType = "pi-base-uri-not-preserved";
1808:                        error.fRelatedData = baseURI;
1809:                        error.fSeverity = DOMError.SEVERITY_WARNING;
1810:                        fErrorHandler.getErrorHandler().handleError(error);
1811:                    }
1812:                }
1813:            }
1814:
1815:            //
1816:            // XMLDTDHandler methods
1817:            //
1818:
1819:            /**
1820:             * The start of the DTD.
1821:             *
1822:             * @param locator  The document locator, or null if the document
1823:             *                 location cannot be reported during the parsing of
1824:             *                 the document DTD. However, it is <em>strongly</em>
1825:             *                 recommended that a locator be supplied that can
1826:             *                 at least report the base system identifier of the
1827:             *                 DTD.
1828:             * @param augs Additional information that may include infoset
1829:             *                      augmentations.
1830:             *
1831:             * @throws XNIException Thrown by handler to signal an error.
1832:             */
1833:            public void startDTD(XMLLocator locator, Augmentations augs)
1834:                    throws XNIException {
1835:                if (DEBUG_EVENTS) {
1836:                    System.out.println("==>startDTD");
1837:                    if (DEBUG_BASEURI) {
1838:                        System.out.println("   expandedSystemId: "
1839:                                + locator.getExpandedSystemId());
1840:                        System.out.println("   baseURI:"
1841:                                + locator.getBaseSystemId());
1842:                    }
1843:                }
1844:
1845:                fInDTD = true;
1846:                if (locator != null) {
1847:                    fBaseURIStack.push(locator.getBaseSystemId());
1848:                }
1849:                if (fDeferNodeExpansion || fDocumentImpl != null) {
1850:                    fInternalSubset = new StringBuffer(1024);
1851:                }
1852:            } // startDTD(XMLLocator)
1853:
1854:            /**
1855:             * The end of the DTD.
1856:             *
1857:             * @param augs Additional information that may include infoset
1858:             *                      augmentations.
1859:             *
1860:             * @throws XNIException Thrown by handler to signal an error.
1861:             */
1862:            public void endDTD(Augmentations augs) throws XNIException {
1863:                if (DEBUG_EVENTS) {
1864:                    System.out.println("==>endDTD()");
1865:                }
1866:                fInDTD = false;
1867:                if (!fBaseURIStack.isEmpty()) {
1868:                    fBaseURIStack.pop();
1869:                }
1870:                String internalSubset = fInternalSubset != null
1871:                        && fInternalSubset.length() > 0 ? fInternalSubset
1872:                        .toString() : null;
1873:                if (fDeferNodeExpansion) {
1874:                    if (internalSubset != null) {
1875:                        fDeferredDocumentImpl.setInternalSubset(
1876:                                fDocumentTypeIndex, internalSubset);
1877:                    }
1878:                } else if (fDocumentImpl != null) {
1879:                    if (internalSubset != null) {
1880:                        ((DocumentTypeImpl) fDocumentType)
1881:                                .setInternalSubset(internalSubset);
1882:                    }
1883:                }
1884:            } // endDTD()
1885:
1886:            /**
1887:             * The start of a conditional section.
1888:             *
1889:             * @param type The type of the conditional section. This value will
1890:             *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
1891:             * @param augs Additional information that may include infoset
1892:             *                      augmentations.
1893:             *
1894:             * @throws XNIException Thrown by handler to signal an error.
1895:             *
1896:             * @see #CONDITIONAL_INCLUDE
1897:             * @see #CONDITIONAL_IGNORE
1898:             */
1899:            public void startConditional(short type, Augmentations augs)
1900:                    throws XNIException {
1901:            } // startConditional(short)
1902:
1903:            /**
1904:             * The end of a conditional section.
1905:             *
1906:             * @param augs Additional information that may include infoset
1907:             *                      augmentations.
1908:             *
1909:             * @throws XNIException Thrown by handler to signal an error.
1910:             */
1911:            public void endConditional(Augmentations augs) throws XNIException {
1912:            } // endConditional()
1913:
1914:            /**
1915:             * The start of the DTD external subset.
1916:             *
1917:             * @param augs Additional information that may include infoset
1918:             *                      augmentations.
1919:             *
1920:             * @throws XNIException Thrown by handler to signal an error.
1921:             */
1922:            public void startExternalSubset(XMLResourceIdentifier identifier,
1923:                    Augmentations augs) throws XNIException {
1924:                if (DEBUG_EVENTS) {
1925:                    System.out.println("==>startExternalSubset");
1926:                    if (DEBUG_BASEURI) {
1927:                        System.out.println("   expandedSystemId: "
1928:                                + identifier.getExpandedSystemId());
1929:                        System.out.println("   baseURI:"
1930:                                + identifier.getBaseSystemId());
1931:                    }
1932:                }
1933:                fBaseURIStack.push(identifier.getBaseSystemId());
1934:                fInDTDExternalSubset = true;
1935:            } // startExternalSubset(Augmentations)
1936:
1937:            /**
1938:             * The end of the DTD external subset.
1939:             *
1940:             * @param augs Additional information that may include infoset
1941:             *                      augmentations.
1942:             *
1943:             * @throws XNIException Thrown by handler to signal an error.
1944:             */
1945:            public void endExternalSubset(Augmentations augs)
1946:                    throws XNIException {
1947:                fInDTDExternalSubset = false;
1948:                fBaseURIStack.pop();
1949:            } // endExternalSubset(Augmentations)
1950:
1951:            /**
1952:             * An internal entity declaration.
1953:             *
1954:             * @param name The name of the entity. Parameter entity names start with
1955:             *             '%', whereas the name of a general entity is just the
1956:             *             entity name.
1957:             * @param text The value of the entity.
1958:             * @param nonNormalizedText The non-normalized value of the entity. This
1959:             *             value contains the same sequence of characters that was in
1960:             *             the internal entity declaration, without any entity
1961:             *             references expanded.
1962:             * @param augs Additional information that may include infoset
1963:             *                      augmentations.
1964:             *
1965:             * @throws XNIException Thrown by handler to signal an error.
1966:             */
1967:            public void internalEntityDecl(String name, XMLString text,
1968:                    XMLString nonNormalizedText, Augmentations augs)
1969:                    throws XNIException {
1970:
1971:                if (DEBUG_EVENTS) {
1972:                    System.out.println("==>internalEntityDecl: " + name);
1973:                    if (DEBUG_BASEURI) {
1974:                        System.out.println("   baseURI:"
1975:                                + (String) fBaseURIStack.peek());
1976:                    }
1977:                }
1978:                // internal subset string
1979:                if (fInternalSubset != null && !fInDTDExternalSubset) {
1980:                    fInternalSubset.append("<!ENTITY ");
1981:                    if (name.startsWith("%")) {
1982:                        fInternalSubset.append("% ");
1983:                        fInternalSubset.append(name.substring(1));
1984:                    } else {
1985:                        fInternalSubset.append(name);
1986:                    }
1987:                    fInternalSubset.append(' ');
1988:                    String value = nonNormalizedText.toString();
1989:                    boolean singleQuote = value.indexOf('\'') == -1;
1990:                    fInternalSubset.append(singleQuote ? '\'' : '"');
1991:                    fInternalSubset.append(value);
1992:                    fInternalSubset.append(singleQuote ? '\'' : '"');
1993:                    fInternalSubset.append(">\n");
1994:                }
1995:
1996:                // NOTE: We only know how to create these nodes for the Xerces
1997:                //       DOM implementation because DOM Level 2 does not specify
1998:                //       that functionality. -Ac
1999:
2000:                // create full node
2001:                // don't add parameter entities!
2002:                if (name.startsWith("%"))
2003:                    return;
2004:                if (fDocumentType != null) {
2005:                    NamedNodeMap entities = fDocumentType.getEntities();
2006:                    EntityImpl entity = (EntityImpl) entities
2007:                            .getNamedItem(name);
2008:                    if (entity == null) {
2009:                        entity = (EntityImpl) fDocumentImpl.createEntity(name);
2010:                        entity.setBaseURI((String) fBaseURIStack.peek());
2011:                        entities.setNamedItem(entity);
2012:                    }
2013:                }
2014:
2015:                // create deferred node
2016:                if (fDocumentTypeIndex != -1) {
2017:                    boolean found = false;
2018:                    int node = fDeferredDocumentImpl.getLastChild(
2019:                            fDocumentTypeIndex, false);
2020:                    while (node != -1) {
2021:                        short nodeType = fDeferredDocumentImpl.getNodeType(
2022:                                node, false);
2023:                        if (nodeType == Node.ENTITY_NODE) {
2024:                            String nodeName = fDeferredDocumentImpl
2025:                                    .getNodeName(node, false);
2026:                            if (nodeName.equals(name)) {
2027:                                found = true;
2028:                                break;
2029:                            }
2030:                        }
2031:                        node = fDeferredDocumentImpl.getRealPrevSibling(node,
2032:                                false);
2033:                    }
2034:                    if (!found) {
2035:                        int entityIndex = fDeferredDocumentImpl
2036:                                .createDeferredEntity(name, null, null, null,
2037:                                        (String) fBaseURIStack.peek());
2038:                        fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2039:                                entityIndex);
2040:                    }
2041:                }
2042:
2043:            } // internalEntityDecl(String,XMLString,XMLString)
2044:
2045:            /**
2046:             * An external entity declaration.
2047:             *
2048:             * @param name     The name of the entity. Parameter entity names start
2049:             *                 with '%', whereas the name of a general entity is just
2050:             *                 the entity name.
2051:             * @param identifier    An object containing all location information
2052:             *                      pertinent to this notation.
2053:             * @param augs Additional information that may include infoset
2054:             *                      augmentations.
2055:             *
2056:             * @throws XNIException Thrown by handler to signal an error.
2057:             */
2058:            public void externalEntityDecl(String name,
2059:                    XMLResourceIdentifier identifier, Augmentations augs)
2060:                    throws XNIException {
2061:
2062:                if (DEBUG_EVENTS) {
2063:                    System.out.println("==>externalEntityDecl: " + name);
2064:                    if (DEBUG_BASEURI) {
2065:                        System.out.println("   expandedSystemId:"
2066:                                + identifier.getExpandedSystemId());
2067:                        System.out.println("   baseURI:"
2068:                                + identifier.getBaseSystemId());
2069:                    }
2070:                }
2071:                // internal subset string
2072:                String publicId = identifier.getPublicId();
2073:                String literalSystemId = identifier.getLiteralSystemId();
2074:                if (fInternalSubset != null && !fInDTDExternalSubset) {
2075:                    fInternalSubset.append("<!ENTITY ");
2076:                    if (name.startsWith("%")) {
2077:                        fInternalSubset.append("% ");
2078:                        fInternalSubset.append(name.substring(1));
2079:                    } else {
2080:                        fInternalSubset.append(name);
2081:                    }
2082:                    fInternalSubset.append(' ');
2083:                    if (publicId != null) {
2084:                        fInternalSubset.append("PUBLIC '");
2085:                        fInternalSubset.append(publicId);
2086:                        fInternalSubset.append("' '");
2087:                    } else {
2088:                        fInternalSubset.append("SYSTEM '");
2089:                    }
2090:                    fInternalSubset.append(literalSystemId);
2091:                    fInternalSubset.append("'>\n");
2092:                }
2093:
2094:                // NOTE: We only know how to create these nodes for the Xerces
2095:                //       DOM implementation because DOM Level 2 does not specify
2096:                //       that functionality. -Ac
2097:
2098:                // create full node
2099:                // don't add parameter entities!
2100:                if (name.startsWith("%"))
2101:                    return;
2102:                if (fDocumentType != null) {
2103:                    NamedNodeMap entities = fDocumentType.getEntities();
2104:                    EntityImpl entity = (EntityImpl) entities
2105:                            .getNamedItem(name);
2106:                    if (entity == null) {
2107:                        entity = (EntityImpl) fDocumentImpl.createEntity(name);
2108:                        entity.setPublicId(publicId);
2109:                        entity.setSystemId(literalSystemId);
2110:                        entity.setBaseURI(identifier.getBaseSystemId());
2111:                        entities.setNamedItem(entity);
2112:                    }
2113:                }
2114:
2115:                // create deferred node
2116:                if (fDocumentTypeIndex != -1) {
2117:                    boolean found = false;
2118:                    int nodeIndex = fDeferredDocumentImpl.getLastChild(
2119:                            fDocumentTypeIndex, false);
2120:                    while (nodeIndex != -1) {
2121:                        short nodeType = fDeferredDocumentImpl.getNodeType(
2122:                                nodeIndex, false);
2123:                        if (nodeType == Node.ENTITY_NODE) {
2124:                            String nodeName = fDeferredDocumentImpl
2125:                                    .getNodeName(nodeIndex, false);
2126:                            if (nodeName.equals(name)) {
2127:                                found = true;
2128:                                break;
2129:                            }
2130:                        }
2131:                        nodeIndex = fDeferredDocumentImpl.getRealPrevSibling(
2132:                                nodeIndex, false);
2133:                    }
2134:                    if (!found) {
2135:                        int entityIndex = fDeferredDocumentImpl
2136:                                .createDeferredEntity(name, publicId,
2137:                                        literalSystemId, null, identifier
2138:                                                .getBaseSystemId());
2139:                        fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2140:                                entityIndex);
2141:                    }
2142:                }
2143:
2144:            } // externalEntityDecl(String,XMLResourceIdentifier, Augmentations)
2145:
2146:            /**
2147:             * This method notifies of the start of a parameter entity. The parameter
2148:             * entity name start with a '%' character.
2149:             *
2150:             * @param name     The name of the parameter entity.
2151:             * @param identifier The resource identifier.
2152:             * @param encoding The auto-detected IANA encoding name of the entity
2153:             *                 stream. This value will be null in those situations
2154:             *                 where the entity encoding is not auto-detected (e.g.
2155:             *                 internal parameter entities).
2156:             * @param augs Additional information that may include infoset
2157:             *                      augmentations.
2158:             *
2159:             * @throws XNIException Thrown by handler to signal an error.
2160:             */
2161:            public void startParameterEntity(String name,
2162:                    XMLResourceIdentifier identifier, String encoding,
2163:                    Augmentations augs) throws XNIException {
2164:                if (DEBUG_EVENTS) {
2165:                    System.out.println("==>startParameterEntity: " + name);
2166:                    if (DEBUG_BASEURI) {
2167:                        System.out.println("   expandedSystemId: "
2168:                                + identifier.getExpandedSystemId());
2169:                        System.out.println("   baseURI:"
2170:                                + identifier.getBaseSystemId());
2171:                    }
2172:                }
2173:                if (augs != null
2174:                        && fInternalSubset != null
2175:                        && !fInDTDExternalSubset
2176:                        && Boolean.TRUE.equals(augs
2177:                                .getItem(Constants.ENTITY_SKIPPED))) {
2178:                    fInternalSubset.append(name).append(";\n");
2179:                }
2180:                fBaseURIStack.push(identifier.getExpandedSystemId());
2181:            }
2182:
2183:            /**
2184:             * This method notifies the end of a parameter entity. Parameter entity
2185:             * names begin with a '%' character.
2186:             *
2187:             * @param name The name of the parameter entity.
2188:             * @param augs Additional information that may include infoset
2189:             *                      augmentations.
2190:             *
2191:             * @throws XNIException Thrown by handler to signal an error.
2192:             */
2193:            public void endParameterEntity(String name, Augmentations augs)
2194:                    throws XNIException {
2195:
2196:                if (DEBUG_EVENTS) {
2197:                    System.out.println("==>endParameterEntity: " + name);
2198:                }
2199:                fBaseURIStack.pop();
2200:            }
2201:
2202:            /**
2203:             * An unparsed entity declaration.
2204:             *
2205:             * @param name     The name of the entity.
2206:             * @param identifier    An object containing all location information
2207:             *                      pertinent to this entity.
2208:             * @param notation The name of the notation.
2209:             * @param augs Additional information that may include infoset
2210:             *                      augmentations.
2211:             *
2212:             * @throws XNIException Thrown by handler to signal an error.
2213:             */
2214:            public void unparsedEntityDecl(String name,
2215:                    XMLResourceIdentifier identifier, String notation,
2216:                    Augmentations augs) throws XNIException {
2217:
2218:                if (DEBUG_EVENTS) {
2219:                    System.out.println("==>unparsedEntityDecl: " + name);
2220:                    if (DEBUG_BASEURI) {
2221:                        System.out.println("   expandedSystemId:"
2222:                                + identifier.getExpandedSystemId());
2223:                        System.out.println("   baseURI:"
2224:                                + identifier.getBaseSystemId());
2225:                    }
2226:                }
2227:                // internal subset string
2228:                String publicId = identifier.getPublicId();
2229:                String literalSystemId = identifier.getLiteralSystemId();
2230:                if (fInternalSubset != null && !fInDTDExternalSubset) {
2231:                    fInternalSubset.append("<!ENTITY ");
2232:                    fInternalSubset.append(name);
2233:                    fInternalSubset.append(' ');
2234:                    if (publicId != null) {
2235:                        fInternalSubset.append("PUBLIC '");
2236:                        fInternalSubset.append(publicId);
2237:                        if (literalSystemId != null) {
2238:                            fInternalSubset.append("' '");
2239:                            fInternalSubset.append(literalSystemId);
2240:                        }
2241:                    } else {
2242:                        fInternalSubset.append("SYSTEM '");
2243:                        fInternalSubset.append(literalSystemId);
2244:                    }
2245:                    fInternalSubset.append("' NDATA ");
2246:                    fInternalSubset.append(notation);
2247:                    fInternalSubset.append(">\n");
2248:                }
2249:
2250:                // NOTE: We only know how to create these nodes for the Xerces
2251:                //       DOM implementation because DOM Level 2 does not specify
2252:                //       that functionality. -Ac
2253:
2254:                // create full node
2255:                if (fDocumentType != null) {
2256:                    NamedNodeMap entities = fDocumentType.getEntities();
2257:                    EntityImpl entity = (EntityImpl) entities
2258:                            .getNamedItem(name);
2259:                    if (entity == null) {
2260:                        entity = (EntityImpl) fDocumentImpl.createEntity(name);
2261:                        entity.setPublicId(publicId);
2262:                        entity.setSystemId(literalSystemId);
2263:                        entity.setNotationName(notation);
2264:                        entity.setBaseURI(identifier.getBaseSystemId());
2265:                        entities.setNamedItem(entity);
2266:                    }
2267:                }
2268:
2269:                // create deferred node
2270:                if (fDocumentTypeIndex != -1) {
2271:                    boolean found = false;
2272:                    int nodeIndex = fDeferredDocumentImpl.getLastChild(
2273:                            fDocumentTypeIndex, false);
2274:                    while (nodeIndex != -1) {
2275:                        short nodeType = fDeferredDocumentImpl.getNodeType(
2276:                                nodeIndex, false);
2277:                        if (nodeType == Node.ENTITY_NODE) {
2278:                            String nodeName = fDeferredDocumentImpl
2279:                                    .getNodeName(nodeIndex, false);
2280:                            if (nodeName.equals(name)) {
2281:                                found = true;
2282:                                break;
2283:                            }
2284:                        }
2285:                        nodeIndex = fDeferredDocumentImpl.getRealPrevSibling(
2286:                                nodeIndex, false);
2287:                    }
2288:                    if (!found) {
2289:                        int entityIndex = fDeferredDocumentImpl
2290:                                .createDeferredEntity(name, publicId,
2291:                                        literalSystemId, notation, identifier
2292:                                                .getBaseSystemId());
2293:                        fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2294:                                entityIndex);
2295:                    }
2296:                }
2297:
2298:            } // unparsedEntityDecl(String,XMLResourceIdentifier, String, Augmentations)
2299:
2300:            /**
2301:             * A notation declaration
2302:             *
2303:             * @param name     The name of the notation.
2304:             * @param identifier    An object containing all location information
2305:             *                      pertinent to this notation.
2306:             * @param augs Additional information that may include infoset
2307:             *                      augmentations.
2308:             *
2309:             * @throws XNIException Thrown by handler to signal an error.
2310:             */
2311:            public void notationDecl(String name,
2312:                    XMLResourceIdentifier identifier, Augmentations augs)
2313:                    throws XNIException {
2314:
2315:                // internal subset string
2316:                String publicId = identifier.getPublicId();
2317:                String literalSystemId = identifier.getLiteralSystemId();
2318:                if (fInternalSubset != null && !fInDTDExternalSubset) {
2319:                    fInternalSubset.append("<!NOTATION ");
2320:                    fInternalSubset.append(name);
2321:                    if (publicId != null) {
2322:                        fInternalSubset.append(" PUBLIC '");
2323:                        fInternalSubset.append(publicId);
2324:                        if (literalSystemId != null) {
2325:                            fInternalSubset.append("' '");
2326:                            fInternalSubset.append(literalSystemId);
2327:                        }
2328:                    } else {
2329:                        fInternalSubset.append(" SYSTEM '");
2330:                        fInternalSubset.append(literalSystemId);
2331:                    }
2332:                    fInternalSubset.append("'>\n");
2333:                }
2334:
2335:                // NOTE: We only know how to create these nodes for the Xerces
2336:                //       DOM implementation because DOM Level 2 does not specify
2337:                //       that functionality. -Ac
2338:
2339:                // create full node
2340:                if (fDocumentImpl != null && fDocumentType != null) {
2341:                    NamedNodeMap notations = fDocumentType.getNotations();
2342:                    if (notations.getNamedItem(name) == null) {
2343:                        NotationImpl notation = (NotationImpl) fDocumentImpl
2344:                                .createNotation(name);
2345:                        notation.setPublicId(publicId);
2346:                        notation.setSystemId(literalSystemId);
2347:                        notation.setBaseURI(identifier.getBaseSystemId());
2348:                        notations.setNamedItem(notation);
2349:                    }
2350:                }
2351:
2352:                // create deferred node
2353:                if (fDocumentTypeIndex != -1) {
2354:                    boolean found = false;
2355:                    int nodeIndex = fDeferredDocumentImpl.getLastChild(
2356:                            fDocumentTypeIndex, false);
2357:                    while (nodeIndex != -1) {
2358:                        short nodeType = fDeferredDocumentImpl.getNodeType(
2359:                                nodeIndex, false);
2360:                        if (nodeType == Node.NOTATION_NODE) {
2361:                            String nodeName = fDeferredDocumentImpl
2362:                                    .getNodeName(nodeIndex, false);
2363:                            if (nodeName.equals(name)) {
2364:                                found = true;
2365:                                break;
2366:                            }
2367:                        }
2368:                        nodeIndex = fDeferredDocumentImpl.getPrevSibling(
2369:                                nodeIndex, false);
2370:                    }
2371:                    if (!found) {
2372:                        int notationIndex = fDeferredDocumentImpl
2373:                                .createDeferredNotation(name, publicId,
2374:                                        literalSystemId, identifier
2375:                                                .getBaseSystemId());
2376:                        fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2377:                                notationIndex);
2378:                    }
2379:                }
2380:
2381:            } // notationDecl(String,XMLResourceIdentifier, Augmentations)
2382:
2383:            /**
2384:             * Characters within an IGNORE conditional section.
2385:             *
2386:             * @param text The ignored text.
2387:             * @param augs Additional information that may include infoset
2388:             *                      augmentations.
2389:             *
2390:             * @throws XNIException Thrown by handler to signal an error.
2391:             */
2392:            public void ignoredCharacters(XMLString text, Augmentations augs)
2393:                    throws XNIException {
2394:            } // ignoredCharacters(XMLString, Augmentations)
2395:
2396:            /**
2397:             * An element declaration.
2398:             *
2399:             * @param name         The name of the element.
2400:             * @param contentModel The element content model.
2401:             * @param augs Additional information that may include infoset
2402:             *                      augmentations.
2403:             *
2404:             * @throws XNIException Thrown by handler to signal an error.
2405:             */
2406:            public void elementDecl(String name, String contentModel,
2407:                    Augmentations augs) throws XNIException {
2408:
2409:                // internal subset string
2410:                if (fInternalSubset != null && !fInDTDExternalSubset) {
2411:                    fInternalSubset.append("<!ELEMENT ");
2412:                    fInternalSubset.append(name);
2413:                    fInternalSubset.append(' ');
2414:                    fInternalSubset.append(contentModel);
2415:                    fInternalSubset.append(">\n");
2416:                }
2417:
2418:            } // elementDecl(String,String)
2419:
2420:            /**
2421:             * An attribute declaration.
2422:             *
2423:             * @param elementName   The name of the element that this attribute
2424:             *                      is associated with.
2425:             * @param attributeName The name of the attribute.
2426:             * @param type          The attribute type. This value will be one of
2427:             *                      the following: "CDATA", "ENTITY", "ENTITIES",
2428:             *                      "ENUMERATION", "ID", "IDREF", "IDREFS",
2429:             *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
2430:             * @param enumeration   If the type has the value "ENUMERATION" or
2431:             *                      "NOTATION", this array holds the allowed attribute
2432:             *                      values; otherwise, this array is null.
2433:             * @param defaultType   The attribute default type. This value will be
2434:             *                      one of the following: "#FIXED", "#IMPLIED",
2435:             *                      "#REQUIRED", or null.
2436:             * @param defaultValue  The attribute default value, or null if no
2437:             *                      default value is specified.
2438:             * @param nonNormalizedDefaultValue  The attribute default value with no normalization
2439:             *                      performed, or null if no default value is specified.
2440:             * @param augs Additional information that may include infoset
2441:             *                      augmentations.
2442:             *
2443:             * @throws XNIException Thrown by handler to signal an error.
2444:             */
2445:            public void attributeDecl(String elementName, String attributeName,
2446:                    String type, String[] enumeration, String defaultType,
2447:                    XMLString defaultValue,
2448:                    XMLString nonNormalizedDefaultValue, Augmentations augs)
2449:                    throws XNIException {
2450:
2451:                // internal subset string
2452:                if (fInternalSubset != null && !fInDTDExternalSubset) {
2453:                    fInternalSubset.append("<!ATTLIST ");
2454:                    fInternalSubset.append(elementName);
2455:                    fInternalSubset.append(' ');
2456:                    fInternalSubset.append(attributeName);
2457:                    fInternalSubset.append(' ');
2458:                    if (type.equals("ENUMERATION")) {
2459:                        fInternalSubset.append('(');
2460:                        for (int i = 0; i < enumeration.length; i++) {
2461:                            if (i > 0) {
2462:                                fInternalSubset.append('|');
2463:                            }
2464:                            fInternalSubset.append(enumeration[i]);
2465:                        }
2466:                        fInternalSubset.append(')');
2467:                    } else {
2468:                        fInternalSubset.append(type);
2469:                    }
2470:                    if (defaultType != null) {
2471:                        fInternalSubset.append(' ');
2472:                        fInternalSubset.append(defaultType);
2473:                    }
2474:                    if (defaultValue != null) {
2475:                        fInternalSubset.append(" '");
2476:                        for (int i = 0; i < defaultValue.length; i++) {
2477:                            char c = defaultValue.ch[defaultValue.offset + i];
2478:                            if (c == '\'') {
2479:                                fInternalSubset.append("&apos;");
2480:                            } else {
2481:                                fInternalSubset.append(c);
2482:                            }
2483:                        }
2484:                        fInternalSubset.append('\'');
2485:                    }
2486:                    fInternalSubset.append(">\n");
2487:                }
2488:                // REVISIT: This code applies to the support of domx/grammar-access
2489:                // feature in Xerces 1
2490:
2491:                // deferred expansion
2492:                if (fDeferredDocumentImpl != null) {
2493:
2494:                    // get the default value
2495:                    if (defaultValue != null) {
2496:
2497:                        // get element definition
2498:                        int elementDefIndex = fDeferredDocumentImpl
2499:                                .lookupElementDefinition(elementName);
2500:
2501:                        // create element definition if not already there
2502:                        if (elementDefIndex == -1) {
2503:                            elementDefIndex = fDeferredDocumentImpl
2504:                                    .createDeferredElementDefinition(elementName);
2505:                            fDeferredDocumentImpl.appendChild(
2506:                                    fDocumentTypeIndex, elementDefIndex);
2507:                        }
2508:                        // add default attribute
2509:                        int attrIndex = fDeferredDocumentImpl
2510:                                .createDeferredAttribute(attributeName,
2511:                                        defaultValue.toString(), false);
2512:                        if ("ID".equals(type)) {
2513:                            fDeferredDocumentImpl.setIdAttribute(attrIndex);
2514:                        }
2515:                        // REVISIT: set ID type correctly
2516:                        fDeferredDocumentImpl.appendChild(elementDefIndex,
2517:                                attrIndex);
2518:                    }
2519:
2520:                } // if deferred
2521:
2522:                // full expansion
2523:                else if (fDocumentImpl != null) {
2524:
2525:                    // get the default value
2526:                    if (defaultValue != null) {
2527:
2528:                        // get element definition node
2529:                        NamedNodeMap elements = ((DocumentTypeImpl) fDocumentType)
2530:                                .getElements();
2531:                        ElementDefinitionImpl elementDef = (ElementDefinitionImpl) elements
2532:                                .getNamedItem(elementName);
2533:                        if (elementDef == null) {
2534:                            elementDef = fDocumentImpl
2535:                                    .createElementDefinition(elementName);
2536:                            ((DocumentTypeImpl) fDocumentType).getElements()
2537:                                    .setNamedItem(elementDef);
2538:                        }
2539:
2540:                        // REVISIT: Check for uniqueness of element name? -Ac
2541:
2542:                        // create attribute and set properties
2543:                        boolean nsEnabled = fNamespaceAware;
2544:                        AttrImpl attr;
2545:                        if (nsEnabled) {
2546:                            String namespaceURI = null;
2547:                            // DOM Level 2 wants all namespace declaration attributes
2548:                            // to be bound to "http://www.w3.org/2000/xmlns/"
2549:                            // So as long as the XML parser doesn't do it, it needs to
2550:                            // done here.
2551:                            if (attributeName.startsWith("xmlns:")
2552:                                    || attributeName.equals("xmlns")) {
2553:                                namespaceURI = NamespaceContext.XMLNS_URI;
2554:                            }
2555:                            attr = (AttrImpl) fDocumentImpl.createAttributeNS(
2556:                                    namespaceURI, attributeName);
2557:                        } else {
2558:                            attr = (AttrImpl) fDocumentImpl
2559:                                    .createAttribute(attributeName);
2560:                        }
2561:                        attr.setValue(defaultValue.toString());
2562:                        attr.setSpecified(false);
2563:                        attr.setIdAttribute("ID".equals(type));
2564:
2565:                        // add default attribute to element definition
2566:                        if (nsEnabled) {
2567:                            elementDef.getAttributes().setNamedItemNS(attr);
2568:                        } else {
2569:                            elementDef.getAttributes().setNamedItem(attr);
2570:                        }
2571:                    }
2572:
2573:                } // if NOT defer-node-expansion
2574:
2575:            } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
2576:
2577:            /**
2578:             * The start of an attribute list.
2579:             *
2580:             * @param elementName The name of the element that this attribute
2581:             *                    list is associated with.
2582:             * @param augs Additional information that may include infoset
2583:             *                      augmentations.
2584:             *
2585:             * @throws XNIException Thrown by handler to signal an error.
2586:             */
2587:            public void startAttlist(String elementName, Augmentations augs)
2588:                    throws XNIException {
2589:            } // startAttlist(String)
2590:
2591:            /**
2592:             * The end of an attribute list.
2593:             *
2594:             * @param augs Additional information that may include infoset
2595:             *                      augmentations.
2596:             *
2597:             * @throws XNIException Thrown by handler to signal an error.
2598:             */
2599:            public void endAttlist(Augmentations augs) throws XNIException {
2600:            } // endAttlist()
2601:
2602:            // method to create an element node.
2603:            // subclasses can override this method to create element nodes in other ways.
2604:            protected Element createElementNode(QName element) {
2605:                Element el = null;
2606:
2607:                if (fNamespaceAware) {
2608:                    // if we are using xerces DOM implementation, call our
2609:                    // own constructor to reuse the strings we have here.
2610:                    if (fDocumentImpl != null) {
2611:                        el = fDocumentImpl.createElementNS(element.uri,
2612:                                element.rawname, element.localpart);
2613:                    } else {
2614:                        el = fDocument.createElementNS(element.uri,
2615:                                element.rawname);
2616:                    }
2617:                } else {
2618:                    el = fDocument.createElement(element.rawname);
2619:                }
2620:
2621:                return el;
2622:            }
2623:
2624:            // method to create an attribute node.
2625:            // subclasses can override this method to create attribute nodes in other ways.
2626:            protected Attr createAttrNode(QName attrQName) {
2627:                Attr attr = null;
2628:
2629:                if (fNamespaceAware) {
2630:                    if (fDocumentImpl != null) {
2631:                        // if we are using xerces DOM implementation, call our
2632:                        // own constructor to reuse the strings we have here.
2633:                        attr = fDocumentImpl.createAttributeNS(attrQName.uri,
2634:                                attrQName.rawname, attrQName.localpart);
2635:                    } else {
2636:                        attr = fDocument.createAttributeNS(attrQName.uri,
2637:                                attrQName.rawname);
2638:                    }
2639:                } else {
2640:                    attr = fDocument.createAttribute(attrQName.rawname);
2641:                }
2642:
2643:                return attr;
2644:            }
2645:
2646:            /*
2647:             * When the first characters() call is received, the data is stored in
2648:             * a new Text node. If right after the first characters() we receive another chunk of data,
2649:             * the data from the Text node, following the new characters are appended
2650:             * to the fStringBuffer and the text node data is set to empty.
2651:             *
2652:             * This function is called when the state is changed and the
2653:             * data must be appended to the current node.
2654:             *
2655:             * Note: if DOMFilter is set, you must make sure that if Node is skipped,
2656:             * or removed fFistChunk must be set to true, otherwise some data can be lost.
2657:             *
2658:             */
2659:            protected void setCharacterData(boolean sawChars) {
2660:
2661:                // handle character data
2662:                fFirstChunk = sawChars;
2663:
2664:                // if we have data in the buffer we must have created
2665:                // a text node already.
2666:
2667:                Node child = fCurrentNode.getLastChild();
2668:                if (child != null) {
2669:                    if (fStringBuffer.length() > 0) {
2670:                        // REVISIT: should this check be performed?
2671:                        if (child.getNodeType() == Node.TEXT_NODE) {
2672:                            if (fDocumentImpl != null) {
2673:                                ((TextImpl) child).replaceData(fStringBuffer
2674:                                        .toString());
2675:                            } else {
2676:                                ((Text) child)
2677:                                        .setData(fStringBuffer.toString());
2678:                            }
2679:                        }
2680:                        // reset string buffer
2681:                        fStringBuffer.setLength(0);
2682:                    }
2683:
2684:                    if (fDOMFilter != null && !fInEntityRef) {
2685:                        if ((child.getNodeType() == Node.TEXT_NODE)
2686:                                && ((fDOMFilter.getWhatToShow() & NodeFilter.SHOW_TEXT) != 0)) {
2687:                            short code = fDOMFilter.acceptNode(child);
2688:                            switch (code) {
2689:                            case LSParserFilter.FILTER_INTERRUPT: {
2690:                                throw ABORT;
2691:                            }
2692:                            case LSParserFilter.FILTER_REJECT: {
2693:                                // fall through to SKIP since Comment has no children.
2694:                            }
2695:                            case LSParserFilter.FILTER_SKIP: {
2696:                                fCurrentNode.removeChild(child);
2697:                                return;
2698:                            }
2699:                            default: {
2700:                                // accept node -- do nothing
2701:                            }
2702:                            }
2703:                        }
2704:                    } // end-if fDOMFilter !=null
2705:
2706:                } // end-if child !=null
2707:            }
2708:
2709:            /**
2710:             * @see org.w3c.dom.ls.LSParser#abort()
2711:             */
2712:            public void abort() {
2713:                throw ABORT;
2714:            }
2715:
2716:        } // class AbstractDOMParser
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.