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