1 package org.jaxen.util;
2
3 /*
4 * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/FollowingAxisIterator.java,v 1.8 2006/11/09 18:20:12 elharo Exp $
5 * $Revision: 1.8 $
6 * $Date: 2006/11/09 18:20:12 $
7 *
8 * ====================================================================
9 *
10 * Copyright 2000-2005 bob mcwhirter & James Strachan.
11 * All rights reserved.
12 *
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met:
17 *
18 * * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * * Neither the name of the Jaxen Project nor the names of its
26 * contributors may be used to endorse or promote products derived
27 * from this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
30 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
32 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
33 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
36 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * ====================================================================
42 * This software consists of voluntary contributions made by many
43 * individuals on behalf of the Jaxen Project and was originally
44 * created by bob mcwhirter <bob@werken.com> and
45 * James Strachan <jstrachan@apache.org>. For more information on the
46 * Jaxen Project, please see <http://www.jaxen.org/>.
47 *
48 * $Id: FollowingAxisIterator.java,v 1.8 2006/11/09 18:20:12 elharo Exp $
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 }