1 16 package org.apache.commons.jxpath.ri.axes; 17 18 import java.util.Stack ; 19 20 import org.apache.commons.jxpath.Pointer; 21 import org.apache.commons.jxpath.ri.Compiler; 22 import org.apache.commons.jxpath.ri.EvalContext; 23 import org.apache.commons.jxpath.ri.compiler.NodeTest; 24 import org.apache.commons.jxpath.ri.compiler.NodeTypeTest; 25 import org.apache.commons.jxpath.ri.model.NodeIterator; 26 import org.apache.commons.jxpath.ri.model.NodePointer; 27 28 35 public class DescendantContext extends EvalContext { 36 private NodeTest nodeTest; 37 private boolean setStarted = false; 38 private Stack stack; 39 private NodePointer currentNodePointer; 40 private boolean includeSelf; 41 private static final NodeTest ELEMENT_NODE_TEST = 42 new NodeTypeTest(Compiler.NODE_TYPE_NODE); 43 44 public DescendantContext( 45 EvalContext parentContext, 46 boolean includeSelf, 47 NodeTest nodeTest) 48 { 49 super(parentContext); 50 this.includeSelf = includeSelf; 51 this.nodeTest = nodeTest; 52 } 53 54 public boolean isChildOrderingRequired() { 55 return true; 56 } 57 58 public NodePointer getCurrentNodePointer() { 59 if (position == 0) { 60 if (!setPosition(1)) { 61 return null; 62 } 63 } 64 return currentNodePointer; 65 } 66 67 public void reset() { 68 super.reset(); 69 setStarted = false; 70 } 71 72 public boolean setPosition(int position) { 73 if (position < this.position) { 74 reset(); 75 } 76 77 while (this.position < position) { 78 if (!nextNode()) { 79 return false; 80 } 81 } 82 return true; 83 } 84 85 public boolean nextNode() { 86 if (!setStarted) { 87 setStarted = true; 88 stack = new Stack (); 89 currentNodePointer = parentContext.getCurrentNodePointer(); 90 if (currentNodePointer != null) { 91 if (!currentNodePointer.isLeaf()) { 92 stack.push( 93 currentNodePointer.childIterator( 94 ELEMENT_NODE_TEST, 95 false, 96 null)); 97 } 98 if (includeSelf) { 99 if (currentNodePointer.testNode(nodeTest)) { 100 position++; 101 return true; 102 } 103 } 104 } 105 } 106 107 while (!stack.isEmpty()) { 108 NodeIterator it = (NodeIterator) stack.peek(); 109 if (it.setPosition(it.getPosition() + 1)) { 110 currentNodePointer = it.getNodePointer(); 111 if (!isRecursive()) { 112 if (!currentNodePointer.isLeaf()) { 113 stack.push( 114 currentNodePointer.childIterator( 115 ELEMENT_NODE_TEST, 116 false, 117 null)); 118 } 119 if (currentNodePointer.testNode(nodeTest)) { 120 position++; 121 return true; 122 } 123 } 124 } 125 else { 126 stack.pop(); 129 } 130 } 131 return false; 132 } 133 134 138 private boolean isRecursive() { 139 Object node = currentNodePointer.getNode(); 140 for (int i = stack.size() - 1; --i >= 0;) { 141 NodeIterator it = (NodeIterator) stack.get(i); 142 Pointer pointer = it.getNodePointer(); 143 if (pointer != null && pointer.getNode() == node) { 144 return true; 145 } 146 } 147 return false; 148 } 149 } | Popular Tags |