001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v1.util;
024:
025: import java.util.*;
026: import com.mchange.v1.util.DebugUtils;
027:
028: /**
029: * This implementation does not yet support removes once hasNext() has
030: * been called... will add if necessary.
031: */
032: public abstract class WrapperIterator implements Iterator {
033: protected final static Object SKIP_TOKEN = new Object();
034:
035: final static boolean DEBUG = true;
036:
037: Iterator inner;
038: boolean supports_remove;
039: Object lastOut = null;
040: Object nextOut = SKIP_TOKEN;
041:
042: public WrapperIterator(Iterator inner, boolean supports_remove) {
043: this .inner = inner;
044: this .supports_remove = supports_remove;
045: }
046:
047: public WrapperIterator(Iterator inner) {
048: this (inner, false);
049: }
050:
051: public boolean hasNext() {
052: findNext();
053: return nextOut != SKIP_TOKEN;
054: }
055:
056: private void findNext() {
057: if (nextOut == SKIP_TOKEN) {
058: while (inner.hasNext() && nextOut == SKIP_TOKEN)
059: this .nextOut = transformObject(inner.next());
060: }
061: }
062:
063: public Object next() {
064: findNext();
065: if (nextOut != SKIP_TOKEN) {
066: lastOut = nextOut;
067: nextOut = SKIP_TOKEN;
068: } else
069: throw new NoSuchElementException();
070:
071: //postcondition
072: if (DEBUG)
073: DebugUtils.myAssert(nextOut == SKIP_TOKEN
074: && lastOut != SKIP_TOKEN);
075: return lastOut;
076: }
077:
078: public void remove() {
079: if (supports_remove) {
080: if (nextOut != SKIP_TOKEN)
081: throw new UnsupportedOperationException(this .getClass()
082: .getName()
083: + " cannot support remove after"
084: + " hasNext() has been called!");
085: if (lastOut != SKIP_TOKEN)
086: inner.remove();
087: else
088: throw new NoSuchElementException();
089: } else
090: throw new UnsupportedOperationException();
091: }
092:
093: /**
094: * return SKIP_TOKEN to indicate an object should be
095: * skipped, i.e., not exposed as part of the iterator.
096: * (we don't use null, because we want to support iterators
097: * over null-accepting Collections.)
098: */
099: protected abstract Object transformObject(Object o);
100: }
|