001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xpath.pattern;
030:
031: import com.caucho.log.Log;
032: import com.caucho.xml.XmlUtil;
033: import com.caucho.xpath.ExprEnvironment;
034: import com.caucho.xpath.StylesheetEnv;
035: import com.caucho.xpath.XPathException;
036: import com.caucho.xpath.XPathFun;
037: import com.caucho.xpath.expr.Var;
038:
039: import org.w3c.dom.Attr;
040: import org.w3c.dom.Document;
041: import org.w3c.dom.Node;
042:
043: import java.util.Iterator;
044: import java.util.logging.Level;
045: import java.util.logging.Logger;
046:
047: /**
048: * Iterates through matching nodes.
049: */
050: public abstract class NodeIterator implements ExprEnvironment,
051: Iterator<Node> {
052: protected static final Logger log = Log.open(NodeIterator.class);
053:
054: protected ExprEnvironment _env;
055:
056: protected Node _contextNode;
057: protected int _position;
058: protected int _size;
059:
060: protected NodeIterator(ExprEnvironment env) {
061: /** XXX: children of NodeList implement iterator() for quercus
062: if (env == null)
063: throw new NullPointerException();
064: */
065:
066: _env = env;
067: }
068:
069: /**
070: * True if there's more data.
071: */
072: public abstract boolean hasNext();
073:
074: /**
075: * Returns the next node.
076: */
077: public abstract Node nextNode() throws XPathException;
078:
079: /**
080: * Iterator interface.
081: */
082: public Node next() {
083: Node value = null;
084:
085: try {
086: value = nextNode();
087: } catch (Exception e) {
088: log.log(Level.FINE, e.toString(), e);
089: }
090:
091: return value;
092: }
093:
094: /**
095: * Returns the next selected node.
096: */
097: public SelectedNode nextSelectedNode() throws XPathException {
098: Node node = nextNode();
099:
100: if (node == null)
101: return null;
102: else if (node instanceof Attr)
103: return new SelectedAttribute(node);
104: else
105: return new SelectedNode(node);
106: }
107:
108: /**
109: * Sets the current node.
110: */
111: public Node getCurrentNode() {
112: return _env.getCurrentNode();
113: }
114:
115: /**
116: * Gets the env node.
117: */
118: public Node getContextNode() {
119: if (_contextNode != null)
120: return _contextNode;
121: else
122: return _env.getContextNode();
123: }
124:
125: /**
126: * Sets the env node.
127: */
128: public Node setContextNode(Node node) {
129: Node oldNode = _contextNode;
130: _contextNode = node;
131: return oldNode;
132: }
133:
134: /**
135: * Returns the position of the context node.
136: */
137: public int getContextPosition() {
138: return _position;
139: }
140:
141: /**
142: * Returns the number of nodes in the context list.
143: */
144: public int getContextSize() {
145: if (_size == 0) {
146: _size = _position;
147:
148: NodeIterator clone = (NodeIterator) clone();
149: try {
150: while (clone != null && clone.nextNode() != null)
151: _size++;
152: } catch (XPathException e) {
153: }
154: }
155:
156: return _size;
157: }
158:
159: /**
160: * Returns a document for creating nodes.
161: */
162: public Document getOwnerDocument() {
163: return _env.getOwnerDocument();
164: }
165:
166: /**
167: * Returns the given variable
168: */
169: public Var getVar(String name) {
170: return _env.getVar(name);
171: }
172:
173: /**
174: * Returns the given variable
175: */
176: public XPathFun getFunction(String name) {
177: return _env.getFunction(name);
178: }
179:
180: /**
181: * Returns the stylesheet environment.
182: */
183: public StylesheetEnv getStylesheetEnv() {
184: return _env.getStylesheetEnv();
185: }
186:
187: /**
188: * Returns the given system property.
189: */
190: public Object systemProperty(String namespaceURI, String localName) {
191: return _env.getOwnerDocument();
192: }
193:
194: /**
195: * Returns the string-value of the ndoe.
196: */
197: public String stringValue(Node node) {
198: return XmlUtil.textValue(node);
199: }
200:
201: /**
202: * Returns the position index count.
203: */
204: public int getPositionIndex() {
205: return 0;
206: }
207:
208: /**
209: * Set true if should test more positions.
210: */
211: public void setMorePositions(boolean more) {
212: }
213:
214: /**
215: * clones the iterator
216: */
217: public abstract Object clone();
218:
219: /**
220: * copies the iterator.
221: */
222: public void copy(NodeIterator src) {
223: _env = src._env;
224: _position = src._position;
225: _size = src._size;
226: }
227:
228: /**
229: * remove is unsupported
230: */
231: public void remove() throws UnsupportedOperationException {
232: throw new UnsupportedOperationException();
233: }
234: }
|