0001 /*
0002 * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package javax.imageio.metadata;
0027
0028 import java.util.ArrayList;
0029 import java.util.Iterator;
0030 import java.util.List;
0031
0032 import org.w3c.dom.Attr;
0033 import org.w3c.dom.Document;
0034 import org.w3c.dom.Element;
0035 import org.w3c.dom.DOMException;
0036 import org.w3c.dom.NamedNodeMap;
0037 import org.w3c.dom.Node;
0038 import org.w3c.dom.NodeList;
0039 import org.w3c.dom.TypeInfo;
0040 import org.w3c.dom.UserDataHandler;
0041
0042 class IIODOMException extends DOMException {
0043
0044 public IIODOMException(short code, String message) {
0045 super (code, message);
0046 }
0047 }
0048
0049 class IIONamedNodeMap implements NamedNodeMap {
0050
0051 List nodes;
0052
0053 public IIONamedNodeMap(List nodes) {
0054 this .nodes = nodes;
0055 }
0056
0057 public int getLength() {
0058 return nodes.size();
0059 }
0060
0061 public Node getNamedItem(String name) {
0062 Iterator iter = nodes.iterator();
0063 while (iter.hasNext()) {
0064 Node node = (Node) iter.next();
0065 if (name.equals(node.getNodeName())) {
0066 return node;
0067 }
0068 }
0069
0070 return null;
0071 }
0072
0073 public Node item(int index) {
0074 Node node = (Node) nodes.get(index);
0075 return node;
0076 }
0077
0078 public Node removeNamedItem(java.lang.String name) {
0079 throw new DOMException(
0080 DOMException.NO_MODIFICATION_ALLOWED_ERR,
0081 "This NamedNodeMap is read-only!");
0082 }
0083
0084 public Node setNamedItem(Node arg) {
0085 throw new DOMException(
0086 DOMException.NO_MODIFICATION_ALLOWED_ERR,
0087 "This NamedNodeMap is read-only!");
0088 }
0089
0090 /**
0091 * Equivalent to <code>getNamedItem(localName)</code>.
0092 */
0093 public Node getNamedItemNS(String namespaceURI, String localName) {
0094 return getNamedItem(localName);
0095 }
0096
0097 /**
0098 * Equivalent to <code>setNamedItem(arg)</code>.
0099 */
0100 public Node setNamedItemNS(Node arg) {
0101 return setNamedItem(arg);
0102 }
0103
0104 /**
0105 * Equivalent to <code>removeNamedItem(localName)</code>.
0106 */
0107 public Node removeNamedItemNS(String namespaceURI, String localName) {
0108 return removeNamedItem(localName);
0109 }
0110 }
0111
0112 class IIONodeList implements NodeList {
0113
0114 List nodes;
0115
0116 public IIONodeList(List nodes) {
0117 this .nodes = nodes;
0118 }
0119
0120 public int getLength() {
0121 return nodes.size();
0122 }
0123
0124 public Node item(int index) {
0125 if (index < 0 || index > nodes.size()) {
0126 return null;
0127 }
0128 return (Node) nodes.get(index);
0129 }
0130 }
0131
0132 class IIOAttr extends IIOMetadataNode implements Attr {
0133
0134 boolean specified = true;
0135
0136 Element owner;
0137 String name;
0138 String value;
0139
0140 public IIOAttr(Element owner, String name, String value) {
0141 this .owner = owner;
0142 this .name = name;
0143 this .value = value;
0144 }
0145
0146 public String getName() {
0147 return name;
0148 }
0149
0150 public String getNodeName() {
0151 return name;
0152 }
0153
0154 public short getNodeType() {
0155 return ATTRIBUTE_NODE;
0156 }
0157
0158 public boolean getSpecified() {
0159 return specified;
0160 }
0161
0162 public String getValue() {
0163 return value;
0164 }
0165
0166 public String getNodeValue() {
0167 return value;
0168 }
0169
0170 public void setValue(String value) {
0171 this .value = value;
0172 }
0173
0174 public void setNodeValue(String value) {
0175 this .value = value;
0176 }
0177
0178 public Element getOwnerElement() {
0179 return owner;
0180 }
0181
0182 public void setOwnerElement(Element owner) {
0183 this .owner = owner;
0184 }
0185
0186 // Start of dummy methods for DOM L3. PENDING: Please revisit
0187 public boolean isId() {
0188 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0189 "Method not supported");
0190 }
0191
0192 public TypeInfo getSchemaTypeInfo() {
0193 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0194 "Method not supported");
0195 }
0196
0197 public Object setUserData(String key, Object data,
0198 UserDataHandler handler) {
0199 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0200 "Method not supported");
0201 }
0202
0203 public Object getUserData(String key) {
0204 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0205 "Method not supported");
0206 }
0207
0208 public Object getFeature(String feature, String version) {
0209 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0210 "Method not supported");
0211 }
0212
0213 public boolean isEqualNode(Node node) {
0214 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0215 "Method not supported");
0216 }
0217
0218 public boolean isSameNode(Node node) {
0219 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0220 "Method not supported");
0221 }
0222
0223 public String lookupNamespaceURI(String prefix) {
0224 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0225 "Method not supported");
0226 }
0227
0228 public boolean isDefaultNamespace(String namespaceURI) {
0229 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0230 "Method not supported");
0231 }
0232
0233 public String lookupPrefix(String namespaceURI) {
0234 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0235 "Method not supported");
0236 }
0237
0238 String textContent;
0239
0240 public String getTextContent() throws DOMException {
0241 return textContent;
0242 }
0243
0244 public void setTextContent(String textContent) throws DOMException {
0245 this .textContent = textContent; //PENDING
0246 }
0247
0248 public short compareDocumentPosition(Node other)
0249 throws DOMException {
0250 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0251 "Method not supported");
0252 }
0253
0254 public String getBaseURI() {
0255 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0256 "Method not supported");
0257 }
0258 // End of dummy methods for DOM L3. PENDING: Please revisit
0259
0260 }
0261
0262 /**
0263 * A class representing a node in a meta-data tree, which implements
0264 * the <a
0265 * href="../../../../api/org/w3c/dom/Element.html">
0266 * <code>org.w3c.dom.Element</code></a> interface and additionally allows
0267 * for the storage of non-textual objects via the
0268 * <code>getUserObject</code> and <code>setUserObject</code> methods.
0269 *
0270 * <p> This class is not intended to be used for general XML
0271 * processing. In particular, <code>Element</code> nodes created
0272 * within the Image I/O API are not compatible with those created by
0273 * Sun's standard implementation of the <code>org.w3.dom</code> API.
0274 * In particular, the implementation is tuned for simple uses and may
0275 * not perform well for intensive processing.
0276 *
0277 * <p> Namespaces are ignored in this implementation. The terms "tag
0278 * name" and "node name" are always considered to be synonymous.
0279 *
0280 * @see IIOMetadata#getAsTree
0281 * @see IIOMetadata#setFromTree
0282 * @see IIOMetadata#mergeTree
0283 *
0284 * @version 0.5
0285 */
0286 public class IIOMetadataNode implements Element, NodeList {
0287
0288 /**
0289 * The name of the node as a <code>String</code>.
0290 */
0291 private String nodeName = null;
0292
0293 /**
0294 * The value of the node as a <code>String</code>. The Image I/O
0295 * API typically does not make use of the node value.
0296 */
0297 private String nodeValue = null;
0298
0299 /**
0300 * The <code>Object</code> value associated with this node.
0301 */
0302 private Object userObject = null;
0303
0304 /**
0305 * The parent node of this node, or <code>null</code> if this node
0306 * forms the root of its own tree.
0307 */
0308 private IIOMetadataNode parent = null;
0309
0310 /**
0311 * The number of child nodes.
0312 */
0313 private int numChildren = 0;
0314
0315 /**
0316 * The first (leftmost) child node of this node, or
0317 * <code>null</code> if this node is a leaf node.
0318 */
0319 private IIOMetadataNode firstChild = null;
0320
0321 /**
0322 * The last (rightmost) child node of this node, or
0323 * <code>null</code> if this node is a leaf node.
0324 */
0325 private IIOMetadataNode lastChild = null;
0326
0327 /**
0328 * The next (right) sibling node of this node, or
0329 * <code>null</code> if this node is its parent's last child node.
0330 */
0331 private IIOMetadataNode nextSibling = null;
0332
0333 /**
0334 * The previous (left) sibling node of this node, or
0335 * <code>null</code> if this node is its parent's first child node.
0336 */
0337 private IIOMetadataNode previousSibling = null;
0338
0339 /**
0340 * A <code>List</code> of <code>IIOAttr</code> nodes representing
0341 * attributes.
0342 */
0343 private List attributes = new ArrayList();
0344
0345 /**
0346 * Constructs an empty <code>IIOMetadataNode</code>.
0347 */
0348 public IIOMetadataNode() {
0349 }
0350
0351 /**
0352 * Constructs an <code>IIOMetadataNode</code> with a given node
0353 * name.
0354 *
0355 * @param nodeName the name of the node, as a <code>String</code>.
0356 */
0357 public IIOMetadataNode(String nodeName) {
0358 this .nodeName = nodeName;
0359 }
0360
0361 /**
0362 * Check that the node is either <code>null</code> or an
0363 * <code>IIOMetadataNode</code>.
0364 */
0365 private void checkNode(Node node) throws DOMException {
0366 if (node == null) {
0367 return;
0368 }
0369 if (!(node instanceof IIOMetadataNode)) {
0370 throw new IIODOMException(DOMException.WRONG_DOCUMENT_ERR,
0371 "Node not an IIOMetadataNode!");
0372 }
0373 }
0374
0375 // Methods from Node
0376
0377 /**
0378 * Returns the node name associated with this node.
0379 *
0380 * @return the node name, as a <code>String</code>.
0381 */
0382 public String getNodeName() {
0383 return nodeName;
0384 }
0385
0386 public String getNodeValue() throws DOMException {
0387 return nodeValue;
0388 }
0389
0390 public void setNodeValue(String nodeValue) throws DOMException {
0391 this .nodeValue = nodeValue;
0392 }
0393
0394 /**
0395 * Returns the node type, which is always
0396 * <code>ELEMENT_NODE</code>.
0397 *
0398 * @return the <code>short</code> value <code>ELEMENT_NODE</code>.
0399 */
0400 public short getNodeType() {
0401 return ELEMENT_NODE;
0402 }
0403
0404 /**
0405 * Returns the parent of this node. A <code>null</code> value
0406 * indicates that the node is the root of its own tree. To add a
0407 * node to an existing tree, use one of the
0408 * <code>insertBefore</code>, <code>replaceChild</code>, or
0409 * <code>appendChild</code> methods.
0410 *
0411 * @return the parent, as a <code>Node</code>.
0412 *
0413 * @see #insertBefore
0414 * @see #replaceChild
0415 * @see #appendChild
0416 */
0417 public Node getParentNode() {
0418 return parent;
0419 }
0420
0421 public NodeList getChildNodes() {
0422 return this ;
0423 }
0424
0425 /**
0426 * Returns the first child of this node, or <code>null</code> if
0427 * the node has no children.
0428 *
0429 * @return the first child, as a <code>Node</code>, or
0430 * <code>null</code>
0431 */
0432 public Node getFirstChild() {
0433 return firstChild;
0434 }
0435
0436 /**
0437 * Returns the last child of this node, or <code>null</code> if
0438 * the node has no children.
0439 *
0440 * @return the last child, as a <code>Node</code>, or
0441 * <code>null</code>.
0442 */
0443 public Node getLastChild() {
0444 return lastChild;
0445 }
0446
0447 /**
0448 * Returns the previous sibling of this node, or <code>null</code>
0449 * if this node has no previous sibling.
0450 *
0451 * @return the previous sibling, as a <code>Node</code>, or
0452 * <code>null</code>.
0453 */
0454 public Node getPreviousSibling() {
0455 return previousSibling;
0456 }
0457
0458 /**
0459 * Returns the next sibling of this node, or <code>null</code> if
0460 * the node has no next sibling.
0461 *
0462 * @return the next sibling, as a <code>Node</code>, or
0463 * <code>null</code>.
0464 */
0465 public Node getNextSibling() {
0466 return nextSibling;
0467 }
0468
0469 public NamedNodeMap getAttributes() {
0470 return new IIONamedNodeMap(attributes);
0471 }
0472
0473 /**
0474 * Returns <code>null</code>, since <code>IIOMetadataNode</code>s
0475 * do not belong to any <code>Document</code>.
0476 *
0477 * @return <code>null</code>.
0478 */
0479 public Document getOwnerDocument() {
0480 return null;
0481 }
0482
0483 /**
0484 * Inserts the node <code>newChild</code> before the existing
0485 * child node <code>refChild</code>. If <code>refChild</code> is
0486 * <code>null</code>, insert <code>newChild</code> at the end of
0487 * the list of children.
0488 *
0489 * @param newChild the <code>Node</code> to insert.
0490 * @param refChild the reference <code>Node</code>.
0491 *
0492 * @return the node being inserted.
0493 *
0494 * @exception IllegalArgumentException if <code>newChild</code> is
0495 * <code>null</code>.
0496 */
0497 public Node insertBefore(Node newChild, Node refChild) {
0498 if (newChild == null) {
0499 throw new IllegalArgumentException("newChild == null!");
0500 }
0501
0502 checkNode(newChild);
0503 checkNode(refChild);
0504
0505 IIOMetadataNode newChildNode = (IIOMetadataNode) newChild;
0506 IIOMetadataNode refChildNode = (IIOMetadataNode) refChild;
0507
0508 // Siblings, can be null.
0509 IIOMetadataNode previous = null;
0510 IIOMetadataNode next = null;
0511
0512 if (refChild == null) {
0513 previous = this .lastChild;
0514 next = null;
0515 this .lastChild = newChildNode;
0516 } else {
0517 previous = refChildNode.previousSibling;
0518 next = refChildNode;
0519 }
0520
0521 if (previous != null) {
0522 previous.nextSibling = newChildNode;
0523 }
0524 if (next != null) {
0525 next.previousSibling = newChildNode;
0526 }
0527
0528 newChildNode.parent = this ;
0529 newChildNode.previousSibling = previous;
0530 newChildNode.nextSibling = next;
0531
0532 // N.B.: O.K. if refChild == null
0533 if (this .firstChild == refChildNode) {
0534 this .firstChild = newChildNode;
0535 }
0536
0537 ++numChildren;
0538 return newChildNode;
0539 }
0540
0541 /**
0542 * Replaces the child node <code>oldChild</code> with
0543 * <code>newChild</code> in the list of children, and returns the
0544 * <code>oldChild</code> node.
0545 *
0546 * @param newChild the <code>Node</code> to insert.
0547 * @param oldChild the <code>Node</code> to be replaced.
0548 *
0549 * @return the node replaced.
0550 *
0551 * @exception IllegalArgumentException if <code>newChild</code> is
0552 * <code>null</code>.
0553 */
0554 public Node replaceChild(Node newChild, Node oldChild) {
0555 if (newChild == null) {
0556 throw new IllegalArgumentException("newChild == null!");
0557 }
0558
0559 checkNode(newChild);
0560 checkNode(oldChild);
0561
0562 IIOMetadataNode newChildNode = (IIOMetadataNode) newChild;
0563 IIOMetadataNode oldChildNode = (IIOMetadataNode) oldChild;
0564
0565 IIOMetadataNode previous = oldChildNode.previousSibling;
0566 IIOMetadataNode next = oldChildNode.nextSibling;
0567
0568 if (previous != null) {
0569 previous.nextSibling = newChildNode;
0570 }
0571 if (next != null) {
0572 next.previousSibling = newChildNode;
0573 }
0574
0575 newChildNode.parent = this ;
0576 newChildNode.previousSibling = previous;
0577 newChildNode.nextSibling = next;
0578
0579 if (firstChild == oldChildNode) {
0580 firstChild = newChildNode;
0581 }
0582 if (lastChild == oldChildNode) {
0583 lastChild = newChildNode;
0584 }
0585
0586 oldChildNode.parent = null;
0587 oldChildNode.previousSibling = null;
0588 oldChildNode.nextSibling = null;
0589
0590 return oldChildNode;
0591 }
0592
0593 /**
0594 * Removes the child node indicated by <code>oldChild</code> from
0595 * the list of children, and returns it.
0596 *
0597 * @param oldChild the <code>Node</code> to be removed.
0598 *
0599 * @return the node removed.
0600 *
0601 * @exception IllegalArgumentException if <code>oldChild</code> is
0602 * <code>null</code>.
0603 */
0604 public Node removeChild(Node oldChild) {
0605 if (oldChild == null) {
0606 throw new IllegalArgumentException("oldChild == null!");
0607 }
0608 checkNode(oldChild);
0609
0610 IIOMetadataNode oldChildNode = (IIOMetadataNode) oldChild;
0611
0612 IIOMetadataNode previous = oldChildNode.previousSibling;
0613 IIOMetadataNode next = oldChildNode.nextSibling;
0614
0615 if (previous != null) {
0616 previous.nextSibling = next;
0617 }
0618 if (next != null) {
0619 next.previousSibling = previous;
0620 }
0621
0622 if (this .firstChild == oldChildNode) {
0623 this .firstChild = next;
0624 }
0625 if (this .lastChild == oldChildNode) {
0626 this .lastChild = previous;
0627 }
0628
0629 oldChildNode.parent = null;
0630 oldChildNode.previousSibling = null;
0631 oldChildNode.nextSibling = null;
0632
0633 --numChildren;
0634 return oldChildNode;
0635 }
0636
0637 /**
0638 * Adds the node <code>newChild</code> to the end of the list of
0639 * children of this node.
0640 *
0641 * @param newChild the <code>Node</code> to insert.
0642 *
0643 * @return the node added.
0644 *
0645 * @exception IllegalArgumentException if <code>newChild</code> is
0646 * <code>null</code>.
0647 */
0648 public Node appendChild(Node newChild) {
0649 if (newChild == null) {
0650 throw new IllegalArgumentException("newChild == null!");
0651 }
0652 checkNode(newChild);
0653
0654 // insertBefore will increment numChildren
0655 return insertBefore(newChild, null);
0656 }
0657
0658 /**
0659 * Returns <code>true</code> if this node has child nodes.
0660 *
0661 * @return <code>true</code> if this node has children.
0662 */
0663 public boolean hasChildNodes() {
0664 return numChildren > 0;
0665 }
0666
0667 /**
0668 * Returns a duplicate of this node. The duplicate node has no
0669 * parent (<code>getParentNode</code> returns <code>null</code>).
0670 * If a shallow clone is being performed (<code>deep</code> is
0671 * <code>false</code>), the new node will not have any children or
0672 * siblings. If a deep clone is being performed, the new node
0673 * will form the root of a complete cloned subtree.
0674 *
0675 * @param deep if <code>true</code>, recursively clone the subtree
0676 * under the specified node; if <code>false</code>, clone only the
0677 * node itself.
0678 *
0679 * @return the duplicate node.
0680 */
0681 public Node cloneNode(boolean deep) {
0682 IIOMetadataNode newNode = new IIOMetadataNode(this .nodeName);
0683 newNode.setUserObject(getUserObject());
0684 // Attributes
0685
0686 if (deep) {
0687 for (IIOMetadataNode child = firstChild; child != null; child = child.nextSibling) {
0688 newNode.appendChild(child.cloneNode(true));
0689 }
0690 }
0691
0692 return newNode;
0693 }
0694
0695 /**
0696 * Does nothing, since <code>IIOMetadataNode</code>s do not
0697 * contain <code>Text</code> children.
0698 */
0699 public void normalize() {
0700 }
0701
0702 /**
0703 * Returns <code>false</code> since DOM features are not
0704 * supported.
0705 *
0706 * @return <code>false</code>.
0707 *
0708 * @param feature a <code>String</code>, which is ignored.
0709 * @param version a <code>String</code>, which is ignored.
0710 */
0711 public boolean isSupported(String feature, String version) {
0712 return false;
0713 }
0714
0715 /**
0716 * Returns <code>null</code>, since namespaces are not supported.
0717 */
0718 public String getNamespaceURI() throws DOMException {
0719 return null;
0720 }
0721
0722 /**
0723 * Returns <code>null</code>, since namespaces are not supported.
0724 *
0725 * @return <code>null</code>.
0726 *
0727 * @see #setPrefix
0728 */
0729 public String getPrefix() {
0730 return null;
0731 }
0732
0733 /**
0734 * Does nothing, since namespaces are not supported.
0735 *
0736 * @param prefix a <code>String</code>, which is ignored.
0737 *
0738 * @see #getPrefix
0739 */
0740 public void setPrefix(String prefix) {
0741 }
0742
0743 /**
0744 * Equivalent to <code>getNodeName</code>.
0745 *
0746 * @return the node name, as a <code>String</code>.
0747 */
0748 public String getLocalName() {
0749 return nodeName;
0750 }
0751
0752 // Methods from Element
0753
0754 public String getTagName() {
0755 return nodeName;
0756 }
0757
0758 public String getAttribute(String name) {
0759 Attr attr = getAttributeNode(name);
0760 if (attr == null) {
0761 return "";
0762 }
0763 return attr.getValue();
0764 }
0765
0766 /**
0767 * Equivalent to <code>getAttribute(localName)</code>.
0768 *
0769 * @see #setAttributeNS
0770 */
0771 public String getAttributeNS(String namespaceURI, String localName) {
0772 return getAttribute(localName);
0773 }
0774
0775 public void setAttribute(String name, String value) {
0776 // Note minor dependency on Crimson package
0777 // Steal the code if Crimson ever goes away
0778 if (!com.sun.imageio.metadata.XmlNames.isName(name)) {
0779 throw new IIODOMException(
0780 DOMException.INVALID_CHARACTER_ERR,
0781 "Attribute name is illegal!");
0782 }
0783 removeAttribute(name, false);
0784 attributes.add(new IIOAttr(this , name, value));
0785 }
0786
0787 /**
0788 * Equivalent to <code>setAttribute(qualifiedName, value)</code>.
0789 *
0790 * @see #getAttributeNS
0791 */
0792 public void setAttributeNS(String namespaceURI,
0793 String qualifiedName, String value) {
0794 setAttribute(qualifiedName, value);
0795 }
0796
0797 public void removeAttribute(String name) {
0798 removeAttribute(name, true);
0799 }
0800
0801 private void removeAttribute(String name, boolean checkPresent) {
0802 int numAttributes = attributes.size();
0803 for (int i = 0; i < numAttributes; i++) {
0804 IIOAttr attr = (IIOAttr) attributes.get(i);
0805 if (name.equals(attr.getName())) {
0806 attr.setOwnerElement(null);
0807 attributes.remove(i);
0808 return;
0809 }
0810 }
0811
0812 // If we get here, the attribute doesn't exist
0813 if (checkPresent) {
0814 throw new IIODOMException(DOMException.NOT_FOUND_ERR,
0815 "No such attribute!");
0816 }
0817 }
0818
0819 /**
0820 * Equivalent to <code>removeAttribute(localName)</code>.
0821 */
0822 public void removeAttributeNS(String namespaceURI, String localName) {
0823 removeAttribute(localName);
0824 }
0825
0826 public Attr getAttributeNode(String name) {
0827 Node node = getAttributes().getNamedItem(name);
0828 return (Attr) node;
0829 }
0830
0831 /**
0832 * Equivalent to <code>getAttributeNode(localName)</code>.
0833 *
0834 * @see #setAttributeNodeNS
0835 */
0836 public Attr getAttributeNodeNS(String namespaceURI, String localName) {
0837 return getAttributeNode(localName);
0838 }
0839
0840 public Attr setAttributeNode(Attr newAttr) throws DOMException {
0841 Element owner = newAttr.getOwnerElement();
0842 if (owner != null) {
0843 if (owner == this ) {
0844 return null;
0845 } else {
0846 throw new DOMException(
0847 DOMException.INUSE_ATTRIBUTE_ERR,
0848 "Attribute is already in use");
0849 }
0850 }
0851
0852 IIOAttr attr;
0853 if (newAttr instanceof IIOAttr) {
0854 attr = (IIOAttr) newAttr;
0855 attr.setOwnerElement(this );
0856 } else {
0857 attr = new IIOAttr(this , newAttr.getName(), newAttr
0858 .getValue());
0859 }
0860
0861 Attr oldAttr = getAttributeNode(attr.getName());
0862 if (oldAttr != null) {
0863 removeAttributeNode(oldAttr);
0864 }
0865
0866 attributes.add(attr);
0867
0868 return oldAttr;
0869 }
0870
0871 /**
0872 * Equivalent to <code>setAttributeNode(newAttr)</code>.
0873 *
0874 * @see #getAttributeNodeNS
0875 */
0876 public Attr setAttributeNodeNS(Attr newAttr) {
0877 return setAttributeNode(newAttr);
0878 }
0879
0880 public Attr removeAttributeNode(Attr oldAttr) {
0881 removeAttribute(oldAttr.getName());
0882 return oldAttr;
0883 }
0884
0885 public NodeList getElementsByTagName(String name) {
0886 List l = new ArrayList();
0887 getElementsByTagName(name, l);
0888 return new IIONodeList(l);
0889 }
0890
0891 private void getElementsByTagName(String name, List l) {
0892 if (nodeName.equals(name)) {
0893 l.add(this );
0894 }
0895
0896 Node child = getFirstChild();
0897 while (child != null) {
0898 ((IIOMetadataNode) child).getElementsByTagName(name, l);
0899 child = child.getNextSibling();
0900 }
0901 }
0902
0903 /**
0904 * Equivalent to <code>getElementsByTagName(localName)</code>.
0905 */
0906 public NodeList getElementsByTagNameNS(String namespaceURI,
0907 String localName) {
0908 return getElementsByTagName(localName);
0909 }
0910
0911 public boolean hasAttributes() {
0912 return attributes.size() > 0;
0913 }
0914
0915 public boolean hasAttribute(String name) {
0916 return getAttributeNode(name) != null;
0917 }
0918
0919 /**
0920 * Equivalent to <code>hasAttribute(localName)</code>.
0921 */
0922 public boolean hasAttributeNS(String namespaceURI, String localName) {
0923 return hasAttribute(localName);
0924 }
0925
0926 // Methods from NodeList
0927
0928 public int getLength() {
0929 return numChildren;
0930 }
0931
0932 public Node item(int index) {
0933 if (index < 0) {
0934 return null;
0935 }
0936
0937 Node child = getFirstChild();
0938 while (child != null && index-- > 0) {
0939 child = child.getNextSibling();
0940 }
0941 return child;
0942 }
0943
0944 /**
0945 * Returns the <code>Object</code> value associated with this node.
0946 *
0947 * @return the user <code>Object</code>.
0948 *
0949 * @see #setUserObject
0950 */
0951 public Object getUserObject() {
0952 return userObject;
0953 }
0954
0955 /**
0956 * Sets the value associated with this node.
0957 *
0958 * @param userObject the user <code>Object</code>.
0959 *
0960 * @see #getUserObject
0961 */
0962 public void setUserObject(Object userObject) {
0963 this .userObject = userObject;
0964 }
0965
0966 // Start of dummy methods for DOM L3. PENDING: Please revisit
0967 public void setIdAttribute(String name, boolean isId)
0968 throws DOMException {
0969 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0970 "Method not supported");
0971 }
0972
0973 public void setIdAttributeNS(String namespaceURI, String localName,
0974 boolean isId) throws DOMException {
0975 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0976 "Method not supported");
0977 }
0978
0979 public void setIdAttributeNode(Attr idAttr, boolean isId)
0980 throws DOMException {
0981 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0982 "Method not supported");
0983 }
0984
0985 public TypeInfo getSchemaTypeInfo() {
0986 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0987 "Method not supported");
0988 }
0989
0990 public Object setUserData(String key, Object data,
0991 UserDataHandler handler) {
0992 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0993 "Method not supported");
0994 }
0995
0996 public Object getUserData(String key) {
0997 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0998 "Method not supported");
0999 }
1000
1001 public Object getFeature(String feature, String version) {
1002 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1003 "Method not supported");
1004 }
1005
1006 public boolean isSameNode(Node node) {
1007 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1008 "Method not supported");
1009 }
1010
1011 public boolean isEqualNode(Node node) {
1012 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1013 "Method not supported");
1014 }
1015
1016 public String lookupNamespaceURI(String prefix) {
1017 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1018 "Method not supported");
1019 }
1020
1021 public boolean isDefaultNamespace(String namespaceURI) {
1022 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1023 "Method not supported");
1024 }
1025
1026 public String lookupPrefix(String namespaceURI) {
1027 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1028 "Method not supported");
1029 }
1030
1031 String textContent;
1032
1033 public String getTextContent() throws DOMException {
1034 return textContent;
1035 }
1036
1037 public void setTextContent(String textContent) throws DOMException {
1038 this .textContent = textContent; //PENDING
1039 }
1040
1041 public short compareDocumentPosition(Node other)
1042 throws DOMException {
1043 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1044 "Method not supported");
1045 }
1046
1047 public String getBaseURI() {
1048 throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1049 "Method not supported");
1050 }
1051 //End of dummy methods for DOM L3. Please revisit
1052
1053 }
|