001: package com.sun.xml.xsom.impl.scd;
002:
003: import java.util.Iterator;
004: import java.util.NoSuchElementException;
005: import java.util.Set;
006: import java.util.HashSet;
007: import java.util.Collections;
008:
009: /**
010: * Various convenient {@link Iterator} implementations.
011: * @author Kohsuke Kawaguchi
012: */
013: public class Iterators {
014:
015: static abstract class ReadOnly<T> implements Iterator<T> {
016: public final void remove() {
017: throw new UnsupportedOperationException();
018: }
019: }
020:
021: // we need to run on JDK 1.4
022: private static final Iterator EMPTY = Collections.EMPTY_LIST
023: .iterator();
024:
025: public static <T> Iterator<T> empty() {
026: return EMPTY;
027: }
028:
029: public static <T> Iterator<T> singleton(T value) {
030: return new Singleton<T>(value);
031: }
032:
033: /**
034: * {@link Iterator} that returns a single (or no) value.
035: */
036: static final class Singleton<T> extends ReadOnly<T> {
037: private T next;
038:
039: Singleton(T next) {
040: this .next = next;
041: }
042:
043: public boolean hasNext() {
044: return next != null;
045: }
046:
047: public T next() {
048: T r = next;
049: next = null;
050: return r;
051: }
052: }
053:
054: /**
055: * {@link Iterator} that wraps another {@link Iterator} and changes its type.
056: */
057: public static abstract class Adapter<T, U> extends ReadOnly<T> {
058: private final Iterator<? extends U> core;
059:
060: public Adapter(Iterator<? extends U> core) {
061: this .core = core;
062: }
063:
064: public boolean hasNext() {
065: return core.hasNext();
066: }
067:
068: public T next() {
069: return filter(core.next());
070: }
071:
072: protected abstract T filter(U u);
073: }
074:
075: /**
076: * For each U, apply U->Iterator<T> function and then iterate all
077: * the resulting T.
078: */
079: public static abstract class Map<T, U> extends ReadOnly<T> {
080: private final Iterator<? extends U> core;
081:
082: private Iterator<? extends T> current;
083:
084: protected Map(Iterator<? extends U> core) {
085: this .core = core;
086: }
087:
088: public boolean hasNext() {
089: while (current == null || !current.hasNext()) {
090: if (!core.hasNext())
091: return false; // nothing more to enumerate
092: current = apply(core.next());
093: }
094: return true;
095: }
096:
097: public T next() {
098: return current.next();
099: }
100:
101: protected abstract Iterator<? extends T> apply(U u);
102: }
103:
104: /**
105: * Filter out objects from another iterator.
106: */
107: public static abstract class Filter<T> extends ReadOnly<T> {
108: private final Iterator<? extends T> core;
109: private T next;
110:
111: protected Filter(Iterator<? extends T> core) {
112: this .core = core;
113: }
114:
115: /**
116: * Return true to retain the value.
117: */
118: protected abstract boolean matches(T value);
119:
120: public boolean hasNext() {
121: while (core.hasNext() && next == null) {
122: next = core.next();
123: if (!matches(next))
124: next = null;
125: }
126:
127: return next != null;
128: }
129:
130: public T next() {
131: if (next == null)
132: throw new NoSuchElementException();
133: T r = next;
134: next = null;
135: return r;
136: }
137: }
138:
139: /**
140: * Only return unique items.
141: */
142: static final class Unique<T> extends Filter<T> {
143: private Set<T> values = new HashSet<T>();
144:
145: public Unique(Iterator<? extends T> core) {
146: super (core);
147: }
148:
149: protected boolean matches(T value) {
150: return values.add(value);
151: }
152: }
153:
154: /**
155: * Union of two iterators.
156: */
157: public static final class Union<T> extends ReadOnly<T> {
158: private final Iterator<? extends T> first, second;
159:
160: public Union(Iterator<? extends T> first,
161: Iterator<? extends T> second) {
162: this .first = first;
163: this .second = second;
164: }
165:
166: public boolean hasNext() {
167: return first.hasNext() || second.hasNext();
168: }
169:
170: public T next() {
171: if (first.hasNext())
172: return first.next();
173: else
174: return second.next();
175: }
176: }
177:
178: /**
179: * Array iterator.
180: */
181: public static final class Array<T> extends ReadOnly<T> {
182: private final T[] items;
183: private int index = 0;
184:
185: public Array(T[] items) {
186: this .items = items;
187: }
188:
189: public boolean hasNext() {
190: return index < items.length;
191: }
192:
193: public T next() {
194: return items[index++];
195: }
196: }
197: }
|