1 16 package org.apache.commons.jxpath.ri.axes; 17 18 import java.util.Stack ; 19 20 import org.apache.commons.jxpath.ri.EvalContext; 21 import org.apache.commons.jxpath.ri.compiler.NodeTest; 22 import org.apache.commons.jxpath.ri.model.NodeIterator; 23 import org.apache.commons.jxpath.ri.model.NodePointer; 24 import org.apache.commons.jxpath.ri.model.beans.PropertyIterator; 25 26 32 public class PrecedingOrFollowingContext extends EvalContext { 33 private NodeTest nodeTest; 34 private boolean setStarted = false; 35 private boolean started = false; 36 private Stack stack; 37 private Stack nameStack; 38 private NodePointer currentNodePointer; 39 private NodePointer currentRootLocation; 40 private boolean reverse; 41 42 public PrecedingOrFollowingContext( 43 EvalContext parentContext, 44 NodeTest nodeTest, 45 boolean reverse) 46 { 47 super(parentContext); 48 this.nodeTest = nodeTest; 49 this.reverse = reverse; 50 } 51 52 public NodePointer getCurrentNodePointer() { 53 return currentNodePointer; 54 } 55 56 public int getDocumentOrder() { 57 return reverse ? -1 : 1; 58 } 59 60 public void reset() { 61 super.reset(); 62 stack = new Stack (); 63 setStarted = false; 64 } 65 66 public boolean setPosition(int position) { 67 if (position < this.position) { 68 reset(); 69 } 70 71 while (this.position < position) { 72 if (!nextNode()) { 73 return false; 74 } 75 } 76 return true; 77 } 78 79 public boolean nextNode() { 80 if (!setStarted) { 81 setStarted = true; 82 currentRootLocation = parentContext.getCurrentNodePointer(); 83 NodePointer parent = currentRootLocation.getParent(); 84 if (parent != null) { 85 stack.push( 87 parent.childIterator(null, reverse, currentRootLocation)); 88 } 89 } 90 91 while (true) { 92 if (stack.isEmpty()) { 93 currentRootLocation = currentRootLocation.getParent(); 94 95 if (currentRootLocation == null 96 || currentRootLocation.isRoot()) { 97 break; 98 } 99 100 NodePointer parent = currentRootLocation.getParent(); 101 if (parent != null) { 102 stack.push( 103 parent.childIterator( 104 null, 105 reverse, 106 currentRootLocation)); 107 } 108 } 109 110 while (!stack.isEmpty()) { 111 if (!reverse) { 112 NodeIterator it = (NodeIterator) stack.peek(); 113 if (it.setPosition(it.getPosition() + 1)) { 114 currentNodePointer = it.getNodePointer(); 115 if (!currentNodePointer.isLeaf()) { 116 stack.push( 117 currentNodePointer.childIterator( 118 null, 119 reverse, 120 null)); 121 } 122 if (currentNodePointer.testNode(nodeTest)) { 123 super.setPosition(getCurrentPosition() + 1); 124 return true; 125 } 126 } 127 else { 128 stack.pop(); 131 } 132 } 133 else { 134 NodeIterator it = (NodeIterator) stack.peek(); 135 if (it.setPosition(it.getPosition() + 1)) { 136 currentNodePointer = it.getNodePointer(); 137 if (!currentNodePointer.isLeaf()) { 138 stack.push( 139 currentNodePointer.childIterator( 140 null, 141 reverse, 142 null)); 143 } 144 else if (currentNodePointer.testNode(nodeTest)) { 145 super.setPosition(getCurrentPosition() + 1); 146 return true; 147 } 148 } 149 else { 150 stack.pop(); 151 if (!stack.isEmpty()) { 152 it = (PropertyIterator) stack.peek(); 153 currentNodePointer = it.getNodePointer(); 154 if (currentNodePointer.testNode(nodeTest)) { 155 super.setPosition(getCurrentPosition() + 1); 156 return true; 157 } 158 } 159 } 160 } 161 } 162 } 163 return false; 164 } 165 } | Popular Tags |