View Javadoc

1   package org.jaxen.util;
2   
3   /*
4    * $Header$
5    * $Revision: 1255 $
6    * $Date: 2006-11-09 10:20:12 -0800 (Thu, 09 Nov 2006) $
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 1255 2006-11-09 18:20:12Z elharo $
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 }