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: MatchingIterator.java,v 1.9 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.runtime.BasisLibrary;
  21. import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  22. import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;
  23. /**
  24. * This is a special kind of iterator that takes a source iterator and a
  25. * node N. If initialized with a node M (the parent of N) it computes the
  26. * position of N amongst the children of M. This position can be obtained
  27. * by calling getPosition().
  28. * It is an iterator even though next() will never be called. It is used to
  29. * match patterns with a single predicate like:
  30. *
  31. * BOOK[position() = last()]
  32. *
  33. * In this example, the source iterator will return elements of type BOOK,
  34. * a call to position() will return the position of N. Notice that because
  35. * of the way the pattern matching is implemented, N will always be a node
  36. * in the source since (i) it is a BOOK or the test sequence would not be
  37. * considered and (ii) the source iterator is initialized with M which is
  38. * the parent of N. Also, and still in this example, a call to last() will
  39. * return the number of elements in the source (i.e. the number of BOOKs).
  40. * @author Jacek Ambroziak
  41. * @author Santiago Pericas-Geertsen
  42. */
  43. public final class MatchingIterator extends DTMAxisIteratorBase {
  44. /**
  45. * A reference to a source iterator.
  46. */
  47. private DTMAxisIterator _source;
  48. /**
  49. * The node to match.
  50. */
  51. private final int _match;
  52. public MatchingIterator(int match, DTMAxisIterator source) {
  53. _source = source;
  54. _match = match;
  55. }
  56. public void setRestartable(boolean isRestartable) {
  57. _isRestartable = isRestartable;
  58. _source.setRestartable(isRestartable);
  59. }
  60. public DTMAxisIterator cloneIterator() {
  61. try {
  62. final MatchingIterator clone = (MatchingIterator) super.clone();
  63. clone._source = _source.cloneIterator();
  64. clone._isRestartable = false;
  65. return clone.reset();
  66. }
  67. catch (CloneNotSupportedException e) {
  68. BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  69. e.toString());
  70. return null;
  71. }
  72. }
  73. public DTMAxisIterator setStartNode(int node) {
  74. if (_isRestartable) {
  75. // iterator is not a clone
  76. _source.setStartNode(node);
  77. // Calculate the position of the node in the set
  78. _position = 1;
  79. while ((node = _source.next()) != END && node != _match) {
  80. _position++;
  81. }
  82. }
  83. return this;
  84. }
  85. public DTMAxisIterator reset() {
  86. _source.reset();
  87. return resetPosition();
  88. }
  89. public int next() {
  90. return _source.next();
  91. }
  92. public int getLast() {
  93. if (_last == -1) {
  94. _last = _source.getLast();
  95. }
  96. return _last;
  97. }
  98. public int getPosition() {
  99. return _position;
  100. }
  101. public void setMark() {
  102. _source.setMark();
  103. }
  104. public void gotoMark() {
  105. _source.gotoMark();
  106. }
  107. }