001 package net.sf.tacos.components.tree; 002 003 import java.util.ArrayList; 004 import java.util.Collection; 005 import java.util.Collections; 006 import java.util.Iterator; 007 import java.util.List; 008 import java.util.Stack; 009 010 /** 011 * @author phraktle 012 */ 013 public abstract class TreeIterator implements Iterator { 014 015 private final Stack todo = new Stack(); 016 private int depth = 0; 017 private int previousDepth = 0; 018 private int markers = 0; 019 020 /** 021 * New tree 022 * @param rootElement 023 */ 024 public TreeIterator(Object rootElement) 025 { 026 todo.push(rootElement); 027 } 028 029 /** 030 * Tree iterator 031 * @param rootElements 032 */ 033 public TreeIterator(Collection rootElements) 034 { 035 push(rootElements); 036 } 037 038 /** 039 * Depth 040 * @return 041 */ 042 public int getDepth() 043 { 044 return depth; 045 } 046 047 /** 048 * Previous depth 049 * @return 050 */ 051 public int getPreviousDepth() 052 { 053 return previousDepth; 054 } 055 056 /** 057 * 058 * {@inheritDoc} 059 */ 060 public boolean hasNext() 061 { 062 return !todo.isEmpty() && todo.size() != markers; 063 } 064 065 /** 066 * 067 * {@inheritDoc} 068 */ 069 public Object next() 070 { 071 Object node; 072 do { 073 node = todo.pop(); 074 if (node == MARKER) { 075 markers--; 076 } 077 } while(node == MARKER); 078 previousDepth = depth; 079 depth = markers; 080 Collection children = getChildren(node); 081 if (!children.isEmpty()) { 082 todo.push(MARKER); 083 markers++; 084 push(children); 085 } 086 return node; 087 } 088 089 /** 090 * Push set of elements 091 * @param elements 092 */ 093 private void push(Collection elements) 094 { 095 List rev = new ArrayList(elements); 096 Collections.reverse(rev); 097 todo.addAll(rev); 098 } 099 100 /** 101 * Gets children 102 * @param node 103 * @return 104 */ 105 protected abstract Collection getChildren(Object node); 106 107 /** 108 * 109 * {@inheritDoc} 110 */ 111 public void remove() 112 { 113 throw new UnsupportedOperationException(); 114 } 115 116 private final static Object MARKER = new Object(); 117 118 }