1 package org.jaxen.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 import java.util.Iterator;
52 import java.util.NoSuchElementException;
53
54 import org.jaxen.Navigator;
55 import org.jaxen.UnsupportedAxisException;
56 import org.jaxen.JaxenRuntimeException;
57 import org.jaxen.JaxenConstants;
58
59 /***
60 * Represents the XPath <code>following</code> axis.
61 * The "<code>following</code> axis contains all nodes in the same document as the context
62 * node that are after the context node in document order, excluding any descendants
63 * and excluding attribute nodes and namespace nodes."
64 *
65 * @version 1.2b12
66 */
67 public class FollowingAxisIterator implements Iterator
68 {
69 private Object contextNode;
70
71 private Navigator navigator;
72
73 private Iterator siblings;
74
75 private Iterator currentSibling;
76
77 /***
78 * Create a new <code>following</code> axis iterator.
79 *
80 * @param contextNode the node to start from
81 * @param navigator the object model specific navigator
82 */
83 public FollowingAxisIterator(Object contextNode,
84 Navigator navigator) throws UnsupportedAxisException
85 {
86 this.contextNode = contextNode;
87 this.navigator = navigator;
88 this.siblings = navigator.getFollowingSiblingAxisIterator(contextNode);
89 this.currentSibling = JaxenConstants.EMPTY_ITERATOR;
90 }
91
92 private boolean goForward()
93 {
94 while ( ! siblings.hasNext() )
95 {
96 if ( !goUp() )
97 {
98 return false;
99 }
100 }
101
102 Object nextSibling = siblings.next();
103
104 this.currentSibling = new DescendantOrSelfAxisIterator(nextSibling, navigator);
105
106 return true;
107 }
108
109 private boolean goUp()
110 {
111 if ( contextNode == null
112 ||
113 navigator.isDocument(contextNode) )
114 {
115 return false;
116 }
117
118 try
119 {
120 contextNode = navigator.getParentNode( contextNode );
121
122 if ( contextNode != null
123 &&
124 !navigator.isDocument(contextNode) )
125 {
126 siblings = navigator.getFollowingSiblingAxisIterator(contextNode);
127 return true;
128 }
129 else
130 {
131 return false;
132 }
133 }
134 catch (UnsupportedAxisException e)
135 {
136 throw new JaxenRuntimeException(e);
137 }
138 }
139
140 /***
141 * Returns true if there are any following nodes remaining;
142 * false otherwise.
143 *
144 * @return true if any following nodes remain
145 *
146 * @see java.util.Iterator#hasNext()
147 */
148 public boolean hasNext()
149 {
150 while ( ! currentSibling.hasNext() )
151 {
152 if ( ! goForward() )
153 {
154 return false;
155 }
156 }
157
158 return true;
159 }
160
161 /***
162 * Returns the next following node.
163 *
164 * @return the next following node
165 *
166 * @throws NoSuchElementException if no following nodes remain
167 *
168 * @see java.util.Iterator#next()
169 */
170 public Object next() throws NoSuchElementException
171 {
172 if ( ! hasNext() )
173 {
174 throw new NoSuchElementException();
175 }
176
177 return currentSibling.next();
178 }
179
180 /***
181 * This operation is not supported.
182 *
183 * @throws UnsupportedOperationException always
184 */
185 public void remove() throws UnsupportedOperationException
186 {
187 throw new UnsupportedOperationException();
188 }
189 }