1 16 19 package org.apache.xpath.axes; 20 21 import java.util.Vector ; 22 23 import org.apache.xml.dtm.DTM; 24 import org.apache.xml.dtm.DTMFilter; 25 import org.apache.xml.dtm.DTMIterator; 26 import org.apache.xml.dtm.DTMManager; 27 import org.apache.xml.utils.NodeVector; 28 import org.apache.xpath.NodeSetDTM; 29 import org.apache.xpath.XPathContext; 30 import org.apache.xpath.objects.XObject; 31 32 36 public class NodeSequence extends XObject 37 implements DTMIterator, Cloneable , PathComponent 38 { 39 40 protected int m_last = -1; 41 42 47 protected int m_next = 0; 48 49 53 protected NodeVector getVector() 54 { 55 return (NodeVector)m_obj; 56 } 57 58 61 protected void SetVector(NodeVector v) 62 { 63 m_obj = v; 64 } 65 66 67 71 public boolean hasCache() 72 { 73 return (m_obj != null); 74 } 75 76 77 80 protected DTMIterator m_iter; 81 82 86 public final void setIter(DTMIterator iter) 87 { 88 m_iter = iter; 89 } 90 91 95 public final DTMIterator getContainedIter() 96 { 97 return m_iter; 98 } 99 100 104 protected DTMManager m_dtmMgr; 105 106 108 116 public NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes) 117 { 118 setIter(iter); 119 setRoot(context, xctxt); 120 setShouldCacheNodes(shouldCacheNodes); 121 } 122 123 128 public NodeSequence(Object nodeVector) 129 { 130 super(nodeVector); 131 if(null != nodeVector) 132 { 133 assertion(nodeVector instanceof NodeVector, 134 "Must have a NodeVector as the object for NodeSequence!"); 135 if(nodeVector instanceof DTMIterator) 136 { 137 setIter((DTMIterator)nodeVector); 138 m_last = ((DTMIterator)nodeVector).getLength(); 139 } 140 141 } 142 } 143 144 148 public NodeSequence(DTMManager dtmMgr) 149 { 150 super(new NodeVector()); 151 m_last = 0; 152 m_dtmMgr = dtmMgr; 153 } 154 155 156 159 public NodeSequence() 160 { 161 } 162 163 164 167 public DTM getDTM(int nodeHandle) 168 { 169 DTMManager mgr = getDTMManager(); 170 if(null != mgr) 171 return getDTMManager().getDTM(nodeHandle); 172 else 173 { 174 assertion(false, "Can not get a DTM Unless a DTMManager has been set!"); 175 return null; 176 } 177 } 178 179 182 public DTMManager getDTMManager() 183 { 184 return m_dtmMgr; 185 } 186 187 190 public int getRoot() 191 { 192 if(null != m_iter) 193 return m_iter.getRoot(); 194 else 195 { 196 return DTM.NULL; 200 } 201 } 202 203 206 public void setRoot(int nodeHandle, Object environment) 207 { 208 if(null != m_iter) 209 { 210 XPathContext xctxt = (XPathContext)environment; 211 m_dtmMgr = xctxt.getDTMManager(); 212 m_iter.setRoot(nodeHandle, environment); 213 if(!m_iter.isDocOrdered()) 214 { 215 if(!hasCache()) 216 setShouldCacheNodes(true); 217 runTo(-1); 218 m_next=0; 219 } 220 } 221 else 222 assertion(false, "Can not setRoot on a non-iterated NodeSequence!"); 223 } 224 225 228 public void reset() 229 { 230 m_next = 0; 231 } 233 234 237 public int getWhatToShow() 238 { 239 return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE) 240 : m_iter.getWhatToShow(); 241 } 242 243 246 public boolean getExpandEntityReferences() 247 { 248 if(null != m_iter) 249 return m_iter.getExpandEntityReferences(); 250 else 251 return true; 252 } 253 254 257 public int nextNode() 258 { 259 NodeVector vec = getVector(); 262 if (null != vec) 263 { 264 if(m_next < vec.size()) 265 { 266 int next = vec.elementAt(m_next); 267 m_next++; 268 return next; 269 } 270 else if((-1 != m_last) || (null == m_iter)) 271 { 272 m_next++; 273 return DTM.NULL; 274 } 275 } 276 277 if (null == m_iter) 278 return DTM.NULL; 279 280 int next = m_iter.nextNode(); 281 if(DTM.NULL != next) 282 { 283 if(hasCache()) 284 { 285 if(m_iter.isDocOrdered()) 286 { 287 getVector().addElement(next); 288 m_next++; 289 } 290 else 291 { 292 int insertIndex = addNodeInDocOrder(next); 293 if(insertIndex >= 0) 294 m_next++; 295 } 296 } 297 else 298 m_next++; 299 } 300 else 301 { 302 m_last = m_next; 303 m_next++; 304 } 305 306 return next; 307 } 308 309 312 public int previousNode() 313 { 314 if(hasCache()) 315 { 316 if(m_next <= 0) 317 return DTM.NULL; 318 else 319 { 320 m_next--; 321 return item(m_next); 322 } 323 } 324 else 325 { 326 int n = m_iter.previousNode(); 327 m_next = m_iter.getCurrentPos(); 328 return m_next; 329 } 330 } 331 332 335 public void detach() 336 { 337 if(null != m_iter) 338 m_iter.detach(); 339 super.detach(); 340 } 341 342 347 public void allowDetachToRelease(boolean allowRelease) 348 { 349 if((false == allowRelease) && !hasCache()) 350 { 351 setShouldCacheNodes(true); 352 } 353 354 if(null != m_iter) 355 m_iter.allowDetachToRelease(allowRelease); 356 super.allowDetachToRelease(allowRelease); 357 } 358 359 362 public int getCurrentNode() 363 { 364 if(hasCache()) 365 { 366 int currentIndex = m_next-1; 367 NodeVector vec = getVector(); 368 if((currentIndex >= 0) && (currentIndex < vec.size())) 369 return vec.elementAt(currentIndex); 370 else 371 return DTM.NULL; 372 } 373 374 if(null != m_iter) 375 { 376 return m_iter.getCurrentNode(); 377 } 378 else 379 return DTM.NULL; 380 } 381 382 385 public boolean isFresh() 386 { 387 return (0 == m_next); 388 } 389 390 393 public void setShouldCacheNodes(boolean b) 394 { 395 if (b) 396 { 397 if(!hasCache()) 398 { 399 SetVector(new NodeVector()); 400 } 401 } 404 else 405 SetVector(null); 406 } 407 408 411 public boolean isMutable() 412 { 413 return hasCache(); } 415 416 419 public int getCurrentPos() 420 { 421 return m_next; 422 } 423 424 427 public void runTo(int index) 428 { 429 int n; 430 431 if (-1 == index) 432 { 433 int pos = m_next; 434 while (DTM.NULL != (n = nextNode())); 435 m_next = pos; 436 } 437 else if(m_next == index) 438 { 439 return; 440 } 441 else if(hasCache() && m_next < getVector().size()) 442 { 443 m_next = index; 444 } 445 else if((null == getVector()) && (index < m_next)) 446 { 447 while ((m_next >= index) && DTM.NULL != (n = previousNode())); 448 } 449 else 450 { 451 while ((m_next < index) && DTM.NULL != (n = nextNode())); 452 } 453 454 } 455 456 459 public void setCurrentPos(int i) 460 { 461 runTo(i); 462 } 463 464 467 public int item(int index) 468 { 469 setCurrentPos(index); 470 int n = nextNode(); 471 m_next = index; 472 return n; 473 } 474 475 478 public void setItem(int node, int index) 479 { 480 NodeVector vec = getVector(); 481 if(null != vec) 482 { 483 vec.setElementAt(node, index); 484 m_last = vec.size(); 485 } 486 else 487 m_iter.setItem(node, index); 488 } 489 490 493 public int getLength() 494 { 495 if(hasCache()) 496 { 497 if (m_iter instanceof NodeSetDTM) 501 { 502 return m_iter.getLength(); 503 } 504 505 if(-1 == m_last) 506 { 507 int pos = m_next; 508 runTo(-1); 509 m_next = pos; 510 } 511 return m_last; 512 } 513 else 514 { 515 return (-1 == m_last) ? (m_last = m_iter.getLength()) : m_last; 516 } 517 } 518 519 523 public DTMIterator cloneWithReset() throws CloneNotSupportedException 524 { 525 NodeSequence seq = (NodeSequence)super.clone(); 526 seq.m_next = 0; 527 return seq; 528 } 529 530 539 public Object clone() throws CloneNotSupportedException 540 { 541 return super.clone(); 542 } 543 544 545 548 public boolean isDocOrdered() 549 { 550 if(null != m_iter) 551 return m_iter.isDocOrdered(); 552 else 553 return true; } 555 556 559 public int getAxis() 560 { 561 if(null != m_iter) 562 return m_iter.getAxis(); 563 else 564 { 565 assertion(false, "Can not getAxis from a non-iterated node sequence!"); 566 return 0; 567 } 568 } 569 570 573 public int getAnalysisBits() 574 { 575 if((null != m_iter) && (m_iter instanceof PathComponent)) 576 return ((PathComponent)m_iter).getAnalysisBits(); 577 else 578 return 0; 579 } 580 581 584 public void fixupVariables(Vector vars, int globalsSize) 585 { 586 super.fixupVariables(vars, globalsSize); 587 } 588 589 602 protected int addNodeInDocOrder(int node) 603 { 604 assertion(hasCache(), "addNodeInDocOrder must be done on a mutable sequence!"); 605 606 int insertIndex = -1; 607 608 NodeVector vec = getVector(); 609 610 int size = vec.size(), i; 614 615 for (i = size - 1; i >= 0; i--) 616 { 617 int child = vec.elementAt(i); 618 619 if (child == node) 620 { 621 i = -2; 623 break; 624 } 625 626 DTM dtm = m_dtmMgr.getDTM(node); 627 if (!dtm.isNodeAfter(node, child)) 628 { 629 break; 630 } 631 } 632 633 if (i != -2) 634 { 635 insertIndex = i + 1; 636 637 vec.insertElementAt(node, insertIndex); 638 } 639 640 return insertIndex; 642 } } 644 645 | Popular Tags |