001 /* IIOMetadataNode.java -- 002 Copyright (C) 2004 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.imageio.metadata; 040 041 import java.util.ArrayList; 042 import java.util.HashMap; 043 import java.util.Iterator; 044 import java.util.List; 045 046 import org.w3c.dom.Attr; 047 import org.w3c.dom.DOMException; 048 import org.w3c.dom.Document; 049 import org.w3c.dom.Element; 050 import org.w3c.dom.NamedNodeMap; 051 import org.w3c.dom.Node; 052 import org.w3c.dom.NodeList; 053 import org.w3c.dom.TypeInfo; 054 import org.w3c.dom.UserDataHandler; 055 import javax.imageio.metadata.IIOMetadataFormatImpl.IIOMetadataNodeAttr; 056 057 public class IIOMetadataNode 058 implements Element, NodeList 059 { 060 private String name; 061 private HashMap attrs = new HashMap(); 062 private List children = new ArrayList(); 063 private IIOMetadataNode parent; 064 private Object obj; 065 066 /** 067 * Simple NamedNodeMap class for IIOMetadataNode. 068 * 069 * @author jlquinn 070 */ 071 private class IIONamedNodeMap implements NamedNodeMap 072 { 073 HashMap attrs; 074 075 /** 076 * @param attrs 077 * @param node 078 */ 079 public IIONamedNodeMap(HashMap attrs) 080 { 081 this.attrs = attrs; 082 } 083 084 /* (non-Javadoc) 085 * @see org.w3c.dom.NamedNodeMap#getNamedItem(java.lang.String) 086 */ 087 public Node getNamedItem(String name) 088 { 089 return (Node)attrs.get(name); 090 } 091 092 /* (non-Javadoc) 093 * @see org.w3c.dom.NamedNodeMap#setNamedItem(org.w3c.dom.Node) 094 */ 095 public Node setNamedItem(Node arg) throws DOMException 096 { 097 if (arg instanceof IIOMetadataNodeAttr) 098 { 099 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) arg; 100 // The only code that can successfully do this is in this package. 101 if (attr.owner != null) 102 throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, ""); 103 return (Node)attrs.put(attr.name, attr); 104 } 105 // Anything else gets treated as an invalid op. 106 throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, ""); 107 } 108 109 /* (non-Javadoc) 110 * @see org.w3c.dom.NamedNodeMap#removeNamedItem(java.lang.String) 111 */ 112 public Node removeNamedItem(String name) throws DOMException 113 { 114 return (Node)attrs.remove(name); 115 } 116 117 /* (non-Javadoc) 118 * @see org.w3c.dom.NamedNodeMap#item(int) 119 */ 120 public Node item(int index) 121 { 122 return (Node)attrs.values().toArray()[index]; 123 } 124 125 /* (non-Javadoc) 126 * @see org.w3c.dom.NamedNodeMap#getLength() 127 */ 128 public int getLength() 129 { 130 return attrs.size(); 131 } 132 133 /* (non-Javadoc) 134 * @see org.w3c.dom.NamedNodeMap#getNamedItemNS(java.lang.String, java.lang.String) 135 */ 136 public Node getNamedItemNS(String namespaceURI, String localName) 137 { 138 return getNamedItem(localName); 139 } 140 141 /* (non-Javadoc) 142 * @see org.w3c.dom.NamedNodeMap#setNamedItemNS(org.w3c.dom.Node) 143 */ 144 public Node setNamedItemNS(Node arg) throws DOMException 145 { 146 return setNamedItem(arg); 147 } 148 149 /* (non-Javadoc) 150 * @see org.w3c.dom.NamedNodeMap#removeNamedItemNS(java.lang.String, java.lang.String) 151 */ 152 public Node removeNamedItemNS(String namespaceURI, String localName) 153 throws DOMException 154 { 155 return removeNamedItem(localName); 156 } 157 } 158 159 /** 160 * Simple NodeList implementation for IIOMetadataNode. 161 * 162 * @author jlquinn 163 * 164 */ 165 private class IIONodeList implements NodeList 166 { 167 List children = new ArrayList(); 168 169 /* (non-Javadoc) 170 * @see org.w3c.dom.NodeList#item(int) 171 */ 172 public Node item(int index) 173 { 174 return (index < children.size()) ? (Node)children.get(index) : null; 175 } 176 177 /* (non-Javadoc) 178 * @see org.w3c.dom.NodeList#getLength() 179 */ 180 public int getLength() 181 { 182 return children.size(); 183 } 184 } 185 186 public IIOMetadataNode() 187 { 188 // Do nothing here. 189 } 190 191 public IIOMetadataNode(String nodename) 192 { 193 name = nodename; 194 } 195 196 public Object getUserObject() 197 { 198 return obj; 199 } 200 201 public void setUserObject(Object o) 202 { 203 obj = o; 204 } 205 206 public short compareDocumentPosition(Node other) 207 throws DOMException 208 { 209 return Element.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; 210 } 211 212 /* (non-Javadoc) 213 * @see org.w3c.dom.Element#getAttribute(java.lang.String) 214 */ 215 public String getAttribute(String name) 216 { 217 Attr anode = (Attr) attrs.get(name); 218 return anode != null ? anode.getValue() : null; 219 } 220 221 /* (non-Javadoc) 222 * @see org.w3c.dom.Element#getAttributeNode(java.lang.String) 223 */ 224 public Attr getAttributeNode(String name) 225 { 226 String val = getAttribute(name); 227 if (val != null) 228 return new IIOMetadataNodeAttr(this, name, val); 229 return null; 230 } 231 232 /* (non-Javadoc) 233 * @see org.w3c.dom.Element#getAttributeNodeNS(java.lang.String, java.lang.String) 234 */ 235 public Attr getAttributeNodeNS(String namespaceURI, String localName) 236 { 237 return getAttributeNode(localName); 238 } 239 240 /* (non-Javadoc) 241 * @see org.w3c.dom.Element#getAttributeNS(java.lang.String, java.lang.String) 242 */ 243 public String getAttributeNS(String namespaceURI, String localName) 244 { 245 return getAttribute(localName); 246 } 247 248 public String getBaseURI() 249 { 250 return null; 251 } 252 253 // Recursive function for assembling a node list. 254 private void getElementsRecurse(IIONodeList list, String name) 255 { 256 for (int i=0; i < children.size(); i++) 257 { 258 if (((Node)children.get(i)).getNodeName().equals(name)) 259 list.children.add(children.get(i)); 260 getElementsRecurse(list, name); 261 } 262 } 263 264 /* (non-Javadoc) 265 * @see org.w3c.dom.Element#getElementsByTagName(java.lang.String) 266 */ 267 public NodeList getElementsByTagName(String name) 268 { 269 IIONodeList list = new IIONodeList(); 270 getElementsRecurse(list, name); 271 return list; 272 } 273 274 /* (non-Javadoc) 275 * @see org.w3c.dom.Element#getElementsByTagNameNS(java.lang.String, java.lang.String) 276 */ 277 public NodeList getElementsByTagNameNS(String namespaceURI, String localName) 278 { 279 IIONodeList list = new IIONodeList(); 280 getElementsRecurse(list, name); 281 return list; 282 } 283 284 /* (non-Javadoc) 285 * @see org.w3c.dom.Element#getTagName() 286 */ 287 public String getTagName() 288 { 289 return name; 290 } 291 292 /* (non-Javadoc) 293 * @see org.w3c.dom.Element#hasAttribute(java.lang.String) 294 */ 295 public boolean hasAttribute(String name) 296 { 297 return attrs.containsKey(name); 298 } 299 300 /* (non-Javadoc) 301 * @see org.w3c.dom.Element#hasAttributeNS(java.lang.String, java.lang.String) 302 */ 303 public boolean hasAttributeNS(String namespaceURI, String localName) 304 { 305 return attrs.containsKey(localName); 306 } 307 308 /* (non-Javadoc) 309 * @see org.w3c.dom.Element#removeAttribute(java.lang.String) 310 */ 311 public void removeAttribute(String name) 312 { 313 attrs.remove(name); 314 } 315 316 /* (non-Javadoc) 317 * @see org.w3c.dom.Element#removeAttributeNode(org.w3c.dom.Attr) 318 */ 319 public Attr removeAttributeNode(Attr oldAttr) 320 { 321 return (Attr)attrs.remove(oldAttr.getName()); 322 } 323 324 /* (non-Javadoc) 325 * @see org.w3c.dom.Element#removeAttributeNS(java.lang.String, java.lang.String) 326 */ 327 public void removeAttributeNS(String namespaceURI, String localName) 328 { 329 removeAttribute(localName); 330 } 331 332 /* (non-Javadoc) 333 * @see org.w3c.dom.Element#setAttribute(java.lang.String, java.lang.String) 334 */ 335 public void setAttribute(String name, String value) 336 { 337 Attr attr = (Attr) getAttributeNode(name); 338 if (attr != null) 339 attr.setValue(value); 340 else 341 attrs.put(name, new IIOMetadataNodeAttr(this, name, value)); 342 } 343 344 /* (non-Javadoc) 345 * @see org.w3c.dom.Element#setAttributeNode(org.w3c.dom.Attr) 346 */ 347 public Attr setAttributeNode(Attr newAttr) 348 { 349 return (Attr)attrs.put(newAttr.getName(), newAttr); 350 } 351 352 /* (non-Javadoc) 353 * @see org.w3c.dom.Element#setAttributeNodeNS(org.w3c.dom.Attr) 354 */ 355 public Attr setAttributeNodeNS(Attr newAttr) 356 { 357 return (Attr)attrs.put(newAttr.getName(), newAttr); 358 } 359 360 /* (non-Javadoc) 361 * @see org.w3c.dom.Element#setAttributeNS(java.lang.String, java.lang.String, java.lang.String) 362 */ 363 public void setAttributeNS(String namespaceURI, String qualifiedName, String value) 364 { 365 setAttribute(qualifiedName, value); 366 } 367 368 /* (non-Javadoc) 369 * @see org.w3c.dom.NodeList#getLength() 370 */ 371 public int getLength() 372 { 373 return children.size(); 374 } 375 376 /* (non-Javadoc) 377 * @see org.w3c.dom.NodeList#item(int) 378 */ 379 public Node item(int index) 380 { 381 if (index < children.size()) 382 return (Node)children.get(index); 383 else 384 return null; 385 } 386 387 /* (non-Javadoc) 388 * @see org.w3c.dom.Node#appendChild(org.w3c.dom.Node) 389 */ 390 public Node appendChild(Node newChild) 391 { 392 if (newChild == null) 393 throw new IllegalArgumentException("Child node is null"); 394 395 IIOMetadataNode child = (IIOMetadataNode) newChild; 396 397 children.add(child); 398 child.parent = this; 399 return this; 400 } 401 402 /* (non-Javadoc) 403 * @see org.w3c.dom.Node#cloneNode(boolean) 404 */ 405 public Node cloneNode(boolean deep) 406 { 407 IIOMetadataNode newnode = new IIOMetadataNode(name); 408 newnode.parent = null; 409 newnode.obj = obj; 410 if (deep) 411 { 412 for (int i=0; i < children.size(); i++) 413 newnode.children.add(((Node)children.get(i)).cloneNode(deep)); 414 } 415 416 // clone attrs 417 for (Iterator it = attrs.values().iterator(); it.hasNext();) 418 { 419 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr)it.next(); 420 newnode.attrs.put(attr.name, attr.cloneNode(deep)); 421 attr.owner = newnode; 422 } 423 424 return newnode; 425 } 426 427 /* (non-Javadoc) 428 * @see org.w3c.dom.Node#getAttributes() 429 */ 430 public NamedNodeMap getAttributes() 431 { 432 return new IIONamedNodeMap(attrs); 433 } 434 435 /* (non-Javadoc) 436 * @see org.w3c.dom.Node#getChildNodes() 437 */ 438 public NodeList getChildNodes() 439 { 440 return this; 441 } 442 443 public Object getFeature(String feature, String version) 444 { 445 return null; 446 } 447 448 /* (non-Javadoc) 449 * @see org.w3c.dom.Node#getFirstChild() 450 */ 451 public Node getFirstChild() 452 { 453 return (children.size() > 0) ? (Node)children.get(0) : null; 454 } 455 456 /* (non-Javadoc) 457 * @see org.w3c.dom.Node#getLastChild() 458 */ 459 public Node getLastChild() 460 { 461 return (children.size() > 0) ? (Node)children.get(children.size() - 1) 462 : null; 463 } 464 465 /* (non-Javadoc) 466 * @see org.w3c.dom.Node#getLocalName() 467 */ 468 public String getLocalName() 469 { 470 return name; 471 } 472 473 /* (non-Javadoc) 474 * @see org.w3c.dom.Node#getNamespaceURI() 475 */ 476 public String getNamespaceURI() 477 { 478 return null; 479 } 480 481 /* (non-Javadoc) 482 * @see org.w3c.dom.Node#getNextSibling() 483 */ 484 public Node getNextSibling() 485 { 486 // If this op needs to be faster, add links to prev and next nodes. 487 if (parent == null) return null; 488 int idx = parent.children.indexOf(this); 489 return (idx == parent.children.size() - 1) ? null 490 : (Node)parent.children.get(idx + 1); 491 } 492 493 /* (non-Javadoc) 494 * @see org.w3c.dom.Node#getNodeName() 495 */ 496 public String getNodeName() 497 { 498 return name; 499 } 500 501 /* (non-Javadoc) 502 * @see org.w3c.dom.Node#getNodeType() 503 */ 504 public short getNodeType() 505 { 506 return ELEMENT_NODE; 507 } 508 509 /* (non-Javadoc) 510 * @see org.w3c.dom.Node#getNodeValue() 511 */ 512 public String getNodeValue() 513 { 514 return null; 515 } 516 517 /* (non-Javadoc) 518 * @see org.w3c.dom.Node#getOwnerDocument() 519 */ 520 public Document getOwnerDocument() 521 { 522 // IOMetadataNodes have no owner 523 return null; 524 } 525 526 /* (non-Javadoc) 527 * @see org.w3c.dom.Node#getParentNode() 528 */ 529 public Node getParentNode() 530 { 531 return parent; 532 } 533 534 /* (non-Javadoc) 535 * @see org.w3c.dom.Node#getPrefix() 536 */ 537 public String getPrefix() 538 { 539 return null; 540 } 541 542 /* (non-Javadoc) 543 * @see org.w3c.dom.Node#getPreviousSibling() 544 */ 545 public Node getPreviousSibling() 546 { 547 // If this op needs to be faster, add links to prev and next nodes. 548 if (parent == null) return null; 549 int idx = parent.children.indexOf(this); 550 return (idx == 0) ? null 551 : (Node)parent.children.get(idx - 1); 552 } 553 554 public TypeInfo getSchemaTypeInfo() 555 { 556 return null; 557 } 558 559 public String getTextContent() 560 throws DOMException 561 { 562 return null; 563 } 564 565 public Object getUserData(String key) 566 { 567 return null; 568 } 569 570 /* (non-Javadoc) 571 * @see org.w3c.dom.Node#hasAttributes() 572 */ 573 public boolean hasAttributes() 574 { 575 return !attrs.isEmpty(); 576 } 577 578 /* (non-Javadoc) 579 * @see org.w3c.dom.Node#hasChildNodes() 580 */ 581 public boolean hasChildNodes() 582 { 583 return !children.isEmpty(); 584 } 585 586 /* (non-Javadoc) 587 * @see org.w3c.dom.Node#insertBefore(org.w3c.dom.Node, org.w3c.dom.Node) 588 */ 589 public Node insertBefore(Node newChild, Node refChild) 590 { 591 if (newChild == null) 592 throw new IllegalArgumentException(); 593 594 int idx = children.indexOf(refChild); 595 if (idx == -1) 596 children.add(newChild); 597 else 598 children.add(idx, newChild); 599 ((IIOMetadataNode)newChild).parent = this; 600 601 return newChild; 602 } 603 604 public boolean isDefaultNamespace(String namespaceURI) 605 { 606 return true; 607 } 608 609 public boolean isEqualNode(Node arg) 610 { 611 return true; 612 } 613 614 public boolean isSameNode(Node other) 615 { 616 return this == other; 617 } 618 619 /* (non-Javadoc) 620 * @see org.w3c.dom.Node#isSupported(java.lang.String, java.lang.String) 621 */ 622 public boolean isSupported(String feature, String version) 623 { 624 // No DOM features are supported 625 return false; 626 } 627 628 public String lookupNamespaceURI(String prefix) 629 { 630 return null; 631 } 632 633 public String lookupPrefix(String namespaceURI) 634 { 635 return null; 636 } 637 638 /* (non-Javadoc) 639 * @see org.w3c.dom.Node#normalize() 640 */ 641 public void normalize() 642 { 643 // No text nodes so no action 644 } 645 646 /* (non-Javadoc) 647 * @see org.w3c.dom.Node#removeChild(org.w3c.dom.Node) 648 */ 649 public Node removeChild(Node oldChild) 650 { 651 if (oldChild == null) 652 throw new IllegalArgumentException(); 653 children.remove(oldChild); 654 ((IIOMetadataNode)oldChild).parent = null; 655 656 return oldChild; 657 } 658 659 /* (non-Javadoc) 660 * @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node) 661 */ 662 public Node replaceChild(Node newChild, Node oldChild) 663 { 664 if (newChild == null) 665 throw new IllegalArgumentException(); 666 children.set(children.indexOf(oldChild), newChild); 667 ((IIOMetadataNode)oldChild).parent = null; 668 return oldChild; 669 } 670 671 public void setIdAttribute(String name, boolean isId) 672 throws DOMException 673 { 674 } 675 676 public void setIdAttributeNode(Attr idAttr, boolean isId) 677 throws DOMException 678 { 679 } 680 681 public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) 682 throws DOMException 683 { 684 } 685 686 /* (non-Javadoc) 687 * @see org.w3c.dom.Node#setNodeValue(java.lang.String) 688 */ 689 public void setNodeValue(String nodeValue) throws DOMException 690 { 691 } 692 693 /* (non-Javadoc) 694 * @see org.w3c.dom.Node#setPrefix(java.lang.String) 695 */ 696 public void setPrefix(String prefix) 697 { 698 } 699 700 public void setTextContent(String textContent) 701 throws DOMException 702 { 703 } 704 705 public Object setUserData(String key, Object data, UserDataHandler handler) 706 { 707 return null; 708 } 709 }