001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.jxpath.ri.model.dom;
017:
018: import java.util.ArrayList;
019: import java.util.List;
020:
021: import org.apache.commons.jxpath.ri.QName;
022: import org.apache.commons.jxpath.ri.model.NodeIterator;
023: import org.apache.commons.jxpath.ri.model.NodePointer;
024: import org.w3c.dom.Attr;
025: import org.w3c.dom.Element;
026: import org.w3c.dom.NamedNodeMap;
027: import org.w3c.dom.Node;
028:
029: /**
030: * An iterator of attributes of a DOM Node.
031: *
032: * @author Dmitri Plotnikov
033: * @version $Revision: 1.11 $ $Date: 2004/02/29 14:17:44 $
034: */
035: public class DOMAttributeIterator implements NodeIterator {
036: private NodePointer parent;
037: private QName name;
038: private List attributes;
039: private int position = 0;
040:
041: public DOMAttributeIterator(NodePointer parent, QName name) {
042: this .parent = parent;
043: this .name = name;
044: attributes = new ArrayList();
045: Node node = (Node) parent.getNode();
046: if (node.getNodeType() == Node.ELEMENT_NODE) {
047: String lname = name.getName();
048: if (!lname.equals("*")) {
049: Attr attr = getAttribute((Element) node, name);
050: if (attr != null) {
051: attributes.add(attr);
052: }
053: } else {
054: NamedNodeMap map = node.getAttributes();
055: int count = map.getLength();
056: for (int i = 0; i < count; i++) {
057: Attr attr = (Attr) map.item(i);
058: if (testAttr(attr, name)) {
059: attributes.add(attr);
060: }
061: }
062: }
063: }
064: }
065:
066: private boolean testAttr(Attr attr, QName testName) {
067: String nodePrefix = DOMNodePointer.getPrefix(attr);
068: String nodeLocalName = DOMNodePointer.getLocalName(attr);
069:
070: if (nodePrefix != null && nodePrefix.equals("xmlns")) {
071: return false;
072: }
073:
074: if (nodePrefix == null && nodeLocalName.equals("xmlns")) {
075: return false;
076: }
077:
078: String testLocalName = name.getName();
079: if (testLocalName.equals("*")
080: || testLocalName.equals(nodeLocalName)) {
081: String testPrefix = testName.getPrefix();
082:
083: if (equalStrings(testPrefix, nodePrefix)) {
084: return true;
085: }
086:
087: String testNS = null;
088: if (testPrefix != null) {
089: testNS = parent.getNamespaceURI(testPrefix);
090: }
091:
092: String nodeNS = null;
093: if (nodePrefix != null) {
094: nodeNS = parent.getNamespaceURI(nodePrefix);
095: }
096: return equalStrings(testNS, nodeNS);
097: }
098: return false;
099: }
100:
101: private static boolean equalStrings(String s1, String s2) {
102: if (s1 == null && s2 != null) {
103: return false;
104: }
105: if (s1 != null && !s1.equals(s2)) {
106: return false;
107: }
108: return true;
109: }
110:
111: private Attr getAttribute(Element element, QName name) {
112: String testPrefix = name.getPrefix();
113: String testNS = null;
114:
115: if (testPrefix != null) {
116: testNS = parent.getNamespaceURI(testPrefix);
117: }
118:
119: if (testNS != null) {
120: Attr attr = element.getAttributeNodeNS(testNS, name
121: .getName());
122: if (attr != null) {
123: return attr;
124: }
125:
126: // This may mean that the parser does not support NS for
127: // attributes, example - the version of Crimson bundled
128: // with JDK 1.4.0
129: NamedNodeMap nnm = element.getAttributes();
130: for (int i = 0; i < nnm.getLength(); i++) {
131: attr = (Attr) nnm.item(i);
132: if (testAttr(attr, name)) {
133: return attr;
134: }
135: }
136: return null;
137: } else {
138: return element.getAttributeNode(name.getName());
139: }
140: }
141:
142: public NodePointer getNodePointer() {
143: if (position == 0) {
144: if (!setPosition(1)) {
145: return null;
146: }
147: position = 0;
148: }
149: int index = position - 1;
150: if (index < 0) {
151: index = 0;
152: }
153: return new DOMAttributePointer(parent, (Attr) attributes
154: .get(index));
155: }
156:
157: public int getPosition() {
158: return position;
159: }
160:
161: public boolean setPosition(int position) {
162: this .position = position;
163: return position >= 1 && position <= attributes.size();
164: }
165: }
|