001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: NodeIteratorBase.java 468651 2006-10-28 07:04:25Z minchau $ 020 */ 021 022 package org.apache.xalan.xsltc.dom; 023 024 import org.apache.xalan.xsltc.NodeIterator; 025 import org.apache.xalan.xsltc.runtime.BasisLibrary; 026 027 /** 028 * @author Jacek Ambroziak 029 * @author Santiago Pericas-Geertsen 030 * @author Morten Jorgensen 031 */ 032 public abstract class NodeIteratorBase implements NodeIterator { 033 034 /** 035 * Cached computed value of last(). 036 */ 037 protected int _last = -1; 038 039 /** 040 * Value of position() in this iterator. Incremented in 041 * returnNode(). 042 */ 043 protected int _position = 0; 044 045 /** 046 * Store node in call to setMark(). 047 */ 048 protected int _markedNode; 049 050 /** 051 * Store node in call to setStartNode(). 052 */ 053 protected int _startNode = NodeIterator.END; 054 055 /** 056 * Flag indicating if "self" should be returned. 057 */ 058 protected boolean _includeSelf = false; 059 060 /** 061 * Flag indicating if iterator can be restarted. 062 */ 063 protected boolean _isRestartable = true; 064 065 /** 066 * Setter for _isRestartable flag. 067 */ 068 public void setRestartable(boolean isRestartable) { 069 _isRestartable = isRestartable; 070 } 071 072 /** 073 * Initialize iterator using a node. If iterator is not 074 * restartable, then do nothing. If node is equal to END then 075 * subsequent calls to next() must return END. 076 */ 077 abstract public NodeIterator setStartNode(int node); 078 079 /** 080 * Reset this iterator using state from last call to 081 * setStartNode(). 082 */ 083 public NodeIterator reset() { 084 final boolean temp = _isRestartable; 085 _isRestartable = true; 086 // Must adjust _startNode if self is included 087 setStartNode(_includeSelf ? _startNode + 1 : _startNode); 088 _isRestartable = temp; 089 return this; 090 } 091 092 /** 093 * Setter for _includeSelf flag. 094 */ 095 public NodeIterator includeSelf() { 096 _includeSelf = true; 097 return this; 098 } 099 100 /** 101 * Default implementation of getLast(). Stores current position 102 * and current node, resets the iterator, counts all nodes and 103 * restores iterator to original state. 104 */ 105 public int getLast() { 106 if (_last == -1) { 107 final int temp = _position; 108 setMark(); 109 reset(); 110 do { 111 _last++; 112 } while (next() != END); 113 gotoMark(); 114 _position = temp; 115 } 116 return _last; 117 } 118 119 /** 120 * Returns the position() in this iterator. 121 */ 122 public int getPosition() { 123 return _position == 0 ? 1 : _position; 124 } 125 126 /** 127 * Indicates if position in this iterator is computed in reverse 128 * document order. Note that nodes are always returned in document 129 * order. 130 */ 131 public boolean isReverse() { 132 return false; 133 } 134 135 /** 136 * Clones and resets this iterator. Note that the cloned iterator is 137 * not restartable. This is because cloning is needed for variable 138 * references, and the context node of the original variable 139 * declaration must be preserved. 140 */ 141 public NodeIterator cloneIterator() { 142 try { 143 final NodeIteratorBase clone = (NodeIteratorBase)super.clone(); 144 clone._isRestartable = false; 145 return clone.reset(); 146 } 147 catch (CloneNotSupportedException e) { 148 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR, 149 e.toString()); 150 return null; 151 } 152 } 153 154 /** 155 * Utility method that increments position and returns its 156 * argument. 157 */ 158 protected final int returnNode(final int node) { 159 _position++; 160 return node; 161 } 162 163 /** 164 * Reset the position in this iterator. 165 */ 166 protected final NodeIterator resetPosition() { 167 _position = 0; 168 return this; 169 } 170 }