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


0001:        /*
0002:         * The Apache Software License, Version 1.1
0003:         *
0004:         *
0005:         * Copyright (c) 1999,2000 The Apache Software Foundation.  All rights
0006:         * reserved.
0007:         *
0008:         * Redistribution and use in source and binary forms, with or without
0009:         * modification, are permitted provided that the following conditions
0010:         * are met:
0011:         *
0012:         * 1. Redistributions of source code must retain the above copyright
0013:         *    notice, this list of conditions and the following disclaimer.
0014:         *
0015:         * 2. Redistributions in binary form must reproduce the above copyright
0016:         *    notice, this list of conditions and the following disclaimer in
0017:         *    the documentation and/or other materials provided with the
0018:         *    distribution.
0019:         *
0020:         * 3. The end-user documentation included with the redistribution,
0021:         *    if any, must include the following acknowledgment:
0022:         *       "This product includes software developed by the
0023:         *        Apache Software Foundation (http://www.apache.org/)."
0024:         *    Alternately, this acknowledgment may appear in the software itself,
0025:         *    if and wherever such third-party acknowledgments normally appear.
0026:         *
0027:         * 4. The names "Xerces" and "Apache Software Foundation" must
0028:         *    not be used to endorse or promote products derived from this
0029:         *    software without prior written permission. For written
0030:         *    permission, please contact apache@apache.org.
0031:         *
0032:         * 5. Products derived from this software may not be called "Apache",
0033:         *    nor may "Apache" appear in their name, without prior written
0034:         *    permission of the Apache Software Foundation.
0035:         *
0036:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0040:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047:         * SUCH DAMAGE.
0048:         * ====================================================================
0049:         *
0050:         * This software consists of voluntary contributions made by many
0051:         * individuals on behalf of the Apache Software Foundation and was
0052:         * originally based on software copyright (c) 1999, International
0053:         * Business Machines, Inc., http://www.apache.org.  For more
0054:         * information on the Apache Software Foundation, please see
0055:         * <http://www.apache.org/>.
0056:         */
0057:
0058:        package org.apache.xerces.parsers;
0059:
0060:        import java.io.IOException;
0061:        import java.util.Enumeration;
0062:        import java.util.Hashtable;
0063:        import java.util.StringTokenizer;
0064:
0065:        import org.apache.xerces.dom.TextImpl;
0066:        import org.apache.xerces.framework.XMLAttrList;
0067:        import org.apache.xerces.framework.XMLContentSpec;
0068:        import org.apache.xerces.framework.XMLDocumentHandler;
0069:        import org.apache.xerces.framework.XMLParser;
0070:        import org.apache.xerces.readers.XMLEntityHandler;
0071:        import org.apache.xerces.utils.QName;
0072:        import org.apache.xerces.utils.StringPool;
0073:        import org.apache.xerces.validators.common.XMLAttributeDecl;
0074:        import org.apache.xerces.validators.common.XMLElementDecl;
0075:        import org.apache.xerces.validators.schema.XUtil;
0076:        import org.apache.xerces.validators.schema.SchemaSymbols;
0077:
0078:        import org.apache.xerces.dom.DeferredDocumentImpl;
0079:        import org.apache.xerces.dom.DocumentImpl;
0080:        import org.apache.xerces.dom.DocumentTypeImpl;
0081:        import org.apache.xerces.dom.NodeImpl;
0082:        import org.apache.xerces.dom.EntityImpl;
0083:        import org.apache.xerces.dom.NotationImpl;
0084:        import org.apache.xerces.dom.ElementDefinitionImpl;
0085:        import org.apache.xerces.dom.AttrImpl;
0086:        import org.apache.xerces.dom.TextImpl;
0087:        import org.apache.xerces.dom.ElementImpl;
0088:        import org.apache.xerces.dom.EntityImpl;
0089:
0090:        import org.w3c.dom.Attr;
0091:        import org.w3c.dom.Comment;
0092:        import org.w3c.dom.Document;
0093:        import org.w3c.dom.DocumentType;
0094:        import org.w3c.dom.Element;
0095:        import org.w3c.dom.Entity;
0096:        import org.w3c.dom.EntityReference;
0097:        import org.w3c.dom.Node;
0098:        import org.w3c.dom.NodeList;
0099:        import org.w3c.dom.NamedNodeMap;
0100:        import org.w3c.dom.ProcessingInstruction;
0101:        import org.w3c.dom.Text;
0102:
0103:        import org.xml.sax.SAXException;
0104:        import org.xml.sax.SAXNotRecognizedException;
0105:        import org.xml.sax.SAXNotSupportedException;
0106:
0107:        /**
0108:         * DOMParser provides a parser which produces a W3C DOM tree as its output
0109:         *
0110:         *
0111:         * @version $Id: DOMParser.java,v 1.51 2001/07/09 19:29:09 sandygao Exp $
0112:         */
0113:        public class DOMParser extends XMLParser implements  XMLDocumentHandler {
0114:
0115:            //
0116:            // Constants
0117:            //
0118:
0119:            // public
0120:
0121:            /** Default programmatic document class name (org.apache.xerces.dom.DocumentImpl). */
0122:            public static final String DEFAULT_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.DocumentImpl";
0123:
0124:            /** Default deferred document class name (org.apache.xerces.dom.DeferredDocumentImpl). */
0125:            public static final String DEFAULT_DEFERRED_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.DeferredDocumentImpl";
0126:
0127:            // debugging
0128:
0129:            /** Set to true to debug attribute list declaration calls. */
0130:            private static final boolean DEBUG_ATTLIST_DECL = false;
0131:
0132:            // features and properties
0133:
0134:            /** Features recognized by this parser. */
0135:            private static final String RECOGNIZED_FEATURES[] = {
0136:                    // SAX2 core features
0137:                    // Xerces features
0138:                    "http://apache.org/xml/features/dom/defer-node-expansion",
0139:                    "http://apache.org/xml/features/dom/create-entity-ref-nodes",
0140:                    "http://apache.org/xml/features/dom/include-ignorable-whitespace",
0141:                    // Experimental features
0142:                    "http://apache.org/xml/features/domx/grammar-access", };
0143:
0144:            /** Properties recognized by this parser. */
0145:            private static final String RECOGNIZED_PROPERTIES[] = {
0146:                    // SAX2 core properties
0147:                    // Xerces properties
0148:                    "http://apache.org/xml/properties/dom/document-class-name",
0149:                    "http://apache.org/xml/properties/dom/current-element-node", };
0150:
0151:            //
0152:            // Data
0153:            //
0154:
0155:            // common data
0156:
0157:            protected Document fDocument;
0158:
0159:            // deferred expansion data
0160:
0161:            protected DeferredDocumentImpl fDeferredDocumentImpl;
0162:            protected int fDocumentIndex;
0163:            protected int fDocumentTypeIndex;
0164:            protected int fCurrentNodeIndex;
0165:
0166:            //DOM Level 3 WD - experimental
0167:
0168:            protected int fCurrentEntityName; //name of current entity reference
0169:            protected int fCurrentEntityNode; //index of entity node corresponding to current entity reference
0170:
0171:            // full expansion data
0172:
0173:            protected DocumentImpl fDocumentImpl;
0174:            protected DocumentType fDocumentType;
0175:            protected Node fCurrentElementNode;
0176:
0177:            // state
0178:
0179:            protected boolean fInDTD;
0180:            protected boolean fWithinElement;
0181:            protected boolean fInCDATA;
0182:
0183:            // features
0184:            private boolean fGrammarAccess;
0185:
0186:            // properties
0187:
0188:            // REVISIT: Even though these have setters and getters, should they
0189:            //          be protected visibility? -Ac
0190:            private String fDocumentClassName;
0191:            private boolean fDeferNodeExpansion;
0192:            private boolean fCreateEntityReferenceNodes;
0193:            private boolean fIncludeIgnorableWhitespace;
0194:
0195:            // built-in entities
0196:
0197:            protected int fAmpIndex;
0198:            protected int fLtIndex;
0199:            protected int fGtIndex;
0200:            protected int fAposIndex;
0201:            protected int fQuotIndex;
0202:
0203:            private boolean fSeenRootElement;
0204:
0205:            private boolean fStringPoolInUse;
0206:
0207:            private XMLAttrList fAttrList;
0208:
0209:            //
0210:            // Constructors
0211:            //
0212:
0213:            /** Default constructor. */
0214:            public DOMParser() {
0215:
0216:                initHandlers(false, this , this );
0217:
0218:                // setup parser state
0219:                init();
0220:
0221:                // set default values
0222:                try {
0223:                    setDocumentClassName(DEFAULT_DOCUMENT_CLASS_NAME);
0224:                    setCreateEntityReferenceNodes(true);
0225:                    setDeferNodeExpansion(true);
0226:                    setIncludeIgnorableWhitespace(true);
0227:                } catch (SAXException e) {
0228:                    throw new RuntimeException(
0229:                            "PAR001 Fatal error constructing DOMParser.");
0230:                }
0231:
0232:            } // <init>()
0233:
0234:            //
0235:            // Public methods
0236:            //
0237:
0238:            // document
0239:
0240:            /** Returns the document. */
0241:            public Document getDocument() {
0242:                return fDocument;
0243:            }
0244:
0245:            // features and properties
0246:
0247:            /**
0248:             * Returns a list of features that this parser recognizes.
0249:             * This method will never return null; if no features are
0250:             * recognized, this method will return a zero length array.
0251:             *
0252:             * @see #isFeatureRecognized
0253:             * @see #setFeature
0254:             * @see #getFeature
0255:             */
0256:            public String[] getFeaturesRecognized() {
0257:
0258:                // get features that super/this recognizes
0259:                String super Recognized[] = super .getFeaturesRecognized();
0260:                String this Recognized[] = RECOGNIZED_FEATURES;
0261:
0262:                // is one or the other the empty set?
0263:                int this Length = this Recognized.length;
0264:                if (this Length == 0) {
0265:                    return super Recognized;
0266:                }
0267:                int super Length = super Recognized.length;
0268:                if (super Length == 0) {
0269:                    return this Recognized;
0270:                }
0271:
0272:                // combine the two lists and return
0273:                String recognized[] = new String[super Length + this Length];
0274:                System
0275:                        .arraycopy(super Recognized, 0, recognized, 0,
0276:                                super Length);
0277:                System.arraycopy(this Recognized, 0, recognized, super Length,
0278:                        this Length);
0279:                return recognized;
0280:
0281:            } // getFeaturesRecognized():String[]
0282:
0283:            /**
0284:             * Returns a list of properties that this parser recognizes.
0285:             * This method will never return null; if no properties are
0286:             * recognized, this method will return a zero length array.
0287:             *
0288:             * @see #isPropertyRecognized
0289:             * @see #setProperty
0290:             * @see #getProperty
0291:             */
0292:            public String[] getPropertiesRecognized() {
0293:
0294:                // get properties that super/this recognizes
0295:                String super Recognized[] = super .getPropertiesRecognized();
0296:                String this Recognized[] = RECOGNIZED_PROPERTIES;
0297:
0298:                // is one or the other the empty set?
0299:                int this Length = this Recognized.length;
0300:                if (this Length == 0) {
0301:                    return super Recognized;
0302:                }
0303:                int super Length = super Recognized.length;
0304:                if (super Length == 0) {
0305:                    return this Recognized;
0306:                }
0307:
0308:                // combine the two lists and return
0309:                String recognized[] = new String[super Length + this Length];
0310:                System
0311:                        .arraycopy(super Recognized, 0, recognized, 0,
0312:                                super Length);
0313:                System.arraycopy(this Recognized, 0, recognized, super Length,
0314:                        this Length);
0315:                return recognized;
0316:
0317:            }
0318:
0319:            // resetting
0320:
0321:            /** Resets the parser. */
0322:            public void reset() throws Exception {
0323:                if (fStringPoolInUse) {
0324:                    // we can't reuse the string pool, let's create another one
0325:                    fStringPool = new StringPool();
0326:                    fStringPoolInUse = false;
0327:                }
0328:                super .reset();
0329:                init();
0330:            }
0331:
0332:            /** Resets or copies the parser. */
0333:            public void resetOrCopy() throws Exception {
0334:                super .resetOrCopy();
0335:                init();
0336:            }
0337:
0338:            //
0339:            // Protected methods
0340:            //
0341:
0342:            // initialization
0343:
0344:            /**
0345:             * Initializes the parser to a pre-parse state. This method is
0346:             * called between calls to <code>parse()</code>.
0347:             */
0348:            protected void init() {
0349:
0350:                // init common
0351:                fDocument = null;
0352:
0353:                // init deferred expansion
0354:                fDeferredDocumentImpl = null;
0355:                fDocumentIndex = -1;
0356:                fDocumentTypeIndex = -1;
0357:                fCurrentNodeIndex = -1;
0358:
0359:                //DOM Level 3 WD - experimental
0360:                fCurrentEntityNode = -1;
0361:                fCurrentEntityName = -1;
0362:
0363:                // init full expansion
0364:                fDocumentImpl = null;
0365:                fDocumentType = null;
0366:                fCurrentElementNode = null;
0367:
0368:                // state
0369:                fInDTD = false;
0370:                fWithinElement = false;
0371:                fInCDATA = false;
0372:
0373:                // built-in entities
0374:                fAmpIndex = fStringPool.addSymbol("amp");
0375:                fLtIndex = fStringPool.addSymbol("lt");
0376:                fGtIndex = fStringPool.addSymbol("gt");
0377:                fAposIndex = fStringPool.addSymbol("apos");
0378:                fQuotIndex = fStringPool.addSymbol("quot");
0379:
0380:                fSeenRootElement = false;
0381:                fStringPoolInUse = false;
0382:
0383:                fAttrList = new XMLAttrList(fStringPool);
0384:
0385:            } // init()
0386:
0387:            // features
0388:
0389:            /**
0390:             * This method sets whether the expansion of the nodes in the default
0391:             * DOM implementation are deferred.
0392:             *
0393:             * @see #getDeferNodeExpansion
0394:             * @see #setDocumentClassName
0395:             */
0396:            protected void setDeferNodeExpansion(boolean deferNodeExpansion)
0397:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0398:                fDeferNodeExpansion = deferNodeExpansion;
0399:            }
0400:
0401:            /**
0402:             * Returns true if the expansion of the nodes in the default DOM
0403:             * implementation are deferred.
0404:             *
0405:             * @see #setDeferNodeExpansion
0406:             */
0407:            protected boolean getDeferNodeExpansion()
0408:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0409:                return fDeferNodeExpansion;
0410:            }
0411:
0412:            /**
0413:             * This feature determines whether entity references within
0414:             * the document are included in the document tree as
0415:             * EntityReference nodes.
0416:             * <p>
0417:             * Note: The children of the entity reference are always
0418:             * added to the document. This feature only affects
0419:             * whether an EntityReference node is also included
0420:             * as the parent of the entity reference children.
0421:             *
0422:             * @param create True to create entity reference nodes; false
0423:             *               to only insert the entity reference children.
0424:             *
0425:             * @see #getCreateEntityReferenceNodes
0426:             */
0427:            protected void setCreateEntityReferenceNodes(boolean create)
0428:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0429:                fCreateEntityReferenceNodes = create;
0430:            }
0431:
0432:            /**
0433:             * Returns true if entity references within the document are
0434:             * included in the document tree as EntityReference nodes.
0435:             *
0436:             * @see #setCreateEntityReferenceNodes
0437:             */
0438:            public boolean getCreateEntityReferenceNodes()
0439:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0440:                return fCreateEntityReferenceNodes;
0441:            }
0442:
0443:            /**
0444:             * This feature determines whether text nodes that can be
0445:             * considered "ignorable whitespace" are included in the DOM
0446:             * tree.
0447:             * <p>
0448:             * Note: The only way that the parser can determine if text
0449:             * is ignorable is by reading the associated grammar
0450:             * and having a content model for the document. When
0451:             * ignorable whitespace text nodes *are* included in
0452:             * the DOM tree, they will be flagged as ignorable.
0453:             * The ignorable flag can be queried by calling the
0454:             * TextImpl#isIgnorableWhitespace():boolean method.
0455:             *
0456:             * @param include True to include ignorable whitespace text nodes;
0457:             *                false to not include ignorable whitespace text
0458:             *                nodes.
0459:             *
0460:             * @see #getIncludeIgnorableWhitespace
0461:             */
0462:            public void setIncludeIgnorableWhitespace(boolean include)
0463:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0464:                fIncludeIgnorableWhitespace = include;
0465:            }
0466:
0467:            /**
0468:             * Returns true if ignorable whitespace text nodes are included
0469:             * in the DOM tree.
0470:             *
0471:             * @see #setIncludeIgnorableWhitespace
0472:             */
0473:            public boolean getIncludeIgnorableWhitespace()
0474:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0475:                return fIncludeIgnorableWhitespace;
0476:            }
0477:
0478:            // properties
0479:
0480:            /**
0481:             * This method allows the programmer to decide which document
0482:             * factory to use when constructing the DOM tree. However, doing
0483:             * so will lose the functionality of the default factory. Also,
0484:             * a document class other than the default will lose the ability
0485:             * to defer node expansion on the DOM tree produced.
0486:             *
0487:             * @param documentClassName The fully qualified class name of the
0488:             *                      document factory to use when constructing
0489:             *                      the DOM tree.
0490:             *
0491:             * @see #getDocumentClassName
0492:             * @see #setDeferNodeExpansion
0493:             * @see #DEFAULT_DOCUMENT_CLASS_NAME
0494:             */
0495:            protected void setDocumentClassName(String documentClassName)
0496:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0497:
0498:                // normalize class name
0499:                if (documentClassName == null) {
0500:                    documentClassName = DEFAULT_DOCUMENT_CLASS_NAME;
0501:                }
0502:
0503:                // verify that this class exists and is of the right type
0504:                try {
0505:                    Class _class = Class.forName(documentClassName);
0506:                    //if (!_class.isAssignableFrom(Document.class)) {
0507:                    if (!Document.class.isAssignableFrom(_class)) {
0508:                        throw new IllegalArgumentException("PAR002 Class, \""
0509:                                + documentClassName
0510:                                + "\", is not of type org.w3c.dom.Document."
0511:                                + "\n" + documentClassName);
0512:                    }
0513:                } catch (ClassNotFoundException e) {
0514:                    throw new IllegalArgumentException("PAR003 Class, \""
0515:                            + documentClassName + "\", not found." + "\n"
0516:                            + documentClassName);
0517:                }
0518:
0519:                // set document class name
0520:                fDocumentClassName = documentClassName;
0521:                if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)) {
0522:                    setDeferNodeExpansion(false);
0523:                }
0524:
0525:            } // setDocumentClassName(String)
0526:
0527:            /**
0528:             * Returns the fully qualified class name of the document factory
0529:             * used when constructing the DOM tree.
0530:             *
0531:             * @see #setDocumentClassName
0532:             */
0533:            protected String getDocumentClassName()
0534:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0535:                return fDocumentClassName;
0536:            }
0537:
0538:            /**
0539:             * Returns the current element node.
0540:             * <p>
0541:             * Note: This method is not supported when the "deferNodeExpansion"
0542:             *       property is set to true and the document factory is set to
0543:             *       the default factory.
0544:             */
0545:            protected Element getCurrentElementNode()
0546:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0547:
0548:                if (fCurrentElementNode != null
0549:                        && fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
0550:                    return (Element) fCurrentElementNode;
0551:                }
0552:                return null;
0553:
0554:            } // getCurrentElementNode():Element
0555:
0556:            //
0557:            // Configurable methods
0558:            //
0559:
0560:            /**
0561:             * Set the state of any feature in a SAX2 parser.  The parser
0562:             * might not recognize the feature, and if it does recognize
0563:             * it, it might not be able to fulfill the request.
0564:             *
0565:             * @param featureId The unique identifier (URI) of the feature.
0566:             * @param state The requested state of the feature (true or false).
0567:             *
0568:             * @exception SAXNotRecognizedException If the requested feature is
0569:             *                                      not known.
0570:             * @exception SAXNotSupportedException If the requested feature is
0571:             *                                     known, but the requested state
0572:             *                                     is not supported.
0573:             */
0574:            public void setFeature(String featureId, boolean state)
0575:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0576:
0577:                //
0578:                // SAX2 core features
0579:                //
0580:
0581:                if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
0582:                    //
0583:                    // No additional SAX properties defined for DOMParser.
0584:                    // Pass request off to XMLParser for the common cases.
0585:                    //
0586:                }
0587:
0588:                //
0589:                // Xerces features
0590:                //
0591:
0592:                else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
0593:                    String feature = featureId.substring(XERCES_FEATURES_PREFIX
0594:                            .length());
0595:                    //
0596:                    // http://apache.org/xml/features/dom/defer-node-expansion
0597:                    //   Allows the document tree returned by getDocument()
0598:                    //   to be constructed lazily. In other words, the DOM
0599:                    //   nodes are constructed as the tree is traversed.
0600:                    //   This allows the document to be returned sooner with
0601:                    //   the expense of holding all of the blocks of character
0602:                    //   data held in memory. Then again, lots of DOM nodes
0603:                    //   use a lot of memory as well.
0604:                    //
0605:                    if (feature.equals("dom/defer-node-expansion")) {
0606:                        if (fParseInProgress) {
0607:                            throw new SAXNotSupportedException(
0608:                                    "PAR004 Cannot setFeature(" + featureId
0609:                                            + "): parse is in progress." + "\n"
0610:                                            + featureId);
0611:                        }
0612:                        setDeferNodeExpansion(state);
0613:                        return;
0614:                    }
0615:                    //
0616:                    // http://apache.org/xml/features/dom/create-entity-ref-nodes
0617:                    //   This feature determines whether entity references within
0618:                    //   the document are included in the document tree as
0619:                    //   EntityReference nodes.
0620:                    //   Note: The children of the entity reference are always
0621:                    //         added to the document. This feature only affects
0622:                    //         whether an EntityReference node is also included
0623:                    //         as the parent of the entity reference children.
0624:                    //
0625:                    if (feature.equals("dom/create-entity-ref-nodes")) {
0626:                        setCreateEntityReferenceNodes(state);
0627:                        return;
0628:                    }
0629:
0630:                    //
0631:                    // http://apache.org/xml/features/dom/include-ignorable-whitespace
0632:                    //   This feature determines whether text nodes that can be
0633:                    //   considered "ignorable whitespace" are included in the DOM
0634:                    //   tree.
0635:                    //   Note: The only way that the parser can determine if text
0636:                    //         is ignorable is by reading the associated grammar
0637:                    //         and having a content model for the document. When
0638:                    //         ignorable whitespace text nodes *are* included in
0639:                    //         the DOM tree, they will be flagged as ignorable.
0640:                    //         The ignorable flag can be queried by calling the
0641:                    //         TextImpl#isIgnorableWhitespace():boolean method.
0642:                    //
0643:                    if (feature.equals("dom/include-ignorable-whitespace")) {
0644:                        setIncludeIgnorableWhitespace(state);
0645:                        return;
0646:                    }
0647:
0648:                    //
0649:                    // Experimental features
0650:                    //
0651:
0652:                    //
0653:                    // http://apache.org/xml/features/domx/grammar-access
0654:                    //   Allows grammar access in the DOM tree. Currently, this
0655:                    //   means that there is an XML Schema document tree as a
0656:                    //   child of the Doctype node.
0657:                    //
0658:                    if (feature.equals("domx/grammar-access")) {
0659:                        fGrammarAccess = state;
0660:                        return;
0661:                    }
0662:
0663:                    //
0664:                    // Pass request off to XMLParser for the common cases.
0665:                    //
0666:                }
0667:
0668:                //
0669:                // Pass request off to XMLParser for the common cases.
0670:                //
0671:                super .setFeature(featureId, state);
0672:
0673:            } // setFeature(String,boolean)
0674:
0675:            /**
0676:             * Query the current state of any feature in a SAX2 parser.  The
0677:             * parser might not recognize the feature.
0678:             *
0679:             * @param featureId The unique identifier (URI) of the feature
0680:             *                  being set.
0681:             *
0682:             * @return The current state of the feature.
0683:             *
0684:             * @exception SAXNotRecognizedException If the requested feature is
0685:             *                                      not known.
0686:             */
0687:            public boolean getFeature(String featureId)
0688:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0689:
0690:                //
0691:                // SAX2 core features
0692:                //
0693:
0694:                if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
0695:                    //
0696:                    // No additional SAX properties defined for DOMParser.
0697:                    // Pass request off to XMLParser for the common cases.
0698:                    //
0699:                }
0700:
0701:                //
0702:                // Xerces features
0703:                //
0704:
0705:                else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
0706:                    String feature = featureId.substring(XERCES_FEATURES_PREFIX
0707:                            .length());
0708:                    //
0709:                    // http://apache.org/xml/features/dom/defer-node-expansion
0710:                    //   Allows the document tree returned by getDocument()
0711:                    //   to be constructed lazily. In other words, the DOM
0712:                    //   nodes are constructed as the tree is traversed.
0713:                    //   This allows the document to be returned sooner with
0714:                    //   the expense of holding all of the blocks of character
0715:                    //   data held in memory. Then again, lots of DOM nodes
0716:                    //   use a lot of memory as well.
0717:                    //
0718:                    if (feature.equals("dom/defer-node-expansion")) {
0719:                        return getDeferNodeExpansion();
0720:                    }
0721:                    //
0722:                    // http://apache.org/xml/features/dom/create-entity-ref-nodes
0723:                    //   This feature determines whether entity references within
0724:                    //   the document are included in the document tree as
0725:                    //   EntityReference nodes.
0726:                    //   Note: The children of the entity reference are always
0727:                    //         added to the document. This feature only affects
0728:                    //         whether an EntityReference node is also included
0729:                    //         as the parent of the entity reference children.
0730:                    //
0731:                    else if (feature.equals("dom/create-entity-ref-nodes")) {
0732:                        return getCreateEntityReferenceNodes();
0733:                    }
0734:
0735:                    //
0736:                    // http://apache.org/xml/features/dom/include-ignorable-whitespace
0737:                    //   This feature determines whether text nodes that can be
0738:                    //   considered "ignorable whitespace" are included in the DOM
0739:                    //   tree.
0740:                    //   Note: The only way that the parser can determine if text
0741:                    //         is ignorable is by reading the associated grammar
0742:                    //         and having a content model for the document. When
0743:                    //         ignorable whitespace text nodes *are* included in
0744:                    //         the DOM tree, they will be flagged as ignorable.
0745:                    //         The ignorable flag can be queried by calling the
0746:                    //         TextImpl#isIgnorableWhitespace():boolean method.
0747:                    //
0748:                    if (feature.equals("dom/include-ignorable-whitespace")) {
0749:                        return getIncludeIgnorableWhitespace();
0750:                    }
0751:
0752:                    //
0753:                    // Experimental features
0754:                    //
0755:
0756:                    //
0757:                    // http://apache.org/xml/features/domx/grammar-access
0758:                    //   Allows grammar access in the DOM tree. Currently, this
0759:                    //   means that there is an XML Schema document tree as a
0760:                    //   child of the Doctype node.
0761:                    //
0762:                    if (feature.equals("domx/grammar-access")) {
0763:                        return fGrammarAccess;
0764:                    }
0765:
0766:                    //
0767:                    // Pass request off to XMLParser for the common cases.
0768:                    //
0769:                }
0770:
0771:                //
0772:                // Pass request off to XMLParser for the common cases.
0773:                //
0774:                return super .getFeature(featureId);
0775:
0776:            } // getFeature(String):boolean
0777:
0778:            /**
0779:             * Set the value of any property in a SAX2 parser.  The parser
0780:             * might not recognize the property, and if it does recognize
0781:             * it, it might not support the requested value.
0782:             *
0783:             * @param propertyId The unique identifier (URI) of the property
0784:             *                   being set.
0785:             * @param Object The value to which the property is being set.
0786:             *
0787:             * @exception SAXNotRecognizedException If the requested property is
0788:             *                                      not known.
0789:             * @exception SAXNotSupportedException If the requested property is
0790:             *                                     known, but the requested
0791:             *                                     value is not supported.
0792:             */
0793:            public void setProperty(String propertyId, Object value)
0794:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0795:
0796:                //
0797:                // Xerces properties
0798:                //
0799:
0800:                if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
0801:                    String property = propertyId
0802:                            .substring(XERCES_PROPERTIES_PREFIX.length());
0803:                    //
0804:                    // http://apache.org/xml/properties/dom/current-element-node
0805:                    //   Returns the current element node as the DOM Parser is
0806:                    //   parsing. This property is useful for determining the
0807:                    //   relative location of the document when an error is
0808:                    //   encountered. Note that this feature does *not* work
0809:                    //   when the http://apache.org/xml/features/dom/defer-node-expansion
0810:                    //   is set to true.
0811:                    //
0812:                    if (property.equals("dom/current-element-node")) {
0813:                        throw new SAXNotSupportedException(
0814:                                "PAR005 Property, \"" + propertyId
0815:                                        + "\" is read-only.\n" + propertyId);
0816:                    }
0817:                    //
0818:                    // http://apache.org/xml/properties/dom/document-class-name
0819:                    //   This property can be used to set/query the name of the
0820:                    //   document factory.
0821:                    //
0822:                    else if (property.equals("dom/document-class-name")) {
0823:                        if (value != null && !(value instanceof  String)) {
0824:                            throw new SAXNotSupportedException(
0825:                                    "PAR006 Property value must be of type java.lang.String.");
0826:                        }
0827:                        setDocumentClassName((String) value);
0828:                        return;
0829:                    }
0830:                }
0831:
0832:                //
0833:                // Pass request off to XMLParser for the common cases.
0834:                //
0835:                super .setProperty(propertyId, value);
0836:
0837:            } // setProperty(String,Object)
0838:
0839:            /**
0840:             * Return the current value of a property in a SAX2 parser.
0841:             * The parser might not recognize the property.
0842:             *
0843:             * @param propertyId The unique identifier (URI) of the property
0844:             *                   being set.
0845:             *
0846:             * @return The current value of the property.
0847:             *
0848:             * @exception SAXNotRecognizedException If the requested property is
0849:             *                                      not known.
0850:             *
0851:             * @see Configurable#getProperty
0852:             */
0853:            public Object getProperty(String propertyId)
0854:                    throws SAXNotRecognizedException, SAXNotSupportedException {
0855:
0856:                //
0857:                // Xerces properties
0858:                //
0859:
0860:                if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
0861:                    String property = propertyId
0862:                            .substring(XERCES_PROPERTIES_PREFIX.length());
0863:                    //
0864:                    // http://apache.org/xml/properties/dom/current-element-node
0865:                    //   Returns the current element node as the DOM Parser is
0866:                    //   parsing. This property is useful for determining the
0867:                    //   relative location of the document when an error is
0868:                    //   encountered. Note that this feature does *not* work
0869:                    //   when the http://apache.org/xml/features/dom/defer-node-expansion
0870:                    //   is set to true.
0871:                    //
0872:                    if (property.equals("dom/current-element-node")) {
0873:                        boolean throwException = false;
0874:                        try {
0875:                            throwException = getFeature(XERCES_FEATURES_PREFIX
0876:                                    + "dom/defer-node-expansion");
0877:                        } catch (SAXNotSupportedException e) {
0878:                            // ignore
0879:                        } catch (SAXNotRecognizedException e) {
0880:                            // ignore
0881:                        }
0882:                        if (throwException) {
0883:                            throw new SAXNotSupportedException(
0884:                                    "PAR007 Current element node cannot be queried when node expansion is deferred.");
0885:                        }
0886:                        return getCurrentElementNode();
0887:                    }
0888:                    //
0889:                    // http://apache.org/xml/properties/dom/document-class-name
0890:                    //   This property can be used to set/query the name of the
0891:                    //   document factory.
0892:                    //
0893:                    else if (property.equals("dom/document-class-name")) {
0894:                        return getDocumentClassName();
0895:                    }
0896:                }
0897:
0898:                //
0899:                // Pass request off to XMLParser for the common cases.
0900:                //
0901:                return super .getProperty(propertyId);
0902:
0903:            } // getProperty(String):Object
0904:
0905:            //
0906:            // XMLParser methods
0907:            //
0908:
0909:            /** Start document. */
0910:            public void startDocument() {
0911:
0912:                // deferred expansion
0913:                String documentClassName = null;
0914:                try {
0915:                    documentClassName = getDocumentClassName();
0916:                } catch (SAXException e) {
0917:                    throw new RuntimeException(
0918:                            "PAR008 Fatal error getting document factory.");
0919:                }
0920:                boolean deferNodeExpansion = true;
0921:                try {
0922:                    deferNodeExpansion = getDeferNodeExpansion();
0923:                } catch (SAXException e) {
0924:                    throw new RuntimeException(
0925:                            "PAR009 Fatal error reading expansion mode.");
0926:                }
0927:                try {
0928:                    boolean isDocumentImpl = fDocumentClassName
0929:                            .equals(DEFAULT_DOCUMENT_CLASS_NAME);
0930:                    boolean isDeferredImpl = fDocumentClassName
0931:                            .equals(DEFAULT_DEFERRED_DOCUMENT_CLASS_NAME);
0932:                    if (deferNodeExpansion
0933:                            && (isDocumentImpl || isDeferredImpl)) {
0934:                        boolean nsEnabled = false;
0935:                        try {
0936:                            nsEnabled = getNamespaces();
0937:                        } catch (SAXException s) {
0938:                        }
0939:                        fDeferredDocumentImpl = new DeferredDocumentImpl(
0940:                                fStringPool, nsEnabled, fGrammarAccess);
0941:                        fStringPoolInUse = true;
0942:                        fDocument = fDeferredDocumentImpl;
0943:                        fDocumentIndex = fDeferredDocumentImpl.createDocument();
0944:                        fCurrentNodeIndex = fDocumentIndex;
0945:                    }
0946:
0947:                    // full expansion
0948:                    else {
0949:                        if (isDocumentImpl) {
0950:                            fDocumentImpl = new DocumentImpl(fGrammarAccess);
0951:                            fDocument = fDocumentImpl;
0952:                            // set DOM error checking off
0953:                            fDocumentImpl.setErrorChecking(false);
0954:                        } else {
0955:                            Class documentClass = Class
0956:                                    .forName(documentClassName);
0957:                            try {
0958:                                fDocument = (Document) documentClass
0959:                                        .newInstance();
0960:                            } catch (Exception e) {
0961:                                // REVISIT: Localize this message.
0962:                                throw new RuntimeException(
0963:                                        "Failed to create document object of class: "
0964:                                                + documentClassName);
0965:                            }
0966:                            // if subclass of our own class that's cool too
0967:                            Class defaultDocClass = Class
0968:                                    .forName(DEFAULT_DOCUMENT_CLASS_NAME);
0969:                            if (defaultDocClass.isAssignableFrom(documentClass)) {
0970:                                fDocumentImpl = (DocumentImpl) fDocument;
0971:                                // set DOM error checking off
0972:                                fDocumentImpl.setErrorChecking(false);
0973:                            }
0974:                        }
0975:                        fCurrentElementNode = fDocument;
0976:                    }
0977:                } catch (ClassNotFoundException e) {
0978:                    // REVISIT: Localize this message.
0979:                    throw new RuntimeException(documentClassName);
0980:                }
0981:
0982:            } // startDocument()
0983:
0984:            /** End document. */
0985:            public void endDocument() throws Exception {
0986:                // set DOM error checking back on
0987:                if (fDocumentImpl != null) {
0988:                    fDocumentImpl.setErrorChecking(true);
0989:
0990:                    if (fDocumentType != null) {
0991:                        // set entities and notations read_only per DOM spec
0992:                        ((DocumentTypeImpl) fDocumentType).setReadOnly(true,
0993:                                false);
0994:                    }
0995:                }
0996:            }
0997:
0998:            /** XML declaration. */
0999:            public void xmlDecl(int versionIndex, int encodingIndex,
1000:                    int standaloneIndex) throws Exception {
1001:                boolean standalone = (standaloneIndex != -1) ? (fStringPool
1002:                        .toString(standaloneIndex).equals("yes")) ? true
1003:                        : false : false;
1004:                if (fDocumentImpl != null) { //full node expansion
1005:                    fDocumentImpl
1006:                            .setVersion(fStringPool.toString(versionIndex));
1007:                    fDocumentImpl.setEncoding(fStringPool
1008:                            .toString(encodingIndex));
1009:                    fDocumentImpl.setStandalone(standalone);
1010:                } else if (fDeferredDocumentImpl != null) {
1011:                    fDeferredDocumentImpl.setVersion(fStringPool
1012:                            .toString(versionIndex));
1013:                    fDeferredDocumentImpl.setEncoding(fStringPool
1014:                            .toString(encodingIndex));
1015:                    fDeferredDocumentImpl.setStandalone(standalone);
1016:                } else {
1017:                    //non xerces implementation
1018:                }
1019:
1020:            }
1021:
1022:            /** Text declaration.
1023:             * added DOM Level 3 WD support - experimental
1024:             */
1025:            public void textDecl(int versionIndex, int encodingIndex)
1026:                    throws Exception {
1027:                if (fDeferredDocumentImpl != null) {
1028:                    String name = fStringPool.toString(fCurrentEntityName);
1029:                    // we only support one context for entity references (name !=null)
1030:                    if (fDocumentTypeIndex != -1 && name != null) {
1031:                        // find Entity decl for fCurrentEntityName.
1032:                        int entityDecl = fDeferredDocumentImpl.getLastChild(
1033:                                fDocumentTypeIndex, false);
1034:                        while (entityDecl != -1) {
1035:                            if (fDeferredDocumentImpl.getNodeType(entityDecl,
1036:                                    false) == Node.ENTITY_NODE
1037:                                    && fDeferredDocumentImpl.getNodeNameString(
1038:                                            entityDecl, false).equals(name)) {
1039:                                break;
1040:                            }
1041:                            entityDecl = fDeferredDocumentImpl.getPrevSibling(
1042:                                    entityDecl, false);
1043:                        }
1044:                        fCurrentEntityNode = entityDecl;
1045:                        fDeferredDocumentImpl.setEntityInfo(entityDecl,
1046:                                versionIndex, encodingIndex);
1047:                    }
1048:                }
1049:                // full node expansion
1050:                else if (fDocumentImpl != null) {
1051:                    NamedNodeMap entities = fDocumentType.getEntities();
1052:                    if (entities != null) {
1053:                        EntityImpl entityNode = (EntityImpl) entities
1054:                                .getNamedItem(fCurrentElementNode.getNodeName());
1055:                        if (entityNode != null) {
1056:                            entityNode.setVersion(fStringPool
1057:                                    .toString(versionIndex));
1058:                            entityNode.setEncoding(fStringPool
1059:                                    .toString(encodingIndex));
1060:                        }
1061:                    }
1062:                } else {
1063:                    //non xerces implementation
1064:                }
1065:            }
1066:
1067:            /** Report the start of the scope of a namespace declaration. */
1068:            public void startNamespaceDeclScope(int prefix, int uri)
1069:                    throws Exception {
1070:            }
1071:
1072:            /** Report the end of the scope of a namespace declaration. */
1073:            public void endNamespaceDeclScope(int prefix) throws Exception {
1074:            }
1075:
1076:            /** Start element. */
1077:            public void startElement(QName elementQName,
1078:                    XMLAttrList xmlAttrList, int attrListIndex)
1079:                    throws Exception {
1080:
1081:                // deferred expansion
1082:                if (fDeferredDocumentImpl != null) {
1083:
1084:                    // copy schema grammar, if needed
1085:                    if (!fSeenRootElement) {
1086:                        fSeenRootElement = true;
1087:                        // REVISIT: How do we know which grammar is in use?
1088:                        //Document schemaDocument = fValidator.getSchemaDocument();
1089:                        if (fGrammarAccess && fGrammarResolver.size() > 0) {
1090:                            if (fDocumentTypeIndex == -1) {
1091:                                fDocumentTypeIndex = fDeferredDocumentImpl
1092:                                        .createDocumentType(
1093:                                                elementQName.rawname, -1, -1);
1094:                                fDeferredDocumentImpl.appendChild(0,
1095:                                        fDocumentTypeIndex);
1096:                            }
1097:                            Enumeration schemas = fGrammarResolver
1098:                                    .nameSpaceKeys();
1099:                            Document schemaDocument = fGrammarResolver
1100:                                    .getGrammar((String) schemas.nextElement())
1101:                                    .getGrammarDocument();
1102:                            if (schemaDocument != null) {
1103:                                Element schema = schemaDocument
1104:                                        .getDocumentElement();
1105:                                copyInto(schema, fDocumentTypeIndex);
1106:                            }
1107:                        }
1108:                    }
1109:
1110:                    int element = fDeferredDocumentImpl.createElement(
1111:                            elementQName.rawname, elementQName.uri,
1112:                            xmlAttrList, attrListIndex);
1113:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
1114:                            element);
1115:                    fCurrentNodeIndex = element;
1116:                    fWithinElement = true;
1117:
1118:                    // identifier registration
1119:                    int index = xmlAttrList.getFirstAttr(attrListIndex);
1120:                    while (index != -1) {
1121:                        if (xmlAttrList.getAttType(index) == fStringPool
1122:                                .addSymbol("ID")) {
1123:                            int nameIndex = xmlAttrList.getAttValue(index);
1124:                            fDeferredDocumentImpl.putIdentifier(nameIndex,
1125:                                    element);
1126:                        }
1127:                        index = xmlAttrList.getNextAttr(index);
1128:                    }
1129:                }
1130:
1131:                // full expansion
1132:                else {
1133:
1134:                    boolean nsEnabled = false;
1135:                    try {
1136:                        nsEnabled = getNamespaces();
1137:                    } catch (SAXException s) {
1138:                    }
1139:
1140:                    String elementName = fStringPool
1141:                            .toString(elementQName.rawname);
1142:
1143:                    // copy schema grammar, if needed
1144:                    if (!fSeenRootElement) {
1145:                        fSeenRootElement = true;
1146:                        if (fDocumentImpl != null && fGrammarAccess
1147:                                && fGrammarResolver.size() > 0) {
1148:                            if (fDocumentType == null) {
1149:                                String rootName = elementName;
1150:                                String systemId = ""; // REVISIT: How do we get this value? -Ac
1151:                                String publicId = ""; // REVISIT: How do we get this value? -Ac
1152:                                fDocumentType = fDocumentImpl
1153:                                        .createDocumentType(rootName, publicId,
1154:                                                systemId);
1155:                                fDocument.appendChild(fDocumentType);
1156:                                // REVISIT: We could use introspection to get the
1157:                                //          DOMImplementation#createDocumentType method
1158:                                //          for DOM Level 2 implementations. The only
1159:                                //          problem is that the owner document for the
1160:                                //          node created is null. How does it get set
1161:                                //          for document when appended? A cursory look
1162:                                //          at the DOM Level 2 CR didn't yield any
1163:                                //          information. -Ac
1164:                            }
1165:                            Enumeration schemas = fGrammarResolver
1166:                                    .nameSpaceKeys();
1167:                            Document schemaDocument = fGrammarResolver
1168:                                    .getGrammar((String) schemas.nextElement())
1169:                                    .getGrammarDocument();
1170:                            if (schemaDocument != null) {
1171:                                Element schema = schemaDocument
1172:                                        .getDocumentElement();
1173:                                XUtil.copyInto(schema, fDocumentType);
1174:                            }
1175:                        }
1176:                    }
1177:
1178:                    Element e;
1179:                    if (nsEnabled) {
1180:                        String namespaceURI = fStringPool
1181:                                .toString(elementQName.uri);
1182:                        // hide the fact that our parser uses an empty string for null
1183:                        if (namespaceURI.length() == 0) {
1184:                            namespaceURI = null;
1185:                        }
1186:                        e = fDocument
1187:                                .createElementNS(namespaceURI, elementName);
1188:                    } else {
1189:                        e = fDocument.createElement(elementName);
1190:                    }
1191:                    int attrHandle = xmlAttrList.getFirstAttr(attrListIndex);
1192:                    while (attrHandle != -1) {
1193:                        int attName = xmlAttrList.getAttrName(attrHandle);
1194:                        String attrName = fStringPool.toString(attName);
1195:                        String attrValue = fStringPool.toString(xmlAttrList
1196:                                .getAttValue(attrHandle));
1197:                        if (nsEnabled) {
1198:                            int nsURIIndex = xmlAttrList.getAttrURI(attrHandle);
1199:                            String namespaceURI = fStringPool
1200:                                    .toString(nsURIIndex);
1201:                            // DOM Level 2 wants all namespace declaration attributes
1202:                            // to be bound to "http://www.w3.org/2000/xmlns/"
1203:                            // So as long as the XML parser doesn't do it, it needs to
1204:                            // done here.
1205:                            int prefixIndex = xmlAttrList
1206:                                    .getAttrPrefix(attrHandle);
1207:                            String prefix = fStringPool.toString(prefixIndex);
1208:                            // hide that our parser uses an empty string for null
1209:                            if (namespaceURI.length() == 0) {
1210:                                namespaceURI = null;
1211:                            }
1212:                            if (namespaceURI == null) {
1213:                                if (prefix != null) {
1214:                                    if (prefix.equals("xmlns")) {
1215:                                        namespaceURI = "http://www.w3.org/2000/xmlns/";
1216:                                    }
1217:                                } else if (attrName.equals("xmlns")) {
1218:                                    namespaceURI = "http://www.w3.org/2000/xmlns/";
1219:                                }
1220:                            }
1221:                            e.setAttributeNS(namespaceURI, attrName, attrValue);
1222:                        } else {
1223:                            e.setAttribute(attrName, attrValue);
1224:                        }
1225:                        if (fDocumentImpl != null
1226:                                && !xmlAttrList.isSpecified(attrHandle)) {
1227:                            ((AttrImpl) e.getAttributeNode(attrName))
1228:                                    .setSpecified(false);
1229:                        }
1230:                        attrHandle = xmlAttrList.getNextAttr(attrHandle);
1231:                    }
1232:                    fCurrentElementNode.appendChild(e);
1233:                    fCurrentElementNode = e;
1234:                    fWithinElement = true;
1235:
1236:                    // identifier registration
1237:                    if (fDocumentImpl != null) {
1238:                        int index = xmlAttrList.getFirstAttr(attrListIndex);
1239:                        while (index != -1) {
1240:                            if (xmlAttrList.getAttType(index) == fStringPool
1241:                                    .addSymbol("ID")) {
1242:                                String name = fStringPool.toString(xmlAttrList
1243:                                        .getAttValue(index));
1244:                                fDocumentImpl.putIdentifier(name, e);
1245:                            }
1246:                            index = xmlAttrList.getNextAttr(index);
1247:                        }
1248:                    }
1249:
1250:                    // release attributes
1251:                    xmlAttrList.releaseAttrList(attrListIndex);
1252:                }
1253:
1254:            } // startElement(QName,XMLAttrList,int)
1255:
1256:            /** End element. */
1257:            public void endElement(QName elementQName) throws Exception {
1258:
1259:                // deferred node expansion
1260:                if (fDeferredDocumentImpl != null) {
1261:                    fCurrentNodeIndex = fDeferredDocumentImpl.getParentNode(
1262:                            fCurrentNodeIndex, false);
1263:                    fWithinElement = false;
1264:                }
1265:
1266:                // full node expansion
1267:                else {
1268:                    fCurrentElementNode = fCurrentElementNode.getParentNode();
1269:                    fWithinElement = false;
1270:                }
1271:
1272:            } // endElement(QName)
1273:
1274:            /** Characters. */
1275:            public void characters(int dataIndex) throws Exception {
1276:
1277:                // deferred node expansion
1278:                if (fDeferredDocumentImpl != null) {
1279:
1280:                    int text;
1281:
1282:                    if (fInCDATA) {
1283:                        text = fDeferredDocumentImpl.createCDATASection(
1284:                                dataIndex, false);
1285:                    } else {
1286:                        // The Text normalization is taken care of within the Text Node
1287:                        // in the DEFERRED case.
1288:                        text = fDeferredDocumentImpl.createTextNode(dataIndex,
1289:                                false);
1290:                    }
1291:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, text);
1292:                }
1293:
1294:                // full node expansion
1295:                else {
1296:
1297:                    Text text;
1298:
1299:                    if (fInCDATA) {
1300:                        text = fDocument.createCDATASection(fStringPool
1301:                                .orphanString(dataIndex));
1302:                    } else {
1303:
1304:                        if (fWithinElement
1305:                                && fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
1306:                            Node lastChild = fCurrentElementNode.getLastChild();
1307:                            if (lastChild != null
1308:                                    && lastChild.getNodeType() == Node.TEXT_NODE) {
1309:                                // Normalization of Text Nodes - append rather than create.
1310:                                ((Text) lastChild).appendData(fStringPool
1311:                                        .orphanString(dataIndex));
1312:                                return;
1313:                            }
1314:                        }
1315:                        text = fDocument.createTextNode(fStringPool
1316:                                .orphanString(dataIndex));
1317:                    }
1318:
1319:                    fCurrentElementNode.appendChild(text);
1320:
1321:                }
1322:
1323:            } // characters(int)
1324:
1325:            /** Ignorable whitespace. */
1326:            public void ignorableWhitespace(int dataIndex) throws Exception {
1327:
1328:                // ignore the whitespace
1329:                if (!fIncludeIgnorableWhitespace) {
1330:                    fStringPool.orphanString(dataIndex);
1331:                    return;
1332:                }
1333:
1334:                // deferred node expansion
1335:                if (fDeferredDocumentImpl != null) {
1336:
1337:                    int text;
1338:
1339:                    if (fInCDATA) {
1340:                        text = fDeferredDocumentImpl.createCDATASection(
1341:                                dataIndex, true);
1342:                    } else {
1343:                        // The Text normalization is taken care of within the Text Node
1344:                        // in the DEFERRED case.
1345:                        text = fDeferredDocumentImpl.createTextNode(dataIndex,
1346:                                true);
1347:                    }
1348:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, text);
1349:                }
1350:
1351:                // full node expansion
1352:                else {
1353:
1354:                    Text text;
1355:
1356:                    if (fInCDATA) {
1357:                        text = fDocument.createCDATASection(fStringPool
1358:                                .orphanString(dataIndex));
1359:                    } else {
1360:
1361:                        if (fWithinElement
1362:                                && fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
1363:                            Node lastChild = fCurrentElementNode.getLastChild();
1364:                            if (lastChild != null
1365:                                    && lastChild.getNodeType() == Node.TEXT_NODE) {
1366:                                // Normalization of Text Nodes - append rather than create.
1367:                                ((Text) lastChild).appendData(fStringPool
1368:                                        .orphanString(dataIndex));
1369:                                return;
1370:                            }
1371:                        }
1372:                        text = fDocument.createTextNode(fStringPool
1373:                                .orphanString(dataIndex));
1374:                    }
1375:
1376:                    if (fDocumentImpl != null) {
1377:                        ((TextImpl) text).setIgnorableWhitespace(true);
1378:                    }
1379:
1380:                    fCurrentElementNode.appendChild(text);
1381:
1382:                }
1383:
1384:            } // ignorableWhitespace(int)
1385:
1386:            /** Processing instruction. */
1387:            public void processingInstruction(int targetIndex, int dataIndex)
1388:                    throws Exception {
1389:
1390:                // deferred node expansion
1391:                if (fDeferredDocumentImpl != null) {
1392:                    int pi = fDeferredDocumentImpl.createProcessingInstruction(
1393:                            targetIndex, dataIndex);
1394:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, pi);
1395:                }
1396:
1397:                // full node expansion
1398:                else {
1399:                    String target = fStringPool.orphanString(targetIndex);
1400:                    String data = fStringPool.orphanString(dataIndex);
1401:                    ProcessingInstruction pi = fDocument
1402:                            .createProcessingInstruction(target, data);
1403:                    fCurrentElementNode.appendChild(pi);
1404:                }
1405:
1406:            } // processingInstruction(int,int)
1407:
1408:            /** Comment. */
1409:            public void comment(int dataIndex) throws Exception {
1410:
1411:                if (fInDTD && !fGrammarAccess) {
1412:                    fStringPool.orphanString(dataIndex);
1413:                } else {
1414:                    // deferred node expansion
1415:                    if (fDeferredDocumentImpl != null) {
1416:                        int comment = fDeferredDocumentImpl
1417:                                .createComment(dataIndex);
1418:                        fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
1419:                                comment);
1420:                    }
1421:
1422:                    // full node expansion
1423:                    else {
1424:                        Comment comment = fDocument.createComment(fStringPool
1425:                                .orphanString(dataIndex));
1426:                        fCurrentElementNode.appendChild(comment);
1427:                    }
1428:                }
1429:
1430:            } // comment(int)
1431:
1432:            // Callers who know they're interacting with this parser should use
1433:            // characters(int); callers who don't know which parser they
1434:            // are interacting with, or who can't be sure of sharing
1435:            // the same stringPool, should use this method.
1436:            public void characters(char ch[], int start, int length)
1437:                    throws Exception {
1438:                characters(fStringPool.addSymbol(new String(ch, start, length)));
1439:            } // characters(char[], int, int)
1440:
1441:            /** Not called. */
1442:            public void ignorableWhitespace(char ch[], int start, int length)
1443:                    throws Exception {
1444:            }
1445:
1446:            //
1447:            // XMLDocumentScanner methods
1448:            //
1449:
1450:            /** Start CDATA section. */
1451:            public void startCDATA() throws Exception {
1452:                fInCDATA = true;
1453:            }
1454:
1455:            /** End CDATA section. */
1456:            public void endCDATA() throws Exception {
1457:                fInCDATA = false;
1458:            }
1459:
1460:            //
1461:            // XMLEntityHandler methods
1462:            //
1463:
1464:            /** Start entity reference. */
1465:            public void startEntityReference(int entityName, int entityType,
1466:                    int entityContext) throws Exception {
1467:
1468:                fCurrentEntityName = entityName;
1469:                // are we ignoring entity reference nodes?
1470:                if (!fCreateEntityReferenceNodes) {
1471:                    return;
1472:                }
1473:
1474:                // ignore built-in entities
1475:                if (entityName == fAmpIndex || entityName == fGtIndex
1476:                        || entityName == fLtIndex || entityName == fAposIndex
1477:                        || entityName == fQuotIndex) {
1478:                    return;
1479:                }
1480:
1481:                // we only support one context for entity references right now...
1482:                if (entityContext != XMLEntityHandler.ENTITYREF_IN_CONTENT) {
1483:                    return;
1484:                }
1485:
1486:                // deferred node expansion
1487:
1488:                if (fDeferredDocumentImpl != null) {
1489:
1490:                    int entityRefIndex = fDeferredDocumentImpl
1491:                            .createEntityReference(entityName);
1492:                    fDeferredDocumentImpl.appendChild(fCurrentNodeIndex,
1493:                            entityRefIndex);
1494:
1495:                    fCurrentNodeIndex = entityRefIndex;
1496:
1497:                }
1498:
1499:                // full node expansion
1500:                else {
1501:
1502:                    EntityReference er = fDocument
1503:                            .createEntityReference(fStringPool
1504:                                    .toString(entityName));
1505:
1506:                    fCurrentElementNode.appendChild(er);
1507:                    fCurrentElementNode = er;
1508:                }
1509:
1510:            } // startEntityReference(int,int,int)
1511:
1512:            /** End entity reference. */
1513:            public void endEntityReference(int entityName, int entityType,
1514:                    int entityContext) throws Exception {
1515:                // are we ignoring entity reference nodes?
1516:                if (!fCreateEntityReferenceNodes) {
1517:                    return;
1518:                }
1519:
1520:                // ignore built-in entities
1521:                if (entityName == fAmpIndex || entityName == fGtIndex
1522:                        || entityName == fLtIndex || entityName == fAposIndex
1523:                        || entityName == fQuotIndex) {
1524:                    return;
1525:                }
1526:
1527:                // we only support one context for entity references right now...
1528:                if (entityContext != XMLEntityHandler.ENTITYREF_IN_CONTENT) {
1529:                    return;
1530:                }
1531:
1532:                // deferred node expansion
1533:                if (fDeferredDocumentImpl != null) {
1534:
1535:                    String name = fStringPool.toString(entityName);
1536:
1537:                    int erChild = fCurrentNodeIndex;
1538:                    fCurrentNodeIndex = fDeferredDocumentImpl.getParentNode(
1539:                            erChild, false);
1540:
1541:                    // should never be true - we should not return here.
1542:                    if (fDeferredDocumentImpl.getNodeType(erChild, false) != Node.ENTITY_REFERENCE_NODE)
1543:                        return;
1544:
1545:                    erChild = fDeferredDocumentImpl
1546:                            .getLastChild(erChild, false); // first Child of EntityReference
1547:                    if (fDocumentTypeIndex != -1) {
1548:                        // if we have seen <?xml..> decl then Entity decl was found and
1549:                        // set in textDecl() using fCurrentEntityNode
1550:                        if (fCurrentEntityNode == -1) {
1551:                            // find Entity decl for this EntityReference.
1552:                            int entityDecl = fDeferredDocumentImpl
1553:                                    .getLastChild(fDocumentTypeIndex, false);
1554:                            while (entityDecl != -1) {
1555:                                if (fDeferredDocumentImpl.getNodeType(
1556:                                        entityDecl, false) == Node.ENTITY_NODE
1557:                                        && fDeferredDocumentImpl
1558:                                                .getNodeNameString(entityDecl,
1559:                                                        false).equals(name)) // string compare...
1560:                                {
1561:                                    break;
1562:                                }
1563:                                entityDecl = fDeferredDocumentImpl
1564:                                        .getPrevSibling(entityDecl, false);
1565:                            }
1566:                            fCurrentEntityNode = entityDecl;
1567:                        }
1568:                        if (fCurrentEntityNode != -1
1569:                                && fDeferredDocumentImpl.getLastChild(
1570:                                        fCurrentEntityNode, false) == -1) {
1571:                            // found entityDecl with same name as this reference
1572:                            // AND it doesn't have any children.
1573:
1574:                            // we don't need to iterate, because the whole structure
1575:                            // should already be connected to the 1st child.
1576:                            fDeferredDocumentImpl.setAsLastChild(
1577:                                    fCurrentEntityNode, erChild);
1578:                        }
1579:                        // done with current entity reference.
1580:                        // reset values
1581:                        fCurrentEntityNode = -1;
1582:                        fCurrentEntityName = -1;
1583:                    }
1584:
1585:                }
1586:
1587:                // full node expansion
1588:                else {
1589:
1590:                    Node erNode = fCurrentElementNode;//fCurrentElementNode.getParentNode();
1591:                    fCurrentElementNode = erNode.getParentNode();
1592:
1593:                    // if necessary populate the related entity now
1594:                    if (fDocumentImpl != null) {
1595:                        NamedNodeMap entities = fDocumentType.getEntities();
1596:                        String name = fStringPool.toString(entityName);
1597:                        Node entityNode = entities.getNamedItem(name);
1598:
1599:                        // simply return here if there is no entity for
1600:                        // the reference or if the entity is already populated.
1601:                        if (entityNode == null || entityNode.hasChildNodes()) {
1602:                            return;
1603:                        }
1604:
1605:                        EntityImpl entity = (EntityImpl) entityNode;
1606:                        for (Node child = erNode.getFirstChild(); child != null; child = child
1607:                                .getNextSibling()) {
1608:                            Node childClone = child.cloneNode(true);
1609:                            entity.appendChild(childClone);
1610:                        }
1611:                    }
1612:                }
1613:
1614:            } // endEntityReference(int,int,int)
1615:
1616:            //
1617:            // DTDValidator.EventHandler methods
1618:            //
1619:
1620:            /**
1621:             *  This function will be called when a &lt;!DOCTYPE...&gt; declaration is
1622:             *  encountered.
1623:             */
1624:            public void startDTD(QName rootElement, int publicId, int systemId)
1625:                    throws Exception {
1626:
1627:                fInDTD = true;
1628:
1629:                // full expansion
1630:                if (fDocumentImpl != null) {
1631:                    String rootElementName = fStringPool
1632:                            .toString(rootElement.rawname);
1633:                    String publicString = fStringPool.toString(publicId);
1634:                    String systemString = fStringPool.toString(systemId);
1635:                    fDocumentType = fDocumentImpl.createDocumentType(
1636:                            rootElementName, publicString, systemString);
1637:                    fDocumentImpl.appendChild(fDocumentType);
1638:
1639:                    if (fGrammarAccess) {
1640:                        Element schema = fDocument.createElement("schema");
1641:                        // REVISIT: What should the namespace be? -Ac
1642:                        schema.setAttribute("xmlns",
1643:                                SchemaSymbols.URI_SCHEMAFORSCHEMA);
1644:                        ((AttrImpl) schema.getAttributeNode("xmlns"))
1645:                                .setSpecified(false);
1646:                        schema.setAttribute("finalDefault", "");
1647:                        ((AttrImpl) schema.getAttributeNode("finalDefault"))
1648:                                .setSpecified(false);
1649:                        schema.setAttribute("exactDefault", "");
1650:                        ((AttrImpl) schema.getAttributeNode("exactDefault"))
1651:                                .setSpecified(false);
1652:                        fDocumentType.appendChild(schema);
1653:                        fCurrentElementNode = schema;
1654:                    }
1655:                }
1656:
1657:                // deferred expansion
1658:                else if (fDeferredDocumentImpl != null) {
1659:                    fDocumentTypeIndex = fDeferredDocumentImpl
1660:                            .createDocumentType(rootElement.rawname, publicId,
1661:                                    systemId);
1662:                    fDeferredDocumentImpl.appendChild(fDocumentIndex,
1663:                            fDocumentTypeIndex);
1664:
1665:                    if (fGrammarAccess) {
1666:                        int handle = fAttrList.startAttrList();
1667:                        fAttrList
1668:                                .addAttr(
1669:                                        fStringPool.addSymbol("xmlns"),
1670:                                        fStringPool
1671:                                                .addString(SchemaSymbols.URI_SCHEMAFORSCHEMA),
1672:                                        fStringPool.addSymbol("CDATA"), false,
1673:                                        false); // search
1674:                        fAttrList.addAttr(
1675:                                fStringPool.addSymbol("finalDefault"),
1676:                                fStringPool.addString(""), fStringPool
1677:                                        .addSymbol("CDATA"), false, false); // search
1678:                        fAttrList.addAttr(
1679:                                fStringPool.addSymbol("exactDefault"),
1680:                                fStringPool.addString(""), fStringPool
1681:                                        .addSymbol("CDATA"), false, false); // search
1682:                        fAttrList.endAttrList();
1683:                        int schemaIndex = fDeferredDocumentImpl.createElement(
1684:                                fStringPool.addSymbol("schema"), fAttrList,
1685:                                handle);
1686:                        // REVISIT: What should the namespace be? -Ac
1687:                        fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
1688:                                schemaIndex);
1689:                        fCurrentNodeIndex = schemaIndex;
1690:                    }
1691:                }
1692:
1693:            } // startDTD(int,int,int)
1694:
1695:            /**
1696:             * Supports DOM Level 2 internalSubset additions.
1697:             * Called when the internal subset is completely scanned.
1698:             */
1699:            public void internalSubset(int internalSubset) {
1700:
1701:                //System.out.println("internalSubset callback:"+fStringPool.toString(internalSubset));
1702:
1703:                // full expansion
1704:                if (fDocumentImpl != null && fDocumentType != null) {
1705:                    ((DocumentTypeImpl) fDocumentType)
1706:                            .setInternalSubset(fStringPool
1707:                                    .toString(internalSubset));
1708:                }
1709:
1710:                // deferred expansion
1711:                else if (fDeferredDocumentImpl != null) {
1712:                    fDeferredDocumentImpl.setInternalSubset(fDocumentTypeIndex,
1713:                            internalSubset);
1714:                }
1715:
1716:            }
1717:
1718:            /**
1719:             *  This function will be called at the end of the DTD.
1720:             */
1721:            public void endDTD() throws Exception {
1722:
1723:                fInDTD = false;
1724:
1725:                if (fGrammarAccess) {
1726:                    if (fDocumentImpl != null) {
1727:                        fCurrentElementNode = fDocumentImpl;
1728:                    } else if (fDeferredDocumentImpl != null) {
1729:                        fCurrentNodeIndex = 0;
1730:                    }
1731:                }
1732:
1733:            } // endDTD()
1734:
1735:            /**
1736:             * &lt;!ELEMENT Name contentspec&gt;
1737:             */
1738:            public void elementDecl(QName elementDecl, int contentSpecType,
1739:                    int contentSpecIndex,
1740:                    XMLContentSpec.Provider contentSpecProvider)
1741:                    throws Exception {
1742:
1743:                if (DEBUG_ATTLIST_DECL) {
1744:                    String contentModel = XMLContentSpec.toString(
1745:                            contentSpecProvider, fStringPool, contentSpecIndex);
1746:                    System.out.println("elementDecl("
1747:                            + fStringPool.toString(elementDecl.rawname) + ", "
1748:                            + contentModel + ")");
1749:                }
1750:
1751:                //
1752:                // Create element declaration
1753:                //
1754:                if (fGrammarAccess) {
1755:
1756:                    if (fDeferredDocumentImpl != null) {
1757:
1758:                        //
1759:                        // Build element
1760:                        //
1761:
1762:                        // get element declaration; create if necessary
1763:                        int schemaIndex = getLastChildElement(
1764:                                fDocumentTypeIndex, "schema");
1765:                        String elementName = fStringPool
1766:                                .toString(elementDecl.rawname);
1767:                        int elementIndex = getLastChildElement(schemaIndex,
1768:                                "element", "name", elementName);
1769:                        if (elementIndex == -1) {
1770:                            int handle = fAttrList.startAttrList();
1771:                            fAttrList.addAttr(fStringPool.addSymbol("name"),
1772:                                    fStringPool.addString(elementName),
1773:                                    fStringPool.addSymbol("NMTOKEN"), true,
1774:                                    false); // search
1775:                            fAttrList.addAttr(fStringPool
1776:                                    .addSymbol("minOccurs"), // name
1777:                                    fStringPool.addString("1"), // value
1778:                                    fStringPool.addSymbol("NMTOKEN"), // type
1779:                                    false, // specified
1780:                                    false); // search
1781:                            fAttrList.addAttr(
1782:                                    fStringPool.addSymbol("nillable"), // name
1783:                                    fStringPool.addString("false"), // value
1784:                                    fStringPool.addSymbol("ENUMERATION"), // type
1785:                                    false, // specified
1786:                                    false); // search
1787:                            fAttrList.addAttr(
1788:                                    fStringPool.addSymbol("abstract"), // name
1789:                                    fStringPool.addString("false"), // value
1790:                                    fStringPool.addSymbol("ENUMERATION"), // type
1791:                                    false, // specified
1792:                                    false); // search
1793:                            fAttrList.addAttr(fStringPool.addSymbol("final"), // name
1794:                                    fStringPool.addString("false"), // value
1795:                                    fStringPool.addSymbol("ENUMERATION"), // type
1796:                                    false, // specified
1797:                                    false); // search
1798:                            fAttrList.endAttrList();
1799:                            elementIndex = fDeferredDocumentImpl.createElement(
1800:                                    fStringPool.addSymbol("element"),
1801:                                    fAttrList, handle);
1802:                            fDeferredDocumentImpl.appendChild(schemaIndex,
1803:                                    elementIndex);
1804:                        }
1805:
1806:                        //
1807:                        // Build content model
1808:                        //
1809:
1810:                        // get type element; create if necessary
1811:                        int typeIndex = getLastChildElement(elementIndex,
1812:                                "complexType");
1813:                        if (typeIndex == -1
1814:                                && contentSpecType != XMLElementDecl.TYPE_MIXED_SIMPLE) {
1815:                            typeIndex = fDeferredDocumentImpl.createElement(
1816:                                    fStringPool.addSymbol("complexType"), null,
1817:                                    -1);
1818:                            // REVISIT: Check for type redeclaration? -Ac
1819:                            fDeferredDocumentImpl.insertBefore(elementIndex,
1820:                                    typeIndex,
1821:                                    getFirstChildElement(elementIndex));
1822:                        }
1823:
1824:                        // create models
1825:                        switch (contentSpecType) {
1826:                        case XMLElementDecl.TYPE_EMPTY: {
1827:                            int attributeIndex = fDeferredDocumentImpl
1828:                                    .createAttribute(fStringPool
1829:                                            .addSymbol("content"), fStringPool
1830:                                            .addString("empty"), true);
1831:                            fDeferredDocumentImpl.setAttributeNode(typeIndex,
1832:                                    attributeIndex);
1833:                            break;
1834:                        }
1835:                        case XMLElementDecl.TYPE_ANY: {
1836:                            int anyIndex = fDeferredDocumentImpl.createElement(
1837:                                    fStringPool.addSymbol("any"), null, -1);
1838:                            fDeferredDocumentImpl.insertBefore(typeIndex,
1839:                                    anyIndex, getFirstChildElement(typeIndex));
1840:                            break;
1841:                        }
1842:                        case XMLElementDecl.TYPE_MIXED_SIMPLE: {
1843:                            XMLContentSpec contentSpec = new XMLContentSpec();
1844:                            contentSpecProvider.getContentSpec(
1845:                                    contentSpecIndex, contentSpec);
1846:                            contentSpecIndex = contentSpec.value;
1847:                            if (contentSpecIndex == -1) {
1848:                                int attributeIndex = fDeferredDocumentImpl
1849:                                        .createAttribute(fStringPool
1850:                                                .addSymbol("type"), fStringPool
1851:                                                .addString("string"), true);
1852:                                fDeferredDocumentImpl.setAttributeNode(
1853:                                        elementIndex, attributeIndex);
1854:                            } else {
1855:                                if (typeIndex == -1) {
1856:                                    typeIndex = fDeferredDocumentImpl
1857:                                            .createElement(fStringPool
1858:                                                    .addSymbol("complexType"),
1859:                                                    null, -1);
1860:                                    // REVISIT: Check for type redeclaration? -Ac
1861:                                    fDeferredDocumentImpl.insertBefore(
1862:                                            elementIndex, typeIndex,
1863:                                            getFirstChildElement(elementIndex));
1864:                                }
1865:                                int attributeIndex = fDeferredDocumentImpl
1866:                                        .createAttribute(fStringPool
1867:                                                .addSymbol("content"),
1868:                                                fStringPool.addString("mixed"),
1869:                                                true);
1870:                                fDeferredDocumentImpl.setAttributeNode(
1871:                                        typeIndex, attributeIndex);
1872:                                int handle = fAttrList.startAttrList();
1873:                                fAttrList.addAttr(fStringPool
1874:                                        .addSymbol("minOccurs"), fStringPool
1875:                                        .addString("0"), fStringPool
1876:                                        .addSymbol("NMTOKEN"), true, false); // search
1877:                                fAttrList.addAttr(fStringPool
1878:                                        .addSymbol("maxOccurs"), fStringPool
1879:                                        .addString("unbounded"), fStringPool
1880:                                        .addSymbol("CDATA"), true, false); // search
1881:                                fAttrList.endAttrList();
1882:                                int choiceIndex = fDeferredDocumentImpl
1883:                                        .createElement(fStringPool
1884:                                                .addSymbol("choice"),
1885:                                                fAttrList, handle);
1886:                                fDeferredDocumentImpl.appendChild(typeIndex,
1887:                                        choiceIndex);
1888:                                while (contentSpecIndex != -1) {
1889:
1890:                                    // get node
1891:                                    contentSpecProvider.getContentSpec(
1892:                                            contentSpecIndex, contentSpec);
1893:                                    int type = contentSpec.type;
1894:                                    int left = contentSpec.value;
1895:                                    int right = contentSpec.otherValue;
1896:
1897:                                    // if leaf, skip "#PCDATA" and stop
1898:                                    if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
1899:                                        break;
1900:                                    }
1901:
1902:                                    // add right hand leaf
1903:                                    contentSpecProvider.getContentSpec(right,
1904:                                            contentSpec);
1905:                                    handle = fAttrList.startAttrList();
1906:                                    fAttrList
1907:                                            .addAttr(
1908:                                                    fStringPool
1909:                                                            .addSymbol("ref"),
1910:                                                    fStringPool
1911:                                                            .addString(fStringPool
1912:                                                                    .toString(contentSpec.value)),
1913:                                                    fStringPool
1914:                                                            .addSymbol("NMTOKEN"),
1915:                                                    true, false); //search
1916:                                    fAttrList.endAttrList();
1917:                                    int rightIndex = fDeferredDocumentImpl
1918:                                            .createElement(fStringPool
1919:                                                    .addSymbol("element"),
1920:                                                    fAttrList, handle);
1921:                                    int refIndex = getFirstChildElement(choiceIndex);
1922:                                    fDeferredDocumentImpl.insertBefore(
1923:                                            choiceIndex, rightIndex, refIndex);
1924:
1925:                                    // go to next node
1926:                                    contentSpecIndex = left;
1927:                                }
1928:                            }
1929:                            break;
1930:                        }
1931:                        case XMLElementDecl.TYPE_CHILDREN: {
1932:                            int attributeIndex = fDeferredDocumentImpl
1933:                                    .createAttribute(fStringPool
1934:                                            .addSymbol("content"), fStringPool
1935:                                            .addString("elementOnly"), true);
1936:                            fDeferredDocumentImpl.setAttributeNode(typeIndex,
1937:                                    attributeIndex);
1938:                            int children = createChildren(contentSpecProvider,
1939:                                    contentSpecIndex, new XMLContentSpec(),
1940:                                    fDeferredDocumentImpl, -1);
1941:                            fDeferredDocumentImpl.insertBefore(typeIndex,
1942:                                    children, getFirstChildElement(typeIndex));
1943:                            break;
1944:                        }
1945:                        }
1946:
1947:                    } // if defer-node-expansion
1948:
1949:                    else if (fDocumentImpl != null) {
1950:
1951:                        //
1952:                        // Build element
1953:                        //
1954:
1955:                        // get element declaration; create if necessary
1956:                        Element schema = XUtil.getLastChildElement(
1957:                                fDocumentType, "schema");
1958:                        String elementName = fStringPool
1959:                                .toString(elementDecl.rawname);
1960:                        Element element = XUtil.getLastChildElement(schema,
1961:                                "element", "name", elementName);
1962:                        if (element == null) {
1963:                            element = fDocumentImpl.createElement("element");
1964:                            element.setAttribute("name", elementName);
1965:                            element.setAttribute("minOccurs", "1");
1966:                            ((AttrImpl) element.getAttributeNode("minOccurs"))
1967:                                    .setSpecified(false);
1968:                            element.setAttribute("nillable", "false");
1969:                            ((AttrImpl) element.getAttributeNode("nillable"))
1970:                                    .setSpecified(false);
1971:                            element.setAttribute("abstract", "false");
1972:                            ((AttrImpl) element.getAttributeNode("abstract"))
1973:                                    .setSpecified(false);
1974:                            element.setAttribute("final", "false");
1975:                            ((AttrImpl) element.getAttributeNode("final"))
1976:                                    .setSpecified(false);
1977:                            schema.appendChild(element);
1978:                        }
1979:
1980:                        //
1981:                        // Build content model
1982:                        //
1983:
1984:                        // get type element; create if necessary
1985:                        Element type = XUtil.getLastChildElement(element,
1986:                                "complexType");
1987:                        if (type == null
1988:                                && contentSpecType != XMLElementDecl.TYPE_MIXED_SIMPLE) {
1989:                            type = fDocumentImpl.createElement("complexType");
1990:                            // REVISIT: Check for type redeclaration? -Ac
1991:                            element.insertBefore(type, XUtil
1992:                                    .getFirstChildElement(element));
1993:                        }
1994:
1995:                        // create models
1996:                        switch (contentSpecType) {
1997:                        case XMLElementDecl.TYPE_EMPTY: {
1998:                            type.setAttribute("content", "empty");
1999:                            break;
2000:                        }
2001:                        case XMLElementDecl.TYPE_ANY: {
2002:                            Element any = fDocumentImpl.createElement("any");
2003:                            type.insertBefore(any, XUtil
2004:                                    .getFirstChildElement(type));
2005:                            break;
2006:                        }
2007:                        case XMLElementDecl.TYPE_MIXED_SIMPLE: {
2008:                            XMLContentSpec contentSpec = new XMLContentSpec();
2009:                            contentSpecProvider.getContentSpec(
2010:                                    contentSpecIndex, contentSpec);
2011:                            contentSpecIndex = contentSpec.value;
2012:                            if (contentSpecIndex == -1) {
2013:                                element.setAttribute("type", "string");
2014:                            } else {
2015:                                if (type == null) {
2016:                                    type = fDocumentImpl
2017:                                            .createElement("complexType");
2018:                                    // REVISIT: Check for type redeclaration? -Ac
2019:                                    element.insertBefore(type, XUtil
2020:                                            .getFirstChildElement(element));
2021:                                }
2022:                                type.setAttribute("content", "mixed");
2023:                                Element choice = fDocumentImpl
2024:                                        .createElement("choice");
2025:                                choice.setAttribute("minOccurs", "0");
2026:                                choice.setAttribute("maxOccurs", "unbounded");
2027:                                type.appendChild(choice);
2028:                                while (contentSpecIndex != -1) {
2029:
2030:                                    // get node
2031:                                    contentSpecProvider.getContentSpec(
2032:                                            contentSpecIndex, contentSpec);
2033:                                    int cstype = contentSpec.type;
2034:                                    int csleft = contentSpec.value;
2035:                                    int csright = contentSpec.otherValue;
2036:
2037:                                    // if leaf, skip "#PCDATA" and stop
2038:                                    if (cstype == XMLContentSpec.CONTENTSPECNODE_LEAF) {
2039:                                        break;
2040:                                    }
2041:
2042:                                    // add right hand leaf
2043:                                    contentSpecProvider.getContentSpec(csright,
2044:                                            contentSpec);
2045:                                    Element right = fDocumentImpl
2046:                                            .createElement("element");
2047:                                    right.setAttribute("ref", fStringPool
2048:                                            .toString(contentSpec.value));
2049:                                    Element ref = XUtil
2050:                                            .getFirstChildElement(choice);
2051:                                    choice.insertBefore(right, ref);
2052:
2053:                                    // go to next node
2054:                                    contentSpecIndex = csleft;
2055:                                }
2056:                            }
2057:                            break;
2058:                        }
2059:                        case XMLElementDecl.TYPE_CHILDREN: {
2060:                            type.setAttribute("content", "elementOnly");
2061:                            Element children = createChildren(
2062:                                    contentSpecProvider, contentSpecIndex,
2063:                                    new XMLContentSpec(), fDocumentImpl, null);
2064:                            type.insertBefore(children, XUtil
2065:                                    .getFirstChildElement(type));
2066:                            break;
2067:                        }
2068:                        }
2069:
2070:                    } // if NOT defer-node-expansion
2071:
2072:                } // if grammar-access
2073:
2074:            } // elementDecl(int,String)
2075:
2076:            /**
2077:             * &lt;!ATTLIST Name AttDef&gt;
2078:             */
2079:            public void attlistDecl(QName elementDecl, QName attributeDecl,
2080:                    int attType, boolean attList, String enumString,
2081:                    int attDefaultType, int attDefaultValue) throws Exception {
2082:
2083:                if (DEBUG_ATTLIST_DECL) {
2084:                    System.out.println("attlistDecl("
2085:                            + fStringPool.toString(elementDecl.rawname) + ", "
2086:                            + fStringPool.toString(attributeDecl.rawname)
2087:                            + ", " + fStringPool.toString(attType) + ", "
2088:                            + enumString + ", "
2089:                            + fStringPool.toString(attDefaultType) + ", "
2090:                            + fStringPool.toString(attDefaultValue) + ")");
2091:                }
2092:
2093:                // deferred expansion
2094:                if (fDeferredDocumentImpl != null) {
2095:
2096:                    // get the default value
2097:                    if (attDefaultValue != -1) {
2098:                        if (DEBUG_ATTLIST_DECL) {
2099:                            System.out
2100:                                    .println("  adding default attribute value: "
2101:                                            + fStringPool
2102:                                                    .toString(attDefaultValue));
2103:                        }
2104:
2105:                        // get element definition
2106:                        int elementDefIndex = fDeferredDocumentImpl
2107:                                .lookupElementDefinition(elementDecl.rawname);
2108:
2109:                        // create element definition if not already there
2110:                        if (elementDefIndex == -1) {
2111:                            elementDefIndex = fDeferredDocumentImpl
2112:                                    .createElementDefinition(elementDecl.rawname);
2113:                            fDeferredDocumentImpl.appendChild(
2114:                                    fDocumentTypeIndex, elementDefIndex);
2115:                        }
2116:
2117:                        // add default attribute
2118:                        int attrIndex = fDeferredDocumentImpl.createAttribute(
2119:                                attributeDecl.rawname, attributeDecl.uri,
2120:                                attDefaultValue, false);
2121:                        fDeferredDocumentImpl.appendChild(elementDefIndex,
2122:                                attrIndex);
2123:
2124:                    }
2125:
2126:                    //
2127:                    // Create attribute declaration
2128:                    //
2129:                    if (fGrammarAccess) {
2130:
2131:                        // get element declaration; create it if necessary
2132:                        int schemaIndex = getLastChildElement(
2133:                                fDocumentTypeIndex, "schema");
2134:                        String elementName = fStringPool
2135:                                .toString(elementDecl.rawname);
2136:                        int elementIndex = getLastChildElement(schemaIndex,
2137:                                "element", "name", elementName);
2138:                        if (elementIndex == -1) {
2139:                            int handle = fAttrList.startAttrList();
2140:                            fAttrList.addAttr(fStringPool.addSymbol("name"),
2141:                                    fStringPool.addString(elementName),
2142:                                    fStringPool.addSymbol("NMTOKEN"), true,
2143:                                    false); //search
2144:                            fAttrList.endAttrList();
2145:                            elementIndex = fDeferredDocumentImpl.createElement(
2146:                                    fStringPool.addSymbol("element"),
2147:                                    fAttrList, handle);
2148:                            fDeferredDocumentImpl.appendChild(schemaIndex,
2149:                                    elementIndex);
2150:                        }
2151:
2152:                        // get type element; create it if necessary
2153:                        int typeIndex = getLastChildElement(elementIndex,
2154:                                "complexType");
2155:                        if (typeIndex == -1) {
2156:                            typeIndex = fDeferredDocumentImpl.createElement(
2157:                                    fStringPool.addSymbol("complexType"), null,
2158:                                    -1);
2159:                            fDeferredDocumentImpl.insertBefore(elementIndex,
2160:                                    typeIndex,
2161:                                    getLastChildElement(elementIndex));
2162:                        }
2163:
2164:                        // create attribute and set its attributes
2165:                        String attributeName = fStringPool
2166:                                .toString(attributeDecl.rawname);
2167:                        int attributeIndex = getLastChildElement(elementIndex,
2168:                                "attribute", "name", attributeName);
2169:                        if (attributeIndex == -1) {
2170:                            int handle = fAttrList.startAttrList();
2171:                            fAttrList.addAttr(fStringPool.addSymbol("name"),
2172:                                    fStringPool.addString(attributeName),
2173:                                    fStringPool.addSymbol("NMTOKEN"), true,
2174:                                    false); // search
2175:                            fAttrList.addAttr(fStringPool
2176:                                    .addSymbol("maxOccurs"), fStringPool
2177:                                    .addString("1"), fStringPool
2178:                                    .addSymbol("CDATA"), false, false); // search
2179:                            fAttrList.endAttrList();
2180:                            attributeIndex = fDeferredDocumentImpl
2181:                                    .createElement(fStringPool
2182:                                            .addSymbol("attribute"), fAttrList,
2183:                                            handle);
2184:                            fDeferredDocumentImpl.appendChild(typeIndex,
2185:                                    attributeIndex);
2186:
2187:                            // attribute type: CDATA, ENTITY, ... , NMTOKENS; ENUMERATION
2188:                            if (attType == XMLAttributeDecl.TYPE_ENUMERATION) {
2189:                                handle = fAttrList.startAttrList();
2190:                                fAttrList.addAttr(
2191:                                        fStringPool.addSymbol("base"),
2192:                                        fStringPool.addString("NMTOKEN"),
2193:                                        fStringPool.addSymbol("NMTOKEN"), true,
2194:                                        false); // search
2195:                                fAttrList.endAttrList();
2196:                                int simpleTypeIndex = fDeferredDocumentImpl
2197:                                        .createElement(fStringPool
2198:                                                .addSymbol("simpleType"),
2199:                                                fAttrList, handle);
2200:                                fDeferredDocumentImpl.appendChild(
2201:                                        attributeIndex, simpleTypeIndex);
2202:                                String tokenizerString = enumString.substring(
2203:                                        1, enumString.length() - 1);
2204:                                StringTokenizer tokenizer = new StringTokenizer(
2205:                                        tokenizerString, "|");
2206:                                while (tokenizer.hasMoreTokens()) {
2207:                                    handle = fAttrList.startAttrList();
2208:                                    fAttrList.addAttr(fStringPool
2209:                                            .addSymbol("value"), fStringPool
2210:                                            .addString(tokenizer.nextToken()),
2211:                                            fStringPool.addSymbol("CDATA"),
2212:                                            true, false); // search
2213:                                    fAttrList.endAttrList();
2214:                                    int enumerationIndex = fDeferredDocumentImpl
2215:                                            .createElement(fStringPool
2216:                                                    .addSymbol("enumeration"),
2217:                                                    fAttrList, handle);
2218:                                    fDeferredDocumentImpl.appendChild(
2219:                                            simpleTypeIndex, enumerationIndex);
2220:                                }
2221:                            } else {
2222:                                int typeNameIndex = -1;
2223:                                switch (attType) {
2224:                                case XMLAttributeDecl.TYPE_ENTITY: {
2225:                                    typeNameIndex = fStringPool
2226:                                            .addString(attList ? "ENTITIES"
2227:                                                    : "ENTITY");
2228:                                    break;
2229:                                }
2230:                                case XMLAttributeDecl.TYPE_ID: {
2231:                                    typeNameIndex = fStringPool.addString("ID");
2232:                                    break;
2233:                                }
2234:                                case XMLAttributeDecl.TYPE_IDREF: {
2235:                                    typeNameIndex = fStringPool
2236:                                            .addString(attList ? "IDREFS"
2237:                                                    : "IDREF");
2238:                                    break;
2239:                                }
2240:                                case XMLAttributeDecl.TYPE_NMTOKEN: {
2241:                                    typeNameIndex = fStringPool
2242:                                            .addString(attList ? "NMTOKENS"
2243:                                                    : "NMTOKEN");
2244:                                    break;
2245:                                }
2246:                                case XMLAttributeDecl.TYPE_NOTATION: {
2247:                                    typeNameIndex = fStringPool
2248:                                            .addString("NOTATION");
2249:                                    break;
2250:                                }
2251:                                case XMLAttributeDecl.TYPE_CDATA:
2252:                                default: {
2253:                                    typeNameIndex = fStringPool
2254:                                            .addString("string");
2255:                                    break;
2256:                                }
2257:                                }
2258:                                int attrIndex = fDeferredDocumentImpl
2259:                                        .createAttribute(fStringPool
2260:                                                .addSymbol("type"),
2261:                                                typeNameIndex, true);
2262:                                fDeferredDocumentImpl.setAttributeNode(
2263:                                        attributeIndex, attrIndex);
2264:                            }
2265:
2266:                            // attribute default type: #IMPLIED, #REQUIRED, #FIXED
2267:                            boolean fixed = false;
2268:                            switch (attDefaultType) {
2269:                            case XMLAttributeDecl.DEFAULT_TYPE_REQUIRED: {
2270:                                int useAttrIndex = fDeferredDocumentImpl
2271:                                        .createAttribute(fStringPool
2272:                                                .addSymbol("use"), fStringPool
2273:                                                .addString("required"), true);
2274:                                fDeferredDocumentImpl.setAttributeNode(
2275:                                        attributeIndex, useAttrIndex);
2276:                                break;
2277:                            }
2278:                            case XMLAttributeDecl.DEFAULT_TYPE_FIXED: {
2279:                                fixed = true;
2280:                                int useAttrIndex = fDeferredDocumentImpl
2281:                                        .createAttribute(fStringPool
2282:                                                .addSymbol("use"), fStringPool
2283:                                                .addString("fixed"), true);
2284:                                fDeferredDocumentImpl.setAttributeNode(
2285:                                        attributeIndex, useAttrIndex);
2286:                                break;
2287:                            }
2288:                            }
2289:
2290:                            // attribute default value
2291:                            if (attDefaultValue != -1) {
2292:                                if (!fixed) {
2293:                                    int useAttrIndex = fDeferredDocumentImpl
2294:                                            .createAttribute(
2295:                                                    fStringPool
2296:                                                            .addSymbol("use"),
2297:                                                    fStringPool
2298:                                                            .addString("default"),
2299:                                                    true);
2300:                                    fDeferredDocumentImpl.setAttributeNode(
2301:                                            attributeIndex, useAttrIndex);
2302:                                }
2303:                                int valueAttrIndex = fDeferredDocumentImpl
2304:                                        .createAttribute(fStringPool
2305:                                                .addSymbol("value"),
2306:                                                attDefaultValue, true);
2307:                                fDeferredDocumentImpl.setAttributeNode(
2308:                                        attributeIndex, valueAttrIndex);
2309:                            }
2310:                        }
2311:                    }
2312:                }
2313:
2314:                // full expansion
2315:                else if (fDocumentImpl != null) {
2316:
2317:                    // get the default value
2318:                    if (attDefaultValue != -1) {
2319:                        if (DEBUG_ATTLIST_DECL) {
2320:                            System.out
2321:                                    .println("  adding default attribute value: "
2322:                                            + fStringPool
2323:                                                    .toString(attDefaultValue));
2324:                        }
2325:
2326:                        // get element name
2327:                        String elementName = fStringPool
2328:                                .toString(elementDecl.rawname);
2329:
2330:                        // get element definition node
2331:                        NamedNodeMap elements = ((DocumentTypeImpl) fDocumentType)
2332:                                .getElements();
2333:                        ElementDefinitionImpl elementDef = (ElementDefinitionImpl) elements
2334:                                .getNamedItem(elementName);
2335:                        if (elementDef == null) {
2336:                            elementDef = fDocumentImpl
2337:                                    .createElementDefinition(elementName);
2338:                            ((DocumentTypeImpl) fDocumentType).getElements()
2339:                                    .setNamedItem(elementDef);
2340:                        }
2341:
2342:                        // REVISIT: Check for uniqueness of element name? -Ac
2343:
2344:                        // get attribute name and value index
2345:                        String attrName = fStringPool
2346:                                .toString(attributeDecl.rawname);
2347:                        String attrValue = fStringPool
2348:                                .toString(attDefaultValue);
2349:
2350:                        // create attribute and set properties
2351:                        boolean nsEnabled = false;
2352:                        try {
2353:                            nsEnabled = getNamespaces();
2354:                        } catch (SAXException s) {
2355:                        }
2356:                        AttrImpl attr;
2357:                        if (nsEnabled) {
2358:                            String namespaceURI = fStringPool
2359:                                    .toString(attributeDecl.uri);
2360:                            // DOM Level 2 wants all namespace declaration attributes
2361:                            // to be bound to "http://www.w3.org/2000/xmlns/"
2362:                            // So as long as the XML parser doesn't do it, it needs to
2363:                            // done here.
2364:                            String prefix = fStringPool
2365:                                    .toString(attributeDecl.prefix);
2366:                            // hide that our parser uses an empty string for null
2367:                            if (namespaceURI.length() == 0) {
2368:                                namespaceURI = null;
2369:                            }
2370:                            if (namespaceURI == null) {
2371:                                if (prefix != null) {
2372:                                    if (prefix.equals("xmlns")) {
2373:                                        namespaceURI = "http://www.w3.org/2000/xmlns/";
2374:                                    }
2375:                                } else if (attrName.equals("xmlns")) {
2376:                                    namespaceURI = "http://www.w3.org/2000/xmlns/";
2377:                                }
2378:                            }
2379:                            attr = (AttrImpl) fDocumentImpl.createAttributeNS(
2380:                                    namespaceURI, attrName);
2381:                        } else {
2382:                            attr = (AttrImpl) fDocumentImpl
2383:                                    .createAttribute(attrName);
2384:                        }
2385:                        attr.setValue(attrValue);
2386:                        attr.setSpecified(false);
2387:
2388:                        // add default attribute to element definition
2389:                        if (nsEnabled) {
2390:                            elementDef.getAttributes().setNamedItemNS(attr);
2391:                        } else {
2392:                            elementDef.getAttributes().setNamedItem(attr);
2393:                        }
2394:                    }
2395:
2396:                    //
2397:                    // Create attribute declaration
2398:                    //
2399:                    try {
2400:                        if (fGrammarAccess) {
2401:
2402:                            // get element declaration; create it if necessary
2403:                            Element schema = XUtil.getLastChildElement(
2404:                                    fDocumentType, "schema");
2405:                            String elementName = fStringPool
2406:                                    .toString(elementDecl.rawname);
2407:                            Element element = XUtil.getLastChildElement(schema,
2408:                                    "element", "name", elementName);
2409:                            if (element == null) {
2410:                                element = fDocumentImpl
2411:                                        .createElement("element");
2412:                                element.setAttribute("name", elementName);
2413:                                schema.appendChild(element);
2414:                            }
2415:
2416:                            // get type element; create it if necessary
2417:                            Element type = XUtil.getLastChildElement(element,
2418:                                    "complexType");
2419:                            if (type == null) {
2420:                                type = fDocumentImpl
2421:                                        .createElement("complexType");
2422:                                element.insertBefore(type, XUtil
2423:                                        .getLastChildElement(element));
2424:                            }
2425:
2426:                            // create attribute and set its attributes
2427:                            String attributeName = fStringPool
2428:                                    .toString(attributeDecl.rawname);
2429:                            Element attribute = XUtil
2430:                                    .getLastChildElement(element, "attribute",
2431:                                            "name", attributeName);
2432:                            if (attribute == null) {
2433:                                attribute = fDocumentImpl
2434:                                        .createElement("attribute");
2435:                                attribute.setAttribute("name", attributeName);
2436:                                attribute.setAttribute("maxOccurs", "1");
2437:                                ((AttrImpl) attribute
2438:                                        .getAttributeNode("maxOccurs"))
2439:                                        .setSpecified(false);
2440:                                type.appendChild(attribute);
2441:
2442:                                // attribute type: CDATA, ENTITY, ... , NMTOKENS; ENUMERATION
2443:                                if (attType == XMLAttributeDecl.TYPE_ENUMERATION) {
2444:                                    Element simpleType = fDocumentImpl
2445:                                            .createElement("simpleType");
2446:                                    simpleType.setAttribute("base", "NMTOKEN");
2447:                                    attribute.appendChild(simpleType);
2448:                                    String tokenizerString = enumString
2449:                                            .substring(1,
2450:                                                    enumString.length() - 1);
2451:                                    StringTokenizer tokenizer = new StringTokenizer(
2452:                                            tokenizerString, "|");
2453:                                    while (tokenizer.hasMoreTokens()) {
2454:                                        Element enumeration = fDocumentImpl
2455:                                                .createElement("enumeration");
2456:                                        enumeration.setAttribute("value",
2457:                                                tokenizer.nextToken());
2458:                                        simpleType.appendChild(enumeration);
2459:                                    }
2460:                                } else {
2461:                                    String typeName = null;
2462:                                    switch (attType) {
2463:                                    case XMLAttributeDecl.TYPE_ENTITY: {
2464:                                        typeName = attList ? "ENTITIES"
2465:                                                : "ENTITY";
2466:                                        break;
2467:                                    }
2468:                                    case XMLAttributeDecl.TYPE_ID: {
2469:                                        typeName = "ID";
2470:                                        break;
2471:                                    }
2472:                                    case XMLAttributeDecl.TYPE_IDREF: {
2473:                                        typeName = attList ? "IDREFS" : "IDREF";
2474:                                        break;
2475:                                    }
2476:                                    case XMLAttributeDecl.TYPE_NMTOKEN: {
2477:                                        typeName = attList ? "NMTOKENS"
2478:                                                : "NMTOKEN";
2479:                                        break;
2480:                                    }
2481:                                    case XMLAttributeDecl.TYPE_NOTATION: {
2482:                                        typeName = "NOTATION";
2483:                                        break;
2484:                                    }
2485:                                    case XMLAttributeDecl.TYPE_CDATA:
2486:                                    default: {
2487:                                        typeName = "string";
2488:                                        break;
2489:                                    }
2490:                                    }
2491:                                    attribute.setAttribute("type", typeName);
2492:                                }
2493:
2494:                                // attribute default type: #IMPLIED, #REQUIRED, #FIXED
2495:                                boolean fixed = false;
2496:                                switch (attDefaultType) {
2497:                                case XMLAttributeDecl.DEFAULT_TYPE_REQUIRED: {
2498:                                    attribute.setAttribute("use", "required");
2499:                                    break;
2500:                                }
2501:                                case XMLAttributeDecl.DEFAULT_TYPE_FIXED: {
2502:                                    attribute.setAttribute("use", "fixed");
2503:                                    fixed = true;
2504:                                    break;
2505:                                }
2506:                                }
2507:
2508:                                // attribute default value
2509:                                if (attDefaultValue != -1) {
2510:                                    if (!fixed) {
2511:                                        attribute
2512:                                                .setAttribute("use", "default");
2513:                                    }
2514:                                    attribute.setAttribute("value", fStringPool
2515:                                            .toString(attDefaultValue));
2516:                                }
2517:                            }
2518:                        }
2519:                    } catch (Exception e) {
2520:                        e.printStackTrace(System.err);
2521:                    }
2522:
2523:                } // if NOT defer-node-expansion
2524:
2525:            } // attlistDecl(int,int,int,String,int,int)
2526:
2527:            /**
2528:             * &lt;!ENTITY % Name EntityValue&gt; (internal)
2529:             */
2530:            public void internalPEDecl(int entityNameIndex, int entityValueIndex)
2531:                    throws Exception {
2532:                if (fDeferredDocumentImpl != null) {
2533:                    if (fGrammarAccess) {
2534:                        StringBuffer str = new StringBuffer();
2535:                        str.append("<!ENTITY % ");
2536:                        str.append(fStringPool.toString(entityNameIndex));
2537:                        str.append(" \"");
2538:                        str.append(fStringPool.toString(entityValueIndex));
2539:                        str.append("\">");
2540:                        int commentIndex = fStringPool
2541:                                .addString(str.toString());
2542:                        int internalPEEntityIndex = fDeferredDocumentImpl
2543:                                .createComment(commentIndex);
2544:                        int schemaIndex = getFirstChildElement(
2545:                                fDocumentTypeIndex, "schema");
2546:                        fDeferredDocumentImpl.appendChild(schemaIndex,
2547:                                internalPEEntityIndex);
2548:                    }
2549:                } else if (fDocumentImpl != null) {
2550:                    if (fGrammarAccess) {
2551:                        StringBuffer str = new StringBuffer();
2552:                        str.append("<!ENTITY % ");
2553:                        str.append(fStringPool.toString(entityNameIndex));
2554:                        str.append(" \"");
2555:                        str.append(fStringPool.toString(entityValueIndex));
2556:                        str.append("\">");
2557:                        Node internalPEEntity = fDocumentImpl.createComment(str
2558:                                .toString());
2559:                        Node schema = XUtil.getFirstChildElement(fDocumentType,
2560:                                "schema");
2561:                        schema.appendChild(internalPEEntity);
2562:                    }
2563:                } else {
2564:                    fStringPool.orphanString(entityValueIndex);
2565:                }
2566:            }
2567:
2568:            /**
2569:             * &lt;!ENTITY % Name ExternalID>                (external)
2570:             */
2571:            public void externalPEDecl(int entityNameIndex, int publicIdIndex,
2572:                    int systemIdIndex) throws Exception {
2573:                if (fDeferredDocumentImpl != null) {
2574:                    if (fGrammarAccess) {
2575:                        StringBuffer str = new StringBuffer();
2576:                        str.append("<!ENTITY ");
2577:                        str.append(fStringPool.toString(entityNameIndex));
2578:                        str.append(' ');
2579:                        if (publicIdIndex != -1) {
2580:                            str.append("PUBLIC \"");
2581:                            str.append(fStringPool.toString(publicIdIndex));
2582:                            str.append('"');
2583:                            if (systemIdIndex != -1) {
2584:                                str.append(" \"");
2585:                                str.append(fStringPool.toString(systemIdIndex));
2586:                                str.append('"');
2587:                            }
2588:                        } else if (systemIdIndex != -1) {
2589:                            str.append("SYSTEM \"");
2590:                            str.append(fStringPool.toString(systemIdIndex));
2591:                            str.append('"');
2592:                        }
2593:                        str.append('>');
2594:                        int commentIndex = fStringPool
2595:                                .addString(str.toString());
2596:                        int externalPEEntityIndex = fDeferredDocumentImpl
2597:                                .createComment(commentIndex);
2598:                        int schemaIndex = getFirstChildElement(
2599:                                fDocumentTypeIndex, "schema");
2600:                        fDeferredDocumentImpl.appendChild(schemaIndex,
2601:                                externalPEEntityIndex);
2602:                    }
2603:                } else if (fDocumentImpl != null) {
2604:                    if (fGrammarAccess) {
2605:                        StringBuffer str = new StringBuffer();
2606:                        str.append("<!ENTITY ");
2607:                        str.append(fStringPool.toString(entityNameIndex));
2608:                        str.append(' ');
2609:                        if (publicIdIndex != -1) {
2610:                            str.append("PUBLIC \"");
2611:                            str.append(fStringPool.toString(publicIdIndex));
2612:                            str.append('"');
2613:                            if (systemIdIndex != -1) {
2614:                                str.append(" \"");
2615:                                str.append(fStringPool.toString(systemIdIndex));
2616:                                str.append('"');
2617:                            }
2618:                        } else if (systemIdIndex != -1) {
2619:                            str.append("SYSTEM \"");
2620:                            str.append(fStringPool.toString(systemIdIndex));
2621:                            str.append('"');
2622:                        }
2623:                        str.append('>');
2624:                        Node externalPEEntity = fDocumentImpl.createComment(str
2625:                                .toString());
2626:                        Node schema = XUtil.getFirstChildElement(fDocumentType,
2627:                                "schema");
2628:                        schema.appendChild(externalPEEntity);
2629:                    }
2630:                }
2631:            }
2632:
2633:            /**
2634:             * &lt;!ENTITY Name EntityValue&gt; (internal)
2635:             */
2636:            public void internalEntityDecl(int entityNameIndex,
2637:                    int entityValueIndex) throws Exception {
2638:
2639:                // deferred expansion
2640:                if (fDeferredDocumentImpl != null) {
2641:
2642:                    if (fDocumentTypeIndex == -1)
2643:                        return; //revisit: should never happen. Exception?
2644:
2645:                    //revisit: how to check if entity was already declared.
2646:                    // XML spec says that 1st Entity decl is binding.
2647:
2648:                    int newEntityIndex = fDeferredDocumentImpl.createEntity(
2649:                            entityNameIndex, -1, -1, -1);
2650:                    fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2651:                            newEntityIndex);
2652:
2653:                    // REVISIT: Entities were removed from latest working draft. -Ac
2654:                    // create internal entity declaration
2655:                    if (fGrammarAccess) {
2656:                        StringBuffer str = new StringBuffer();
2657:                        str.append("<!ENTITY ");
2658:                        str.append(fStringPool.toString(entityNameIndex));
2659:                        str.append(" \"");
2660:                        str.append(fStringPool.toString(entityValueIndex));
2661:                        str.append("\">");
2662:                        int commentIndex = fStringPool
2663:                                .addString(str.toString());
2664:                        int textEntityIndex = fDeferredDocumentImpl
2665:                                .createComment(commentIndex);
2666:                        int schemaIndex = getFirstChildElement(
2667:                                fDocumentTypeIndex, "schema");
2668:                        fDeferredDocumentImpl.appendChild(schemaIndex,
2669:                                textEntityIndex);
2670:                    }
2671:                }
2672:
2673:                // full expansion
2674:                else if (fDocumentImpl != null) {
2675:                    if (fDocumentType == null)
2676:                        return; //revisit: should never happen. Exception?
2677:
2678:                    //revisit: how to check if entity was already declared.
2679:                    // XML spec says that 1st Entity decl is binding.
2680:
2681:                    String entityName = fStringPool.toString(entityNameIndex);
2682:
2683:                    Entity entity = fDocumentImpl.createEntity(entityName);
2684:                    fDocumentType.getEntities().setNamedItem(entity);
2685:
2686:                    // REVISIT: Entities were removed from latest working draft. -Ac
2687:                    // create internal entity declaration
2688:                    if (fGrammarAccess) {
2689:                        StringBuffer str = new StringBuffer();
2690:                        str.append("<!ENTITY ");
2691:                        str.append(fStringPool.toString(entityNameIndex));
2692:                        str.append(" \"");
2693:                        str.append(fStringPool.toString(entityValueIndex));
2694:                        str.append("\">");
2695:                        Node textEntity = fDocumentImpl.createComment(str
2696:                                .toString());
2697:                        Node schema = XUtil.getFirstChildElement(fDocumentType,
2698:                                "schema");
2699:                        schema.appendChild(textEntity);
2700:                    }
2701:                }
2702:
2703:            } // internalEntityDecl(int,int)
2704:
2705:            /**
2706:             * &lt;!ENTITY Name ExternalID>                (external)
2707:             */
2708:            public void externalEntityDecl(int entityNameIndex,
2709:                    int publicIdIndex, int systemIdIndex) throws Exception {
2710:
2711:                // deferred expansion
2712:                if (fDeferredDocumentImpl != null) {
2713:
2714:                    //revisit: how to check if entity was already declared.
2715:                    // XML spec says that 1st Entity decl is binding.
2716:
2717:                    int newEntityIndex = fDeferredDocumentImpl.createEntity(
2718:                            entityNameIndex, publicIdIndex, systemIdIndex, -1);
2719:
2720:                    fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2721:                            newEntityIndex);
2722:
2723:                    // REVISIT: Entities were removed from latest working draft. -Ac
2724:                    // create external entity declaration
2725:                    if (fGrammarAccess) {
2726:                        StringBuffer str = new StringBuffer();
2727:                        str.append("<!ENTITY ");
2728:                        str.append(fStringPool.toString(entityNameIndex));
2729:                        str.append(' ');
2730:                        if (publicIdIndex != -1) {
2731:                            str.append("PUBLIC \"");
2732:                            str.append(fStringPool.toString(publicIdIndex));
2733:                            str.append('"');
2734:                            if (systemIdIndex != -1) {
2735:                                str.append(" \"");
2736:                                str.append(fStringPool.toString(systemIdIndex));
2737:                                str.append('"');
2738:                            }
2739:                        } else if (systemIdIndex != -1) {
2740:                            str.append("SYSTEM \"");
2741:                            str.append(fStringPool.toString(systemIdIndex));
2742:                            str.append('"');
2743:                        }
2744:                        str.append('>');
2745:                        int commentIndex = fStringPool
2746:                                .addString(str.toString());
2747:                        int externalEntityIndex = fDeferredDocumentImpl
2748:                                .createComment(commentIndex);
2749:                        int schemaIndex = getFirstChildElement(
2750:                                fDocumentTypeIndex, "schema");
2751:                        fDeferredDocumentImpl.appendChild(schemaIndex,
2752:                                externalEntityIndex);
2753:                    }
2754:                }
2755:
2756:                // full expansion
2757:                else if (fDocumentImpl != null) {
2758:
2759:                    //revisit: how to check if entity was already declared.
2760:                    // XML spec says that 1st Entity decl is binding.
2761:
2762:                    String entityName = fStringPool.toString(entityNameIndex);
2763:                    String publicId = fStringPool.toString(publicIdIndex);
2764:                    String systemId = fStringPool.toString(systemIdIndex);
2765:
2766:                    EntityImpl entity = (EntityImpl) fDocumentImpl
2767:                            .createEntity(entityName);
2768:                    if (publicIdIndex != -1) {
2769:                        entity.setPublicId(publicId);
2770:                    }
2771:                    entity.setSystemId(systemId);
2772:                    fDocumentType.getEntities().setNamedItem(entity);
2773:
2774:                    // REVISIT: Entities were removed from latest working draft. -Ac
2775:                    // create external entity declaration
2776:                    if (fGrammarAccess) {
2777:                        StringBuffer str = new StringBuffer();
2778:                        str.append("<!ENTITY ");
2779:                        str.append(fStringPool.toString(entityNameIndex));
2780:                        str.append(' ');
2781:                        if (publicIdIndex != -1) {
2782:                            str.append("PUBLIC \"");
2783:                            str.append(fStringPool.toString(publicIdIndex));
2784:                            str.append('"');
2785:                            if (systemIdIndex != -1) {
2786:                                str.append(" \"");
2787:                                str.append(fStringPool.toString(systemIdIndex));
2788:                                str.append('"');
2789:                            }
2790:                        } else if (systemIdIndex != -1) {
2791:                            str.append("SYSTEM \"");
2792:                            str.append(fStringPool.toString(systemIdIndex));
2793:                            str.append('"');
2794:                        }
2795:                        str.append('>');
2796:                        Node externalEntity = fDocumentImpl.createComment(str
2797:                                .toString());
2798:                        Node schema = XUtil.getFirstChildElement(fDocumentType,
2799:                                "schema");
2800:                        schema.appendChild(externalEntity);
2801:                    }
2802:                }
2803:
2804:            } // externalEntityDecl(int,int,int)
2805:
2806:            /**
2807:             * &lt;!ENTITY Name ExternalID NDataDecl>      (unparsed)
2808:             */
2809:            public void unparsedEntityDecl(int entityNameIndex,
2810:                    int publicIdIndex, int systemIdIndex, int notationNameIndex)
2811:                    throws Exception {
2812:
2813:                // deferred expansion
2814:                if (fDeferredDocumentImpl != null) {
2815:
2816:                    //revisit: how to check if entity was already declared.
2817:                    // XML spec says that 1st Entity decl is binding.
2818:
2819:                    int newEntityIndex = fDeferredDocumentImpl.createEntity(
2820:                            entityNameIndex, publicIdIndex, systemIdIndex,
2821:                            notationNameIndex);
2822:
2823:                    fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2824:                            newEntityIndex);
2825:
2826:                    // REVISIT: Entities were removed from latest working draft. -Ac
2827:                    // add unparsed entity declaration
2828:                    if (fGrammarAccess) {
2829:                        StringBuffer str = new StringBuffer();
2830:                        str.append("<!ENTITY ");
2831:                        str.append(fStringPool.toString(entityNameIndex));
2832:                        str.append(' ');
2833:                        if (publicIdIndex != -1) {
2834:                            str.append("PUBLIC \"");
2835:                            str.append(fStringPool.toString(publicIdIndex));
2836:                            str.append('"');
2837:                            if (systemIdIndex != -1) {
2838:                                str.append(" \"");
2839:                                str.append(fStringPool.toString(systemIdIndex));
2840:                                str.append('"');
2841:                            }
2842:                        } else if (systemIdIndex != -1) {
2843:                            str.append("SYSTEM \"");
2844:                            str.append(fStringPool.toString(systemIdIndex));
2845:                            str.append('"');
2846:                        }
2847:                        str.append(" NDATA ");
2848:                        str.append(fStringPool.toString(notationNameIndex));
2849:                        str.append('>');
2850:                        int commentIndex = fStringPool
2851:                                .addString(str.toString());
2852:                        int unparsedEntityIndex = fDeferredDocumentImpl
2853:                                .createComment(commentIndex);
2854:                        int schemaIndex = getFirstChildElement(
2855:                                fDocumentTypeIndex, "schema");
2856:                        fDeferredDocumentImpl.appendChild(schemaIndex,
2857:                                unparsedEntityIndex);
2858:                    }
2859:                }
2860:
2861:                // full expansion
2862:                else if (fDocumentImpl != null) {
2863:
2864:                    //revisit: how to check if entity was already declared.
2865:                    // XML spec says that 1st Entity decl is binding.
2866:
2867:                    String entityName = fStringPool.toString(entityNameIndex);
2868:                    String publicId = fStringPool.toString(publicIdIndex);
2869:                    String systemId = fStringPool.toString(systemIdIndex);
2870:                    String notationName = fStringPool
2871:                            .toString(notationNameIndex);
2872:
2873:                    EntityImpl entity = (EntityImpl) fDocumentImpl
2874:                            .createEntity(entityName);
2875:                    if (publicIdIndex != -1) {
2876:                        entity.setPublicId(publicId);
2877:                    }
2878:                    entity.setSystemId(systemId);
2879:                    entity.setNotationName(notationName);
2880:                    fDocumentType.getEntities().setNamedItem(entity);
2881:
2882:                    // REVISIT: Entities were removed from latest working draft. -Ac
2883:                    // add unparsed entity declaration
2884:                    if (fGrammarAccess) {
2885:                        StringBuffer str = new StringBuffer();
2886:                        str.append("<!ENTITY ");
2887:                        str.append(fStringPool.toString(entityNameIndex));
2888:                        str.append(' ');
2889:                        if (publicIdIndex != -1) {
2890:                            str.append("PUBLIC \"");
2891:                            str.append(fStringPool.toString(publicIdIndex));
2892:                            str.append('"');
2893:                            if (systemIdIndex != -1) {
2894:                                str.append(" \"");
2895:                                str.append(fStringPool.toString(systemIdIndex));
2896:                                str.append('"');
2897:                            }
2898:                        } else if (systemIdIndex != -1) {
2899:                            str.append("SYSTEM \"");
2900:                            str.append(fStringPool.toString(systemIdIndex));
2901:                            str.append('"');
2902:                        }
2903:                        str.append(" NDATA ");
2904:                        str.append(fStringPool.toString(notationNameIndex));
2905:                        str.append('>');
2906:                        Node unparsedEntity = fDocumentImpl.createComment(str
2907:                                .toString());
2908:                        Node schema = XUtil.getFirstChildElement(fDocumentType,
2909:                                "schema");
2910:                        schema.appendChild(unparsedEntity);
2911:                    }
2912:                }
2913:
2914:            } // unparsedEntityDecl(int,int,int,int)
2915:
2916:            /**
2917:             * &lt;!NOTATION Name ExternalId>
2918:             */
2919:            public void notationDecl(int notationNameIndex, int publicIdIndex,
2920:                    int systemIdIndex) throws Exception {
2921:
2922:                // deferred expansion
2923:                if (fDeferredDocumentImpl != null) {
2924:
2925:                    //revisit: how to check if entity was already declared.
2926:                    // XML spec says that 1st Entity decl is binding.
2927:
2928:                    int newNotationIndex = fDeferredDocumentImpl
2929:                            .createNotation(notationNameIndex, publicIdIndex,
2930:                                    systemIdIndex);
2931:
2932:                    fDeferredDocumentImpl.appendChild(fDocumentTypeIndex,
2933:                            newNotationIndex);
2934:
2935:                    // create notation declaration
2936:                    if (fGrammarAccess) {
2937:                        int schemaIndex = getLastChildElement(
2938:                                fDocumentTypeIndex, "schema");
2939:                        String notationName = fStringPool
2940:                                .toString(notationNameIndex);
2941:                        int notationIndex = getLastChildElement(schemaIndex,
2942:                                "notation", "name", notationName);
2943:                        if (notationIndex == -1) {
2944:                            int handle = fAttrList.startAttrList();
2945:                            fAttrList.addAttr(fStringPool.addSymbol("name"),
2946:                                    fStringPool.addString(notationName),
2947:                                    fStringPool.addSymbol("NMTOKEN"), true,
2948:                                    false); // search
2949:                            if (publicIdIndex != -1) {
2950:                                fAttrList.addAttr(fStringPool
2951:                                        .addSymbol("public"), publicIdIndex,
2952:                                        fStringPool.addSymbol("CDATA"), true,
2953:                                        false); // search
2954:                            }
2955:                            if (systemIdIndex != -1) {
2956:                                fAttrList.addAttr(fStringPool
2957:                                        .addSymbol("system"), systemIdIndex,
2958:                                        fStringPool.addSymbol("CDATA"), true,
2959:                                        false); // search
2960:                            }
2961:                            fAttrList.endAttrList();
2962:                            notationIndex = fDeferredDocumentImpl
2963:                                    .createElement(fStringPool
2964:                                            .addSymbol("notation"), fAttrList,
2965:                                            handle);
2966:                            fDeferredDocumentImpl.appendChild(schemaIndex,
2967:                                    notationIndex);
2968:                        }
2969:                    }
2970:                }
2971:
2972:                // full expansion
2973:                else if (fDocumentImpl != null) {
2974:
2975:                    // REVISIT: how to check if entity was already declared.
2976:                    // XML spec says that 1st Entity decl is binding.
2977:
2978:                    String notationName = fStringPool
2979:                            .toString(notationNameIndex);
2980:                    String publicId = fStringPool.toString(publicIdIndex);
2981:                    String systemId = fStringPool.toString(systemIdIndex);
2982:
2983:                    NotationImpl notationImpl = (NotationImpl) fDocumentImpl
2984:                            .createNotation(notationName);
2985:                    notationImpl.setPublicId(publicId);
2986:                    if (systemIdIndex != -1) {
2987:                        notationImpl.setSystemId(systemId);
2988:                    }
2989:
2990:                    fDocumentType.getNotations().setNamedItem(notationImpl);
2991:
2992:                    // create notation declaration
2993:                    if (fGrammarAccess) {
2994:                        Element schema = XUtil.getFirstChildElement(
2995:                                fDocumentType, "schema");
2996:                        Element notation = XUtil.getFirstChildElement(schema,
2997:                                "notation", "name", notationName);
2998:                        if (notation == null) {
2999:                            notation = fDocument.createElement("notation");
3000:                            notation.setAttribute("name", notationName);
3001:                            //notation.setAttribute("export", "true");
3002:                            //((AttrImpl)notation.getAttributeNode("export")).setSpecified(false);
3003:                            if (publicId != null) {
3004:                                notation.setAttribute("public", publicId);
3005:                            }
3006:                            if (systemIdIndex != -1) {
3007:                                notation.setAttribute("system", systemId);
3008:                            }
3009:                            schema.appendChild(notation);
3010:                        }
3011:                    }
3012:                }
3013:
3014:            } // notationDecl(int,int,int)
3015:
3016:            //
3017:            // Private methods
3018:            //
3019:
3020:            /** Returns the first child element of the specified node. */
3021:            private int getFirstChildElement(int nodeIndex) {
3022:                int childIndex = getLastChildElement(nodeIndex);
3023:                while (childIndex != -1) {
3024:                    int prevIndex = getPrevSiblingElement(childIndex);
3025:                    if (prevIndex == -1) {
3026:                        break;
3027:                    }
3028:                    childIndex = prevIndex;
3029:                }
3030:                return childIndex;
3031:            }
3032:
3033:            /** Returns the first child element of the specified node. */
3034:            private int getFirstChildElement(int nodeIndex, String name) {
3035:                int childIndex = getLastChildElement(nodeIndex);
3036:                if (childIndex != -1) {
3037:                    int nameIndex = fStringPool.addSymbol(name);
3038:                    while (childIndex != -1) {
3039:                        if (fDeferredDocumentImpl
3040:                                .getNodeName(childIndex, false) == nameIndex) {
3041:                            break;
3042:                        }
3043:                        int prevIndex = getPrevSiblingElement(childIndex);
3044:                        childIndex = prevIndex;
3045:                    }
3046:                }
3047:                return childIndex;
3048:            }
3049:
3050:            /** Returns the last child element of the specified node. */
3051:            private int getLastChildElement(int nodeIndex) {
3052:                int childIndex = fDeferredDocumentImpl.getLastChild(nodeIndex,
3053:                        false);
3054:                while (childIndex != -1) {
3055:                    if (fDeferredDocumentImpl.getNodeType(childIndex, false) == Node.ELEMENT_NODE) {
3056:                        return childIndex;
3057:                    }
3058:                    childIndex = fDeferredDocumentImpl.getPrevSibling(
3059:                            childIndex, false);
3060:                }
3061:                return -1;
3062:            }
3063:
3064:            /** Returns the previous sibling element of the specified node. */
3065:            private int getPrevSiblingElement(int nodeIndex) {
3066:                int siblingIndex = fDeferredDocumentImpl.getPrevSibling(
3067:                        nodeIndex, false);
3068:                while (siblingIndex != -1) {
3069:                    if (fDeferredDocumentImpl.getNodeType(siblingIndex, false) == Node.ELEMENT_NODE) {
3070:                        return siblingIndex;
3071:                    }
3072:                    siblingIndex = fDeferredDocumentImpl.getPrevSibling(
3073:                            siblingIndex, false);
3074:                }
3075:                return -1;
3076:            }
3077:
3078:            /** Returns the first child element with the given name. */
3079:            private int getLastChildElement(int nodeIndex, String elementName) {
3080:                int childIndex = getLastChildElement(nodeIndex);
3081:                if (childIndex != -1) {
3082:                    while (childIndex != -1) {
3083:                        String nodeName = fDeferredDocumentImpl
3084:                                .getNodeNameString(childIndex, false);
3085:                        if (nodeName.equals(elementName)) {
3086:                            return childIndex;
3087:                        }
3088:                        childIndex = getPrevSiblingElement(childIndex);
3089:                    }
3090:                }
3091:                return -1;
3092:            }
3093:
3094:            /** Returns the next sibling element with the given name. */
3095:            private int getPrevSiblingElement(int nodeIndex, String elementName) {
3096:                int siblingIndex = getPrevSiblingElement(nodeIndex);
3097:                if (siblingIndex != -1) {
3098:                    while (siblingIndex != -1) {
3099:                        String nodeName = fDeferredDocumentImpl
3100:                                .getNodeNameString(siblingIndex, false);
3101:                        if (nodeName.equals(elementName)) {
3102:                            return siblingIndex;
3103:                        }
3104:                        siblingIndex = getPrevSiblingElement(siblingIndex);
3105:                    }
3106:                }
3107:                return -1;
3108:            }
3109:
3110:            /** Returns the first child element with the given name. */
3111:            private int getLastChildElement(int nodeIndex, String elemName,
3112:                    String attrName, String attrValue) {
3113:                int childIndex = getLastChildElement(nodeIndex, elemName);
3114:                if (childIndex != -1) {
3115:                    while (childIndex != -1) {
3116:                        int attrIndex = fDeferredDocumentImpl.getNodeValue(
3117:                                childIndex, false);
3118:                        while (attrIndex != -1) {
3119:                            String nodeName = fDeferredDocumentImpl
3120:                                    .getNodeNameString(attrIndex, false);
3121:                            if (nodeName.equals(attrName)) {
3122:                                // REVISIT: Do we need to normalize the text? -Ac
3123:                                int textIndex = fDeferredDocumentImpl
3124:                                        .getLastChild(attrIndex, false);
3125:                                String nodeValue = fDeferredDocumentImpl
3126:                                        .getNodeValueString(textIndex, false);
3127:                                if (nodeValue.equals(attrValue)) {
3128:                                    return childIndex;
3129:                                }
3130:                            }
3131:                            attrIndex = fDeferredDocumentImpl.getPrevSibling(
3132:                                    attrIndex, false);
3133:                        }
3134:                        childIndex = getPrevSiblingElement(childIndex, elemName);
3135:                    }
3136:                }
3137:                return -1;
3138:            }
3139:
3140:            /** Returns the next sibling element with the given name and attribute. */
3141:            private int getPrevSiblingElement(int nodeIndex, String elemName,
3142:                    String attrName, String attrValue) {
3143:                int siblingIndex = getPrevSiblingElement(nodeIndex, elemName);
3144:                if (siblingIndex != -1) {
3145:                    int attributeNameIndex = fStringPool.addSymbol(attrName);
3146:                    while (siblingIndex != -1) {
3147:                        int attrIndex = fDeferredDocumentImpl.getNodeValue(
3148:                                siblingIndex, false);
3149:                        while (attrIndex != -1) {
3150:                            int attrValueIndex = fDeferredDocumentImpl
3151:                                    .getNodeValue(attrIndex, false);
3152:                            if (attrValue.equals(fStringPool
3153:                                    .toString(attrValueIndex))) {
3154:                                return siblingIndex;
3155:                            }
3156:                            attrIndex = fDeferredDocumentImpl.getPrevSibling(
3157:                                    attrIndex, false);
3158:                        }
3159:                        siblingIndex = getPrevSiblingElement(siblingIndex,
3160:                                elemName);
3161:                    }
3162:                }
3163:                return -1;
3164:            }
3165:
3166:            /**
3167:             * Copies the source tree into the specified place in a destination
3168:             * tree. The source node and its children are appended as children
3169:             * of the destination node.
3170:             * <p>
3171:             * <em>Note:</em> This is an iterative implementation.
3172:             */
3173:            private void copyInto(Node src, int destIndex) throws Exception {
3174:
3175:                // for ignorable whitespace features
3176:                boolean domimpl = src != null && src instanceof  DocumentImpl;
3177:
3178:                // placement variables
3179:                Node start = src;
3180:                Node parent = src;
3181:                Node place = src;
3182:
3183:                // traverse source tree
3184:                while (place != null) {
3185:
3186:                    // copy this node
3187:                    int nodeIndex = -1;
3188:                    short type = place.getNodeType();
3189:                    switch (type) {
3190:                    case Node.CDATA_SECTION_NODE: {
3191:                        boolean ignorable = domimpl
3192:                                && ((TextImpl) place).isIgnorableWhitespace();
3193:                        nodeIndex = fDeferredDocumentImpl.createCDATASection(
3194:                                fStringPool.addString(place.getNodeValue()),
3195:                                ignorable);
3196:                        break;
3197:                    }
3198:                    case Node.COMMENT_NODE: {
3199:                        nodeIndex = fDeferredDocumentImpl
3200:                                .createComment(fStringPool.addString(place
3201:                                        .getNodeValue()));
3202:                        break;
3203:                    }
3204:                    case Node.ELEMENT_NODE: {
3205:                        XMLAttrList attrList = null;
3206:                        int handle = -1;
3207:                        NamedNodeMap attrs = place.getAttributes();
3208:                        if (attrs != null) {
3209:                            int length = attrs.getLength();
3210:                            if (length > 0) {
3211:                                handle = fAttrList.startAttrList();
3212:                                for (int i = 0; i < length; i++) {
3213:                                    Attr attr = (Attr) attrs.item(i);
3214:                                    String attrName = attr.getNodeName();
3215:                                    String attrValue = attr.getNodeValue();
3216:                                    fAttrList.addAttr(fStringPool
3217:                                            .addSymbol(attrName), fStringPool
3218:                                            .addString(attrValue), fStringPool
3219:                                            .addSymbol("CDATA"), // REVISIT
3220:                                            attr.getSpecified(), false); // search
3221:                                }
3222:                                fAttrList.endAttrList();
3223:                                attrList = fAttrList;
3224:                            }
3225:                        }
3226:                        nodeIndex = fDeferredDocumentImpl.createElement(
3227:                                fStringPool.addSymbol(place.getNodeName()),
3228:                                attrList, handle);
3229:                        break;
3230:                    }
3231:                    case Node.ENTITY_REFERENCE_NODE: {
3232:                        nodeIndex = fDeferredDocumentImpl
3233:                                .createEntityReference(fStringPool
3234:                                        .addSymbol(place.getNodeName()));
3235:                        break;
3236:                    }
3237:                    case Node.PROCESSING_INSTRUCTION_NODE: {
3238:                        nodeIndex = fDeferredDocumentImpl
3239:                                .createProcessingInstruction(fStringPool
3240:                                        .addSymbol(place.getNodeName()),
3241:                                        fStringPool.addString(place
3242:                                                .getNodeValue()));
3243:                        break;
3244:                    }
3245:                    case Node.TEXT_NODE: {
3246:                        boolean ignorable = domimpl
3247:                                && ((TextImpl) place).isIgnorableWhitespace();
3248:                        nodeIndex = fDeferredDocumentImpl.createTextNode(
3249:                                fStringPool.addString(place.getNodeValue()),
3250:                                ignorable);
3251:                        break;
3252:                    }
3253:                    default: {
3254:                        throw new IllegalArgumentException(
3255:                                "PAR010 Can't copy node type, " + type + " ("
3256:                                        + place.getNodeName() + ')' + "\n"
3257:                                        + type + "\t" + place.getNodeName());
3258:                    }
3259:                    }
3260:                    fDeferredDocumentImpl.appendChild(destIndex, nodeIndex);
3261:
3262:                    // iterate over children
3263:                    if (place.hasChildNodes()) {
3264:                        parent = place;
3265:                        place = place.getFirstChild();
3266:                        destIndex = nodeIndex;
3267:                    }
3268:
3269:                    // advance
3270:                    else {
3271:                        place = place.getNextSibling();
3272:                        while (place == null && parent != start) {
3273:                            place = parent.getNextSibling();
3274:                            parent = parent.getParentNode();
3275:                            destIndex = fDeferredDocumentImpl.getParentNode(
3276:                                    destIndex, false);
3277:                        }
3278:                    }
3279:
3280:                }
3281:
3282:            } // copyInto(Node,int)
3283:
3284:            /**
3285:             * Sets the appropriate occurrence count attributes on the specified
3286:             * model element.
3287:             */
3288:            private void setOccurrenceCount(Element model, int minOccur,
3289:                    int maxOccur) {
3290:
3291:                // min
3292:                model.setAttribute("minOccurs", Integer.toString(minOccur));
3293:                if (minOccur == 1) {
3294:                    ((AttrImpl) model.getAttributeNode("minOccurs"))
3295:                            .setSpecified(false);
3296:                }
3297:
3298:                // max
3299:                if (maxOccur == -1) {
3300:                    model.setAttribute("maxOccurs", "*");
3301:                } else if (maxOccur != 1) {
3302:                    model.setAttribute("maxOccurs", Integer.toString(maxOccur));
3303:                }
3304:
3305:            } // setOccurrenceCount(Element,int,int)
3306:
3307:            /** Creates the children for the element decl. */
3308:            private Element createChildren(XMLContentSpec.Provider provider,
3309:                    int index, XMLContentSpec node, DocumentImpl factory,
3310:                    Element parent) throws Exception {
3311:
3312:                // get occurrence count
3313:                provider.getContentSpec(index, node);
3314:                int occurs = -1;
3315:                switch (node.type) {
3316:                case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
3317:                    occurs = '+';
3318:                    provider.getContentSpec(node.value, node);
3319:                    break;
3320:                }
3321:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
3322:                    occurs = '*';
3323:                    provider.getContentSpec(node.value, node);
3324:                    break;
3325:                }
3326:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
3327:                    occurs = '?';
3328:                    provider.getContentSpec(node.value, node);
3329:                    break;
3330:                }
3331:                }
3332:
3333:                // flatten model
3334:                int nodeType = node.type;
3335:                switch (nodeType) {
3336:
3337:                // CHOICE or SEQUENCE
3338:                case XMLContentSpec.CONTENTSPECNODE_CHOICE:
3339:                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
3340:
3341:                    // go down left side
3342:                    int leftIndex = node.value;
3343:                    int rightIndex = node.otherValue;
3344:                    Element left = createChildren(provider, leftIndex, node,
3345:                            factory, parent);
3346:
3347:                    // go down right side
3348:                    Element right = createChildren(provider, rightIndex, node,
3349:                            factory, null);
3350:
3351:                    // append left children
3352:                    boolean choice = nodeType == XMLContentSpec.CONTENTSPECNODE_CHOICE;
3353:                    String type = choice ? "choice" : "sequence";
3354:                    Element model = left;
3355:                    if (!left.getNodeName().equals(type)) {
3356:                        String minOccurs = left.getAttribute("minOccurs");
3357:                        String maxOccurs = left.getAttribute("maxOccurs");
3358:                        boolean min1 = minOccurs.length() == 0
3359:                                || minOccurs.equals("1");
3360:                        boolean max1 = maxOccurs.length() == 0
3361:                                || maxOccurs.equals("1");
3362:                        if (parent == null || (min1 && max1)) {
3363:                            model = factory.createElement(type);
3364:                            model.appendChild(left);
3365:                        } else {
3366:                            model = parent;
3367:                        }
3368:                    }
3369:
3370:                    // set occurrence count
3371:                    switch (occurs) {
3372:                    case '+': {
3373:                        model.setAttribute("maxOccurs", "unbounded");
3374:                        break;
3375:                    }
3376:                    case '*': {
3377:                        model.setAttribute("minOccurs", "0");
3378:                        model.setAttribute("maxOccurs", "unbounded");
3379:                        break;
3380:                    }
3381:                    case '?': {
3382:                        model.setAttribute("minOccurs", "0");
3383:                        break;
3384:                    }
3385:                    }
3386:
3387:                    // append right children
3388:                    model.appendChild(right);
3389:
3390:                    // return model
3391:                    return model;
3392:                }
3393:
3394:                    // LEAF
3395:                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
3396:                    Element leaf = factory.createElement("element");
3397:                    leaf.setAttribute("ref", fStringPool.toString(node.value));
3398:                    switch (occurs) {
3399:                    case '+': {
3400:                        leaf.setAttribute("maxOccurs", "unbounded");
3401:                        break;
3402:                    }
3403:                    case '*': {
3404:                        leaf.setAttribute("minOccurs", "0");
3405:                        leaf.setAttribute("maxOccurs", "unbounded");
3406:                        break;
3407:                    }
3408:                    case '?': {
3409:                        leaf.setAttribute("minOccurs", "0");
3410:                        break;
3411:                    }
3412:                    }
3413:                    return leaf;
3414:                }
3415:
3416:                } // switch node type
3417:
3418:                // error
3419:                return null;
3420:
3421:            } // createChildren(XMLContentSpec.Provider,int,XMLContentSpec,DocumentImpl,Element):Element
3422:
3423:            /** Creates the children for the deferred element decl. */
3424:            private int createChildren(XMLContentSpec.Provider provider,
3425:                    int index, XMLContentSpec node,
3426:                    DeferredDocumentImpl factory, int parent) throws Exception {
3427:
3428:                // get occurrence count
3429:                provider.getContentSpec(index, node);
3430:                int occurs = -1;
3431:                switch (node.type) {
3432:                case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
3433:                    occurs = '+';
3434:                    provider.getContentSpec(node.value, node);
3435:                    break;
3436:                }
3437:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
3438:                    occurs = '*';
3439:                    provider.getContentSpec(node.value, node);
3440:                    break;
3441:                }
3442:                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
3443:                    occurs = '?';
3444:                    provider.getContentSpec(node.value, node);
3445:                    break;
3446:                }
3447:                }
3448:
3449:                // flatten model
3450:                int nodeType = node.type;
3451:                switch (nodeType) {
3452:
3453:                // CHOICE or SEQUENCE
3454:                case XMLContentSpec.CONTENTSPECNODE_CHOICE:
3455:                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
3456:
3457:                    // go down left side
3458:                    int leftIndex = node.value;
3459:                    int rightIndex = node.otherValue;
3460:                    int left = createChildren(provider, leftIndex, node,
3461:                            factory, parent);
3462:
3463:                    // go down right side
3464:                    int right = createChildren(provider, rightIndex, node,
3465:                            factory, -1);
3466:
3467:                    // append left children
3468:                    boolean choice = nodeType == XMLContentSpec.CONTENTSPECNODE_CHOICE;
3469:                    int type = fStringPool.addSymbol(choice ? "choice"
3470:                            : "sequence");
3471:                    int model = left;
3472:                    if (factory.getNodeName(left, false) != type) {
3473:                        int minOccurs = factory.getAttribute(left, fStringPool
3474:                                .addSymbol("minOccurs"));
3475:                        int maxOccurs = factory.getAttribute(left, fStringPool
3476:                                .addSymbol("maxOccurs"));
3477:                        boolean min1 = minOccurs == -1
3478:                                || fStringPool.toString(minOccurs).equals("1");
3479:                        boolean max1 = maxOccurs == -1
3480:                                || fStringPool.toString(maxOccurs).equals("1");
3481:                        if (parent == -1 || (min1 && max1)) {
3482:                            model = factory.createElement(type, null, -1);
3483:                            factory.appendChild(model, left);
3484:                        } else {
3485:                            model = parent;
3486:                        }
3487:                    }
3488:
3489:                    // set occurrence count
3490:                    switch (occurs) {
3491:                    case '+': {
3492:                        int maxOccurs = factory.createAttribute(fStringPool
3493:                                .addSymbol("maxOccurs"), fStringPool
3494:                                .addString("unbounded"), true);
3495:                        factory.setAttributeNode(model, maxOccurs);
3496:                        break;
3497:                    }
3498:                    case '*': {
3499:                        int minOccurs = factory.createAttribute(fStringPool
3500:                                .addSymbol("minOccurs"), fStringPool
3501:                                .addString("0"), true);
3502:                        factory.setAttributeNode(model, minOccurs);
3503:                        int maxOccurs = factory.createAttribute(fStringPool
3504:                                .addSymbol("maxOccurs"), fStringPool
3505:                                .addString("unbounded"), true);
3506:                        factory.setAttributeNode(model, maxOccurs);
3507:                        break;
3508:                    }
3509:                    case '?': {
3510:                        int minOccurs = factory.createAttribute(fStringPool
3511:                                .addSymbol("minOccurs"), fStringPool
3512:                                .addString("0"), true);
3513:                        factory.setAttributeNode(model, minOccurs);
3514:                        break;
3515:                    }
3516:                    }
3517:
3518:                    // append right children
3519:                    factory.appendChild(model, right);
3520:
3521:                    // return model
3522:                    return model;
3523:                }
3524:
3525:                    // LEAF
3526:                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
3527:                    int handle = fAttrList.startAttrList();
3528:                    fAttrList.addAttr(fStringPool.addSymbol("ref"), fStringPool
3529:                            .addString(fStringPool.toString(node.value)),
3530:                            fStringPool.addSymbol("NMTOKEN"), true, false); // search
3531:                    switch (occurs) {
3532:                    case '+': {
3533:                        fAttrList.addAttr(fStringPool.addSymbol("maxOccurs"),
3534:                                fStringPool.addString("unbounded"), fStringPool
3535:                                        .addSymbol("CDATA"), true, false); // search
3536:                        break;
3537:                    }
3538:                    case '*': {
3539:                        fAttrList.addAttr(fStringPool.addSymbol("minOccurs"),
3540:                                fStringPool.addString("0"), fStringPool
3541:                                        .addSymbol("NMTOKEN"), true, false); // search
3542:                        fAttrList.addAttr(fStringPool.addSymbol("maxOccurs"),
3543:                                fStringPool.addString("unbounded"), fStringPool
3544:                                        .addSymbol("CDATA"), true, false); // search
3545:                        break;
3546:                    }
3547:                    case '?': {
3548:                        fAttrList.addAttr(fStringPool.addSymbol("minOccurs"),
3549:                                fStringPool.addString("0"), fStringPool
3550:                                        .addSymbol("NMTOKEN"), true, false); // search
3551:                        break;
3552:                    }
3553:                    }
3554:                    fAttrList.endAttrList();
3555:                    int leaf = factory.createElement(fStringPool
3556:                            .addSymbol("element"), fAttrList, handle);
3557:                    return leaf;
3558:                }
3559:
3560:                } // switch node type
3561:
3562:                // error
3563:                return -1;
3564:
3565:            } // createChildren(XMLContentSpec.Provider,int,XMLContentSpec,DeferredDocumentImpl,int):int
3566:
3567:        } // class DOMParser
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.