001:/*
002: * Copyright (c) 1998-2002 Carnegie Mellon University. All rights
003: * reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * 2. Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: *
017: * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
018: * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
019: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
020: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
021: * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: */
030:
031:package rcm.enum;
032:import java.util.Enumeration;
033:import java.util.NoSuchElementException;
034:import java.util.Vector;
035:
036:/**
037: * Enumeration which transforms the elements of another enumeration.
038: */
039:public abstract class PairEnumeration implements Enumeration {
040: Enumeration e1;
041: Enumeration e2;
042:
043: PairEnumeration history;
044: Vector e1History = new Vector (); // all objects returned by e1
045: Vector e2History = new Vector (); // all objects returned by e2
046:
047: Object r; // last object returned by e1
048: Enumeration e; // enumeration of e2's history
049: boolean swapped = false;
050:
051: Object o; // first object yielded by transform ()
052: Vector v; // other objects yielded by transform ()
053: int i; // next object to return from v
054:
055: int state = INIT;
056: static final int INIT = 0;
057: static final int RUNNING = 1;
058: static final int DONE = 2;
059:
060: public PairEnumeration (Enumeration e1, Enumeration e2) {
061: this .e1 = e1;
062: this .e2 = e2;
063: }
064:
065: public PairEnumeration (Enumeration e1, Enumeration e2, PairEnumeration history) {
066: this .e1 = e1;
067: this .e2 = e2;
068: this .history = history;
069: }
070:
071: public boolean hasMoreElements () {
072: next ();
073: return o != null;
074: }
075:
076: public Object nextElement () {
077: next ();
078: if (o == null)
079: throw new NoSuchElementException ();
080: Object result = o;
081: o = null;
082: return result;
083: }
084:
085: void next () {
086: if (state == INIT) {
087: if (history != null) {
088: if (swapped == history.swapped) {
089: e1History = (Vector) history.e1History.clone ();
090: e2History = (Vector) history.e2History.clone ();
091: } else {
092: e2History = (Vector) history.e1History.clone ();
093: e1History = (Vector) history.e2History.clone ();
094: }
095: }
096:
097: if (!e1.hasMoreElements ())
098: swap ();
099:
100: if (e1.hasMoreElements ()) {
101: r = e1.nextElement ();
102: e = e2History.elements ();
103: state = RUNNING;
104: } else
105: state = DONE;
106: }
107:
108: // check if yielded element is waiting to be returned
109: if (o != null)
110: return;
111:
112: // check in v for other yielded elements
113: if (v != null) {
114: if (i < v.size ()) {
115: o = v.elementAt (i);
116: v.setElementAt (null, i);
117: ++i;
118: } else {
119: v.setSize (0);
120: i = 0;
121: }
122: }
123:
124: // transform more pairs of elements until at least one
125: // output element is yielded
126: while (o == null && state != DONE) {
127: while (o == null && e.hasMoreElements ()) {
128: Object s = e.nextElement ();
129: if (swapped)
130: transform (s, r);
131: else
132: transform (r, s);
133: }
134: if (o != null)
135: return;
136:
137: e1History.addElement (r);
138: if (e2.hasMoreElements ())
139: swap ();
140:
141: if (e1.hasMoreElements ()) {
142: r = e1.nextElement ();
143: e = e2History.elements ();
144: } else
145: state = DONE;
146: }
147: }
148:
149: void swap () {
150: Enumeration te;
151: Vector tv;
152:
153: te = e1;
154: e1 = e2;
155: e2 = te;
156:
157: tv = e1History;
158: e1History = e2History;
159: e2History = tv;
160:
161: swapped = !swapped;
162: }
163:
164: public void yield (Object obj) {
165: if (o == null)
166: o = obj;
167: else {
168: if (v == null)
169: v = new Vector ();
170: v.addElement (obj);
171: }
172: }
173:
174: public abstract void transform (Object o1, Object o2);
175:}
|