OSDN Git Service

8337298984816bf284ea2769d035e3a992cd50b5
[mikutoga/TogaGem.git] / src / main / java / jp / sourceforge / mikutoga / xml / SiblingElemIterator.java
1 /*
2  * sibling element iterator on DOM tree
3  *
4  * License : The MIT License
5  * Copyright(c) 2011 MikuToga Partners
6  */
7
8 package jp.sourceforge.mikutoga.xml;
9
10 import java.util.Iterator;
11 import java.util.NoSuchElementException;
12 import org.w3c.dom.Element;
13 import org.w3c.dom.Node;
14
15 /**
16  * 兄弟要素間用Iterator。
17  * <p>同じ親と名前空間とローカル名を持つ要素同士を「兄弟要素」とする。
18  * <p>ノードの持つ名前空間がnullの場合、全ての名前空間引数にマッチする。
19  * <p>削除操作は未サポート。
20  */
21 public class SiblingElemIterator implements Iterator<Element> {
22
23     private Element next;
24     private final String nsuri;
25     private final String localName;
26
27
28     /**
29      * コンストラクタ。
30      * @param first 最初の兄弟要素。nullだと一度もiterateしない。
31      */
32     public SiblingElemIterator(Element first){
33         super();
34
35         this.next = first;
36
37         if(this.next == null){
38             this.nsuri     = null;
39             this.localName = null;
40         }else{
41             this.nsuri     = this.next.getNamespaceURI();
42             this.localName = this.next.getLocalName();
43         }
44
45         return;
46     }
47
48     /**
49      * コンストラクタ。
50      * <p>名前空間引数にnullが渡された場合、全ての名前空間にマッチする。
51      * <p>ローカル名引数にnullが渡された場合、全てのローカル名にマッチする。
52      * @param parent 親要素
53      * @param nsuri 子要素の名前空間URI
54      * @param localName 子要素のローカル名
55      */
56     public SiblingElemIterator(Element parent,
57                                String nsuri,
58                                String localName ){
59         super();
60
61         this.next = DomNsUtils.pickFirstChild(parent, nsuri, localName);
62
63         if(this.next == null){
64             this.nsuri     = null;
65             this.localName = null;
66         }else{
67             this.nsuri     = nsuri;
68             this.localName = localName;
69         }
70
71         return;
72     }
73
74
75     /**
76      * {@inheritDoc}
77      * @return {@inheritDoc}
78      */
79     @Override
80     public boolean hasNext(){
81         if(this.next != null) return true;
82         return false;
83     }
84
85     /**
86      * {@inheritDoc}
87      * @return {@inheritDoc}
88      * @throws NoSuchElementException {@inheritDoc}
89      */
90     @Override
91     public Element next() throws NoSuchElementException {
92         if(this.next == null) throw new NoSuchElementException();
93
94         Element result = this.next;
95
96         Node sibNode = result;
97         do{
98             sibNode = sibNode.getNextSibling();
99             if(sibNode == null) break;
100         }while( ! matchElemName(sibNode) );
101         this.next = (Element) sibNode;
102
103         return result;
104     }
105
106     /**
107      * 兄弟要素にふさわしい名前を持つか判定する。
108      * @param node 判定対象
109      * @return 兄弟にふさわしい名前を持つならtrue
110      */
111     private boolean matchElemName(Node node){
112         return DomNsUtils.hasNsLocalNameElem(node,
113                                              this.nsuri, this.localName );
114     }
115
116     /**
117      * {@inheritDoc}
118      * ※削除不可。
119      * @throws UnsupportedOperationException 削除を試みたので失敗した
120      */
121     @Override
122     public void remove() throws UnsupportedOperationException {
123         throw new UnsupportedOperationException();
124     }
125
126 }