1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22package com.sun.org.apache.xalan.internal.xsltc.dom; 23 24import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary; 25import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 26import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase; 27 28/** 29 * This is a special kind of iterator that takes a source iterator and a 30 * node N. If initialized with a node M (the parent of N) it computes the 31 * position of N amongst the children of M. This position can be obtained 32 * by calling getPosition(). 33 * It is an iterator even though next() will never be called. It is used to 34 * match patterns with a single predicate like: 35 * 36 * BOOK[position() = last()] 37 * 38 * In this example, the source iterator will return elements of type BOOK, 39 * a call to position() will return the position of N. Notice that because 40 * of the way the pattern matching is implemented, N will always be a node 41 * in the source since (i) it is a BOOK or the test sequence would not be 42 * considered and (ii) the source iterator is initialized with M which is 43 * the parent of N. Also, and still in this example, a call to last() will 44 * return the number of elements in the source (i.e. the number of BOOKs). 45 * @author Jacek Ambroziak 46 * @author Santiago Pericas-Geertsen 47 */ 48public final class MatchingIterator extends DTMAxisIteratorBase { 49 50 /** 51 * A reference to a source iterator. 52 */ 53 private DTMAxisIterator _source; 54 55 /** 56 * The node to match. 57 */ 58 private final int _match; 59 60 public MatchingIterator(int match, DTMAxisIterator source) { 61 _source = source; 62 _match = match; 63 } 64 65 66 public void setRestartable(boolean isRestartable) { 67 _isRestartable = isRestartable; 68 _source.setRestartable(isRestartable); 69 } 70 71 public DTMAxisIterator cloneIterator() { 72 73 try { 74 final MatchingIterator clone = (MatchingIterator) super.clone(); 75 clone._source = _source.cloneIterator(); 76 clone._isRestartable = false; 77 return clone.reset(); 78 } 79 catch (CloneNotSupportedException e) { 80 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 81 e.toString()); 82 return null; 83 } 84 } 85 86 public DTMAxisIterator setStartNode(int node) { 87 if (_isRestartable) { 88 // iterator is not a clone 89 _source.setStartNode(node); 90 91 // Calculate the position of the node in the set 92 _position = 1; 93 while ((node = _source.next()) != END && node != _match) { 94 _position++; 95 } 96 } 97 return this; 98 } 99 100 public DTMAxisIterator reset() { 101 _source.reset(); 102 return resetPosition(); 103 } 104 105 public int next() { 106 return _source.next(); 107 } 108 109 public int getLast() { 110 if (_last == -1) { 111 _last = _source.getLast(); 112 } 113 return _last; 114 } 115 116 public int getPosition() { 117 return _position; 118 } 119 120 public void setMark() { 121 _source.setMark(); 122 } 123 124 public void gotoMark() { 125 _source.gotoMark(); 126 } 127} 128