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: StepIterator.java,v 1.2.4.1 2005/09/06 10:26:47 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 * A step iterator is used to evaluate expressions like "BOOK/TITLE". 32 * A better name for this iterator would have been ParentIterator since 33 * both "BOOK" and "TITLE" are steps in XPath lingo. Step iterators are 34 * constructed from two other iterators which we are going to refer to 35 * as "outer" and "inner". Every node from the outer iterator (the one 36 * for BOOK in our example) is used to initialize the inner iterator. 37 * After this initialization, every node from the inner iterator is 38 * returned (in essence, implementing a "nested loop"). 39 * @author Jacek Ambroziak 40 * @author Santiago Pericas-Geertsen 41 * @author Erwin Bolwidt <ejb@klomp.org> 42 * @author Morten Jorgensen 43 */ 44 public class StepIterator extends DTMAxisIteratorBase { 45 46 /** 47 * A reference to the "outer" iterator. 48 */ 49 protected DTMAxisIterator _source; 50 51 /** 52 * A reference to the "inner" iterator. 53 */ 54 protected DTMAxisIterator _iterator; 55 56 /** 57 * Temp variable to store a marked position. 58 */ 59 private int _pos = -1; 60 61 public StepIterator(DTMAxisIterator source, DTMAxisIterator iterator) { 62 _source = source; 63 _iterator = iterator; 64 // System.out.println("SI source = " + source + " this = " + this); 65 // System.out.println("SI iterator = " + iterator + " this = " + this); 66 } 67 68 69 public void setRestartable(boolean isRestartable) { 70 _isRestartable = isRestartable; 71 _source.setRestartable(isRestartable); 72 _iterator.setRestartable(true); // must be restartable 73 } 74 75 public DTMAxisIterator cloneIterator() { 76 _isRestartable = false; 77 try { 78 final StepIterator clone = (StepIterator) super.clone(); 79 clone._source = _source.cloneIterator(); 80 clone._iterator = _iterator.cloneIterator(); 81 clone._iterator.setRestartable(true); // must be restartable 82 clone._isRestartable = false; 83 return clone.reset(); 84 } 85 catch (CloneNotSupportedException e) { 86 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 87 e.toString()); 88 return null; 89 } 90 } 91 92 public DTMAxisIterator setStartNode(int node) { 93 if (_isRestartable) { 94 // Set start node for left-hand iterator... 95 _source.setStartNode(_startNode = node); 96 97 // ... and get start node for right-hand iterator from left-hand, 98 // with special case for //* path - see ParentLocationPath 99 _iterator.setStartNode(_includeSelf ? _startNode : _source.next()); 100 return resetPosition(); 101 } 102 return this; 103 } 104 105 public DTMAxisIterator reset() { 106 _source.reset(); 107 // Special case for //* path - see ParentLocationPath 108 _iterator.setStartNode(_includeSelf ? _startNode : _source.next()); 109 return resetPosition(); 110 } 111 112 public int next() { 113 for (int node;;) { 114 // Try to get another node from the right-hand iterator 115 if ((node = _iterator.next()) != END) { 116 return returnNode(node); 117 } 118 // If not, get the next starting point from left-hand iterator... 119 else if ((node = _source.next()) == END) { 120 return END; 121 } 122 // ...and pass it on to the right-hand iterator 123 else { 124 _iterator.setStartNode(node); 125 } 126 } 127 } 128 129 public void setMark() { 130 _source.setMark(); 131 _iterator.setMark(); 132 //_pos = _position; 133 } 134 135 public void gotoMark() { 136 _source.gotoMark(); 137 _iterator.gotoMark(); 138 //_position = _pos; 139 } 140 }