    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *     http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.jxpath.ri.model.dom;
    018
    019    import java.util.ArrayList;
    020    import java.util.List;
    021
    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.Document;
    026    import org.w3c.dom.NamedNodeMap;
    027    import org.w3c.dom.Node;
    028
    029    /**
    030     * An iterator of namespaces of a DOM Node.
    031     *
    032     * @author Dmitri Plotnikov
    033     * @version $Revision: 652845 $ $Date: 2008-05-02 12:46:46 -0500 (Fri, 02 May 2008) $
    034     */
    035    public class DOMNamespaceIterator implements NodeIterator {
    036        private NodePointer parent;
    037        private List attributes;
    038        private int position = 0;
    039
    040        /**
    041         * Create a new DOMNamespaceIterator.
    042         * @param parent parent pointer
    043         */
    044        public DOMNamespaceIterator(NodePointer parent) {
    045            this.parent = parent;
    046            attributes = new ArrayList();
    047            collectNamespaces(attributes, (Node) parent.getNode());
    048        }
    049
    050        /**
    051         * Collect namespaces from attribute nodes.
    052         * @param attributes attribute list
    053         * @param node target node
    054         */
    055        private void collectNamespaces(List attributes, Node node) {
    056            Node parent = node.getParentNode();
    057            if (parent != null) {
    058                collectNamespaces(attributes, parent);
    059            }
    060            if (node.getNodeType() == Node.DOCUMENT_NODE) {
    061                node = ((Document) node).getDocumentElement();
    062            }
    063            if (node.getNodeType() == Node.ELEMENT_NODE) {
    064                NamedNodeMap map = node.getAttributes();
    065                int count = map.getLength();
    066                for (int i = 0; i < count; i++) {
    067                    Attr attr = (Attr) map.item(i);
    068                    String prefix = DOMNodePointer.getPrefix(attr);
    069                    String name = DOMNodePointer.getLocalName(attr);
    070                    if ((prefix != null && prefix.equals("xmlns"))
    071                        || (prefix == null && name.equals("xmlns"))) {
    072                        attributes.add(attr);
    073                    }
    074                }
    075            }
    076        }
    077
    078        public NodePointer getNodePointer() {
    079            if (position == 0) {
    080                if (!setPosition(1)) {
    081                    return null;
    082                }
    083                position = 0;
    084            }
    085            int index = position - 1;
    086            if (index < 0) {
    087                index = 0;
    088            }
    089            String prefix = "";
    090            Attr attr = (Attr) attributes.get(index);
    091            String name = attr.getPrefix();
    092            if (name != null && name.equals("xmlns")) {
    093                prefix = DOMNodePointer.getLocalName(attr);
    094            }
    095            return new NamespacePointer(parent, prefix, attr.getValue());
    096        }
    097
    098        public int getPosition() {
    099            return position;
    100        }
    101
    102        public boolean setPosition(int position) {
    103            this.position = position;
    104            return position >= 1 && position <= attributes.size();
    105        }
    106    }