1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License. 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xml.dom; 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 19f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilsonimport java.net.URI; 20f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilsonimport java.net.URISyntaxException; 217365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.ArrayList; 227365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.List; 237365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.Map; 241ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilsonimport org.w3c.dom.Attr; 25ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilsonimport org.w3c.dom.CharacterData; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.DOMException; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Document; 2835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilsonimport org.w3c.dom.Element; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.NamedNodeMap; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Node; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.NodeList; 32ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilsonimport org.w3c.dom.ProcessingInstruction; 335b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilsonimport org.w3c.dom.TypeInfo; 34320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilsonimport org.w3c.dom.UserDataHandler; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 371ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * A straightforward implementation of the corresponding W3C DOM node. 381ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * 391ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <p>Some fields have package visibility so other classes can access them while 401ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * maintaining the DOM structure. 411ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * 421ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <p>This class represents a Node that has neither a parent nor children. 431ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Subclasses may have either. 441ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * 451ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <p>Some code was adapted from Apache Xerces. 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class NodeImpl implements Node { 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final NodeList EMPTY_LIST = new NodeListImpl(); 505b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson 515b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson static final TypeInfo NULL_TYPE_INFO = new TypeInfo() { 525b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson public String getTypeName() { 535b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson return null; 545b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson } 555b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson public String getTypeNamespace() { 565b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson return null; 575b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson } 585b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson public boolean isDerivedFrom( 595b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson String typeNamespaceArg, String typeNameArg, int derivationMethod) { 605b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson return false; 615b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson } 625b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson }; 635b6729bd043431bc17f5684fe3b0f5c93b54f76bJesse Wilson 6409c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson /** 6509c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson * The containing document. This is non-null except for DocumentTypeImpl 6609c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson * nodes created by the DOMImplementation. 6709c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson */ 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DocumentImpl document; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeImpl(DocumentImpl document) { 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.document = document; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node appendChild(Node newChild) throws DOMException { 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78df138faff880612d97a8e6e3fa344a91ae9d96acJesse Wilson public final Node cloneNode(boolean deep) { 79df138faff880612d97a8e6e3fa344a91ae9d96acJesse Wilson return document.cloneOrImportNode(UserDataHandler.NODE_CLONED, this, deep); 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NamedNodeMap getAttributes() { 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeList getChildNodes() { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return EMPTY_LIST; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getFirstChild() { 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getLastChild() { 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getLocalName() { 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getNamespaceURI() { 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getNextSibling() { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getNodeName() { 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public abstract short getNodeType(); 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getNodeValue() throws DOMException { 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1208b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson public final Document getOwnerDocument() { 1218b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson return document == this ? null : document; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getParentNode() { 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getPrefix() { 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getPreviousSibling() { 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasAttributes() { 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasChildNodes() { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node insertBefore(Node newChild, Node refChild) throws DOMException { 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isSupported(String feature, String version) { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return DOMImplementationImpl.getInstance().hasFeature(feature, version); 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void normalize() { 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node removeChild(Node oldChild) throws DOMException { 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node replaceChild(Node newChild, Node oldChild) throws DOMException { 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 163ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson public final void setNodeValue(String nodeValue) throws DOMException { 164ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson switch (getNodeType()) { 165ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case CDATA_SECTION_NODE: 166ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case COMMENT_NODE: 167ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case TEXT_NODE: 168ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson ((CharacterData) this).setData(nodeValue); 169ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson return; 170ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson 171ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case PROCESSING_INSTRUCTION_NODE: 172ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson ((ProcessingInstruction) this).setData(nodeValue); 173ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson return; 174ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson 175ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case ATTRIBUTE_NODE: 176ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson ((Attr) this).setValue(nodeValue); 177ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson return; 178ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson 179ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case ELEMENT_NODE: 180ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case ENTITY_REFERENCE_NODE: 181ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case ENTITY_NODE: 182ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case DOCUMENT_NODE: 183ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case DOCUMENT_TYPE_NODE: 184ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case DOCUMENT_FRAGMENT_NODE: 185ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson case NOTATION_NODE: 186ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson return; // do nothing! 187ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson 188ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson default: 189ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 190ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson "Unsupported node type " + getNodeType()); 191ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson } 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setPrefix(String prefix) throws DOMException { 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1981ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Validates the element or attribute namespace prefix on this node. 1991ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * 2001ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * @param namespaceAware whether this node is namespace aware 2011ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * @param namespaceURI this node's namespace URI 2021ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson */ 203503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson static String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) { 2041ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (!namespaceAware) { 2051ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson throw new DOMException(DOMException.NAMESPACE_ERR, prefix); 2061ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 2071ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 2081ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (prefix != null) { 2091ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (namespaceURI == null 2101ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson || !DocumentImpl.isXMLIdentifier(prefix) 2111ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson || "xml".equals(prefix) && !"http://www.w3.org/XML/1998/namespace".equals(namespaceURI) 2121ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson || "xmlns".equals(prefix) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) { 2131ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson throw new DOMException(DOMException.NAMESPACE_ERR, prefix); 2141ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 2151ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 2161ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 2171ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return prefix; 2181ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 2191ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 2201ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson /** 2219c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * Sets {@code node} to be namespace-aware and assigns its namespace URI 2229c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * and qualified name. 223503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson * 2249c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * @param node an element or attribute node. 225503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson * @param namespaceURI this node's namespace URI. May be null. 226503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson * @param qualifiedName a possibly-prefixed name like "img" or "html:img". 227503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson */ 228503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson static void setNameNS(NodeImpl node, String namespaceURI, String qualifiedName) { 229503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson if (qualifiedName == null) { 230503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); 231503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson } 232503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 233503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson String prefix = null; 234503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson int p = qualifiedName.lastIndexOf(":"); 235503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson if (p != -1) { 236503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson prefix = validatePrefix(qualifiedName.substring(0, p), true, namespaceURI); 237503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson qualifiedName = qualifiedName.substring(p + 1); 238503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson } 239503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 240503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson if (!DocumentImpl.isXMLIdentifier(qualifiedName)) { 241503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName); 242503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson } 243503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 244503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson switch (node.getNodeType()) { 2459c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson case ATTRIBUTE_NODE: 2469c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson if ("xmlns".equals(qualifiedName) 2479c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) { 2489c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName); 2499c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } 250503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 2519c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson AttrImpl attr = (AttrImpl) node; 2529c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.namespaceAware = true; 2539c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.namespaceURI = namespaceURI; 2549c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.prefix = prefix; 2559c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.localName = qualifiedName; 2569c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson break; 2579c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson 2589c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson case ELEMENT_NODE: 2599c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson ElementImpl element = (ElementImpl) node; 2609c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.namespaceAware = true; 2619c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.namespaceURI = namespaceURI; 2629c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.prefix = prefix; 2639c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.localName = qualifiedName; 2649c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson break; 2659c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson 2669c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson default: 2679c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 2689c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson "Cannot rename nodes of type " + node.getNodeType()); 2699c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } 2709c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } 271503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 2729c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson /** 2739c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * Sets {@code node} to be not namespace-aware and assigns its name. 2749c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * 2759c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson * @param node an element or attribute node. 2769c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson */ 2779c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson static void setName(NodeImpl node, String name) { 2789c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson int prefixSeparator = name.lastIndexOf(":"); 2799c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson if (prefixSeparator != -1) { 2809c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson String prefix = name.substring(0, prefixSeparator); 2819c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson String localName = name.substring(prefixSeparator + 1); 2829c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson if (!DocumentImpl.isXMLIdentifier(prefix) || !DocumentImpl.isXMLIdentifier(localName)) { 2839c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name); 2849c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } 2859c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } else if (!DocumentImpl.isXMLIdentifier(name)) { 2869c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson throw new DOMException(DOMException.INVALID_CHARACTER_ERR, name); 2879c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson } 2889c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson 2899c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson switch (node.getNodeType()) { 2909c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson case ATTRIBUTE_NODE: 2919c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson AttrImpl attr = (AttrImpl) node; 2929c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.namespaceAware = false; 2939c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson attr.localName = name; 2949c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson break; 2959c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson 2969c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson case ELEMENT_NODE: 2979c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson ElementImpl element = (ElementImpl) node; 2989c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.namespaceAware = false; 2999c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson element.localName = name; 3009c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson break; 3019c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson 3029c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson default: 3039c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 3049c075bb3e84c6eaafd016cbc1bf69a6e989eedf3Jesse Wilson "Cannot rename nodes of type " + node.getNodeType()); 305503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson } 306503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson } 307503917e646b5ebd3f23dfe0cb41270cfe484693aJesse Wilson 308302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson public final String getBaseURI() { 309302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson switch (getNodeType()) { 310302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case DOCUMENT_NODE: 311302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return sanitizeUri(((Document) this).getDocumentURI()); 312302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 313302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case ELEMENT_NODE: 314302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson Element element = (Element) this; 315302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson String uri = element.getAttributeNS( 316302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson "http://www.w3.org/XML/1998/namespace", "base"); // or "xml:base" 317302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 318302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson try { 319f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson // if this node has no base URI, return the parent's. 320f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson if (uri == null || uri.isEmpty()) { 321f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson return getParentBaseUri(); 322f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson } 323f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson 324f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson // if this node's URI is absolute, return it 325f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson if (new URI(uri).isAbsolute()) { 326f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson return uri; 327f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson } 328f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson 329f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson // this node has a relative URI. Try to resolve it against the 330f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson // parent, but if that doesn't work just give up and return null. 331f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson String parentUri = getParentBaseUri(); 332f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson if (parentUri == null) { 333f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson return null; 334f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson } 335f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson 336f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson return new URI(parentUri).resolve(uri).toString(); 337f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson } catch (URISyntaxException e) { 338f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson return null; 339302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 340302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 341302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case PROCESSING_INSTRUCTION_NODE: 342302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return getParentBaseUri(); 343302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 344302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case NOTATION_NODE: 345302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case ENTITY_NODE: 346302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson // When we support these node types, the parser should 347302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson // initialize a base URI field on these nodes. 348302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return null; 349302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 350302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case ENTITY_REFERENCE_NODE: 351302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson // TODO: get this value from the parser, falling back to the 352302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson // referenced entity's baseURI if that doesn't exist 353302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return null; 354302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 355302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case DOCUMENT_TYPE_NODE: 356302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case DOCUMENT_FRAGMENT_NODE: 357302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case ATTRIBUTE_NODE: 358302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case TEXT_NODE: 359302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case CDATA_SECTION_NODE: 360302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson case COMMENT_NODE: 361302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return null; 362302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 363302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson default: 364302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 365302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson "Unsupported node type " + getNodeType()); 366302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 367302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 368302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 369302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson private String getParentBaseUri() { 370302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson Node parentNode = getParentNode(); 371302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return parentNode != null ? parentNode.getBaseURI() : null; 372302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 373302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson 374302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson /** 375302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson * Returns the sanitized input if it is a URI, or {@code null} otherwise. 376302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson */ 377302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson private String sanitizeUri(String uri) { 378302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson if (uri == null || uri.length() == 0) { 379302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return null; 380302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 381302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson try { 382302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return new URI(uri).toString(); 383f029395dff382fc4dcba0689fd948ec06644e1f0Jesse Wilson } catch (URISyntaxException e) { 384302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson return null; 385302f069f38e7890594816ceab517c15bcd59a9b7Jesse Wilson } 386320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 387320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 388320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public short compareDocumentPosition(Node other) 389320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson throws DOMException { 390320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson throw new UnsupportedOperationException(); // TODO 391320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 392320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 393320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public String getTextContent() throws DOMException { 3942e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson return getNodeValue(); 3952e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 3962e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson 3972e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson void getTextContent(StringBuilder buf) throws DOMException { 3982e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson String content = getNodeValue(); 3992e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson if (content != null) { 4002e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson buf.append(content); 4012e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 402320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 403320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 404ea5adee4813216359fda6529e7064c42ccdbc4cdJesse Wilson public final void setTextContent(String textContent) throws DOMException { 4051ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson switch (getNodeType()) { 4061ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_TYPE_NODE: 4071ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_NODE: 4081ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return; // do nothing! 4091ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4101ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ELEMENT_NODE: 4111ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ENTITY_NODE: 4121ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ENTITY_REFERENCE_NODE: 4131ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_FRAGMENT_NODE: 4141ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // remove all existing children 4151ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson Node child; 4161ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson while ((child = getFirstChild()) != null) { 4171ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson removeChild(child); 4181ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4191ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // create a text node to hold the given content 420bda224da00c0372a7752b1304aeda98e2930c4afJesse Wilson if (textContent != null && textContent.length() != 0) { 4218b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson appendChild(document.createTextNode(textContent)); 4221ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4231ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return; 4241ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4251ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ATTRIBUTE_NODE: 4261ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case TEXT_NODE: 4271ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case CDATA_SECTION_NODE: 4281ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case PROCESSING_INSTRUCTION_NODE: 4291ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case COMMENT_NODE: 4301ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case NOTATION_NODE: 4311ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson setNodeValue(textContent); 4321ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return; 4331ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4341ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson default: 4351ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 4361ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson "Unsupported node type " + getNodeType()); 4371ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 438320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 439320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 440320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson public boolean isSameNode(Node other) { 4411ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return this == other; 442320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 443320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 4441ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson /** 4451ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Returns the element whose namespace definitions apply to this node. Use 4461ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * this element when mapping prefixes to URIs and vice versa. 4471ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson */ 4481ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson private NodeImpl getNamespacingElement() { 4491ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson switch (this.getNodeType()) { 4501ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ELEMENT_NODE: 4511ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return this; 4521ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4531ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_NODE: 4541ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return (NodeImpl) ((Document) this).getDocumentElement(); 4551ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4561ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ENTITY_NODE: 4571ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case NOTATION_NODE: 4581ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_FRAGMENT_NODE: 4591ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case DOCUMENT_TYPE_NODE: 4601ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return null; 4611ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4621ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ATTRIBUTE_NODE: 4631ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return (NodeImpl) ((Attr) this).getOwnerElement(); 4641ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4651ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case TEXT_NODE: 4661ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case CDATA_SECTION_NODE: 4671ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case ENTITY_REFERENCE_NODE: 4681ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case PROCESSING_INSTRUCTION_NODE: 4691ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson case COMMENT_NODE: 4701ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return getContainingElement(); 4711ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4721ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson default: 4731ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson throw new DOMException(DOMException.NOT_SUPPORTED_ERR, 4741ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson "Unsupported node type " + getNodeType()); 4751ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4761ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4771ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4781ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson /** 4791ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Returns the nearest ancestor element that contains this node. 4801ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson */ 4811ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson private NodeImpl getContainingElement() { 4821ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson for (Node p = getParentNode(); p != null; p = p.getParentNode()) { 4831ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (p.getNodeType() == ELEMENT_NODE) { 4841ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return (NodeImpl) p; 4851ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4861ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4871ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return null; 4881ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4891ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4901ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson public final String lookupPrefix(String namespaceURI) { 4911ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (namespaceURI == null) { 4921ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return null; 4931ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 4941ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4951ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // the XML specs define some prefixes (like "xml" and "xmlns") but this 4961ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // API is explicitly defined to ignore those. 4971ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 4981ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson NodeImpl target = getNamespacingElement(); 4991ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson for (NodeImpl node = target; node != null; node = node.getContainingElement()) { 5001ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // check this element's namespace first 5011ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (namespaceURI.equals(node.getNamespaceURI()) 5021ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson && target.isPrefixMappedToUri(node.getPrefix(), namespaceURI)) { 5031ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return node.getPrefix(); 5041ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5051ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5061ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // search this element for an attribute of this form: 5071ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // xmlns:foo="http://namespaceURI" 5081ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (!node.hasAttributes()) { 5091ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson continue; 5101ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5111ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson NamedNodeMap attributes = node.getAttributes(); 5121ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson for (int i = 0, length = attributes.getLength(); i < length; i++) { 5131ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson Node attr = attributes.item(i); 5141ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (!"http://www.w3.org/2000/xmlns/".equals(attr.getNamespaceURI()) 5151ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson || !"xmlns".equals(attr.getPrefix()) 5161ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson || !namespaceURI.equals(attr.getNodeValue())) { 5171ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson continue; 5181ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5191ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (target.isPrefixMappedToUri(attr.getLocalName(), namespaceURI)) { 5201ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return attr.getLocalName(); 5211ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5221ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5231ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5241ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5251ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return null; 5261ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5271ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5281ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson /** 5291ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * Returns true if the given prefix is mapped to the given URI on this 5301ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * element. Since child elements can redefine prefixes, this check is 5311ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * necessary: {@code 5321ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <foo xmlns:a="http://good"> 5331ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <bar xmlns:a="http://evil"> 5341ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * <a:baz /> 5351ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * </bar> 5361ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * </foo>} 5371ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * 5381ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * @param prefix the prefix to find. Nullable. 5391ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson * @param uri the URI to match. Non-null. 5401ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson */ 5411ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson boolean isPrefixMappedToUri(String prefix, String uri) { 5421ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (prefix == null) { 5431ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return false; 5441ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5451ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5461ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson String actual = lookupNamespaceURI(prefix); 5471ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return uri.equals(actual); 548320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 549320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 55035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson public final boolean isDefaultNamespace(String namespaceURI) { 55135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson String actual = lookupNamespaceURI(null); // null yields the default namespace 55235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return namespaceURI == null 55335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson ? actual == null 55435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson : namespaceURI.equals(actual); 555320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 556320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 5571ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson public final String lookupNamespaceURI(String prefix) { 5581ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson NodeImpl target = getNamespacingElement(); 5591ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson for (NodeImpl node = target; node != null; node = node.getContainingElement()) { 5601ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // check this element's namespace first 5611ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson String nodePrefix = node.getPrefix(); 5621ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (node.getNamespaceURI() != null) { 5631ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (prefix == null // null => default prefix 5641ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson ? nodePrefix == null 5651ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson : prefix.equals(nodePrefix)) { 5661ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return node.getNamespaceURI(); 5671ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5681ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5691ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5701ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // search this element for an attribute of the appropriate form. 5711ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // default namespace: xmlns="http://resultUri" 5721ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson // non default: xmlns:specifiedPrefix="http://resultUri" 5731ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (!node.hasAttributes()) { 5741ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson continue; 5751ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5761ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson NamedNodeMap attributes = node.getAttributes(); 5771ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson for (int i = 0, length = attributes.getLength(); i < length; i++) { 5781ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson Node attr = attributes.item(i); 5791ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (!"http://www.w3.org/2000/xmlns/".equals(attr.getNamespaceURI())) { 5801ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson continue; 5811ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5821ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson if (prefix == null // null => default prefix 5831ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson ? "xmlns".equals(attr.getNodeName()) 5841ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson : "xmlns".equals(attr.getPrefix()) && prefix.equals(attr.getLocalName())) { 5851ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson String value = attr.getNodeValue(); 5861ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return value.length() > 0 ? value : null; 5871ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5881ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5891ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson } 5901ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson 5911ec94feeb09591c30996c7c0834d6f131e204922Jesse Wilson return null; 592320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 593320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 59435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson /** 59535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson * Returns a list of objects such that two nodes are equal if their lists 59635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson * are equal. Be careful: the lists may contain NamedNodeMaps and Nodes, 59735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson * neither of which override Object.equals(). Such values must be compared 59835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson * manually. 59935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson */ 60035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson private static List<Object> createEqualityKey(Node node) { 60135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson List<Object> values = new ArrayList<Object>(); 60235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getNodeType()); 60335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getNodeName()); 60435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getLocalName()); 60535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getNamespaceURI()); 60635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getPrefix()); 60735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(node.getNodeValue()); 60835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { 60935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(child); 61035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 61135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 61235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson switch (node.getNodeType()) { 61335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson case DOCUMENT_TYPE_NODE: 61435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson DocumentTypeImpl doctype = (DocumentTypeImpl) node; 61535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(doctype.getPublicId()); 61635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(doctype.getSystemId()); 61735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(doctype.getInternalSubset()); 61835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(doctype.getEntities()); 61935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(doctype.getNotations()); 62035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson break; 62135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 62235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson case ELEMENT_NODE: 62335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson Element element = (Element) node; 62435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson values.add(element.getAttributes()); 62535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson break; 62635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 62735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 62835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return values; 629320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 630320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 63135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson public final boolean isEqualNode(Node arg) { 63235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (arg == this) { 63335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return true; 63435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 63535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 63635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson List<Object> listA = createEqualityKey(this); 63735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson List<Object> listB = createEqualityKey(arg); 63835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 63935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (listA.size() != listB.size()) { 64035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 64135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 64235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 64335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson for (int i = 0; i < listA.size(); i++) { 64435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson Object a = listA.get(i); 64535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson Object b = listB.get(i); 64635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 64735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (a == b) { 64835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson continue; 64935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 65035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } else if (a == null || b == null) { 65135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 65235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 65335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } else if (a instanceof String || a instanceof Short) { 65435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (!a.equals(b)) { 65535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 65635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 65735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 65835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } else if (a instanceof NamedNodeMap) { 65935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (!(b instanceof NamedNodeMap) 66035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson || !namedNodeMapsEqual((NamedNodeMap) a, (NamedNodeMap) b)) { 66135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 66235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 66335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 66435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } else if (a instanceof Node) { 66535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (!(b instanceof Node) 66635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson || !((Node) a).isEqualNode((Node) b)) { 66735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 66835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 66935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 67035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } else { 67135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson throw new AssertionError(); // unexpected type 67235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 67335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 674f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 67535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return true; 67635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 67735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 67835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson private boolean namedNodeMapsEqual(NamedNodeMap a, NamedNodeMap b) { 67935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (a.getLength() != b.getLength()) { 68035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 68135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 68235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson for (int i = 0; i < a.getLength(); i++) { 68335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson Node aNode = a.item(i); 68435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson Node bNode = aNode.getLocalName() == null 68535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson ? b.getNamedItem(aNode.getNodeName()) 68635d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson : b.getNamedItemNS(aNode.getNamespaceURI(), aNode.getLocalName()); 68735d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson if (bNode == null || !aNode.isEqualNode(bNode)) { 68835d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return false; 68935d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 69035d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 69135d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return true; 69235d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson } 69335d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson 69435d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson public final Object getFeature(String feature, String version) { 69535d7c089bd45f1030407b9b69b46e66f02c03043Jesse Wilson return isSupported(feature, version) ? this : null; 696320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 697320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 6988b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson public final Object setUserData(String key, Object data, UserDataHandler handler) { 6998b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson if (key == null) { 70086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("key == null"); 7018b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson } 7028b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson Map<String, UserData> map = document.getUserDataMap(this); 7038b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson UserData previous = data == null 7048b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson ? map.remove(key) 7058b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson : map.put(key, new UserData(data, handler)); 7068b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson return previous != null ? previous.value : null; 707320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 708320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson 7098b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson public final Object getUserData(String key) { 7108b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson if (key == null) { 71186acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("key == null"); 7128b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson } 7138b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson Map<String, UserData> map = document.getUserDataMapForRead(this); 7148b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson UserData userData = map.get(key); 7158b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson return userData != null ? userData.value : null; 7168b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson } 7178b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson 7188b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson static class UserData { 7198b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson final Object value; 7208b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson final UserDataHandler handler; 7218b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson UserData(Object value, UserDataHandler handler) { 7228b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson this.value = value; 7238b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson this.handler = handler; 7248b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson } 725320c9890e8241fb0ad05de6fa5e6c3eb3aece159Jesse Wilson } 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 727