    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
    018package org.apache.commons.jxpath.ri.model.jdom;
    019
    020import java.util.ArrayList;
    021import java.util.Collections;
    022import java.util.List;
    023
    024import org.apache.commons.jxpath.ri.QName;
    025import org.apache.commons.jxpath.ri.model.NodeIterator;
    026import org.apache.commons.jxpath.ri.model.NodePointer;
    027import org.jdom.Attribute;
    028import org.jdom.Element;
    029import org.jdom.Namespace;
    030
    031/**
    032 * An iterator of attributes of a DOM Node.
    033 */
    034public class JDOMAttributeIterator implements NodeIterator {
    035
    036    private NodePointer parent;
    037    private List<Attribute> attributes;
    038    private int position;
    039
    040    /**
    041     * Constructs a new JDOMAttributeIterator.
    042     *
    043     * @param parent pointer
    044     * @param qName   test
    045     */
    046    public JDOMAttributeIterator(final NodePointer parent, final QName qName) {
    047        this.parent = parent;
    048        if (parent.getNode() instanceof Element) {
    049            final Element element = (Element) parent.getNode();
    050            final String prefix = qName.getPrefix();
    051            Namespace ns = null;
    052            if (prefix != null) {
    053                if (prefix.equals("xml")) {
    054                    ns = Namespace.XML_NAMESPACE;
    055                } else {
    056                    final String uri = parent.getNamespaceResolver().getNamespaceURI(prefix);
    057                    if (uri != null) {
    058                        ns = Namespace.getNamespace(prefix, uri);
    059                    }
    060                    if (ns == null) {
    061                        // TBD: no attributes
    062                        attributes = Collections.emptyList();
    063                        return;
    064                    }
    065                }
    066            } else {
    067                ns = Namespace.NO_NAMESPACE;
    068            }
    069            final String lname = qName.getName();
    070            if (!lname.equals("*")) {
    071                attributes = new ArrayList<>();
    072                final Attribute attr = element.getAttribute(lname, ns);
    073                if (attr != null) {
    074                    attributes.add(attr);
    075                }
    076            } else {
    077                attributes = new ArrayList<>();
    078                final List<Attribute> allAttributes = element.getAttributes();
    079                for (int i = 0; i < allAttributes.size(); i++) {
    080                    final Attribute attr = allAttributes.get(i);
    081                    if (ns == Namespace.NO_NAMESPACE || attr.getNamespace().equals(ns)) {
    082                        attributes.add(attr);
    083                    }
    084                }
    085            }
    086        }
    087    }
    088
    089    @Override
    090    public NodePointer getNodePointer() {
    091        if (position == 0) {
    092            if (!setPosition(1)) {
    093                return null;
    094            }
    095            position = 0;
    096        }
    097        int index = position - 1;
    098        if (index < 0) {
    099            index = 0;
    100        }
    101        return new JDOMAttributePointer(parent, attributes.get(index));
    102    }
    103
    104    @Override
    105    public int getPosition() {
    106        return position;
    107    }
    108
    109    @Override
    110    public boolean setPosition(final int position) {
    111        if (attributes == null) {
    112            return false;
    113        }
    114        this.position = position;
    115        return position >= 1 && position <= attributes.size();
    116    }
    117}