blob: 3e94dbc8459ccacba5bfea266d5ecd751a41783c [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.imageio.metadata;
27
28import java.util.ArrayList;
29import java.util.Iterator;
30import java.util.List;
31
32import org.w3c.dom.Attr;
33import org.w3c.dom.Document;
34import org.w3c.dom.Element;
35import org.w3c.dom.DOMException;
36import org.w3c.dom.NamedNodeMap;
37import org.w3c.dom.Node;
38import org.w3c.dom.NodeList;
39import org.w3c.dom.TypeInfo;
40import org.w3c.dom.UserDataHandler;
41
42
43class IIODOMException extends DOMException {
44
45 public IIODOMException(short code, String message) {
46 super(code, message);
47 }
48}
49
50class IIONamedNodeMap implements NamedNodeMap {
51
52 List nodes;
53
54 public IIONamedNodeMap(List nodes) {
55 this.nodes = nodes;
56 }
57
58 public int getLength() {
59 return nodes.size();
60 }
61
62 public Node getNamedItem(String name) {
63 Iterator iter = nodes.iterator();
64 while (iter.hasNext()) {
65 Node node = (Node)iter.next();
66 if (name.equals(node.getNodeName())) {
67 return node;
68 }
69 }
70
71 return null;
72 }
73
74 public Node item(int index) {
75 Node node = (Node)nodes.get(index);
76 return node;
77 }
78
79 public Node removeNamedItem(java.lang.String name) {
80 throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
81 "This NamedNodeMap is read-only!");
82 }
83
84 public Node setNamedItem(Node arg) {
85 throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
86 "This NamedNodeMap is read-only!");
87 }
88
89 /**
90 * Equivalent to <code>getNamedItem(localName)</code>.
91 */
92 public Node getNamedItemNS(String namespaceURI, String localName) {
93 return getNamedItem(localName);
94 }
95
96 /**
97 * Equivalent to <code>setNamedItem(arg)</code>.
98 */
99 public Node setNamedItemNS(Node arg) {
100 return setNamedItem(arg);
101 }
102
103 /**
104 * Equivalent to <code>removeNamedItem(localName)</code>.
105 */
106 public Node removeNamedItemNS(String namespaceURI, String localName) {
107 return removeNamedItem(localName);
108 }
109}
110
111class IIONodeList implements NodeList {
112
113 List nodes;
114
115 public IIONodeList(List nodes) {
116 this.nodes = nodes;
117 }
118
119 public int getLength() {
120 return nodes.size();
121 }
122
123 public Node item(int index) {
124 if (index < 0 || index > nodes.size()) {
125 return null;
126 }
127 return (Node)nodes.get(index);
128 }
129}
130
131class IIOAttr extends IIOMetadataNode implements Attr {
132
133 Element owner;
134 String name;
135 String value;
136
137 public IIOAttr(Element owner, String name, String value) {
138 this.owner = owner;
139 this.name = name;
140 this.value = value;
141 }
142
143 public String getName() {
144 return name;
145 }
146
147 public String getNodeName() {
148 return name;
149 }
150
151 public short getNodeType() {
152 return ATTRIBUTE_NODE;
153 }
154
155 public boolean getSpecified() {
156 return true;
157 }
158
159 public String getValue() {
160 return value;
161 }
162
163 public String getNodeValue() {
164 return value;
165 }
166
167 public void setValue(String value) {
168 this.value = value;
169 }
170
171 public void setNodeValue(String value) {
172 this.value = value;
173 }
174
175 public Element getOwnerElement() {
176 return owner;
177 }
178
179 public void setOwnerElement(Element owner) {
180 this.owner = owner;
181 }
182
183 /** This method is new in the DOM L3 for Attr interface.
184 * Could throw DOMException here, but its probably OK
185 * to always return false. One reason for this, is we have no good
186 * way to document this exception, since this class, IIOAttr,
187 * is not a public class. The rest of the methods that throw
188 * DOMException are publically documented as such on IIOMetadataNode.
189 * @return false
190 */
191 public boolean isId() {
192 return false;
193 }
194
195
196}
197
198/**
199 * A class representing a node in a meta-data tree, which implements
200 * the <a
201 * href="../../../../api/org/w3c/dom/Element.html">
202 * <code>org.w3c.dom.Element</code></a> interface and additionally allows
203 * for the storage of non-textual objects via the
204 * <code>getUserObject</code> and <code>setUserObject</code> methods.
205 *
206 * <p> This class is not intended to be used for general XML
207 * processing. In particular, <code>Element</code> nodes created
208 * within the Image I/O API are not compatible with those created by
209 * Sun's standard implementation of the <code>org.w3.dom</code> API.
210 * In particular, the implementation is tuned for simple uses and may
211 * not perform well for intensive processing.
212 *
213 * <p> Namespaces are ignored in this implementation. The terms "tag
214 * name" and "node name" are always considered to be synonymous.
215 *
216 * <em>Note:</em>
217 * The DOM Level 3 specification added a number of new methods to the
218 * {@code Node}, {@code Element} and {@code Attr} interfaces that are not
219 * of value to the {@code IIOMetadataNode} implementation or specification.
220 *
221 * Calling such methods on an {@code IIOMetadataNode}, or an {@code Attr}
222 * instance returned from an {@code IIOMetadataNode} will result in a
223 * {@code DOMException} being thrown.
224 *
225 * @see IIOMetadata#getAsTree
226 * @see IIOMetadata#setFromTree
227 * @see IIOMetadata#mergeTree
228 *
229 */
230public class IIOMetadataNode implements Element, NodeList {
231
232 /**
233 * The name of the node as a <code>String</code>.
234 */
235 private String nodeName = null;
236
237 /**
238 * The value of the node as a <code>String</code>. The Image I/O
239 * API typically does not make use of the node value.
240 */
241 private String nodeValue = null;
242
243 /**
244 * The <code>Object</code> value associated with this node.
245 */
246 private Object userObject = null;
247
248 /**
249 * The parent node of this node, or <code>null</code> if this node
250 * forms the root of its own tree.
251 */
252 private IIOMetadataNode parent = null;
253
254 /**
255 * The number of child nodes.
256 */
257 private int numChildren = 0;
258
259 /**
260 * The first (leftmost) child node of this node, or
261 * <code>null</code> if this node is a leaf node.
262 */
263 private IIOMetadataNode firstChild = null;
264
265 /**
266 * The last (rightmost) child node of this node, or
267 * <code>null</code> if this node is a leaf node.
268 */
269 private IIOMetadataNode lastChild = null;
270
271 /**
272 * The next (right) sibling node of this node, or
273 * <code>null</code> if this node is its parent's last child node.
274 */
275 private IIOMetadataNode nextSibling = null;
276
277 /**
278 * The previous (left) sibling node of this node, or
279 * <code>null</code> if this node is its parent's first child node.
280 */
281 private IIOMetadataNode previousSibling = null;
282
283 /**
284 * A <code>List</code> of <code>IIOAttr</code> nodes representing
285 * attributes.
286 */
287 private List attributes = new ArrayList();
288
289 /**
290 * Constructs an empty <code>IIOMetadataNode</code>.
291 */
292 public IIOMetadataNode() {}
293
294 /**
295 * Constructs an <code>IIOMetadataNode</code> with a given node
296 * name.
297 *
298 * @param nodeName the name of the node, as a <code>String</code>.
299 */
300 public IIOMetadataNode(String nodeName) {
301 this.nodeName = nodeName;
302 }
303
304 /**
305 * Check that the node is either <code>null</code> or an
306 * <code>IIOMetadataNode</code>.
307 */
308 private void checkNode(Node node) throws DOMException {
309 if (node == null) {
310 return;
311 }
312 if (!(node instanceof IIOMetadataNode)) {
313 throw new IIODOMException(DOMException.WRONG_DOCUMENT_ERR,
314 "Node not an IIOMetadataNode!");
315 }
316 }
317
318 // Methods from Node
319
320 /**
321 * Returns the node name associated with this node.
322 *
323 * @return the node name, as a <code>String</code>.
324 */
325 public String getNodeName() {
326 return nodeName;
327 }
328
329 /**
330 * Returns the value associated with this node.
331 *
332 * @return the node value, as a <code>String</code>.
333 */
334 public String getNodeValue(){
335 return nodeValue;
336 }
337
338 /**
339 * Sets the <code>String</code> value associated with this node.
340 */
341 public void setNodeValue(String nodeValue) {
342 this.nodeValue = nodeValue;
343 }
344
345 /**
346 * Returns the node type, which is always
347 * <code>ELEMENT_NODE</code>.
348 *
349 * @return the <code>short</code> value <code>ELEMENT_NODE</code>.
350 */
351 public short getNodeType() {
352 return ELEMENT_NODE;
353 }
354
355 /**
356 * Returns the parent of this node. A <code>null</code> value
357 * indicates that the node is the root of its own tree. To add a
358 * node to an existing tree, use one of the
359 * <code>insertBefore</code>, <code>replaceChild</code>, or
360 * <code>appendChild</code> methods.
361 *
362 * @return the parent, as a <code>Node</code>.
363 *
364 * @see #insertBefore
365 * @see #replaceChild
366 * @see #appendChild
367 */
368 public Node getParentNode() {
369 return parent;
370 }
371
372 /**
373 * Returns a <code>NodeList</code> that contains all children of this node.
374 * If there are no children, this is a <code>NodeList</code> containing
375 * no nodes.
376 *
377 * @return the children as a <code>NodeList</code>
378 */
379 public NodeList getChildNodes() {
380 return this;
381 }
382
383 /**
384 * Returns the first child of this node, or <code>null</code> if
385 * the node has no children.
386 *
387 * @return the first child, as a <code>Node</code>, or
388 * <code>null</code>
389 */
390 public Node getFirstChild() {
391 return firstChild;
392 }
393
394 /**
395 * Returns the last child of this node, or <code>null</code> if
396 * the node has no children.
397 *
398 * @return the last child, as a <code>Node</code>, or
399 * <code>null</code>.
400 */
401 public Node getLastChild() {
402 return lastChild;
403 }
404
405 /**
406 * Returns the previous sibling of this node, or <code>null</code>
407 * if this node has no previous sibling.
408 *
409 * @return the previous sibling, as a <code>Node</code>, or
410 * <code>null</code>.
411 */
412 public Node getPreviousSibling() {
413 return previousSibling;
414 }
415
416 /**
417 * Returns the next sibling of this node, or <code>null</code> if
418 * the node has no next sibling.
419 *
420 * @return the next sibling, as a <code>Node</code>, or
421 * <code>null</code>.
422 */
423 public Node getNextSibling() {
424 return nextSibling;
425 }
426
427 /**
428 * Returns a <code>NamedNodeMap</code> containing the attributes of
429 * this node.
430 *
431 * @return a <code>NamedNodeMap</code> containing the attributes of
432 * this node.
433 */
434 public NamedNodeMap getAttributes() {
435 return new IIONamedNodeMap(attributes);
436 }
437
438 /**
439 * Returns <code>null</code>, since <code>IIOMetadataNode</code>s
440 * do not belong to any <code>Document</code>.
441 *
442 * @return <code>null</code>.
443 */
444 public Document getOwnerDocument() {
445 return null;
446 }
447
448 /**
449 * Inserts the node <code>newChild</code> before the existing
450 * child node <code>refChild</code>. If <code>refChild</code> is
451 * <code>null</code>, insert <code>newChild</code> at the end of
452 * the list of children.
453 *
454 * @param newChild the <code>Node</code> to insert.
455 * @param refChild the reference <code>Node</code>.
456 *
457 * @return the node being inserted.
458 *
459 * @exception IllegalArgumentException if <code>newChild</code> is
460 * <code>null</code>.
461 */
462 public Node insertBefore(Node newChild,
463 Node refChild) {
464 if (newChild == null) {
465 throw new IllegalArgumentException("newChild == null!");
466 }
467
468 checkNode(newChild);
469 checkNode(refChild);
470
471 IIOMetadataNode newChildNode = (IIOMetadataNode)newChild;
472 IIOMetadataNode refChildNode = (IIOMetadataNode)refChild;
473
474 // Siblings, can be null.
475 IIOMetadataNode previous = null;
476 IIOMetadataNode next = null;
477
478 if (refChild == null) {
479 previous = this.lastChild;
480 next = null;
481 this.lastChild = newChildNode;
482 } else {
483 previous = refChildNode.previousSibling;
484 next = refChildNode;
485 }
486
487 if (previous != null) {
488 previous.nextSibling = newChildNode;
489 }
490 if (next != null) {
491 next.previousSibling = newChildNode;
492 }
493
494 newChildNode.parent = this;
495 newChildNode.previousSibling = previous;
496 newChildNode.nextSibling = next;
497
498 // N.B.: O.K. if refChild == null
499 if (this.firstChild == refChildNode) {
500 this.firstChild = newChildNode;
501 }
502
503 ++numChildren;
504 return newChildNode;
505 }
506
507 /**
508 * Replaces the child node <code>oldChild</code> with
509 * <code>newChild</code> in the list of children, and returns the
510 * <code>oldChild</code> node.
511 *
512 * @param newChild the <code>Node</code> to insert.
513 * @param oldChild the <code>Node</code> to be replaced.
514 *
515 * @return the node replaced.
516 *
517 * @exception IllegalArgumentException if <code>newChild</code> is
518 * <code>null</code>.
519 */
520 public Node replaceChild(Node newChild,
521 Node oldChild) {
522 if (newChild == null) {
523 throw new IllegalArgumentException("newChild == null!");
524 }
525
526 checkNode(newChild);
527 checkNode(oldChild);
528
529 IIOMetadataNode newChildNode = (IIOMetadataNode)newChild;
530 IIOMetadataNode oldChildNode = (IIOMetadataNode)oldChild;
531
532 IIOMetadataNode previous = oldChildNode.previousSibling;
533 IIOMetadataNode next = oldChildNode.nextSibling;
534
535 if (previous != null) {
536 previous.nextSibling = newChildNode;
537 }
538 if (next != null) {
539 next.previousSibling = newChildNode;
540 }
541
542 newChildNode.parent = this;
543 newChildNode.previousSibling = previous;
544 newChildNode.nextSibling = next;
545
546 if (firstChild == oldChildNode) {
547 firstChild = newChildNode;
548 }
549 if (lastChild == oldChildNode) {
550 lastChild = newChildNode;
551 }
552
553 oldChildNode.parent = null;
554 oldChildNode.previousSibling = null;
555 oldChildNode.nextSibling = null;
556
557 return oldChildNode;
558 }
559
560 /**
561 * Removes the child node indicated by <code>oldChild</code> from
562 * the list of children, and returns it.
563 *
564 * @param oldChild the <code>Node</code> to be removed.
565 *
566 * @return the node removed.
567 *
568 * @exception IllegalArgumentException if <code>oldChild</code> is
569 * <code>null</code>.
570 */
571 public Node removeChild(Node oldChild) {
572 if (oldChild == null) {
573 throw new IllegalArgumentException("oldChild == null!");
574 }
575 checkNode(oldChild);
576
577 IIOMetadataNode oldChildNode = (IIOMetadataNode)oldChild;
578
579 IIOMetadataNode previous = oldChildNode.previousSibling;
580 IIOMetadataNode next = oldChildNode.nextSibling;
581
582 if (previous != null) {
583 previous.nextSibling = next;
584 }
585 if (next != null) {
586 next.previousSibling = previous;
587 }
588
589 if (this.firstChild == oldChildNode) {
590 this.firstChild = next;
591 }
592 if (this.lastChild == oldChildNode) {
593 this.lastChild = previous;
594 }
595
596 oldChildNode.parent = null;
597 oldChildNode.previousSibling = null;
598 oldChildNode.nextSibling = null;
599
600 --numChildren;
601 return oldChildNode;
602 }
603
604 /**
605 * Adds the node <code>newChild</code> to the end of the list of
606 * children of this node.
607 *
608 * @param newChild the <code>Node</code> to insert.
609 *
610 * @return the node added.
611 *
612 * @exception IllegalArgumentException if <code>newChild</code> is
613 * <code>null</code>.
614 */
615 public Node appendChild(Node newChild) {
616 if (newChild == null) {
617 throw new IllegalArgumentException("newChild == null!");
618 }
619 checkNode(newChild);
620
621 // insertBefore will increment numChildren
622 return insertBefore(newChild, null);
623 }
624
625 /**
626 * Returns <code>true</code> if this node has child nodes.
627 *
628 * @return <code>true</code> if this node has children.
629 */
630 public boolean hasChildNodes() {
631 return numChildren > 0;
632 }
633
634 /**
635 * Returns a duplicate of this node. The duplicate node has no
636 * parent (<code>getParentNode</code> returns <code>null</code>).
637 * If a shallow clone is being performed (<code>deep</code> is
638 * <code>false</code>), the new node will not have any children or
639 * siblings. If a deep clone is being performed, the new node
640 * will form the root of a complete cloned subtree.
641 *
642 * @param deep if <code>true</code>, recursively clone the subtree
643 * under the specified node; if <code>false</code>, clone only the
644 * node itself.
645 *
646 * @return the duplicate node.
647 */
648 public Node cloneNode(boolean deep) {
649 IIOMetadataNode newNode = new IIOMetadataNode(this.nodeName);
650 newNode.setUserObject(getUserObject());
651 // Attributes
652
653 if (deep) {
654 for (IIOMetadataNode child = firstChild;
655 child != null;
656 child = child.nextSibling) {
657 newNode.appendChild(child.cloneNode(true));
658 }
659 }
660
661 return newNode;
662 }
663
664 /**
665 * Does nothing, since <code>IIOMetadataNode</code>s do not
666 * contain <code>Text</code> children.
667 */
668 public void normalize() {
669 }
670
671 /**
672 * Returns <code>false</code> since DOM features are not
673 * supported.
674 *
675 * @return <code>false</code>.
676 *
677 * @param feature a <code>String</code>, which is ignored.
678 * @param version a <code>String</code>, which is ignored.
679 */
680 public boolean isSupported(String feature, String version) {
681 return false;
682 }
683
684 /**
685 * Returns <code>null</code>, since namespaces are not supported.
686 */
687 public String getNamespaceURI() throws DOMException {
688 return null;
689 }
690
691 /**
692 * Returns <code>null</code>, since namespaces are not supported.
693 *
694 * @return <code>null</code>.
695 *
696 * @see #setPrefix
697 */
698 public String getPrefix() {
699 return null;
700 }
701
702 /**
703 * Does nothing, since namespaces are not supported.
704 *
705 * @param prefix a <code>String</code>, which is ignored.
706 *
707 * @see #getPrefix
708 */
709 public void setPrefix(String prefix) {
710 }
711
712 /**
713 * Equivalent to <code>getNodeName</code>.
714 *
715 * @return the node name, as a <code>String</code>.
716 */
717 public String getLocalName() {
718 return nodeName;
719 }
720
721 // Methods from Element
722
723
724 /**
725 * Equivalent to <code>getNodeName</code>.
726 *
727 * @return the node name, as a <code>String</code
728 */
729 public String getTagName() {
730 return nodeName;
731 }
732
733 /**
734 * Retrieves an attribute value by name.
735 * @param name The name of the attribute to retrieve.
736 * @return The <code>Attr</code> value as a string, or the empty string
737 * if that attribute does not have a specified or default value.
738 */
739 public String getAttribute(String name) {
740 Attr attr = getAttributeNode(name);
741 if (attr == null) {
742 return "";
743 }
744 return attr.getValue();
745 }
746
747 /**
748 * Equivalent to <code>getAttribute(localName)</code>.
749 *
750 * @see #setAttributeNS
751 */
752 public String getAttributeNS(String namespaceURI, String localName) {
753 return getAttribute(localName);
754 }
755
756 public void setAttribute(String name, String value) {
757 // Name must be valid unicode chars
758 boolean valid = true;
759 char[] chs = name.toCharArray();
760 for (int i=0;i<chs.length;i++) {
761 if (chs[i] >= 0xfffe) {
762 valid = false;
763 break;
764 }
765 }
766 if (!valid) {
767 throw new IIODOMException(DOMException.INVALID_CHARACTER_ERR,
768 "Attribute name is illegal!");
769 }
770 removeAttribute(name, false);
771 attributes.add(new IIOAttr(this, name, value));
772 }
773
774 /**
775 * Equivalent to <code>setAttribute(qualifiedName, value)</code>.
776 *
777 * @see #getAttributeNS
778 */
779 public void setAttributeNS(String namespaceURI,
780 String qualifiedName, String value) {
781 setAttribute(qualifiedName, value);
782 }
783
784 public void removeAttribute(String name) {
785 removeAttribute(name, true);
786 }
787
788 private void removeAttribute(String name, boolean checkPresent) {
789 int numAttributes = attributes.size();
790 for (int i = 0; i < numAttributes; i++) {
791 IIOAttr attr = (IIOAttr)attributes.get(i);
792 if (name.equals(attr.getName())) {
793 attr.setOwnerElement(null);
794 attributes.remove(i);
795 return;
796 }
797 }
798
799 // If we get here, the attribute doesn't exist
800 if (checkPresent) {
801 throw new IIODOMException(DOMException.NOT_FOUND_ERR,
802 "No such attribute!");
803 }
804 }
805
806 /**
807 * Equivalent to <code>removeAttribute(localName)</code>.
808 */
809 public void removeAttributeNS(String namespaceURI,
810 String localName) {
811 removeAttribute(localName);
812 }
813
814 public Attr getAttributeNode(String name) {
815 Node node = getAttributes().getNamedItem(name);
816 return (Attr)node;
817 }
818
819 /**
820 * Equivalent to <code>getAttributeNode(localName)</code>.
821 *
822 * @see #setAttributeNodeNS
823 */
824 public Attr getAttributeNodeNS(String namespaceURI,
825 String localName) {
826 return getAttributeNode(localName);
827 }
828
829 public Attr setAttributeNode(Attr newAttr) throws DOMException {
830 Element owner = newAttr.getOwnerElement();
831 if (owner != null) {
832 if (owner == this) {
833 return null;
834 } else {
835 throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR,
836 "Attribute is already in use");
837 }
838 }
839
840 IIOAttr attr;
841 if (newAttr instanceof IIOAttr) {
842 attr = (IIOAttr)newAttr;
843 attr.setOwnerElement(this);
844 } else {
845 attr = new IIOAttr(this,
846 newAttr.getName(),
847 newAttr.getValue());
848 }
849
850 Attr oldAttr = getAttributeNode(attr.getName());
851 if (oldAttr != null) {
852 removeAttributeNode(oldAttr);
853 }
854
855 attributes.add(attr);
856
857 return oldAttr;
858 }
859
860 /**
861 * Equivalent to <code>setAttributeNode(newAttr)</code>.
862 *
863 * @see #getAttributeNodeNS
864 */
865 public Attr setAttributeNodeNS(Attr newAttr) {
866 return setAttributeNode(newAttr);
867 }
868
869 public Attr removeAttributeNode(Attr oldAttr) {
870 removeAttribute(oldAttr.getName());
871 return oldAttr;
872 }
873
874 public NodeList getElementsByTagName(String name) {
875 List l = new ArrayList();
876 getElementsByTagName(name, l);
877 return new IIONodeList(l);
878 }
879
880 private void getElementsByTagName(String name, List l) {
881 if (nodeName.equals(name)) {
882 l.add(this);
883 }
884
885 Node child = getFirstChild();
886 while (child != null) {
887 ((IIOMetadataNode)child).getElementsByTagName(name, l);
888 child = child.getNextSibling();
889 }
890 }
891
892 /**
893 * Equivalent to <code>getElementsByTagName(localName)</code>.
894 */
895 public NodeList getElementsByTagNameNS(String namespaceURI,
896 String localName) {
897 return getElementsByTagName(localName);
898 }
899
900 public boolean hasAttributes() {
901 return attributes.size() > 0;
902 }
903
904 public boolean hasAttribute(String name) {
905 return getAttributeNode(name) != null;
906 }
907
908 /**
909 * Equivalent to <code>hasAttribute(localName)</code>.
910 */
911 public boolean hasAttributeNS(String namespaceURI,
912 String localName) {
913 return hasAttribute(localName);
914 }
915
916 // Methods from NodeList
917
918 public int getLength() {
919 return numChildren;
920 }
921
922 public Node item(int index) {
923 if (index < 0) {
924 return null;
925 }
926
927 Node child = getFirstChild();
928 while (child != null && index-- > 0) {
929 child = child.getNextSibling();
930 }
931 return child;
932 }
933
934 /**
935 * Returns the <code>Object</code> value associated with this node.
936 *
937 * @return the user <code>Object</code>.
938 *
939 * @see #setUserObject
940 */
941 public Object getUserObject() {
942 return userObject;
943 }
944
945 /**
946 * Sets the value associated with this node.
947 *
948 * @param userObject the user <code>Object</code>.
949 *
950 * @see #getUserObject
951 */
952 public void setUserObject(Object userObject) {
953 this.userObject = userObject;
954 }
955
956 // Start of dummy methods for DOM L3.
957
958 /**
959 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
960 * and will throw a {@code DOMException}.
961 * @throws DOMException - always.
962 */
963 public void setIdAttribute(String name,
964 boolean isId)
965 throws DOMException {
966 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
967 "Method not supported");
968 }
969
970 /**
971 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
972 * and will throw a {@code DOMException}.
973 * @throws DOMException - always.
974 */
975 public void setIdAttributeNS(String namespaceURI,
976 String localName,
977 boolean isId)
978 throws DOMException {
979 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
980 "Method not supported");
981 }
982
983 /**
984 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
985 * and will throw a {@code DOMException}.
986 * @throws DOMException - always.
987 */
988 public void setIdAttributeNode(Attr idAttr,
989 boolean isId)
990 throws DOMException {
991 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
992 "Method not supported");
993 }
994
995 /**
996 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
997 * and will throw a {@code DOMException}.
998 * @throws DOMException - always.
999 */
1000 public TypeInfo getSchemaTypeInfo() throws DOMException {
1001 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1002 "Method not supported");
1003 }
1004
1005 /**
1006 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1007 * and will throw a {@code DOMException}.
1008 * @throws DOMException - always.
1009 */
1010 public Object setUserData(String key,
1011 Object data,
1012 UserDataHandler handler) throws DOMException {
1013 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1014 "Method not supported");
1015 }
1016
1017 /**
1018 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1019 * and will throw a {@code DOMException}.
1020 * @throws DOMException - always.
1021 */
1022 public Object getUserData(String key) throws DOMException {
1023 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1024 "Method not supported");
1025 }
1026
1027 /**
1028 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1029 * and will throw a {@code DOMException}.
1030 * @throws DOMException - always.
1031 */
1032 public Object getFeature(String feature, String version)
1033 throws DOMException {
1034 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1035 "Method not supported");
1036 }
1037
1038 /**
1039 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1040 * and will throw a {@code DOMException}.
1041 * @throws DOMException - always.
1042 */
1043 public boolean isSameNode(Node node) throws DOMException {
1044 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1045 "Method not supported");
1046 }
1047
1048 /**
1049 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1050 * and will throw a {@code DOMException}.
1051 * @throws DOMException - always.
1052 */
1053 public boolean isEqualNode(Node node) throws DOMException {
1054 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1055 "Method not supported");
1056 }
1057
1058 /**
1059 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1060 * and will throw a {@code DOMException}.
1061 * @throws DOMException - always.
1062 */
1063 public String lookupNamespaceURI(String prefix) throws DOMException {
1064 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1065 "Method not supported");
1066 }
1067
1068 /**
1069 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1070 * and will throw a {@code DOMException}.
1071 * @throws DOMException - always.
1072 */
1073 public boolean isDefaultNamespace(String namespaceURI)
1074 throws DOMException {
1075 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1076 "Method not supported");
1077 }
1078
1079 /**
1080 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1081 * and will throw a {@code DOMException}.
1082 * @throws DOMException - always.
1083 */
1084 public String lookupPrefix(String namespaceURI) throws DOMException {
1085 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1086 "Method not supported");
1087 }
1088
1089 /**
1090 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1091 * and will throw a {@code DOMException}.
1092 * @throws DOMException - always.
1093 */
1094 public String getTextContent() throws DOMException {
1095 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1096 "Method not supported");
1097 }
1098
1099 /**
1100 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1101 * and will throw a {@code DOMException}.
1102 * @throws DOMException - always.
1103 */
1104 public void setTextContent(String textContent) throws DOMException {
1105 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1106 "Method not supported");
1107 }
1108
1109 /**
1110 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1111 * and will throw a {@code DOMException}.
1112 * @throws DOMException - always.
1113 */
1114 public short compareDocumentPosition(Node other)
1115 throws DOMException {
1116 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1117 "Method not supported");
1118 }
1119
1120 /**
1121 * This DOM Level 3 method is not supported for {@code IIOMetadataNode}
1122 * and will throw a {@code DOMException}.
1123 * @throws DOMException - always.
1124 */
1125 public String getBaseURI() throws DOMException {
1126 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1127 "Method not supported");
1128 }
1129 //End of dummy methods for DOM L3.
1130
1131
1132}