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.HashSet; 022import java.util.List; 023import java.util.Set; 024 025import org.apache.commons.jxpath.ri.model.NodeIterator; 026import org.apache.commons.jxpath.ri.model.NodePointer; 027import org.jdom.Document; 028import org.jdom.Element; 029import org.jdom.Namespace; 030 031/** 032 * An iterator of namespaces of a DOM Node. 033 */ 034public class JDOMNamespaceIterator implements NodeIterator { 035 036 private final NodePointer parent; 037 private List<Namespace> namespaces; 038 private Set<String> prefixes; 039 private int position; 040 041 /** 042 * Constructs a new JDOMNamespaceIterator. 043 * 044 * @param parent the parent NodePointer. 045 */ 046 public JDOMNamespaceIterator(final NodePointer parent) { 047 this.parent = parent; 048 Object node = parent.getNode(); 049 if (node instanceof Document) { 050 node = ((Document) node).getRootElement(); 051 } 052 if (node instanceof Element) { 053 namespaces = new ArrayList<>(); 054 prefixes = new HashSet<>(); 055 collectNamespaces((Element) node); 056 } 057 } 058 059 /** 060 * Collect the namespaces from a JDOM Element. 061 * 062 * @param element the source Element 063 */ 064 private void collectNamespaces(final Element element) { 065 Namespace ns = element.getNamespace(); 066 if (ns != null && !prefixes.contains(ns.getPrefix())) { 067 namespaces.add(ns); 068 prefixes.add(ns.getPrefix()); 069 } 070 final List others = element.getAdditionalNamespaces(); 071 for (final Object other : others) { 072 ns = (Namespace) other; 073 if (ns != null && !prefixes.contains(ns.getPrefix())) { 074 namespaces.add(ns); 075 prefixes.add(ns.getPrefix()); 076 } 077 } 078 final Object elementParent = element.getParent(); 079 if (elementParent instanceof Element) { 080 collectNamespaces((Element) elementParent); 081 } 082 } 083 084 @Override 085 public NodePointer getNodePointer() { 086 if (position == 0) { 087 if (!setPosition(1)) { 088 return null; 089 } 090 position = 0; 091 } 092 int index = position - 1; 093 if (index < 0) { 094 index = 0; 095 } 096 final Namespace ns = namespaces.get(index); 097 return new JDOMNamespacePointer(parent, ns.getPrefix(), ns.getURI()); 098 } 099 100 @Override 101 public int getPosition() { 102 return position; 103 } 104 105 @Override 106 public boolean setPosition(final int position) { 107 if (namespaces == null) { 108 return false; 109 } 110 this.position = position; 111 return position >= 1 && position <= namespaces.size(); 112 } 113}