/* * (c) Rob Gordon 2005 */ package org.oddjob.tools; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.log4j.Logger; import org.oddjob.Structural; import org.oddjob.structural.StructuralEvent; import org.oddjob.structural.StructuralListener; /** * Utility class to wait for a certain number of children to be * added to a structural node. * */ public class WaitForChildren implements StructuralListener { private static final Logger logger = Logger.getLogger(WaitForChildren.class); private final Structural structural; private List<Object> children; private final int retry = 3; public WaitForChildren(Object o) { structural = (Structural) o; } public void waitFor(int count) { children = new ArrayList<Object>(); structural.addStructuralListener(this); try { synchronized (this) { for (int i = 0; i < retry && children.size() != count; ++i) { logger.debug("Waiting for [" + structural + "] to have [" + count + "] children (has " + children.size() + ")"); wait(5000); } if (children.size() != count) { throw new RuntimeException("Giving up waiting for [ + " + structural + "] to have [" + count + "] children. Children so far: " + Arrays.toString(children.toArray( new Object[children.size()]))); } } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { structural.removeStructuralListener(this); } } synchronized public Object[] children() { return children.toArray(); } synchronized public void childAdded(StructuralEvent event) { logger.debug("Child [" + event.getIndex() + "] adding [" + event.getChild() + "]"); try { children.add(event.getIndex(), event.getChild()); } catch (IndexOutOfBoundsException e) { throw new IndexOutOfBoundsException("Failed adding child to [" + structural + "] " + e.getMessage()); } notifyAll(); } synchronized public void childRemoved(StructuralEvent event) { logger.debug("Child [" + event.getIndex() + "] removed [" + event.getChild() + "]"); try { children.remove(event.getIndex()); } catch (IndexOutOfBoundsException e) { throw new IndexOutOfBoundsException("Failed removing child from [" + structural + "] " + e.getMessage()); } notifyAll(); } }