View Javadoc
1 /* 2 Copyright (C) 2003 Together 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with this library; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 package org.enhydra.xml; 20 21 import java.io.File; 22 import java.io.FileOutputStream; 23 import java.util.ArrayList; 24 import java.util.Iterator; 25 import java.util.List; 26 import java.util.HashMap; 27 import java.util.HashMap; 28 29 import org.w3c.dom.Attr; 30 import org.w3c.dom.Document; 31 import org.w3c.dom.Element; 32 import org.w3c.dom.DOMException; 33 import org.w3c.dom.NamedNodeMap; 34 import org.w3c.dom.Node; 35 import org.w3c.dom.NodeList; 36 37 /*** 38 * @author Tweety 39 * 40 * A class representing a node in a meta-data tree, which implements 41 * the <a href="../../../../api/org/w3c/dom/Element.html"> 42 * 43 * <p> Namespaces are ignored in this implementation. The terms "tag 44 * name" and "node name" are always considered to be synonymous. 45 * 46 * @version 1.0 47 */ 48 public class HashMapElement extends ElementImpl { 49 50 51 /*** 52 * All <code>Element<code> type children of this <code>Element<code> 53 */ 54 protected HashMap children = null; 55 56 57 /*** 58 * Constructs an empty <code>HashMapElement</code>. 59 */ 60 public HashMapElement() { 61 super(); 62 children = new HashMap(); 63 } 64 65 66 /*** 67 * Constructs a <code>HashMapElement</code> from the given node, 68 * without creating entire children subtree. 69 * 70 * @param element , as a <code>HashMapElement</code>. 71 */ 72 public HashMapElement(HashMapElement element) { 73 super(element); 74 children = element.children; 75 } 76 77 78 /*** 79 * Constructs an <code>HashMapElement</code> with the given 80 * document owner and node name. 81 * 82 * @param ownerDoc the document owner of the node, as a <code>Document</code>. 83 * @param name is the name of the node, as a <code>String</code>. 84 */ 85 public HashMapElement(Document ownerDoc, String name) { 86 super(ownerDoc, name); 87 this.children = new HashMap(); 88 } 89 90 91 /*** 92 * Constructs an <code>HashMapElement</code> with the given 93 * document owner, node name, node type and node value. 94 * 95 * @param ownerDoc the document owner of the node, as a <code>Document</code>. 96 * @param nodeName the name of the node, as a <code>String</code>. 97 * @param type the type of the node, as a <code>short</code>. 98 * @param value the value of the node, as a <code>String</code>. 99 */ 100 protected HashMapElement(Document ownerDoc, String nodeName, short type, String value) { 101 super(ownerDoc, nodeName, type, value); 102 } 103 104 105 /*** 106 * Constructs an <code>HashMapElement</code> from a given node 107 * (creates the children subtree too), as a <code>Node</code> 108 * 109 * @param node , as a <code>Node</code>. 110 */ 111 public HashMapElement(Node node) { 112 this(node, true); 113 } 114 115 /*** 116 * Constructs an <code>HashMapElement</code> from a given node, 117 * as a <code>Node</code>, and deep as <code>boolean</code>. 118 * 119 * @param node , as a <code>Node</code>. 120 * @param deep if <code>true</code>, recursively clone the subtree 121 * under the specified node; if <code>false</code>, clone only the 122 * node itself. 123 */ 124 public HashMapElement(Node node, boolean deep) { 125 super(node, false); 126 children = new HashMap(); 127 if (deep) 128 initNodeImplChildren(node); 129 } 130 131 132 /*** 133 * Creates new instance of the HashMapElement class from the given <code>Node</code>. 134 * 135 * @param node , as a <code>Node</code>. 136 * 137 * @return new instance of the HashMapElement class. 138 */ 139 protected Node newElementInstance(Node node) { 140 return new HashMapElement(node); 141 } 142 143 /*** 144 * Creates new instance of <code>HashMapElement</code> from a given document 145 * as a <code>Document</code>. 146 * 147 * @param document document. 148 * 149 * @return new <code>Element</code> node as a root of the <code>Document</code>. 150 */ 151 public static Element newInstance(Document document) { 152 Node root = document.getDocumentElement(); 153 return new HashMapElement(root); 154 } 155 156 /*** 157 * Inserts the node <code>newChild</code> before the existing 158 * child node <code>refChild</code>. If <code>refChild</code> is 159 * <code>null</code>, insert <code>newChild</code> at the end of 160 * the list of children. 161 * 162 * @param newChild the <code>Node</code> to insert. 163 * @param refChild the reference <code>Node</code>. 164 * 165 * @return the node being inserted. 166 * 167 * @exception IllegalArgumentException if <code>newChild</code> is 168 * <code>null</code>. 169 */ 170 public Node insertBefore(Node newChild, Node refChild) { 171 super.insertBefore(newChild, refChild); 172 173 if (newChild.getNodeType() == ELEMENT_NODE) { 174 HashMapElement newChildNode = (HashMapElement) newChild; 175 176 List list = (List) children.get(newChildNode.getTagName()); 177 if (list == null) 178 list = new ArrayList(); 179 list.add(newChildNode); 180 children.put(newChildNode.getTagName(), list); 181 } 182 return newChild; 183 } 184 185 186 /*** 187 * Replaces the child node <code>oldChild</code> with 188 * <code>newChild</code> in the list of children, and returns the 189 * <code>oldChild</code> node. 190 * 191 * @param newChild the <code>Node</code> to insert. 192 * @param oldChild the <code>Node</code> to be replaced. 193 * 194 * @return the node replaced. 195 * 196 * @exception IllegalArgumentException if <code>newChild</code> is 197 * <code>null</code>. 198 */ 199 public Node replaceChild(Node newChild, Node oldChild) { 200 super.replaceChild(newChild, oldChild); 201 202 if (oldChild.getNodeType() == ELEMENT_NODE) { 203 HashMapElement oldChildNode = (HashMapElement) oldChild; 204 List list = (List) children.get(oldChildNode.getTagName()); 205 if (list != null) { 206 int index = list.indexOf(oldChildNode); 207 if (index != -1) 208 list.remove(index); 209 if (list.size() == 0) 210 children.remove(oldChildNode.getTagName()); 211 } 212 } 213 if (newChild.getNodeType() == ELEMENT_NODE) { 214 HashMapElement newChildNode = (HashMapElement) newChild; 215 List list = (List) children.get(newChildNode.getTagName()); 216 if (list == null) 217 list = new ArrayList(); 218 list.add(newChildNode); 219 children.put(newChildNode.getTagName(), list); 220 } 221 222 return oldChild; 223 } 224 225 226 /*** 227 * Removes the child node indicated by <code>oldChild</code> from 228 * the list of children, and returns it. 229 * 230 * @param oldChild the <code>Node</code> to be removed. 231 * 232 * @return the node removed. 233 * 234 * @exception IllegalArgumentException if <code>oldChild</code> is 235 * <code>null</code>. 236 */ 237 public Node removeChild(Node oldChild) { 238 super.removeChild(oldChild); 239 240 if (oldChild.getNodeType() == ELEMENT_NODE) { 241 HashMapElement oldChildNode = (HashMapElement) oldChild; 242 243 List list = (List) children.get(oldChildNode.getTagName()); 244 if (list != null) { 245 int index = list.indexOf(oldChildNode); 246 if (index != -1) 247 list.remove(index); 248 if (list.size() == 0) 249 children.remove(oldChildNode.getTagName()); 250 } 251 } 252 return oldChild; 253 } 254 255 256 /*** 257 * Check that the node is either <code>null</code> or an 258 * <code>NodeImpl</code>. 259 * 260 * @exception DOMException if node is not an instance of <code>NodeImpl</code>. 261 */ 262 // protected void checkNode(Node node) throws DOMException { 263 // if (node == null) { 264 // return; 265 // } 266 // if (!(node instanceof HashMapElement)) 267 // throw new NodeDOMException(DOMException.WRONG_DOCUMENT_ERR, "Node is not an instance of HashMapElement!"); 268 // } 269 270 271 /*** 272 * Returns a duplicate of this node. The duplicate node has no 273 * parent (<code>getParentNode</code> returns <code>null</code>). 274 * If a shallow clone is being performed (<code>deep</code> is 275 * <code>false</code>), the new node will not have any children or 276 * siblings. If a deep clone is being performed, the new node 277 * will form the root of a complete cloned subtree. 278 * 279 * @param deep if <code>true</code>, recursively clone the subtree 280 * under the specified node; if <code>false</code>, clone only the 281 * node itself. 282 * 283 * @return the duplicate node. 284 */ 285 public Node cloneNode(boolean deep) { 286 return new HashMapElement(this, deep); 287 } 288 289 290 291 /*** 292 * Returns all <code>Element</code> nodes with given name, 293 * searching by all sub nodes from this node. 294 * 295 * @param name tag name. 296 * 297 * @return all <code>Element</code> vith given name as <code>NodeList</code>. 298 */ 299 public NodeList getElementsByTagName(String name) { 300 List list = new ArrayList(); 301 302 // added for new search 303 if (nodeName.equals(name)) { 304 list.add(this); 305 } 306 307 getElementsByTagName(name, list); 308 return new NodeListImpl(list); 309 } 310 311 312 private void getElementsByTagName(String name, List list) { 313 if (numChildren == 0) 314 return; 315 List fList = (List) children.get(name); 316 if (fList != null); 317 list.addAll(fList); 318 for (Iterator iter = children.values().iterator(); iter.hasNext();) { 319 fList = (List) iter.next(); 320 for (int i = 0; i < fList.size(); i++) { 321 ((HashMapElement) fList.get(i)).getElementsByTagName( 322 name, 323 list); 324 } 325 } 326 } 327 328 329 /*** 330 * Returns <code>true</code> if this node has child nodes. 331 * 332 * @return <code>true</code> if this node has children. 333 */ 334 public boolean hasElementChildNodes() { 335 return children.size() > 0; 336 } 337 338 339 /*** 340 * Returns the list of all children nodes with the given tag name. 341 * 342 * @param name tag name. 343 * 344 * @return the list of all children nodes with the given tag name. 345 */ 346 public NodeList getChildrenByTagName(String name) { 347 List list = (List) this.children.get(name); 348 if (list != null) 349 return new NodeListImpl(list); 350 return null; 351 } 352 353 354 /*** 355 * Returns the first child <code>Element</code> with the given tag name. 356 * 357 * @param name tag name. 358 * 359 * @return the first child <code>Element</code> with the given tag name. 360 */ 361 public Element getFirstChildByTagName(String name) { 362 NodeList children = getChildrenByTagName(name); 363 if (children != null && children.getLength() > 0) 364 return (HashMapElement) children.item(0); 365 return null; 366 } 367 368 369 /*** 370 * Returns the next <code>Element</code> node (if exists) with the same tag name. 371 * 372 * @return the next <code>Element</code> node (if exists) with the same tag name. 373 */ 374 public Element getNextSameNameNode() { 375 try { 376 HashMapElement parent = (HashMapElement) this.getParentNode(); 377 List tagList = (List) parent.children.get(this.nodeName); 378 int index = tagList.indexOf(this); 379 if (++index <= tagList.size()) 380 return (HashMapElement) tagList.get(index); 381 } catch (NullPointerException e) { 382 throw new NodeDOMException( 383 DOMException.NOT_FOUND_ERR, 384 "Root node doesn't have a successor"); 385 } 386 return null; 387 } 388 389 390 /*** 391 * Returns the concatenation of values of all text type children. 392 * 393 * @return the concatenation of values of all text type children. 394 */ 395 public String getText() { 396 String text = ""; 397 Node child = this.getFirstChild(); 398 while (child != null) { 399 if (child.getNodeType() == Node.TEXT_NODE) 400 text += child.getNodeValue(); 401 child = child.getNextSibling(); 402 } 403 if (!text.equals("")) 404 return text; 405 return null; 406 } 407 408 409 /*** 410 * Set the value of the first text child node to the given text, 411 * and remove all other text child nodes. 412 * 413 * @param text new text. 414 */ 415 public void setText(String text) { 416 Node child = this.getFirstChild(); 417 if (child != null) { 418 child.setNodeValue(text); 419 child = child.getNextSibling(); 420 while (child != null) { 421 if (child.getNodeType() == Node.TEXT_NODE) { 422 Node temp = child; 423 child = child.getNextSibling(); 424 this.removeChild(temp); 425 } else { 426 child = child.getNextSibling(); 427 } 428 } 429 } 430 } 431 432 433 }

This page was automatically generated by Maven