1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. /*
  17. * $Id: NodeIteratorBase.java,v 1.10 2004/02/16 22:54:59 minchau Exp $
  18. */
  19. package com.sun.org.apache.xalan.internal.xsltc.dom;
  20. import com.sun.org.apache.xalan.internal.xsltc.NodeIterator;
  21. import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
  22. /**
  23. * @author Jacek Ambroziak
  24. * @author Santiago Pericas-Geertsen
  25. * @author Morten Jorgensen
  26. */
  27. public abstract class NodeIteratorBase implements NodeIterator {
  28. /**
  29. * Cached computed value of last().
  30. */
  31. protected int _last = -1;
  32. /**
  33. * Value of position() in this iterator. Incremented in
  34. * returnNode().
  35. */
  36. protected int _position = 0;
  37. /**
  38. * Store node in call to setMark().
  39. */
  40. protected int _markedNode;
  41. /**
  42. * Store node in call to setStartNode().
  43. */
  44. protected int _startNode = NodeIterator.END;
  45. /**
  46. * Flag indicating if "self" should be returned.
  47. */
  48. protected boolean _includeSelf = false;
  49. /**
  50. * Flag indicating if iterator can be restarted.
  51. */
  52. protected boolean _isRestartable = true;
  53. /**
  54. * Setter for _isRestartable flag.
  55. */
  56. public void setRestartable(boolean isRestartable) {
  57. _isRestartable = isRestartable;
  58. }
  59. /**
  60. * Initialize iterator using a node. If iterator is not
  61. * restartable, then do nothing. If node is equal to END then
  62. * subsequent calls to next() must return END.
  63. */
  64. abstract public NodeIterator setStartNode(int node);
  65. /**
  66. * Reset this iterator using state from last call to
  67. * setStartNode().
  68. */
  69. public NodeIterator reset() {
  70. final boolean temp = _isRestartable;
  71. _isRestartable = true;
  72. // Must adjust _startNode if self is included
  73. setStartNode(_includeSelf ? _startNode + 1 : _startNode);
  74. _isRestartable = temp;
  75. return this;
  76. }
  77. /**
  78. * Setter for _includeSelf flag.
  79. */
  80. public NodeIterator includeSelf() {
  81. _includeSelf = true;
  82. return this;
  83. }
  84. /**
  85. * Default implementation of getLast(). Stores current position
  86. * and current node, resets the iterator, counts all nodes and
  87. * restores iterator to original state.
  88. */
  89. public int getLast() {
  90. if (_last == -1) {
  91. final int temp = _position;
  92. setMark();
  93. reset();
  94. do {
  95. _last++;
  96. } while (next() != END);
  97. gotoMark();
  98. _position = temp;
  99. }
  100. return _last;
  101. }
  102. /**
  103. * Returns the position() in this iterator.
  104. */
  105. public int getPosition() {
  106. return _position == 0 ? 1 : _position;
  107. }
  108. /**
  109. * Indicates if position in this iterator is computed in reverse
  110. * document order. Note that nodes are always returned in document
  111. * order.
  112. */
  113. public boolean isReverse() {
  114. return false;
  115. }
  116. /**
  117. * Clones and resets this iterator. Note that the cloned iterator is
  118. * not restartable. This is because cloning is needed for variable
  119. * references, and the context node of the original variable
  120. * declaration must be preserved.
  121. */
  122. public NodeIterator cloneIterator() {
  123. try {
  124. final NodeIteratorBase clone = (NodeIteratorBase)super.clone();
  125. clone._isRestartable = false;
  126. return clone.reset();
  127. }
  128. catch (CloneNotSupportedException e) {
  129. BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  130. e.toString());
  131. return null;
  132. }
  133. }
  134. /**
  135. * Utility method that increments position and returns its
  136. * argument.
  137. */
  138. protected final int returnNode(final int node) {
  139. _position++;
  140. return node;
  141. }
  142. /**
  143. * Reset the position in this iterator.
  144. */
  145. protected final NodeIterator resetPosition() {
  146. _position = 0;
  147. return this;
  148. }
  149. }