1 16 package org.apache.commons.jxpath.ri; 17 18 import java.util.ArrayList ; 19 import java.util.Collections ; 20 import java.util.Comparator ; 21 import java.util.HashSet ; 22 import java.util.Iterator ; 23 import java.util.List ; 24 import java.util.NoSuchElementException ; 25 26 import org.apache.commons.jxpath.BasicNodeSet; 27 import org.apache.commons.jxpath.ExpressionContext; 28 import org.apache.commons.jxpath.JXPathContext; 29 import org.apache.commons.jxpath.JXPathException; 30 import org.apache.commons.jxpath.NodeSet; 31 import org.apache.commons.jxpath.Pointer; 32 import org.apache.commons.jxpath.ri.axes.RootContext; 33 import org.apache.commons.jxpath.ri.model.NodePointer; 34 35 45 public abstract class EvalContext implements ExpressionContext, Iterator { 46 protected EvalContext parentContext; 47 protected RootContext rootContext; 48 protected int position = 0; 49 private boolean startedSetIteration = false; 50 private boolean done = false; 51 private boolean hasPerformedIteratorStep = false; 52 private Iterator pointerIterator; 53 54 private static final Comparator REVERSE_COMPARATOR = new Comparator () { 57 public int compare(Object o1, Object o2) { 58 return ((Comparable ) o2).compareTo(o1); 59 } 60 }; 61 62 public EvalContext(EvalContext parentContext) { 63 this.parentContext = parentContext; 64 } 65 66 public Pointer getContextNodePointer() { 67 return getCurrentNodePointer(); 68 } 69 70 public JXPathContext getJXPathContext() { 71 return getRootContext().getJXPathContext(); 72 } 73 74 public int getPosition() { 75 return position; 76 } 77 78 84 public int getDocumentOrder() { 85 if (parentContext != null && parentContext.isChildOrderingRequired()) { 86 return 1; 87 } 88 return 0; 89 } 90 91 96 public boolean isChildOrderingRequired() { 97 if (getDocumentOrder() != 0) { 100 return true; 101 } 102 return false; 103 } 104 105 108 public boolean hasNext() { 109 if (pointerIterator != null) { 110 return pointerIterator.hasNext(); 111 } 112 113 if (getDocumentOrder() != 0) { 114 return constructIterator(); 115 } 116 else { 117 if (!done && !hasPerformedIteratorStep) { 118 performIteratorStep(); 119 } 120 return !done; 121 } 122 } 123 124 127 public Object next() { 128 if (pointerIterator != null) { 129 return pointerIterator.next(); 130 } 131 132 if (getDocumentOrder() != 0) { 133 if (!constructIterator()) { 134 throw new NoSuchElementException (); 135 } 136 return pointerIterator.next(); 137 } 138 else { 139 if (!done && !hasPerformedIteratorStep) { 140 performIteratorStep(); 141 } 142 if (done) { 143 throw new NoSuchElementException (); 144 } 145 hasPerformedIteratorStep = false; 146 return getCurrentNodePointer(); 147 } 148 } 149 150 153 private void performIteratorStep() { 154 done = true; 155 if (position != 0 && nextNode()) { 156 done = false; 157 } 158 else { 159 while (nextSet()) { 160 if (nextNode()) { 161 done = false; 162 break; 163 } 164 } 165 } 166 hasPerformedIteratorStep = true; 167 } 168 169 172 public void remove() { 173 throw new UnsupportedOperationException ( 174 "JXPath iterators cannot remove nodes"); 175 } 176 177 private boolean constructIterator() { 178 HashSet set = new HashSet (); 179 ArrayList list = new ArrayList (); 180 while (nextSet()) { 181 while (nextNode()) { 182 NodePointer pointer = getCurrentNodePointer(); 183 if (!set.contains(pointer)) { 184 set.add(pointer); 186 list.add(pointer); 187 } 188 } 189 } 190 if (list.isEmpty()) { 191 return false; 192 } 193 194 if (getDocumentOrder() == 1) { 195 Collections.sort(list); 196 } 197 else { 198 Collections.sort(list, REVERSE_COMPARATOR); 199 } 200 pointerIterator = list.iterator(); 201 return true; 202 } 203 204 208 public List getContextNodeList() { 209 int pos = position; 210 if (pos != 0) { 211 reset(); 212 } 213 List list = new ArrayList (); 214 while (nextNode()) { 215 list.add(getCurrentNodePointer()); 216 } 217 if (pos != 0) { 218 setPosition(pos); 219 } 220 else { 221 reset(); 222 } 223 return list; 224 } 225 226 231 public NodeSet getNodeSet() { 232 if (position != 0) { 233 throw new JXPathException( 234 "Simultaneous operations: " 235 + "should not request pointer list while " 236 + "iterating over an EvalContext"); 237 } 238 BasicNodeSet set = new BasicNodeSet(); 239 while (nextSet()) { 240 while (nextNode()) { 241 set.add((Pointer)getCurrentNodePointer().clone()); 242 } 243 } 244 245 return set; 246 } 247 248 253 public Object getValue() { 254 return getNodeSet(); 255 } 256 257 public String toString() { 258 Pointer ptr = getContextNodePointer(); 259 if (ptr == null) { 260 return "Empty expression context"; 261 } 262 else { 263 return "Expression context [" + getPosition() + "] " + ptr.asPath(); 264 } 265 } 266 267 271 public RootContext getRootContext() { 272 if (rootContext == null) { 273 rootContext = parentContext.getRootContext(); 274 } 275 return rootContext; 276 } 277 278 281 public void reset() { 282 position = 0; 283 } 284 285 public int getCurrentPosition() { 286 return position; 287 } 288 289 293 public Pointer getSingleNodePointer() { 294 reset(); 295 while (nextSet()) { 296 if (nextNode()) { 297 return getCurrentNodePointer(); 298 } 299 } 300 return null; 301 } 302 303 307 public abstract NodePointer getCurrentNodePointer(); 308 309 313 public boolean nextSet() { 314 reset(); 316 if (!startedSetIteration) { 320 startedSetIteration = true; 321 while (parentContext.nextSet()) { 322 if (parentContext.nextNode()) { 323 return true; 324 } 325 } 326 return false; 327 } 328 329 if (parentContext.nextNode()) { 332 return true; 333 } 334 335 while (parentContext.nextSet()) { 338 if (parentContext.nextNode()) { 339 return true; 340 } 341 } 342 return false; 343 } 344 345 349 public abstract boolean nextNode(); 350 351 357 public boolean setPosition(int position) { 358 this.position = position; 359 return true; 360 } 361 } | Popular Tags |