package abbot.finder; import java.awt.Container; import java.awt.Component; import java.awt.Window; import java.util.*; import javax.swing.SwingUtilities; import abbot.i18n.Strings; /** Provides basic component lookup, examining each component in turn. Searches all components of interest in a given hierarchy. */ public class BasicFinder implements ComponentFinder { private Hierarchy hierarchy; private static final ComponentFinder DEFAULT = new BasicFinder(new AWTHierarchy()); public static ComponentFinder getDefault() { return DEFAULT; } private class SingleComponentHierarchy implements Hierarchy { private Component root; private ArrayList list = new ArrayList(); public SingleComponentHierarchy(Container root) { this.root = root; list.add(root); } public Collection getRoots() { return list; } public Collection getComponents(Component c) { return getHierarchy().getComponents(c); } public Container getParent(Component c) { return getHierarchy().getParent(c); } public boolean contains(Component c) { return getHierarchy().contains(c) && SwingUtilities.isDescendingFrom(c, root); } public void dispose(Window w) { getHierarchy().dispose(w); } } public BasicFinder() { this(AWTHierarchy.getDefault()); } public BasicFinder(Hierarchy h) { hierarchy = h; } protected Hierarchy getHierarchy() { return hierarchy; } /** Find a Component, using the given Matcher to determine whether a given component in the hierarchy under the given root is the desired one. */ public Component find(Container root, Matcher m) throws ComponentNotFoundException, MultipleComponentsFoundException { Hierarchy h = root != null ? new SingleComponentHierarchy(root) : getHierarchy(); return find(h, m); } /** Find a Component, using the given Matcher to determine whether a given component in the hierarchy used by this ComponentFinder is the desired one. */ public Component find(Matcher m) throws ComponentNotFoundException, MultipleComponentsFoundException { return find(getHierarchy(), m); } protected Component find(Hierarchy h, Matcher m) throws ComponentNotFoundException, MultipleComponentsFoundException { Set found = new HashSet(); Iterator iter = h.getRoots().iterator(); while (iter.hasNext()) { findMatches(h, m, (Component)iter.next(), found); } if (found.size() == 0) { String msg = Strings.get("finder.not_found", new Object[] { m.toString() }); throw new ComponentNotFoundException(msg); } else if (found.size() > 1) { Component[] list = (Component[]) found.toArray(new Component[found.size()]); if (!(m instanceof MultiMatcher)) { String msg = Strings.get("finder.multiple_found", new Object[] { m.toString() }); throw new MultipleComponentsFoundException(msg, list); } return ((MultiMatcher)m).bestMatch(list); } return (Component)found.iterator().next(); } protected void findMatches(Hierarchy h, Matcher m, Component c, Set found) { if (found.size() == 1 && !(m instanceof MultiMatcher)) return; Iterator iter = h.getComponents(c).iterator(); while (iter.hasNext()) { findMatches(h, m, (Component)iter.next(), found); } if (m.matches(c)) { found.add(c); } } }