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

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


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         * 
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         * 
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:
0018:        package org.apache.xerces.dom;
0019:
0020:        import java.io.IOException;
0021:        import java.io.ObjectOutputStream;
0022:        import java.io.Serializable;
0023:        import java.util.Hashtable;
0024:
0025:        import org.w3c.dom.UserDataHandler;
0026:        import org.w3c.dom.DOMException;
0027:        import org.w3c.dom.Document;
0028:        import org.w3c.dom.DocumentType;
0029:        import org.w3c.dom.NamedNodeMap;
0030:        import org.w3c.dom.Node;
0031:        import org.w3c.dom.NodeList;
0032:        import org.w3c.dom.events.Event;
0033:        import org.w3c.dom.events.EventListener;
0034:        import org.w3c.dom.events.EventTarget;
0035:
0036:        /**
0037:         * NodeImpl provides the basic structure of a DOM tree. It is never used
0038:         * directly, but instead is subclassed to add type and data
0039:         * information, and additional methods, appropriate to each node of
0040:         * the tree. Only its subclasses should be instantiated -- and those,
0041:         * with the exception of Document itself, only through a specific
0042:         * Document's factory methods.
0043:         * <P>
0044:         * The Node interface provides shared behaviors such as siblings and
0045:         * children, both for consistancy and so that the most common tree
0046:         * operations may be performed without constantly having to downcast
0047:         * to specific node types. When there is no obvious mapping for one of
0048:         * these queries, it will respond with null.
0049:         * Note that the default behavior is that children are forbidden. To
0050:         * permit them, the subclass ParentNode overrides several methods.
0051:         * <P>
0052:         * NodeImpl also implements NodeList, so it can return itself in
0053:         * response to the getChildNodes() query. This eliminiates the need
0054:         * for a separate ChildNodeList object. Note that this is an
0055:         * IMPLEMENTATION DETAIL; applications should _never_ assume that
0056:         * this identity exists.
0057:         * <P>
0058:         * All nodes in a single document must originate
0059:         * in that document. (Note that this is much tighter than "must be
0060:         * same implementation") Nodes are all aware of their ownerDocument,
0061:         * and attempts to mismatch will throw WRONG_DOCUMENT_ERR.
0062:         * <P>
0063:         * However, to save memory not all nodes always have a direct reference
0064:         * to their ownerDocument. When a node is owned by another node it relies
0065:         * on its owner to store its ownerDocument. Parent nodes always store it
0066:         * though, so there is never more than one level of indirection.
0067:         * And when a node doesn't have an owner, ownerNode refers to its
0068:         * ownerDocument.
0069:         * <p>
0070:         * This class doesn't directly support mutation events, however, it still
0071:         * implements the EventTarget interface and forward all related calls to the
0072:         * document so that the document class do so.
0073:         * 
0074:         * @xerces.internal
0075:         *
0076:         * @author Arnaud  Le Hors, IBM
0077:         * @author Joe Kesselman, IBM
0078:         * @version $Id: NodeImpl.java 449328 2006-09-23 22:58:23Z mrglavas $
0079:         * @since  PR-DOM-Level-1-19980818.
0080:         */
0081:        public abstract class NodeImpl implements  Node, NodeList, EventTarget,
0082:                Cloneable, Serializable {
0083:
0084:            //
0085:            // Constants
0086:            //
0087:
0088:            // TreePosition Constants.
0089:            // Taken from DOM L3 Node interface.
0090:            /**
0091:             * The node precedes the reference node.
0092:             */
0093:            public static final short TREE_POSITION_PRECEDING = 0x01;
0094:            /**
0095:             * The node follows the reference node.
0096:             */
0097:            public static final short TREE_POSITION_FOLLOWING = 0x02;
0098:            /**
0099:             * The node is an ancestor of the reference node.
0100:             */
0101:            public static final short TREE_POSITION_ANCESTOR = 0x04;
0102:            /**
0103:             * The node is a descendant of the reference node.
0104:             */
0105:            public static final short TREE_POSITION_DESCENDANT = 0x08;
0106:            /**
0107:             * The two nodes have an equivalent position. This is the case of two 
0108:             * attributes that have the same <code>ownerElement</code>, and two 
0109:             * nodes that are the same.
0110:             */
0111:            public static final short TREE_POSITION_EQUIVALENT = 0x10;
0112:            /**
0113:             * The two nodes are the same. Two nodes that are the same have an 
0114:             * equivalent position, though the reverse may not be true.
0115:             */
0116:            public static final short TREE_POSITION_SAME_NODE = 0x20;
0117:            /**
0118:             * The two nodes are disconnected, they do not have any common ancestor. 
0119:             * This is the case of two nodes that are not in the same document.
0120:             */
0121:            public static final short TREE_POSITION_DISCONNECTED = 0x00;
0122:
0123:            // DocumentPosition
0124:            public static final short DOCUMENT_POSITION_DISCONNECTED = 0x01;
0125:            public static final short DOCUMENT_POSITION_PRECEDING = 0x02;
0126:            public static final short DOCUMENT_POSITION_FOLLOWING = 0x04;
0127:            public static final short DOCUMENT_POSITION_CONTAINS = 0x08;
0128:            public static final short DOCUMENT_POSITION_IS_CONTAINED = 0x10;
0129:            public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
0130:
0131:            /** Serialization version. */
0132:            static final long serialVersionUID = -6316591992167219696L;
0133:
0134:            // public
0135:
0136:            /** Element definition node type. */
0137:            public static final short ELEMENT_DEFINITION_NODE = 21;
0138:
0139:            //
0140:            // Data
0141:            //
0142:
0143:            // links
0144:
0145:            protected NodeImpl ownerNode; // typically the parent but not always!
0146:
0147:            // data
0148:
0149:            protected short flags;
0150:
0151:            protected final static short READONLY = 0x1 << 0;
0152:            protected final static short SYNCDATA = 0x1 << 1;
0153:            protected final static short SYNCCHILDREN = 0x1 << 2;
0154:            protected final static short OWNED = 0x1 << 3;
0155:            protected final static short FIRSTCHILD = 0x1 << 4;
0156:            protected final static short SPECIFIED = 0x1 << 5;
0157:            protected final static short IGNORABLEWS = 0x1 << 6;
0158:            protected final static short HASSTRING = 0x1 << 7;
0159:            protected final static short NORMALIZED = 0x1 << 8;
0160:            protected final static short ID = 0x1 << 9;
0161:
0162:            //
0163:            // Constructors
0164:            //
0165:
0166:            /**
0167:             * No public constructor; only subclasses of Node should be
0168:             * instantiated, and those normally via a Document's factory methods
0169:             * <p>
0170:             * Every Node knows what Document it belongs to.
0171:             */
0172:            protected NodeImpl(CoreDocumentImpl ownerDocument) {
0173:                // as long as we do not have any owner, ownerNode is our ownerDocument
0174:                ownerNode = ownerDocument;
0175:            } // <init>(CoreDocumentImpl)
0176:
0177:            /** Constructor for serialization. */
0178:            public NodeImpl() {
0179:            }
0180:
0181:            //
0182:            // Node methods
0183:            //
0184:
0185:            /**
0186:             * A short integer indicating what type of node this is. The named
0187:             * constants for this value are defined in the org.w3c.dom.Node interface.
0188:             */
0189:            public abstract short getNodeType();
0190:
0191:            /**
0192:             * the name of this node.
0193:             */
0194:            public abstract String getNodeName();
0195:
0196:            /**
0197:             * Returns the node value.
0198:             * @throws DOMException(DOMSTRING_SIZE_ERR)
0199:             */
0200:            public String getNodeValue() throws DOMException {
0201:                return null; // overridden in some subclasses
0202:            }
0203:
0204:            /**
0205:             * Sets the node value.
0206:             * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR)
0207:             */
0208:            public void setNodeValue(String x) throws DOMException {
0209:                // Default behavior is to do nothing, overridden in some subclasses
0210:            }
0211:
0212:            /**
0213:             * Adds a child node to the end of the list of children for this node.
0214:             * Convenience shorthand for insertBefore(newChild,null).
0215:             * @see #insertBefore(Node, Node)
0216:             * <P>
0217:             * By default we do not accept any children, ParentNode overrides this.
0218:             * @see ParentNode
0219:             *
0220:             * @return newChild, in its new state (relocated, or emptied in the case of
0221:             * DocumentNode.)
0222:             *
0223:             * @throws DOMException(HIERARCHY_REQUEST_ERR) if newChild is of a
0224:             * type that shouldn't be a child of this node.
0225:             *
0226:             * @throws DOMException(WRONG_DOCUMENT_ERR) if newChild has a
0227:             * different owner document than we do.
0228:             *
0229:             * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if this node is
0230:             * read-only.
0231:             */
0232:            public Node appendChild(Node newChild) throws DOMException {
0233:                return insertBefore(newChild, null);
0234:            }
0235:
0236:            /**
0237:             * Returns a duplicate of a given node. You can consider this a
0238:             * generic "copy constructor" for nodes. The newly returned object should
0239:             * be completely independent of the source object's subtree, so changes
0240:             * in one after the clone has been made will not affect the other.
0241:             * <P>
0242:             * Note: since we never have any children deep is meaningless here,
0243:             * ParentNode overrides this behavior.
0244:             * @see ParentNode
0245:             *
0246:             * <p>
0247:             * Example: Cloning a Text node will copy both the node and the text it
0248:             * contains.
0249:             * <p>
0250:             * Example: Cloning something that has children -- Element or Attr, for
0251:             * example -- will _not_ clone those children unless a "deep clone"
0252:             * has been requested. A shallow clone of an Attr node will yield an
0253:             * empty Attr of the same name.
0254:             * <p>
0255:             * NOTE: Clones will always be read/write, even if the node being cloned
0256:             * is read-only, to permit applications using only the DOM API to obtain
0257:             * editable copies of locked portions of the tree.
0258:             */
0259:            public Node cloneNode(boolean deep) {
0260:
0261:                if (needsSyncData()) {
0262:                    synchronizeData();
0263:                }
0264:
0265:                NodeImpl newnode;
0266:                try {
0267:                    newnode = (NodeImpl) clone();
0268:                } catch (CloneNotSupportedException e) {
0269:                    // if we get here we have an error in our program we may as well
0270:                    // be vocal about it, so that people can take appropriate action.
0271:                    throw new RuntimeException("**Internal Error**" + e);
0272:                }
0273:
0274:                // Need to break the association w/ original kids
0275:                newnode.ownerNode = ownerDocument();
0276:                newnode.isOwned(false);
0277:
0278:                // By default we make all clones readwrite,
0279:                // this is overriden in readonly subclasses
0280:                newnode.isReadOnly(false);
0281:
0282:                ownerDocument().callUserDataHandlers(this , newnode,
0283:                        UserDataHandler.NODE_CLONED);
0284:
0285:                return newnode;
0286:
0287:            } // cloneNode(boolean):Node
0288:
0289:            /**
0290:             * Find the Document that this Node belongs to (the document in
0291:             * whose context the Node was created). The Node may or may not
0292:             * currently be part of that Document's actual contents.
0293:             */
0294:            public Document getOwnerDocument() {
0295:                // if we have an owner simply forward the request
0296:                // otherwise ownerNode is our ownerDocument
0297:                if (isOwned()) {
0298:                    return ownerNode.ownerDocument();
0299:                } else {
0300:                    return (Document) ownerNode;
0301:                }
0302:            }
0303:
0304:            /**
0305:             * same as above but returns internal type and this one is not overridden
0306:             * by CoreDocumentImpl to return null 
0307:             */
0308:            CoreDocumentImpl ownerDocument() {
0309:                // if we have an owner simply forward the request
0310:                // otherwise ownerNode is our ownerDocument
0311:                if (isOwned()) {
0312:                    return ownerNode.ownerDocument();
0313:                } else {
0314:                    return (CoreDocumentImpl) ownerNode;
0315:                }
0316:            }
0317:
0318:            /**
0319:             * NON-DOM
0320:             * set the ownerDocument of this node
0321:             */
0322:            protected void setOwnerDocument(CoreDocumentImpl doc) {
0323:                if (needsSyncData()) {
0324:                    synchronizeData();
0325:                }
0326:                // if we have an owner we rely on it to have it right
0327:                // otherwise ownerNode is our ownerDocument
0328:                if (!isOwned()) {
0329:                    ownerNode = doc;
0330:                }
0331:            }
0332:
0333:            /**
0334:             * Returns the node number
0335:             */
0336:            protected int getNodeNumber() {
0337:                int nodeNumber;
0338:                CoreDocumentImpl cd = (CoreDocumentImpl) (this 
0339:                        .getOwnerDocument());
0340:                nodeNumber = cd.getNodeNumber(this );
0341:                return nodeNumber;
0342:            }
0343:
0344:            /**
0345:             * Obtain the DOM-tree parent of this node, or null if it is not
0346:             * currently active in the DOM tree (perhaps because it has just been
0347:             * created or removed). Note that Document, DocumentFragment, and
0348:             * Attribute will never have parents.
0349:             */
0350:            public Node getParentNode() {
0351:                return null; // overriden by ChildNode
0352:            }
0353:
0354:            /*
0355:             * same as above but returns internal type
0356:             */
0357:            NodeImpl parentNode() {
0358:                return null;
0359:            }
0360:
0361:            /** The next child of this node's parent, or null if none */
0362:            public Node getNextSibling() {
0363:                return null; // default behavior, overriden in ChildNode
0364:            }
0365:
0366:            /** The previous child of this node's parent, or null if none */
0367:            public Node getPreviousSibling() {
0368:                return null; // default behavior, overriden in ChildNode
0369:            }
0370:
0371:            ChildNode previousSibling() {
0372:                return null; // default behavior, overriden in ChildNode
0373:            }
0374:
0375:            /**
0376:             * Return the collection of attributes associated with this node,
0377:             * or null if none. At this writing, Element is the only type of node
0378:             * which will ever have attributes.
0379:             *
0380:             * @see ElementImpl
0381:             */
0382:            public NamedNodeMap getAttributes() {
0383:                return null; // overridden in ElementImpl
0384:            }
0385:
0386:            /**
0387:             *  Returns whether this node (if it is an element) has any attributes.
0388:             * @return <code>true</code> if this node has any attributes, 
0389:             *   <code>false</code> otherwise.
0390:             * @since DOM Level 2
0391:             * @see ElementImpl
0392:             */
0393:            public boolean hasAttributes() {
0394:                return false; // overridden in ElementImpl
0395:            }
0396:
0397:            /**
0398:             * Test whether this node has any children. Convenience shorthand
0399:             * for (Node.getFirstChild()!=null)
0400:             * <P>
0401:             * By default we do not have any children, ParentNode overrides this.
0402:             * @see ParentNode
0403:             */
0404:            public boolean hasChildNodes() {
0405:                return false;
0406:            }
0407:
0408:            /**
0409:             * Obtain a NodeList enumerating all children of this node. If there
0410:             * are none, an (initially) empty NodeList is returned.
0411:             * <p>
0412:             * NodeLists are "live"; as children are added/removed the NodeList
0413:             * will immediately reflect those changes. Also, the NodeList refers
0414:             * to the actual nodes, so changes to those nodes made via the DOM tree
0415:             * will be reflected in the NodeList and vice versa.
0416:             * <p>
0417:             * In this implementation, Nodes implement the NodeList interface and
0418:             * provide their own getChildNodes() support. Other DOMs may solve this
0419:             * differently.
0420:             */
0421:            public NodeList getChildNodes() {
0422:                return this ;
0423:            }
0424:
0425:            /** The first child of this Node, or null if none.
0426:             * <P>
0427:             * By default we do not have any children, ParentNode overrides this.
0428:             * @see ParentNode
0429:             */
0430:            public Node getFirstChild() {
0431:                return null;
0432:            }
0433:
0434:            /** The first child of this Node, or null if none.
0435:             * <P>
0436:             * By default we do not have any children, ParentNode overrides this.
0437:             * @see ParentNode
0438:             */
0439:            public Node getLastChild() {
0440:                return null;
0441:            }
0442:
0443:            /**
0444:             * Move one or more node(s) to our list of children. Note that this
0445:             * implicitly removes them from their previous parent.
0446:             * <P>
0447:             * By default we do not accept any children, ParentNode overrides this.
0448:             * @see ParentNode
0449:             *
0450:             * @param newChild The Node to be moved to our subtree. As a
0451:             * convenience feature, inserting a DocumentNode will instead insert
0452:             * all its children.
0453:             *
0454:             * @param refChild Current child which newChild should be placed
0455:             * immediately before. If refChild is null, the insertion occurs
0456:             * after all existing Nodes, like appendChild().
0457:             *
0458:             * @return newChild, in its new state (relocated, or emptied in the case of
0459:             * DocumentNode.)
0460:             *
0461:             * @throws DOMException(HIERARCHY_REQUEST_ERR) if newChild is of a
0462:             * type that shouldn't be a child of this node, or if newChild is an
0463:             * ancestor of this node.
0464:             *
0465:             * @throws DOMException(WRONG_DOCUMENT_ERR) if newChild has a
0466:             * different owner document than we do.
0467:             *
0468:             * @throws DOMException(NOT_FOUND_ERR) if refChild is not a child of
0469:             * this node.
0470:             *
0471:             * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if this node is
0472:             * read-only.
0473:             */
0474:            public Node insertBefore(Node newChild, Node refChild)
0475:                    throws DOMException {
0476:                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
0477:                        DOMMessageFormatter.formatMessage(
0478:                                DOMMessageFormatter.DOM_DOMAIN,
0479:                                "HIERARCHY_REQUEST_ERR", null));
0480:            }
0481:
0482:            /**
0483:             * Remove a child from this Node. The removed child's subtree
0484:             * remains intact so it may be re-inserted elsewhere.
0485:             * <P>
0486:             * By default we do not have any children, ParentNode overrides this.
0487:             * @see ParentNode
0488:             *
0489:             * @return oldChild, in its new state (removed).
0490:             *
0491:             * @throws DOMException(NOT_FOUND_ERR) if oldChild is not a child of
0492:             * this node.
0493:             *
0494:             * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if this node is
0495:             * read-only.
0496:             */
0497:            public Node removeChild(Node oldChild) throws DOMException {
0498:                throw new DOMException(DOMException.NOT_FOUND_ERR,
0499:                        DOMMessageFormatter.formatMessage(
0500:                                DOMMessageFormatter.DOM_DOMAIN,
0501:                                "NOT_FOUND_ERR", null));
0502:            }
0503:
0504:            /**
0505:             * Make newChild occupy the location that oldChild used to
0506:             * have. Note that newChild will first be removed from its previous
0507:             * parent, if any. Equivalent to inserting newChild before oldChild,
0508:             * then removing oldChild.
0509:             * <P>
0510:             * By default we do not have any children, ParentNode overrides this.
0511:             * @see ParentNode
0512:             *
0513:             * @return oldChild, in its new state (removed).
0514:             *
0515:             * @throws DOMException(HIERARCHY_REQUEST_ERR) if newChild is of a
0516:             * type that shouldn't be a child of this node, or if newChild is
0517:             * one of our ancestors.
0518:             *
0519:             * @throws DOMException(WRONG_DOCUMENT_ERR) if newChild has a
0520:             * different owner document than we do.
0521:             *
0522:             * @throws DOMException(NOT_FOUND_ERR) if oldChild is not a child of
0523:             * this node.
0524:             *
0525:             * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) if this node is
0526:             * read-only.
0527:             */
0528:            public Node replaceChild(Node newChild, Node oldChild)
0529:                    throws DOMException {
0530:                throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
0531:                        DOMMessageFormatter.formatMessage(
0532:                                DOMMessageFormatter.DOM_DOMAIN,
0533:                                "HIERARCHY_REQUEST_ERR", null));
0534:            }
0535:
0536:            //
0537:            // NodeList methods
0538:            //
0539:
0540:            /**
0541:             * NodeList method: Count the immediate children of this node
0542:             * <P>
0543:             * By default we do not have any children, ParentNode overrides this.
0544:             * @see ParentNode
0545:             *
0546:             * @return int
0547:             */
0548:            public int getLength() {
0549:                return 0;
0550:            }
0551:
0552:            /**
0553:             * NodeList method: Return the Nth immediate child of this node, or
0554:             * null if the index is out of bounds.
0555:             * <P>
0556:             * By default we do not have any children, ParentNode overrides this.
0557:             * @see ParentNode
0558:             *
0559:             * @return org.w3c.dom.Node
0560:             * @param index int
0561:             */
0562:            public Node item(int index) {
0563:                return null;
0564:            }
0565:
0566:            //
0567:            // DOM2: methods, getters, setters
0568:            //
0569:
0570:            /**
0571:             * Puts all <code>Text</code> nodes in the full depth of the sub-tree 
0572:             * underneath this <code>Node</code>, including attribute nodes, into a 
0573:             * "normal" form where only markup (e.g., tags, comments, processing 
0574:             * instructions, CDATA sections, and entity references) separates 
0575:             * <code>Text</code> nodes, i.e., there are no adjacent <code>Text</code> 
0576:             * nodes.  This can be used to ensure that the DOM view of a document is 
0577:             * the same as if it were saved and re-loaded, and is useful when 
0578:             * operations (such as XPointer lookups) that depend on a particular 
0579:             * document tree structure are to be used.In cases where the document 
0580:             * contains <code>CDATASections</code>, the normalize operation alone may 
0581:             * not be sufficient, since XPointers do not differentiate between 
0582:             * <code>Text</code> nodes and <code>CDATASection</code> nodes.
0583:             * <p>
0584:             * Note that this implementation simply calls normalize() on this Node's
0585:             * children. It is up to implementors or Node to override normalize()
0586:             * to take action.
0587:             */
0588:            public void normalize() {
0589:                /* by default we do not have any children,
0590:                   ParentNode overrides this behavior */
0591:            }
0592:
0593:            /**
0594:             * Introduced in DOM Level 2. <p>
0595:             * Tests whether the DOM implementation implements a specific feature and
0596:             * that feature is supported by this node.
0597:             * @param feature The package name of the feature to test. This is the same
0598:             * name as what can be passed to the method hasFeature on
0599:             * DOMImplementation.
0600:             * @param version This is the version number of the package name to
0601:             * test. In Level 2, version 1, this is the string "2.0". If the version is
0602:             * not specified, supporting any version of the feature will cause the
0603:             * method to return true.
0604:             * @return boolean Returns true if this node defines a subtree within which
0605:             * the specified feature is supported, false otherwise.
0606:             * @since WD-DOM-Level-2-19990923
0607:             */
0608:            public boolean isSupported(String feature, String version) {
0609:                return ownerDocument().getImplementation().hasFeature(feature,
0610:                        version);
0611:            }
0612:
0613:            /**
0614:             * Introduced in DOM Level 2. <p>
0615:             *
0616:             * The namespace URI of this node, or null if it is unspecified. When this
0617:             * node is of any type other than ELEMENT_NODE and ATTRIBUTE_NODE, this is
0618:             * always null and setting it has no effect. <p>
0619:             *
0620:             * This is not a computed value that is the result of a namespace lookup
0621:             * based on an examination of the namespace declarations in scope. It is
0622:             * merely the namespace URI given at creation time.<p>
0623:             *
0624:             * For nodes created with a DOM Level 1 method, such as createElement
0625:             * from the Document interface, this is null.
0626:             * @since WD-DOM-Level-2-19990923
0627:             * @see AttrNSImpl
0628:             * @see ElementNSImpl
0629:             */
0630:            public String getNamespaceURI() {
0631:                return null;
0632:            }
0633:
0634:            /**
0635:             * Introduced in DOM Level 2. <p>
0636:             *
0637:             * The namespace prefix of this node, or null if it is unspecified. When
0638:             * this node is of any type other than ELEMENT_NODE and ATTRIBUTE_NODE this
0639:             * is always null and setting it has no effect.<p>
0640:             *
0641:             * For nodes created with a DOM Level 1 method, such as createElement
0642:             * from the Document interface, this is null. <p>
0643:             *
0644:             * @since WD-DOM-Level-2-19990923
0645:             * @see AttrNSImpl
0646:             * @see ElementNSImpl
0647:             */
0648:            public String getPrefix() {
0649:                return null;
0650:            }
0651:
0652:            /**
0653:             *  Introduced in DOM Level 2. <p>
0654:             *
0655:             *  The namespace prefix of this node, or null if it is unspecified. When
0656:             *  this node is of any type other than ELEMENT_NODE and ATTRIBUTE_NODE
0657:             *  this is always null and setting it has no effect.<p>
0658:             *
0659:             *  For nodes created with a DOM Level 1 method, such as createElement from
0660:             *  the Document interface, this is null.<p>
0661:             *
0662:             *  Note that setting this attribute changes the nodeName attribute, which
0663:             *  holds the qualified name, as well as the tagName and name attributes of
0664:             *  the Element and Attr interfaces, when applicable.<p>
0665:             *
0666:             * @throws INVALID_CHARACTER_ERR Raised if the specified
0667:             *  prefix contains an invalid character.
0668:             *
0669:             * @since WD-DOM-Level-2-19990923
0670:             * @see AttrNSImpl
0671:             * @see ElementNSImpl
0672:             */
0673:            public void setPrefix(String prefix) throws DOMException {
0674:                throw new DOMException(DOMException.NAMESPACE_ERR,
0675:                        DOMMessageFormatter.formatMessage(
0676:                                DOMMessageFormatter.DOM_DOMAIN,
0677:                                "NAMESPACE_ERR", null));
0678:            }
0679:
0680:            /**
0681:             * Introduced in DOM Level 2. <p>
0682:             *
0683:             * Returns the local part of the qualified name of this node.
0684:             * For nodes created with a DOM Level 1 method, such as createElement
0685:             * from the Document interface, and for nodes of any type other than
0686:             * ELEMENT_NODE and ATTRIBUTE_NODE this is the same as the nodeName
0687:             * attribute.
0688:             * @since WD-DOM-Level-2-19990923
0689:             * @see AttrNSImpl
0690:             * @see ElementNSImpl
0691:             */
0692:            public String getLocalName() {
0693:                return null;
0694:            }
0695:
0696:            //
0697:            // EventTarget support
0698:            //
0699:
0700:            public void addEventListener(String type, EventListener listener,
0701:                    boolean useCapture) {
0702:                // simply forward to Document
0703:                ownerDocument().addEventListener(this , type, listener,
0704:                        useCapture);
0705:            }
0706:
0707:            public void removeEventListener(String type,
0708:                    EventListener listener, boolean useCapture) {
0709:                // simply forward to Document
0710:                ownerDocument().removeEventListener(this , type, listener,
0711:                        useCapture);
0712:            }
0713:
0714:            public boolean dispatchEvent(Event event) {
0715:                // simply forward to Document
0716:                return ownerDocument().dispatchEvent(this , event);
0717:            }
0718:
0719:            //
0720:            // Public DOM Level 3 methods
0721:            //
0722:
0723:            /**
0724:             * The absolute base URI of this node or <code>null</code> if undefined. 
0725:             * This value is computed according to . However, when the 
0726:             * <code>Document</code> supports the feature "HTML" , the base URI is 
0727:             * computed using first the value of the href attribute of the HTML BASE 
0728:             * element if any, and the value of the <code>documentURI</code> 
0729:             * attribute from the <code>Document</code> interface otherwise.
0730:             * <br> When the node is an <code>Element</code>, a <code>Document</code> 
0731:             * or a a <code>ProcessingInstruction</code>, this attribute represents 
0732:             * the properties [base URI] defined in . When the node is a 
0733:             * <code>Notation</code>, an <code>Entity</code>, or an 
0734:             * <code>EntityReference</code>, this attribute represents the 
0735:             * properties [declaration base URI] in the . How will this be affected 
0736:             * by resolution of relative namespace URIs issue?It's not.Should this 
0737:             * only be on Document, Element, ProcessingInstruction, Entity, and 
0738:             * Notation nodes, according to the infoset? If not, what is it equal to 
0739:             * on other nodes? Null? An empty string? I think it should be the 
0740:             * parent's.No.Should this be read-only and computed or and actual 
0741:             * read-write attribute?Read-only and computed (F2F 19 Jun 2000 and 
0742:             * teleconference 30 May 2001).If the base HTML element is not yet 
0743:             * attached to a document, does the insert change the Document.baseURI?
0744:             * Yes. (F2F 26 Sep 2001)
0745:             * @since DOM Level 3
0746:             */
0747:            public String getBaseURI() {
0748:                return null;
0749:            }
0750:
0751:            /**
0752:             * Compares a node with this node with regard to their position in the 
0753:             * tree and according to the document order. This order can be extended 
0754:             * by module that define additional types of nodes.
0755:             * @param other The node to compare against this node.
0756:             * @return Returns how the given node is positioned relatively to this 
0757:             *   node.
0758:             * @since DOM Level 3
0759:             * @deprecated
0760:             */
0761:            public short compareTreePosition(Node other) {
0762:                // Questions of clarification for this method - to be answered by the
0763:                // DOM WG.   Current assumptions listed - LM
0764:                // 
0765:                // 1. How do ENTITY nodes compare?  
0766:                //    Current assumption: TREE_POSITION_DISCONNECTED, as ENTITY nodes 
0767:                //    aren't really 'in the tree'
0768:                //
0769:                // 2. How do NOTATION nodes compare?
0770:                //    Current assumption: TREE_POSITION_DISCONNECTED, as NOTATION nodes
0771:                //    aren't really 'in the tree'
0772:                //
0773:                // 3. Are TREE_POSITION_ANCESTOR and TREE_POSITION_DESCENDANT     
0774:                //    only relevant for nodes that are "part of the document tree"?   
0775:                //     <outer>
0776:                //         <inner  myattr="true"/>
0777:                //     </outer>
0778:                //    Is the element node "outer" considered an ancestor of "myattr"?
0779:                //    Current assumption: No.                                     
0780:                //
0781:                // 4. How do children of ATTRIBUTE nodes compare (with eachother, or  
0782:                //    with children of other attribute nodes with the same element)    
0783:                //    Current assumption: Children of ATTRIBUTE nodes are treated as if 
0784:                //    they they are the attribute node itself, unless the 2 nodes 
0785:                //    are both children of the same attribute. 
0786:                //
0787:                // 5. How does an ENTITY_REFERENCE node compare with it's children? 
0788:                //    Given the DOM, it should precede its children as an ancestor. 
0789:                //    Given "document order",  does it represent the same position?     
0790:                //    Current assumption: An ENTITY_REFERENCE node is an ancestor of its
0791:                //    children.
0792:                //
0793:                // 6. How do children of a DocumentFragment compare?   
0794:                //    Current assumption: If both nodes are part of the same document 
0795:                //    fragment, there are compared as if they were part of a document. 
0796:
0797:                // If the nodes are the same...
0798:                if (this  == other)
0799:                    return (TREE_POSITION_SAME_NODE | TREE_POSITION_EQUIVALENT);
0800:
0801:                // If either node is of type ENTITY or NOTATION, compare as disconnected
0802:                short this Type = this .getNodeType();
0803:                short otherType = other.getNodeType();
0804:
0805:                // If either node is of type ENTITY or NOTATION, compare as disconnected
0806:                if (this Type == Node.ENTITY_NODE
0807:                        || this Type == Node.NOTATION_NODE
0808:                        || otherType == Node.ENTITY_NODE
0809:                        || otherType == Node.NOTATION_NODE) {
0810:                    return TREE_POSITION_DISCONNECTED;
0811:                }
0812:
0813:                // Find the ancestor of each node, and the distance each node is from 
0814:                // its ancestor.
0815:                // During this traversal, look for ancestor/descendent relationships 
0816:                // between the 2 nodes in question. 
0817:                // We do this now, so that we get this info correct for attribute nodes 
0818:                // and their children. 
0819:
0820:                Node node;
0821:                Node this Ancestor = this ;
0822:                Node otherAncestor = other;
0823:                int this Depth = 0;
0824:                int otherDepth = 0;
0825:                for (node = this ; node != null; node = node.getParentNode()) {
0826:                    this Depth += 1;
0827:                    if (node == other)
0828:                        // The other node is an ancestor of this one.
0829:                        return (TREE_POSITION_ANCESTOR | TREE_POSITION_PRECEDING);
0830:                    this Ancestor = node;
0831:                }
0832:
0833:                for (node = other; node != null; node = node.getParentNode()) {
0834:                    otherDepth += 1;
0835:                    if (node == this )
0836:                        // The other node is a descendent of the reference node.
0837:                        return (TREE_POSITION_DESCENDANT | TREE_POSITION_FOLLOWING);
0838:                    otherAncestor = node;
0839:                }
0840:
0841:                Node this Node = this ;
0842:                Node otherNode = other;
0843:
0844:                int this AncestorType = this Ancestor.getNodeType();
0845:                int otherAncestorType = otherAncestor.getNodeType();
0846:
0847:                // if the ancestor is an attribute, get owning element. 
0848:                // we are now interested in the owner to determine position.
0849:
0850:                if (this AncestorType == Node.ATTRIBUTE_NODE) {
0851:                    this Node = ((AttrImpl) this Ancestor).getOwnerElement();
0852:                }
0853:                if (otherAncestorType == Node.ATTRIBUTE_NODE) {
0854:                    otherNode = ((AttrImpl) otherAncestor).getOwnerElement();
0855:                }
0856:
0857:                // Before proceeding, we should check if both ancestor nodes turned
0858:                // out to be attributes for the same element
0859:                if (this AncestorType == Node.ATTRIBUTE_NODE
0860:                        && otherAncestorType == Node.ATTRIBUTE_NODE
0861:                        && this Node == otherNode)
0862:                    return TREE_POSITION_EQUIVALENT;
0863:
0864:                // Now, find the ancestor of the owning element, if the original
0865:                // ancestor was an attribute
0866:
0867:                // Note:  the following 2 loops are quite close to the ones above.
0868:                // May want to common them up.  LM.
0869:                if (this AncestorType == Node.ATTRIBUTE_NODE) {
0870:                    this Depth = 0;
0871:                    for (node = this Node; node != null; node = node
0872:                            .getParentNode()) {
0873:                        this Depth += 1;
0874:                        if (node == otherNode)
0875:                        // The other node is an ancestor of the owning element
0876:                        {
0877:                            return TREE_POSITION_PRECEDING;
0878:                        }
0879:                        this Ancestor = node;
0880:                    }
0881:                }
0882:
0883:                // Now, find the ancestor of the owning element, if the original
0884:                // ancestor was an attribute
0885:                if (otherAncestorType == Node.ATTRIBUTE_NODE) {
0886:                    otherDepth = 0;
0887:                    for (node = otherNode; node != null; node = node
0888:                            .getParentNode()) {
0889:                        otherDepth += 1;
0890:                        if (node == this Node)
0891:                            // The other node is a descendent of the reference 
0892:                            // node's element
0893:                            return TREE_POSITION_FOLLOWING;
0894:                        otherAncestor = node;
0895:                    }
0896:                }
0897:
0898:                // thisAncestor and otherAncestor must be the same at this point,  
0899:                // otherwise, we are not in the same tree or document fragment
0900:                if (this Ancestor != otherAncestor)
0901:                    return TREE_POSITION_DISCONNECTED;
0902:
0903:                // Go up the parent chain of the deeper node, until we find a node 
0904:                // with the same depth as the shallower node
0905:
0906:                if (this Depth > otherDepth) {
0907:                    for (int i = 0; i < this Depth - otherDepth; i++)
0908:                        this Node = this Node.getParentNode();
0909:                    // Check if the node we have reached is in fact "otherNode". This can
0910:                    // happen in the case of attributes.  In this case, otherNode 
0911:                    // "precedes" this.
0912:                    if (this Node == otherNode)
0913:                        return TREE_POSITION_PRECEDING;
0914:                }
0915:
0916:                else {
0917:                    for (int i = 0; i < otherDepth - this Depth; i++)
0918:                        otherNode = otherNode.getParentNode();
0919:                    // Check if the node we have reached is in fact "thisNode".  This can
0920:                    // happen in the case of attributes.  In this case, otherNode 
0921:                    // "follows" this.
0922:                    if (otherNode == this Node)
0923:                        return TREE_POSITION_FOLLOWING;
0924:                }
0925:
0926:                // We now have nodes at the same depth in the tree.  Find a common 
0927:                // ancestor.                                   
0928:                Node this NodeP, otherNodeP;
0929:                for (this NodeP = this Node.getParentNode(), otherNodeP = otherNode
0930:                        .getParentNode(); this NodeP != otherNodeP;) {
0931:                    this Node = this NodeP;
0932:                    otherNode = otherNodeP;
0933:                    this NodeP = this NodeP.getParentNode();
0934:                    otherNodeP = otherNodeP.getParentNode();
0935:                }
0936:
0937:                // At this point, thisNode and otherNode are direct children of 
0938:                // the common ancestor.  
0939:                // See whether thisNode or otherNode is the leftmost
0940:
0941:                for (Node current = this NodeP.getFirstChild(); current != null; current = current
0942:                        .getNextSibling()) {
0943:                    if (current == otherNode) {
0944:                        return TREE_POSITION_PRECEDING;
0945:                    } else if (current == this Node) {
0946:                        return TREE_POSITION_FOLLOWING;
0947:                    }
0948:                }
0949:                // REVISIT:  shouldn't get here.   Should probably throw an 
0950:                // exception
0951:                return 0;
0952:
0953:            }
0954:
0955:            /**
0956:             * Compares a node with this node with regard to their position in the 
0957:             * document. 
0958:             * @param other The node to compare against this node.
0959:             * @return Returns how the given node is positioned relatively to this 
0960:             *   node.
0961:             * @since DOM Level 3
0962:             */
0963:            public short compareDocumentPosition(Node other)
0964:                    throws DOMException {
0965:
0966:                // If the nodes are the same, no flags should be set
0967:                if (this  == other)
0968:                    return 0;
0969:
0970:                // check if other is from a different implementation
0971:                if (other != null && !(other instanceof  NodeImpl)) {
0972:                    // other comes from a different implementation
0973:                    String msg = DOMMessageFormatter.formatMessage(
0974:                            DOMMessageFormatter.DOM_DOMAIN,
0975:                            "NOT_SUPPORTED_ERR", null);
0976:                    throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
0977:                }
0978:
0979:                Document this OwnerDoc, otherOwnerDoc;
0980:                // get the respective Document owners.  
0981:                if (this .getNodeType() == Node.DOCUMENT_NODE)
0982:                    this OwnerDoc = (Document) this ;
0983:                else
0984:                    this OwnerDoc = this .getOwnerDocument();
0985:                if (other.getNodeType() == Node.DOCUMENT_NODE)
0986:                    otherOwnerDoc = (Document) other;
0987:                else
0988:                    otherOwnerDoc = other.getOwnerDocument();
0989:
0990:                // If from different documents, we know they are disconnected. 
0991:                // and have an implementation dependent order 
0992:                if (this OwnerDoc != otherOwnerDoc && this OwnerDoc != null
0993:                        && otherOwnerDoc != null) {
0994:                    int otherDocNum = ((CoreDocumentImpl) otherOwnerDoc)
0995:                            .getNodeNumber();
0996:                    int this DocNum = ((CoreDocumentImpl) this OwnerDoc)
0997:                            .getNodeNumber();
0998:                    if (otherDocNum > this DocNum)
0999:                        return DOCUMENT_POSITION_DISCONNECTED
1000:                                | DOCUMENT_POSITION_FOLLOWING
1001:                                | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
1002:                    else
1003:                        return DOCUMENT_POSITION_DISCONNECTED
1004:                                | DOCUMENT_POSITION_PRECEDING
1005:                                | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
1006:
1007:                }
1008:
1009:                // Find the ancestor of each node, and the distance each node is from 
1010:                // its ancestor.
1011:                // During this traversal, look for ancestor/descendent relationships 
1012:                // between the 2 nodes in question. 
1013:                // We do this now, so that we get this info correct for attribute nodes 
1014:                // and their children. 
1015:
1016:                Node node;
1017:                Node this Ancestor = this ;
1018:                Node otherAncestor = other;
1019:
1020:                int this Depth = 0;
1021:                int otherDepth = 0;
1022:                for (node = this ; node != null; node = node.getParentNode()) {
1023:                    this Depth += 1;
1024:                    if (node == other)
1025:                        // The other node is an ancestor of this one.
1026:                        return (DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_PRECEDING);
1027:                    this Ancestor = node;
1028:                }
1029:
1030:                for (node = other; node != null; node = node.getParentNode()) {
1031:                    otherDepth += 1;
1032:                    if (node == this )
1033:                        // The other node is a descendent of the reference node.
1034:                        return (DOCUMENT_POSITION_IS_CONTAINED | DOCUMENT_POSITION_FOLLOWING);
1035:                    otherAncestor = node;
1036:                }
1037:
1038:                int this AncestorType = this Ancestor.getNodeType();
1039:                int otherAncestorType = otherAncestor.getNodeType();
1040:                Node this Node = this ;
1041:                Node otherNode = other;
1042:
1043:                // Special casing for ENTITY, NOTATION, DOCTYPE and ATTRIBUTES
1044:                // LM:  should rewrite this.                                          
1045:                switch (this AncestorType) {
1046:                case Node.NOTATION_NODE:
1047:                case Node.ENTITY_NODE: {
1048:                    DocumentType container = this OwnerDoc.getDoctype();
1049:                    if (container == otherAncestor)
1050:                        return (DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_PRECEDING);
1051:                    switch (otherAncestorType) {
1052:                    case Node.NOTATION_NODE:
1053:                    case Node.ENTITY_NODE: {
1054:                        if (this AncestorType != otherAncestorType)
1055:                            // the nodes are of different types
1056:                            return ((this AncestorType > otherAncestorType) ? DOCUMENT_POSITION_PRECEDING
1057:                                    : DOCUMENT_POSITION_FOLLOWING);
1058:                        else {
1059:                            // the nodes are of the same type.  Find order.
1060:                            if (this AncestorType == Node.NOTATION_NODE)
1061:
1062:                                if (((NamedNodeMapImpl) container
1063:                                        .getNotations()).precedes(
1064:                                        otherAncestor, this Ancestor))
1065:                                    return (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1066:                                else
1067:                                    return (DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1068:                            else if (((NamedNodeMapImpl) container
1069:                                    .getEntities()).precedes(otherAncestor,
1070:                                    this Ancestor))
1071:                                return (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1072:                            else
1073:                                return (DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1074:                        }
1075:                    }
1076:                    }
1077:                    this Node = this Ancestor = this OwnerDoc;
1078:                    break;
1079:                }
1080:                case Node.DOCUMENT_TYPE_NODE: {
1081:                    if (otherNode == this OwnerDoc)
1082:                        return (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS);
1083:                    else if (this OwnerDoc != null
1084:                            && this OwnerDoc == otherOwnerDoc)
1085:                        return (DOCUMENT_POSITION_FOLLOWING);
1086:                    break;
1087:                }
1088:                case Node.ATTRIBUTE_NODE: {
1089:                    this Node = ((AttrImpl) this Ancestor).getOwnerElement();
1090:                    if (otherAncestorType == Node.ATTRIBUTE_NODE) {
1091:                        otherNode = ((AttrImpl) otherAncestor)
1092:                                .getOwnerElement();
1093:                        if (otherNode == this Node) {
1094:                            if (((NamedNodeMapImpl) this Node.getAttributes())
1095:                                    .precedes(other, this ))
1096:                                return (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1097:                            else
1098:                                return (DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
1099:                        }
1100:                    }
1101:
1102:                    // Now, find the ancestor of the element
1103:                    this Depth = 0;
1104:                    for (node = this Node; node != null; node = node
1105:                            .getParentNode()) {
1106:                        this Depth += 1;
1107:                        if (node == otherNode) {
1108:                            // The other node is an ancestor of the owning element
1109:                            return (DOCUMENT_POSITION_CONTAINS | DOCUMENT_POSITION_PRECEDING);
1110:                        }
1111:                        this Ancestor = node;
1112:                    }
1113:                }
1114:                }
1115:                switch (otherAncestorType) {
1116:                case Node.NOTATION_NODE:
1117:                case Node.ENTITY_NODE: {
1118:                    DocumentType container = this OwnerDoc.getDoctype();
1119:                    if (container == this )
1120:                        return (DOCUMENT_POSITION_IS_CONTAINED | DOCUMENT_POSITION_FOLLOWING);
1121:                    otherNode = otherAncestor = this OwnerDoc;
1122:                    break;
1123:                }
1124:                case Node.DOCUMENT_TYPE_NODE: {
1125:                    if (this Node == otherOwnerDoc)
1126:                        return (DOCUMENT_POSITION_FOLLOWING | DOCUMENT_POSITION_IS_CONTAINED);
1127:                    else if (otherOwnerDoc != null
1128:                            && this OwnerDoc == otherOwnerDoc)
1129:                        return (DOCUMENT_POSITION_PRECEDING);
1130:                    break;
1131:                }
1132:                case Node.ATTRIBUTE_NODE: {
1133:                    otherDepth = 0;
1134:                    otherNode = ((AttrImpl) otherAncestor).getOwnerElement();
1135:                    for (node = otherNode; node != null; node = node
1136:                            .getParentNode()) {
1137:                        otherDepth += 1;
1138:                        if (node == this Node)
1139:                            // The other node is a descendent of the reference 
1140:                            // node's element
1141:                            return DOCUMENT_POSITION_FOLLOWING
1142:                                    | DOCUMENT_POSITION_IS_CONTAINED;
1143:                        otherAncestor = node;
1144:                    }
1145:
1146:                }
1147:                }
1148:
1149:                // thisAncestor and otherAncestor must be the same at this point,  
1150:                // otherwise, the original nodes are disconnected 
1151:                if (this Ancestor != otherAncestor) {
1152:                    int this AncestorNum, otherAncestorNum;
1153:                    this AncestorNum = ((NodeImpl) this Ancestor).getNodeNumber();
1154:                    otherAncestorNum = ((NodeImpl) otherAncestor)
1155:                            .getNodeNumber();
1156:
1157:                    if (this AncestorNum > otherAncestorNum)
1158:                        return DOCUMENT_POSITION_DISCONNECTED
1159:                                | DOCUMENT_POSITION_FOLLOWING
1160:                                | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
1161:                    else
1162:                        return DOCUMENT_POSITION_DISCONNECTED
1163:                                | DOCUMENT_POSITION_PRECEDING
1164:                                | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
1165:                }
1166:
1167:                // Go up the parent chain of the deeper node, until we find a node 
1168:                // with the same depth as the shallower node
1169:
1170:                if (this Depth > otherDepth) {
1171:                    for (int i = 0; i < this Depth - otherDepth; i++)
1172:                        this Node = this Node.getParentNode();
1173:                    // Check if the node we have reached is in fact "otherNode". This can
1174:                    // happen in the case of attributes.  In this case, otherNode 
1175:                    // "precedes" this.
1176:                    if (this Node == otherNode) {
1177:                        return DOCUMENT_POSITION_PRECEDING;
1178:                    }
1179:                }
1180:
1181:                else {
1182:                    for (int i = 0; i < otherDepth - this Depth; i++)
1183:                        otherNode = otherNode.getParentNode();
1184:                    // Check if the node we have reached is in fact "thisNode".  This can
1185:                    // happen in the case of attributes.  In this case, otherNode 
1186:                    // "follows" this.
1187:                    if (otherNode == this Node)
1188:                        return DOCUMENT_POSITION_FOLLOWING;
1189:                }
1190:
1191:                // We now have nodes at the same depth in the tree.  Find a common 
1192:                // ancestor.                                   
1193:                Node this NodeP, otherNodeP;
1194:                for (this NodeP = this Node.getParentNode(), otherNodeP = otherNode
1195:                        .getParentNode(); this NodeP != otherNodeP;) {
1196:                    this Node = this NodeP;
1197:                    otherNode = otherNodeP;
1198:                    this NodeP = this NodeP.getParentNode();
1199:                    otherNodeP = otherNodeP.getParentNode();
1200:                }
1201:
1202:                // At this point, thisNode and otherNode are direct children of 
1203:                // the common ancestor.  
1204:                // See whether thisNode or otherNode is the leftmost
1205:
1206:                for (Node current = this NodeP.getFirstChild(); current != null; current = current
1207:                        .getNextSibling()) {
1208:                    if (current == otherNode) {
1209:                        return DOCUMENT_POSITION_PRECEDING;
1210:                    } else if (current == this Node) {
1211:                        return DOCUMENT_POSITION_FOLLOWING;
1212:                    }
1213:                }
1214:                // REVISIT:  shouldn't get here.   Should probably throw an 
1215:                // exception
1216:                return 0;
1217:
1218:            }
1219:
1220:            /**
1221:             * This attribute returns the text content of this node and its 
1222:             * descendants. When it is defined to be null, setting it has no effect. 
1223:             * When set, any possible children this node may have are removed and 
1224:             * replaced by a single <code>Text</code> node containing the string 
1225:             * this attribute is set to. On getting, no serialization is performed, 
1226:             * the returned string does not contain any markup. No whitespace 
1227:             * normalization is performed, the returned string does not contain the 
1228:             * element content whitespaces . Similarly, on setting, no parsing is 
1229:             * performed either, the input string is taken as pure textual content.
1230:             * <br>The string returned is made of the text content of this node 
1231:             * depending on its type, as defined below: 
1232:             * <table border='1'>
1233:             * <tr>
1234:             * <th>Node type</th>
1235:             * <th>Content</th>
1236:             * </tr>
1237:
1238:            /**
1239:             * This attribute returns the text content of this node and its 
1240:             * descendants. When it is defined to be null, setting it has no effect. 
1241:             * When set, any possible children this node may have are removed and 
1242:             * replaced by a single <code>Text</code> node containing the string 
1243:             * this attribute is set to. On getting, no serialization is performed, 
1244:             * the returned string does not contain any markup. No whitespace 
1245:             * normalization is performed, the returned string does not contain the 
1246:             * element content whitespaces . Similarly, on setting, no parsing is 
1247:             * performed either, the input string is taken as pure textual content.
1248:             * <br>The string returned is made of the text content of this node 
1249:             * depending on its type, as defined below: 
1250:             * <table border='1'>
1251:             * <tr>
1252:             * <th>Node type</th>
1253:             * <th>Content</th>
1254:             * </tr>
1255:             * <tr>
1256:             * <td valign='top' rowspan='1' colspan='1'>
1257:             * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 
1258:             * DOCUMENT_FRAGMENT_NODE</td>
1259:             * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 
1260:             * attribute value of every child node, excluding COMMENT_NODE and 
1261:             * PROCESSING_INSTRUCTION_NODE nodes</td>
1262:             * </tr>
1263:             * <tr>
1264:             * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 
1265:             * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
1266:             * <td valign='top' rowspan='1' colspan='1'>
1267:             * <code>nodeValue</code></td>
1268:             * </tr>
1269:             * <tr>
1270:             * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
1271:             * <td valign='top' rowspan='1' colspan='1'>
1272:             * null</td>
1273:             * </tr>
1274:             * </table>
1275:             * @exception DOMException
1276:             *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
1277:             * @exception DOMException
1278:             *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than 
1279:             *   fit in a <code>DOMString</code> variable on the implementation 
1280:             *   platform.
1281:             * @since DOM Level 3
1282:             */
1283:            public String getTextContent() throws DOMException {
1284:                return getNodeValue(); // overriden in some subclasses
1285:            }
1286:
1287:            // internal method taking a StringBuffer in parameter
1288:            void getTextContent(StringBuffer buf) throws DOMException {
1289:                String content = getNodeValue();
1290:                if (content != null) {
1291:                    buf.append(content);
1292:                }
1293:            }
1294:
1295:            /**
1296:             * This attribute returns the text content of this node and its 
1297:             * descendants. When it is defined to be null, setting it has no effect. 
1298:             * When set, any possible children this node may have are removed and 
1299:             * replaced by a single <code>Text</code> node containing the string 
1300:             * this attribute is set to. On getting, no serialization is performed, 
1301:             * the returned string does not contain any markup. No whitespace 
1302:             * normalization is performed, the returned string does not contain the 
1303:             * element content whitespaces . Similarly, on setting, no parsing is 
1304:             * performed either, the input string is taken as pure textual content.
1305:             * <br>The string returned is made of the text content of this node 
1306:             * depending on its type, as defined below: 
1307:             * <table border='1'>
1308:             * <tr>
1309:             * <th>Node type</th>
1310:             * <th>Content</th>
1311:             * </tr>
1312:             * <tr>
1313:             * <td valign='top' rowspan='1' colspan='1'>
1314:             * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, 
1315:             * DOCUMENT_FRAGMENT_NODE</td>
1316:             * <td valign='top' rowspan='1' colspan='1'>concatenation of the <code>textContent</code> 
1317:             * attribute value of every child node, excluding COMMENT_NODE and 
1318:             * PROCESSING_INSTRUCTION_NODE nodes</td>
1319:             * </tr>
1320:             * <tr>
1321:             * <td valign='top' rowspan='1' colspan='1'>ATTRIBUTE_NODE, TEXT_NODE, 
1322:             * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE</td>
1323:             * <td valign='top' rowspan='1' colspan='1'>
1324:             * <code>nodeValue</code></td>
1325:             * </tr>
1326:             * <tr>
1327:             * <td valign='top' rowspan='1' colspan='1'>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
1328:             * <td valign='top' rowspan='1' colspan='1'>
1329:             * null</td>
1330:             * </tr>
1331:             * </table>
1332:             * @exception DOMException
1333:             *   NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
1334:             * @exception DOMException
1335:             *   DOMSTRING_SIZE_ERR: Raised when it would return more characters than 
1336:             *   fit in a <code>DOMString</code> variable on the implementation 
1337:             *   platform.
1338:             * @since DOM Level 3
1339:             */
1340:            public void setTextContent(String textContent) throws DOMException {
1341:                setNodeValue(textContent);
1342:            }
1343:
1344:            /**
1345:             * Returns whether this node is the same node as the given one.
1346:             * <br>This method provides a way to determine whether two 
1347:             * <code>Node</code> references returned by the implementation reference 
1348:             * the same object. When two <code>Node</code> references are references 
1349:             * to the same object, even if through a proxy, the references may be 
1350:             * used completely interchangably, such that all attributes have the 
1351:             * same values and calling the same DOM method on either reference 
1352:             * always has exactly the same effect.
1353:             * @param other The node to test against.
1354:             * @return Returns <code>true</code> if the nodes are the same, 
1355:             *   <code>false</code> otherwise.
1356:             * @since DOM Level 3
1357:             */
1358:            public boolean isSameNode(Node other) {
1359:                // we do not use any wrapper so the answer is obvious
1360:                return this  == other;
1361:            }
1362:
1363:            /**
1364:             *  DOM Level 3: Experimental
1365:             *  This method checks if the specified <code>namespaceURI</code> is the 
1366:             *  default namespace or not. 
1367:             *  @param namespaceURI The namespace URI to look for.
1368:             *  @return  <code>true</code> if the specified <code>namespaceURI</code> 
1369:             *   is the default namespace, <code>false</code> otherwise. 
1370:             * @since DOM Level 3
1371:             */
1372:            public boolean isDefaultNamespace(String namespaceURI) {
1373:                // REVISIT: remove casts when DOM L3 becomes REC.
1374:                short type = this .getNodeType();
1375:                switch (type) {
1376:                case Node.ELEMENT_NODE: {
1377:                    String namespace = this .getNamespaceURI();
1378:                    String prefix = this .getPrefix();
1379:
1380:                    // REVISIT: is it possible that prefix is empty string?
1381:                    if (prefix == null || prefix.length() == 0) {
1382:                        if (namespaceURI == null) {
1383:                            return (namespace == namespaceURI);
1384:                        }
1385:                        return namespaceURI.equals(namespace);
1386:                    }
1387:                    if (this .hasAttributes()) {
1388:                        ElementImpl elem = (ElementImpl) this ;
1389:                        NodeImpl attr = (NodeImpl) elem.getAttributeNodeNS(
1390:                                "http://www.w3.org/2000/xmlns/", "xmlns");
1391:                        if (attr != null) {
1392:                            String value = attr.getNodeValue();
1393:                            if (namespaceURI == null) {
1394:                                return (namespace == value);
1395:                            }
1396:                            return namespaceURI.equals(value);
1397:                        }
1398:                    }
1399:
1400:                    NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1401:                    if (ancestor != null) {
1402:                        return ancestor.isDefaultNamespace(namespaceURI);
1403:                    }
1404:                    return false;
1405:                }
1406:                case Node.DOCUMENT_NODE: {
1407:                    return ((NodeImpl) ((Document) this ).getDocumentElement())
1408:                            .isDefaultNamespace(namespaceURI);
1409:                }
1410:
1411:                case Node.ENTITY_NODE:
1412:                case Node.NOTATION_NODE:
1413:                case Node.DOCUMENT_FRAGMENT_NODE:
1414:                case Node.DOCUMENT_TYPE_NODE:
1415:                    // type is unknown
1416:                    return false;
1417:                case Node.ATTRIBUTE_NODE: {
1418:                    if (this .ownerNode.getNodeType() == Node.ELEMENT_NODE) {
1419:                        return ownerNode.isDefaultNamespace(namespaceURI);
1420:
1421:                    }
1422:                    return false;
1423:                }
1424:                default: {
1425:                    NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1426:                    if (ancestor != null) {
1427:                        return ancestor.isDefaultNamespace(namespaceURI);
1428:                    }
1429:                    return false;
1430:                }
1431:
1432:                }
1433:
1434:            }
1435:
1436:            /**
1437:             * 
1438:             * DOM Level 3 - Experimental:
1439:             * Look up the prefix associated to the given namespace URI, starting from this node.
1440:             * 
1441:             * @param namespaceURI
1442:             * @return the prefix for the namespace
1443:             */
1444:            public String lookupPrefix(String namespaceURI) {
1445:
1446:                // REVISIT: When Namespaces 1.1 comes out this may not be true
1447:                // Prefix can't be bound to null namespace
1448:                if (namespaceURI == null) {
1449:                    return null;
1450:                }
1451:
1452:                short type = this .getNodeType();
1453:
1454:                switch (type) {
1455:                case Node.ELEMENT_NODE: {
1456:                    this .getNamespaceURI(); // to flip out children 
1457:                    return lookupNamespacePrefix(namespaceURI,
1458:                            (ElementImpl) this );
1459:                }
1460:                case Node.DOCUMENT_NODE: {
1461:                    return ((NodeImpl) ((Document) this ).getDocumentElement())
1462:                            .lookupPrefix(namespaceURI);
1463:                }
1464:
1465:                case Node.ENTITY_NODE:
1466:                case Node.NOTATION_NODE:
1467:                case Node.DOCUMENT_FRAGMENT_NODE:
1468:                case Node.DOCUMENT_TYPE_NODE:
1469:                    // type is unknown
1470:                    return null;
1471:                case Node.ATTRIBUTE_NODE: {
1472:                    if (this .ownerNode.getNodeType() == Node.ELEMENT_NODE) {
1473:                        return ownerNode.lookupPrefix(namespaceURI);
1474:
1475:                    }
1476:                    return null;
1477:                }
1478:                default: {
1479:                    NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1480:                    if (ancestor != null) {
1481:                        return ancestor.lookupPrefix(namespaceURI);
1482:                    }
1483:                    return null;
1484:                }
1485:
1486:                }
1487:            }
1488:
1489:            /**
1490:             * DOM Level 3 - Experimental:
1491:             * Look up the namespace URI associated to the given prefix, starting from this node.
1492:             * Use lookupNamespaceURI(null) to lookup the default namespace
1493:             * 
1494:             * @param specifiedPrefix
1495:             * @return the URI for the namespace
1496:             * @since DOM Level 3
1497:             */
1498:            public String lookupNamespaceURI(String specifiedPrefix) {
1499:                short type = this .getNodeType();
1500:                switch (type) {
1501:                case Node.ELEMENT_NODE: {
1502:
1503:                    String namespace = this .getNamespaceURI();
1504:                    String prefix = this .getPrefix();
1505:                    if (namespace != null) {
1506:                        // REVISIT: is it possible that prefix is empty string?
1507:                        if (specifiedPrefix == null
1508:                                && prefix == specifiedPrefix) {
1509:                            // looking for default namespace
1510:                            return namespace;
1511:                        } else if (prefix != null
1512:                                && prefix.equals(specifiedPrefix)) {
1513:                            // non default namespace
1514:                            return namespace;
1515:                        }
1516:                    }
1517:                    if (this .hasAttributes()) {
1518:                        NamedNodeMap map = this .getAttributes();
1519:                        int length = map.getLength();
1520:                        for (int i = 0; i < length; i++) {
1521:                            Node attr = map.item(i);
1522:                            String attrPrefix = attr.getPrefix();
1523:                            String value = attr.getNodeValue();
1524:                            namespace = attr.getNamespaceURI();
1525:                            if (namespace != null
1526:                                    && namespace
1527:                                            .equals("http://www.w3.org/2000/xmlns/")) {
1528:                                // at this point we are dealing with DOM Level 2 nodes only
1529:                                if (specifiedPrefix == null
1530:                                        && attr.getNodeName().equals("xmlns")) {
1531:                                    // default namespace
1532:                                    return value;
1533:                                } else if (attrPrefix != null
1534:                                        && attrPrefix.equals("xmlns")
1535:                                        && attr.getLocalName().equals(
1536:                                                specifiedPrefix)) {
1537:                                    // non default namespace
1538:                                    return value;
1539:                                }
1540:                            }
1541:                        }
1542:                    }
1543:                    NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1544:                    if (ancestor != null) {
1545:                        return ancestor.lookupNamespaceURI(specifiedPrefix);
1546:                    }
1547:
1548:                    return null;
1549:
1550:                }
1551:                case Node.DOCUMENT_NODE: {
1552:                    return ((NodeImpl) ((Document) this ).getDocumentElement())
1553:                            .lookupNamespaceURI(specifiedPrefix);
1554:                }
1555:                case Node.ENTITY_NODE:
1556:                case Node.NOTATION_NODE:
1557:                case Node.DOCUMENT_FRAGMENT_NODE:
1558:                case Node.DOCUMENT_TYPE_NODE:
1559:                    // type is unknown
1560:                    return null;
1561:                case Node.ATTRIBUTE_NODE: {
1562:                    if (this .ownerNode.getNodeType() == Node.ELEMENT_NODE) {
1563:                        return ownerNode.lookupNamespaceURI(specifiedPrefix);
1564:
1565:                    }
1566:                    return null;
1567:                }
1568:                default: {
1569:                    NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1570:                    if (ancestor != null) {
1571:                        return ancestor.lookupNamespaceURI(specifiedPrefix);
1572:                    }
1573:                    return null;
1574:                }
1575:
1576:                }
1577:            }
1578:
1579:            Node getElementAncestor(Node currentNode) {
1580:                Node parent = currentNode.getParentNode();
1581:                if (parent != null) {
1582:                    short type = parent.getNodeType();
1583:                    if (type == Node.ELEMENT_NODE) {
1584:                        return parent;
1585:                    }
1586:                    return getElementAncestor(parent);
1587:                }
1588:                return null;
1589:            }
1590:
1591:            String lookupNamespacePrefix(String namespaceURI, ElementImpl el) {
1592:                String namespace = this .getNamespaceURI();
1593:                // REVISIT: if no prefix is available is it null or empty string, or 
1594:                //          could be both?
1595:                String prefix = this .getPrefix();
1596:
1597:                if (namespace != null && namespace.equals(namespaceURI)) {
1598:                    if (prefix != null) {
1599:                        String foundNamespace = el.lookupNamespaceURI(prefix);
1600:                        if (foundNamespace != null
1601:                                && foundNamespace.equals(namespaceURI)) {
1602:                            return prefix;
1603:                        }
1604:
1605:                    }
1606:                }
1607:                if (this .hasAttributes()) {
1608:                    NamedNodeMap map = this .getAttributes();
1609:                    int length = map.getLength();
1610:                    for (int i = 0; i < length; i++) {
1611:                        Node attr = map.item(i);
1612:                        String attrPrefix = attr.getPrefix();
1613:                        String value = attr.getNodeValue();
1614:                        namespace = attr.getNamespaceURI();
1615:                        if (namespace != null
1616:                                && namespace
1617:                                        .equals("http://www.w3.org/2000/xmlns/")) {
1618:                            // DOM Level 2 nodes
1619:                            if (((attr.getNodeName().equals("xmlns")) || (attrPrefix != null && attrPrefix
1620:                                    .equals("xmlns"))
1621:                                    && value.equals(namespaceURI))) {
1622:
1623:                                String localname = attr.getLocalName();
1624:                                String foundNamespace = el
1625:                                        .lookupNamespaceURI(localname);
1626:                                if (foundNamespace != null
1627:                                        && foundNamespace.equals(namespaceURI)) {
1628:                                    return localname;
1629:                                }
1630:                            }
1631:
1632:                        }
1633:                    }
1634:                }
1635:                NodeImpl ancestor = (NodeImpl) getElementAncestor(this );
1636:
1637:                if (ancestor != null) {
1638:                    return ancestor.lookupNamespacePrefix(namespaceURI, el);
1639:                }
1640:                return null;
1641:            }
1642:
1643:            /**
1644:             * Tests whether two nodes are equal.
1645:             * <br>This method tests for equality of nodes, not sameness (i.e., 
1646:             * whether the two nodes are references to the same object) which can be 
1647:             * tested with <code>Node.isSameNode</code>. All nodes that are the same 
1648:             * will also be equal, though the reverse may not be true.
1649:             * <br>Two nodes are equal if and only if the following conditions are 
1650:             * satisfied: The two nodes are of the same type.The following string 
1651:             * attributes are equal: <code>nodeName</code>, <code>localName</code>, 
1652:             * <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code>
1653:             * , <code>baseURI</code>. This is: they are both <code>null</code>, or 
1654:             * they have the same length and are character for character identical.
1655:             * The <code>attributes</code> <code>NamedNodeMaps</code> are equal. 
1656:             * This is: they are both <code>null</code>, or they have the same 
1657:             * length and for each node that exists in one map there is a node that 
1658:             * exists in the other map and is equal, although not necessarily at the 
1659:             * same index.The <code>childNodes</code> <code>NodeLists</code> are 
1660:             * equal. This is: they are both <code>null</code>, or they have the 
1661:             * same length and contain equal nodes at the same index. This is true 
1662:             * for <code>Attr</code> nodes as for any other type of node. Note that 
1663:             * normalization can affect equality; to avoid this, nodes should be 
1664:             * normalized before being compared. 
1665:             * <br>For two <code>DocumentType</code> nodes to be equal, the following 
1666:             * conditions must also be satisfied: The following string attributes 
1667:             * are equal: <code>publicId</code>, <code>systemId</code>, 
1668:             * <code>internalSubset</code>.The <code>entities</code> 
1669:             * <code>NamedNodeMaps</code> are equal.The <code>notations</code> 
1670:             * <code>NamedNodeMaps</code> are equal. 
1671:             * <br>On the other hand, the following do not affect equality: the 
1672:             * <code>ownerDocument</code> attribute, the <code>specified</code> 
1673:             * attribute for <code>Attr</code> nodes, the 
1674:             * <code>isWhitespaceInElementContent</code> attribute for 
1675:             * <code>Text</code> nodes, as well as any user data or event listeners 
1676:             * registered on the nodes.
1677:             * @param arg The node to compare equality with.
1678:             * @return If the nodes, and possibly subtrees are equal, 
1679:             *   <code>true</code> otherwise <code>false</code>.
1680:             * @since DOM Level 3
1681:             */
1682:            public boolean isEqualNode(Node arg) {
1683:                if (arg == this ) {
1684:                    return true;
1685:                }
1686:                if (arg.getNodeType() != getNodeType()) {
1687:                    return false;
1688:                }
1689:                // in theory nodeName can't be null but better be careful
1690:                // who knows what other implementations may be doing?...
1691:                if (getNodeName() == null) {
1692:                    if (arg.getNodeName() != null) {
1693:                        return false;
1694:                    }
1695:                } else if (!getNodeName().equals(arg.getNodeName())) {
1696:                    return false;
1697:                }
1698:
1699:                if (getLocalName() == null) {
1700:                    if (arg.getLocalName() != null) {
1701:                        return false;
1702:                    }
1703:                } else if (!getLocalName().equals(arg.getLocalName())) {
1704:                    return false;
1705:                }
1706:
1707:                if (getNamespaceURI() == null) {
1708:                    if (arg.getNamespaceURI() != null) {
1709:                        return false;
1710:                    }
1711:                } else if (!getNamespaceURI().equals(arg.getNamespaceURI())) {
1712:                    return false;
1713:                }
1714:
1715:                if (getPrefix() == null) {
1716:                    if (arg.getPrefix() != null) {
1717:                        return false;
1718:                    }
1719:                } else if (!getPrefix().equals(arg.getPrefix())) {
1720:                    return false;
1721:                }
1722:
1723:                if (getNodeValue() == null) {
1724:                    if (arg.getNodeValue() != null) {
1725:                        return false;
1726:                    }
1727:                } else if (!getNodeValue().equals(arg.getNodeValue())) {
1728:                    return false;
1729:                }
1730:
1731:                return true;
1732:            }
1733:
1734:            /**
1735:             * @since DOM Level 3
1736:             */
1737:            public Object getFeature(String feature, String version) {
1738:                // we don't have any alternate node, either this node does the job
1739:                // or we don't have anything that does
1740:                return isSupported(feature, version) ? this  : null;
1741:            }
1742:
1743:            /**
1744:             * Associate an object to a key on this node. The object can later be 
1745:             * retrieved from this node by calling <code>getUserData</code> with the 
1746:             * same key.
1747:             * @param key The key to associate the object to.
1748:             * @param data The object to associate to the given key, or 
1749:             *   <code>null</code> to remove any existing association to that key.
1750:             * @param handler The handler to associate to that key, or 
1751:             *   <code>null</code>.
1752:             * @return Returns the <code>DOMObject</code> previously associated to 
1753:             *   the given key on this node, or <code>null</code> if there was none.
1754:             * @since DOM Level 3
1755:             */
1756:            public Object setUserData(String key, Object data,
1757:                    UserDataHandler handler) {
1758:                return ownerDocument().setUserData(this , key, data, handler);
1759:            }
1760:
1761:            /**
1762:             * Retrieves the object associated to a key on a this node. The object 
1763:             * must first have been set to this node by calling 
1764:             * <code>setUserData</code> with the same key.
1765:             * @param key The key the object is associated to.
1766:             * @return Returns the <code>DOMObject</code> associated to the given key 
1767:             *   on this node, or <code>null</code> if there was none.
1768:             * @since DOM Level 3
1769:             */
1770:            public Object getUserData(String key) {
1771:                return ownerDocument().getUserData(this , key);
1772:            }
1773:
1774:            protected Hashtable getUserDataRecord() {
1775:                return ownerDocument().getUserDataRecord(this );
1776:            }
1777:
1778:            //
1779:            // Public methods
1780:            //
1781:
1782:            /**
1783:             * NON-DOM: PR-DOM-Level-1-19980818 mentions readonly nodes in conjunction
1784:             * with Entities, but provides no API to support this.
1785:             * <P>
1786:             * Most DOM users should not touch this method. Its anticpated use
1787:             * is during construction of EntityRefernces, where it will be used to
1788:             * lock the contents replicated from Entity so they can't be casually
1789:             * altered. It _could_ be published as a DOM extension, if desired.
1790:             * <P>
1791:             * Note: since we never have any children deep is meaningless here,
1792:             * ParentNode overrides this behavior.
1793:             * @see ParentNode
1794:             *
1795:             * @param readOnly True or false as desired.
1796:             * @param deep If true, children are also toggled. Note that this will
1797:             *	not change the state of an EntityReference or its children,
1798:             *  which are always read-only.
1799:             */
1800:            public void setReadOnly(boolean readOnly, boolean deep) {
1801:
1802:                if (needsSyncData()) {
1803:                    synchronizeData();
1804:                }
1805:                isReadOnly(readOnly);
1806:
1807:            } // setReadOnly(boolean,boolean)
1808:
1809:            /**
1810:             * NON-DOM: Returns true if this node is read-only. This is a
1811:             * shallow check.
1812:             */
1813:            public boolean getReadOnly() {
1814:
1815:                if (needsSyncData()) {
1816:                    synchronizeData();
1817:                }
1818:                return isReadOnly();
1819:
1820:            } // getReadOnly():boolean
1821:
1822:            /**
1823:             * NON-DOM: As an alternative to subclassing the DOM, this implementation
1824:             * has been extended with the ability to attach an object to each node.
1825:             * (If you need multiple objects, you can attach a collection such as a
1826:             * vector or hashtable, then attach your application information to that.)
1827:             * <p><b>Important Note:</b> You are responsible for removing references
1828:             * to your data on nodes that are no longer used. Failure to do so will
1829:             * prevent the nodes, your data is attached to, to be garbage collected
1830:             * until the whole document is.
1831:             *
1832:             * @param data the object to store or null to remove any existing reference
1833:             */
1834:            public void setUserData(Object data) {
1835:                ownerDocument().setUserData(this , data);
1836:            }
1837:
1838:            /**
1839:             * NON-DOM:
1840:             * Returns the user data associated to this node.
1841:             */
1842:            public Object getUserData() {
1843:                return ownerDocument().getUserData(this );
1844:            }
1845:
1846:            //
1847:            // Protected methods
1848:            //
1849:
1850:            /**
1851:             * Denotes that this node has changed.
1852:             */
1853:            protected void changed() {
1854:                // we do not actually store this information on every node, we only
1855:                // have a global indicator on the Document. Doing otherwise cost us too
1856:                // much for little gain.
1857:                ownerDocument().changed();
1858:            }
1859:
1860:            /**
1861:             * Returns the number of changes to this node.
1862:             */
1863:            protected int changes() {
1864:                // we do not actually store this information on every node, we only
1865:                // have a global indicator on the Document. Doing otherwise cost us too
1866:                // much for little gain.
1867:                return ownerDocument().changes();
1868:            }
1869:
1870:            /**
1871:             * Override this method in subclass to hook in efficient
1872:             * internal data structure.
1873:             */
1874:            protected void synchronizeData() {
1875:                // By default just change the flag to avoid calling this method again
1876:                needsSyncData(false);
1877:            }
1878:
1879:            /** 
1880:             * For non-child nodes, the node which "points" to this node.  
1881:             * For example, the owning element for an attribute
1882:             */
1883:            protected Node getContainer() {
1884:                return null;
1885:            }
1886:
1887:            /*
1888:             * Flags setters and getters
1889:             */
1890:
1891:            final boolean isReadOnly() {
1892:                return (flags & READONLY) != 0;
1893:            }
1894:
1895:            final void isReadOnly(boolean value) {
1896:                flags = (short) (value ? flags | READONLY : flags & ~READONLY);
1897:            }
1898:
1899:            final boolean needsSyncData() {
1900:                return (flags & SYNCDATA) != 0;
1901:            }
1902:
1903:            final void needsSyncData(boolean value) {
1904:                flags = (short) (value ? flags | SYNCDATA : flags & ~SYNCDATA);
1905:            }
1906:
1907:            final boolean needsSyncChildren() {
1908:                return (flags & SYNCCHILDREN) != 0;
1909:            }
1910:
1911:            public final void needsSyncChildren(boolean value) {
1912:                flags = (short) (value ? flags | SYNCCHILDREN : flags
1913:                        & ~SYNCCHILDREN);
1914:            }
1915:
1916:            final boolean isOwned() {
1917:                return (flags & OWNED) != 0;
1918:            }
1919:
1920:            final void isOwned(boolean value) {
1921:                flags = (short) (value ? flags | OWNED : flags & ~OWNED);
1922:            }
1923:
1924:            final boolean isFirstChild() {
1925:                return (flags & FIRSTCHILD) != 0;
1926:            }
1927:
1928:            final void isFirstChild(boolean value) {
1929:                flags = (short) (value ? flags | FIRSTCHILD : flags
1930:                        & ~FIRSTCHILD);
1931:            }
1932:
1933:            final boolean isSpecified() {
1934:                return (flags & SPECIFIED) != 0;
1935:            }
1936:
1937:            final void isSpecified(boolean value) {
1938:                flags = (short) (value ? flags | SPECIFIED : flags & ~SPECIFIED);
1939:            }
1940:
1941:            // inconsistent name to avoid clash with public method on TextImpl
1942:            final boolean internalIsIgnorableWhitespace() {
1943:                return (flags & IGNORABLEWS) != 0;
1944:            }
1945:
1946:            final void isIgnorableWhitespace(boolean value) {
1947:                flags = (short) (value ? flags | IGNORABLEWS : flags
1948:                        & ~IGNORABLEWS);
1949:            }
1950:
1951:            final boolean hasStringValue() {
1952:                return (flags & HASSTRING) != 0;
1953:            }
1954:
1955:            final void hasStringValue(boolean value) {
1956:                flags = (short) (value ? flags | HASSTRING : flags & ~HASSTRING);
1957:            }
1958:
1959:            final boolean isNormalized() {
1960:                return (flags & NORMALIZED) != 0;
1961:            }
1962:
1963:            final void isNormalized(boolean value) {
1964:                // See if flag should propagate to parent.
1965:                if (!value && isNormalized() && ownerNode != null) {
1966:                    ownerNode.isNormalized(false);
1967:                }
1968:                flags = (short) (value ? flags | NORMALIZED : flags
1969:                        & ~NORMALIZED);
1970:            }
1971:
1972:            final boolean isIdAttribute() {
1973:                return (flags & ID) != 0;
1974:            }
1975:
1976:            final void isIdAttribute(boolean value) {
1977:                flags = (short) (value ? flags | ID : flags & ~ID);
1978:            }
1979:
1980:            //
1981:            // Object methods
1982:            //
1983:
1984:            /** NON-DOM method for debugging convenience. */
1985:            public String toString() {
1986:                return "[" + getNodeName() + ": " + getNodeValue() + "]";
1987:            }
1988:
1989:            //
1990:            // Serialization methods
1991:            //
1992:
1993:            /** Serialize object. */
1994:            private void writeObject(ObjectOutputStream out) throws IOException {
1995:
1996:                // synchronize data
1997:                if (needsSyncData()) {
1998:                    synchronizeData();
1999:                }
2000:                // write object
2001:                out.defaultWriteObject();
2002:
2003:            } // writeObject(ObjectOutputStream)
2004:
2005:        } // class NodeImpl
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.