/* ** $Id$ ** ** Class History ** ** Date Name Description ** ---------|------------|----------------------------------------------- ** 15Nov98 subtle created ** */ package key.util; import java.util.Enumeration; import java.util.EmptyStackException; import java.util.Stack; /** * This is a special type of enumerator filter that will * unroll other enumerations that are encountered as * elements. * * For instance, using this on a Vector enumerator, * where the vector contains Enumerations, would * cause a loop through all of each of those enumerations * in turn. * * At the moment, only a shallow unroll is done - to * unroll deeply, each of the sub enumerations should * also be wrapped in this class. */ public final class RecursiveEnumeration implements Enumeration { Enumeration e; Enumeration recurse; Object next; boolean goDeep; Stack st = null; Observer teo = null; /** * @param enum the enumeration to walk through * @param deep recurse deeply through the tree (more than just one level?) * @param o a callback that can be notified as we step into different * enumerations (may be null) */ public RecursiveEnumeration( Enumeration enum, boolean deep, Observer o ) { e = enum; goDeep = deep; teo = o; scanNext(); } public boolean hasMoreElements() { return( next != null ); } private void scanNext() { if( recurse != null && recurse.hasMoreElements() ) { next = recurse.nextElement(); if( goDeep && next instanceof Enumeration ) { if( st == null ) st = new Stack(); st.push( recurse ); recurse = (Enumeration) next; if( teo != null ) teo.notify( recurse, st.size() ); scanNext(); } } else { if( st != null ) { if( !st.empty() ) { recurse = (Enumeration) st.pop(); scanNext(); return; } else st = null; } if( e.hasMoreElements() ) { next = e.nextElement(); if( next instanceof Enumeration ) { recurse = (Enumeration) next; if( teo != null ) teo.notify( recurse, (st != null) ? st.size() : 0 ); scanNext(); } else recurse = null; } else next = null; } } public Object nextElement() { if( next != null ) { Object n = next; scanNext(); return( n ); } else throw new java.util.NoSuchElementException(); } public static interface Observer { /** * @param steppingInto the enumeration we're about to * walk through * @param depth the depth that this enumeration is at. top * level enumerations are at depth 0. */ public void notify( Enumeration steppingInto, int depth ); } }