1 package org.jaxen.util; 2 3 /* 4 * $Header$ 5 * $Revision$ 6 * $Date$ 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$ 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 }