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 197365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.ArrayList; 207365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilsonimport java.util.List; 216186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.Objects; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.DOMException; 235c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilsonimport org.w3c.dom.DocumentFragment; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.Node; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.w3c.dom.NodeList; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Provides a straightforward implementation of the corresponding W3C DOM 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * interface. The class is used internally only, thus only notable members that 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are not in the original interface are documented (the W3C docs are quite 312f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * extensive). 322f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * 332f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * <p>Some of the fields may have package visibility, so other classes belonging 342f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * to the DOM implementation can easily access them while maintaining the DOM 352f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * tree structure. 362f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * 372f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * <p>This class represents a Node that has a parent Node as well as 382f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * (potentially) a number of children. 392f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * 402f4bbf1068869f45783608450731f83c523ded30Jesse Wilson * <p>Some code was adapted from Apache Xerces. 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class InnerNodeImpl extends LeafNodeImpl { 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Maintained by LeafNodeImpl and ElementImpl. 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<LeafNodeImpl> children = new ArrayList<LeafNodeImpl>(); 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 478b2f7a2b953a0ae4f01f7632fab2f29fe4d14a64Jesse Wilson protected InnerNodeImpl(DocumentImpl document) { 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(document); 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node appendChild(Node newChild) throws DOMException { 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return insertChildAt(newChild, children.size()); 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeList getChildNodes() { 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeListImpl list = new NodeListImpl(); 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (NodeImpl node : children) { 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project list.add(node); 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return list; 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getFirstChild() { 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (!children.isEmpty() ? children.get(0) : null); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getLastChild() { 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (!children.isEmpty() ? children.get(children.size() - 1) : null); 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node getNextSibling() { 74ab3721103266c7c9f58d5a9d32521a00a2c478d7Elliott Hughes if (parent == null || index + 1 >= parent.children.size()) { 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parent.children.get(index + 1); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean hasChildNodes() { 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return children.size() != 0; 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node insertBefore(Node newChild, Node refChild) throws DOMException { 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project LeafNodeImpl refChildImpl = (LeafNodeImpl) refChild; 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 8881341fd8822d545037fca9d9820a7814e6d64da7Elliott Hughes if (refChildImpl == null) { 8981341fd8822d545037fca9d9820a7814e6d64da7Elliott Hughes return appendChild(newChild); 9081341fd8822d545037fca9d9820a7814e6d64da7Elliott Hughes } 9181341fd8822d545037fca9d9820a7814e6d64da7Elliott Hughes 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (refChildImpl.document != document) { 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null); 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (refChildImpl.parent != this) { 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return insertChildAt(newChild, refChildImpl.index); 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1045c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson * Inserts {@code newChild} at {@code index}. If it is already child of 1055c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson * another node, it is removed from there. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1075c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson Node insertChildAt(Node newChild, int index) throws DOMException { 1085c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson if (newChild instanceof DocumentFragment) { 1095c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson NodeList toAdd = newChild.getChildNodes(); 1105c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson for (int i = 0; i < toAdd.getLength(); i++) { 1115c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson insertChildAt(toAdd.item(i), index + i); 1125c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson } 1135c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson return newChild; 1145c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson } 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1165c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson LeafNodeImpl toInsert = (LeafNodeImpl) newChild; 11709c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson if (toInsert.document != null && document != null && toInsert.document != document) { 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1205c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson if (toInsert.isParentOf(this)) { 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1245c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson if (toInsert.parent != null) { 1255c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson int oldIndex = toInsert.index; 1265c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson toInsert.parent.children.remove(oldIndex); 1275c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson toInsert.parent.refreshIndices(oldIndex); 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1305c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson children.add(index, toInsert); 1315c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson toInsert.parent = this; 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project refreshIndices(index); 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return newChild; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isParentOf(Node node) { 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project LeafNodeImpl nodeImpl = (LeafNodeImpl) node; 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (nodeImpl != null) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (nodeImpl == this) { 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeImpl = nodeImpl.parent; 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15181ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson /** 15281ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson * Normalize the text nodes within this subtree. Although named similarly, 15381ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson * this method is unrelated to Document.normalize. 15481ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson */ 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 15681ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson public final void normalize() { 1578092253eb6a1cff91f0e4953f1387165169157b5Jesse Wilson Node next; 1588092253eb6a1cff91f0e4953f1387165169157b5Jesse Wilson for (Node node = getFirstChild(); node != null; node = next) { 1598092253eb6a1cff91f0e4953f1387165169157b5Jesse Wilson next = node.getNextSibling(); 16081ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson node.normalize(); 16181ca3dd430f9c038b4257e1124f45a07d0e6b543Jesse Wilson 1628092253eb6a1cff91f0e4953f1387165169157b5Jesse Wilson if (node.getNodeType() == Node.TEXT_NODE) { 1638092253eb6a1cff91f0e4953f1387165169157b5Jesse Wilson ((TextImpl) node).minimize(); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void refreshIndices(int fromIndex) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = fromIndex; i < children.size(); i++) { 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project children.get(i).index = i; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node removeChild(Node oldChild) throws DOMException { 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project LeafNodeImpl oldChildImpl = (LeafNodeImpl) oldChild; 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (oldChildImpl.document != document) { 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null); 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (oldChildImpl.parent != this) { 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, null); 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = oldChildImpl.index; 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project children.remove(index); 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project oldChildImpl.parent = null; 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project refreshIndices(index); 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return oldChild; 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1925c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson /** 1935c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson * Removes {@code oldChild} and adds {@code newChild} in its place. This 1945c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson * is not atomic. 1955c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson */ 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Node replaceChild(Node newChild, Node oldChild) throws DOMException { 1975c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson int index = ((LeafNodeImpl) oldChild).index; 1985c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson removeChild(oldChild); 1995c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson insertChildAt(newChild, index); 2005c0408af32a2b1c78b2d5a93cca60b0fffddd7daJesse Wilson return oldChild; 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2032e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson public String getTextContent() throws DOMException { 2042e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson Node child = getFirstChild(); 2052e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson if (child == null) { 2062e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson return ""; 2072e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2082e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson 2092e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson Node next = child.getNextSibling(); 2102e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson if (next == null) { 2112e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson return hasTextContent(child) ? child.getTextContent() : ""; 2122e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2132e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson 2142e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson StringBuilder buf = new StringBuilder(); 2152e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson getTextContent(buf); 2162e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson return buf.toString(); 2172e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2182e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson 2192e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson void getTextContent(StringBuilder buf) throws DOMException { 2202e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson Node child = getFirstChild(); 2212e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson while (child != null) { 2222e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson if (hasTextContent(child)) { 2232e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson ((NodeImpl) child).getTextContent(buf); 2242e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2252e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson child = child.getNextSibling(); 2262e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2272e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 2282e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson 2292e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson final boolean hasTextContent(Node child) { 2302e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson // TODO: skip text nodes with ignorable whitespace? 2312e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson return child.getNodeType() != Node.COMMENT_NODE 2322e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson && child.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE; 2332e4c40c282464cb5435b3078b8d375634355dbc1Jesse Wilson } 23409c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson 23509c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson void getElementsByTagName(NodeListImpl out, String name) { 23609c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson for (NodeImpl node : children) { 23709c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson if (node.getNodeType() == Node.ELEMENT_NODE) { 23809c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson ElementImpl element = (ElementImpl) node; 23909c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson if (matchesNameOrWildcard(name, element.getNodeName())) { 24009c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson out.add(element); 24109c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 24209c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson element.getElementsByTagName(out, name); 24309c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 24409c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 24509c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 24609c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson 24709c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson void getElementsByTagNameNS(NodeListImpl out, String namespaceURI, String localName) { 24809c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson for (NodeImpl node : children) { 24909c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson if (node.getNodeType() == Node.ELEMENT_NODE) { 25009c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson ElementImpl element = (ElementImpl) node; 25109c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson if (matchesNameOrWildcard(namespaceURI, element.getNamespaceURI()) 25209c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson && matchesNameOrWildcard(localName, element.getLocalName())) { 25309c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson out.add(element); 25409c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 25509c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson element.getElementsByTagNameNS(out, namespaceURI, localName); 25609c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 25709c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 25809c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 25909c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson 26009c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson /** 26109c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson * Returns true if {@code pattern} equals either "*" or {@code s}. Pattern 26209c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson * may be {@code null}. 26309c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson */ 26409c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson private static boolean matchesNameOrWildcard(String pattern, String s) { 26509c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson return "*".equals(pattern) || Objects.equal(pattern, s); 26609c4640423dbe85c606c5b46312cd5c0e5c94eebJesse Wilson } 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 268