    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.model.jdom;
    17
    18  import java.util.ArrayList;
    19  import java.util.Collections;
    20  import java.util.List;
    21
    22  import org.apache.commons.jxpath.ri.QName;
    23  import org.apache.commons.jxpath.ri.model.NodeIterator;
    24  import org.apache.commons.jxpath.ri.model.NodePointer;
    25  import org.jdom.Attribute;
    26  import org.jdom.Element;
    27  import org.jdom.Namespace;
    28
    29  /***
    30   * An iterator of attributes of a DOM Node.
    31   *
    32   * @author Dmitri Plotnikov
    33   * @version $Revision: 1.6 $ $Date: 2004/02/29 14:17:40 $
    34   */
    35  public class JDOMAttributeIterator implements NodeIterator {
    36      private NodePointer parent;
    37      private QName name;
    38      private List attributes;
    39      private int position = 0;
    40
    41      public JDOMAttributeIterator(NodePointer parent, QName name) {
    42          this.parent = parent;
    43          this.name = name;
    44          if (parent.getNode() instanceof Element) {
    45              Element element = (Element) parent.getNode();
    46              String prefix = name.getPrefix();
    47              Namespace ns;
    48              if (prefix != null) {
    49                  if (prefix.equals("xml")) {
    50                      ns = Namespace.XML_NAMESPACE;
    51                  }
    52                  else {
    53                      ns = element.getNamespace(prefix);
    54                      if (ns == null) {
    55                          // TBD: no attributes
    56                          attributes = Collections.EMPTY_LIST;
    57                          return;
    58                      }
    59                  }
    60              }
    61              else {
    62                  ns = Namespace.NO_NAMESPACE;
    63              }
    64
    65              String lname = name.getName();
    66              if (!lname.equals("*")) {
    67                  attributes = new ArrayList();
    68                  if (ns != null) {
    69                      Attribute attr = element.getAttribute(lname, ns);
    70                      if (attr != null) {
    71                          attributes.add(attr);
    72                      }
    73                  }
    74              }
    75              else {
    76                  attributes = new ArrayList();
    77                  List allAttributes = element.getAttributes();
    78                  for (int i = 0; i < allAttributes.size(); i++) {
    79                      Attribute attr = (Attribute) allAttributes.get(i);
    80                      if (attr.getNamespace().equals(ns)) {
    81                          attributes.add(attr);
    82                      }
    83                  }
    84              }
    85          }
    86      }
    87
    88      /*
    89      private boolean testAttr(Attr attr, QName testName) {
    90          String nodePrefix = DOMNodePointer.getPrefix(attr);
    91          String nodeLocalName = DOMNodePointer.getLocalName(attr);
    92
    93          if (nodePrefix != null && nodePrefix.equals("xmlns")) {
    94              return false;
    95          }
    96
    97          if (nodePrefix == null && nodeLocalName.equals("xmlns")) {
    98              return false;
    99          }
    100
    101         String testLocalName = name.getName();
    102         if (testLocalName.equals("*") || testLocalName.equals(nodeLocalName)) {
    103             String testPrefix = testName.getPrefix();
    104
    105             if (equalStrings(testPrefix, nodePrefix)) {
    106                 return true;
    107             }
    108
    109             String testNS = null;
    110             if (testPrefix != null) {
    111                 testNS = parent.getNamespaceURI(testPrefix);
    112             }
    113
    114             String nodeNS = null;
    115             if (nodePrefix != null) {
    116                 nodeNS = parent.getNamespaceURI(nodePrefix);
    117             }
    118             return equalStrings(testNS, nodeNS);
    119         }
    120         return false;
    121     }
    122
    123     private static boolean equalStrings(String s1, String s2) {
    124         if (s1 == null && s2 != null) {
    125             return false;
    126         }
    127         if (s1 != null && !s1.equals(s2)) {
    128             return false;
    129         }
    130         return true;
    131     }
    132
    133     private Attr getAttribute(Element element, QName name) {
    134         String testPrefix = name.getPrefix();
    135         String testNS = null;
    136
    137         if (testPrefix != null) {
    138             testNS = parent.getNamespaceURI(testPrefix);
    139         }
    140
    141         if (testNS != null) {
    142             Attr attr = element.getAttributeNodeNS(testNS, name.getName());
    143             if (attr == null) {
    144                 // This may mean that the parser does not support NS for
    145                 // attributes, example - the version of Crimson bundled
    146                 // with JDK 1.4.0
    147                 NamedNodeMap nnm = element.getAttributes();
    148                 for (int i = 0; i < nnm.getLength(); i++) {
    149                     attr = (Attr)nnm.item(i);
    150                     if (testAttr(attr, name)) {
    151                         return attr;
    152                     }
    153                 }
    154             }
    155             return attr;
    156         }
    157         else {
    158             return element.getAttributeNode(name.getName());
    159         }
    160     }
    161 */
    162     public NodePointer getNodePointer() {
    163         if (position == 0) {
    164             if (!setPosition(1)) {
    165                 return null;
    166             }
    167             position = 0;
    168         }
    169         int index = position - 1;
    170         if (index < 0) {
    171             index = 0;
    172         }
    173         return new JDOMAttributePointer(
    174             parent,
    175             (Attribute) attributes.get(index));
    176     }
    177
    178     public int getPosition() {
    179         return position;
    180     }
    181
    182     public boolean setPosition(int position) {
    183         if (attributes == null) {
    184             return false;
    185         }
    186         this.position = position;
    187         return position >= 1 && position <= attributes.size();
    188     }
    189 }