1 pnkfelix 1.1.2.1 // CloneableIterator.java, created Tue Apr 20 15:34:34 1999 by pnkfelix
  2 cananian 1.1.2.4 // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 pnkfelix 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 pnkfelix 1.1.2.1 package harpoon.Util;
  5 pnkfelix 1.1.2.1 
  6 pnkfelix 1.1.2.2 import java.util.LinkedList;
  7 pnkfelix 1.1.2.1 import java.util.Iterator;
  8 pnkfelix 1.1.2.2 import java.util.ListIterator;
  9 pnkfelix 1.1.2.1 import java.util.NoSuchElementException;
 10 pnkfelix 1.1.2.1 
 11 pnkfelix 1.1.2.1 /**
 12 pnkfelix 1.1.2.1    <code>CloneableIterator</code> is a wrapper around
 13 pnkfelix 1.1.2.1    <code>Iterator</code> that is safely <code>Cloneable</code>.
 14 pnkfelix 1.1.2.1    Essentially <code>this</code> and all of the clones of
 15 pnkfelix 1.1.2.1    <code>this</code> share the original <code>Iterator</code> and
 16 pnkfelix 1.1.2.1    maintain a shared list of objects, each keeping a pointer into
 17 pnkfelix 1.1.2.1    their current object in the shared list.  If <code>this</code> or
 18 pnkfelix 1.1.2.1    one of its clones reaches the end of the shared list, it attempts
 19 pnkfelix 1.1.2.1    to add more elements onto the end of the list by extracting them
 20 pnkfelix 1.1.2.1    from the shared <code>Iterator</code>.
 21 pnkfelix 1.1.2.1   
 22 cananian 1.1.2.4  * @author  Felix S. Klock II <pnkfelix@mit.edu>
 23 cananian 1.5      * @version $Id: CloneableIterator.java,v 1.5 2004/02/08 01:56:15 cananian Exp $ */
 24 pnkfelix 1.1.2.2 public class CloneableIterator implements ListIterator, Cloneable {
 25 pnkfelix 1.1.2.2     int index;
 26 pnkfelix 1.1.2.2     Object next;
 27 pnkfelix 1.1.2.1     final Iterator iter;        
 28 pnkfelix 1.1.2.2     final LinkedList list;
 29 pnkfelix 1.1.2.1     
 30 pnkfelix 1.1.2.1     /** Creates a <code>CloneableIterator</code> using
 31 pnkfelix 1.1.2.1         <code>iter</code> as its source. */ 
 32 pnkfelix 1.1.2.1     public CloneableIterator(Iterator iter) {
 33 pnkfelix 1.1.2.3         if (iter instanceof CloneableIterator) {
 34 pnkfelix 1.1.2.3             CloneableIterator citer = (CloneableIterator) iter;
 35 pnkfelix 1.1.2.3             this.iter = citer.iter;
 36 pnkfelix 1.1.2.3             this.list = citer.list;
 37 pnkfelix 1.1.2.3             this.next = citer.next;
 38 pnkfelix 1.1.2.3             this.index = citer.index;
 39 pnkfelix 1.1.2.3         } else {
 40 pnkfelix 1.1.2.3             this.iter = iter;
 41 pnkfelix 1.1.2.3             list = new LinkedList();
 42 pnkfelix 1.1.2.3             if (iter.hasNext()) {
 43 pnkfelix 1.1.2.3                 next = iter.next();
 44 pnkfelix 1.1.2.3                 list.add(next);
 45 pnkfelix 1.1.2.3                 index = 0;
 46 pnkfelix 1.1.2.3             } else {
 47 pnkfelix 1.1.2.3                 next = null;
 48 pnkfelix 1.1.2.3                 index = 0;
 49 pnkfelix 1.1.2.3             }
 50 pnkfelix 1.1.2.2         }
 51 pnkfelix 1.1.2.1     }
 52 pnkfelix 1.1.2.1 
 53 pnkfelix 1.1.2.1     public boolean hasNext() { 
 54 pnkfelix 1.1.2.2         return (next != null);
 55 pnkfelix 1.1.2.1     }
 56 pnkfelix 1.1.2.1     
 57 pnkfelix 1.1.2.1     public Object next() {
 58 pnkfelix 1.1.2.2         if (next != null) {
 59 pnkfelix 1.1.2.2             index++;
 60 pnkfelix 1.1.2.2             Object rtn = next;
 61 pnkfelix 1.1.2.2             if (index < list.size()) {
 62 pnkfelix 1.1.2.2                 next = list.get(index);
 63 pnkfelix 1.1.2.2             } else if (iter.hasNext()) {
 64 pnkfelix 1.1.2.2                 next = iter.next();
 65 pnkfelix 1.1.2.2                 list.add(next);
 66 pnkfelix 1.1.2.2             } else {
 67 pnkfelix 1.1.2.2                 next = null;
 68 pnkfelix 1.1.2.2             }
 69 pnkfelix 1.1.2.2             return rtn;
 70 pnkfelix 1.1.2.1         } else {
 71 pnkfelix 1.1.2.1             throw new NoSuchElementException();
 72 pnkfelix 1.1.2.1         }
 73 pnkfelix 1.1.2.1     }
 74 pnkfelix 1.1.2.2 
 75 pnkfelix 1.1.2.2     public int nextIndex() {
 76 pnkfelix 1.1.2.2         return index;
 77 pnkfelix 1.1.2.2     }
 78 pnkfelix 1.1.2.1     
 79 pnkfelix 1.1.2.2     public boolean hasPrevious() {
 80 pnkfelix 1.1.2.2         return index > 0;
 81 pnkfelix 1.1.2.2     }
 82 pnkfelix 1.1.2.2 
 83 pnkfelix 1.1.2.2     public Object previous() {
 84 pnkfelix 1.1.2.2         if (index > 0) {
 85 pnkfelix 1.1.2.2             index--;
 86 pnkfelix 1.1.2.2             return list.get(index);
 87 pnkfelix 1.1.2.2         } else {
 88 pnkfelix 1.1.2.2             throw new NoSuchElementException();
 89 pnkfelix 1.1.2.2         }
 90 pnkfelix 1.1.2.2     }
 91 pnkfelix 1.1.2.2     
 92 pnkfelix 1.1.2.2     public int previousIndex() {
 93 pnkfelix 1.1.2.2         return index - 1;
 94 pnkfelix 1.1.2.2     }
 95 pnkfelix 1.1.2.1     
 96 cananian 1.5         public CloneableIterator clone() { 
 97 pnkfelix 1.1.2.1         try { 
 98 cananian 1.5                 return (CloneableIterator) super.clone(); 
 99 pnkfelix 1.1.2.1         } catch (CloneNotSupportedException e) {
100 cananian 1.3.2.1             assert false : "Object should always be cloneable";
101 pnkfelix 1.1.2.1             return null;
102 pnkfelix 1.1.2.1         }
103 pnkfelix 1.1.2.1     }
104 pnkfelix 1.1.2.2 
105 pnkfelix 1.1.2.2     public void remove() { throw new UnsupportedOperationException(); }
106 pnkfelix 1.1.2.2     public void add(Object o) { throw new UnsupportedOperationException(); }
107 pnkfelix 1.1.2.2     public void set(Object o) { throw new UnsupportedOperationException(); }
108 pnkfelix 1.1.2.2 
109 pnkfelix 1.1.2.1 }
110 cananian 1.2