/******************************************************************************* * Copyright (c) 2012 Google, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Google, Inc. - initial API and implementation *******************************************************************************/ package com.windowtester.internal.swing.locator; import java.awt.Component; import java.awt.Container; import java.awt.Window; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import javax.swing.SwingUtilities; import abbot.finder.AWTHierarchy; import abbot.finder.ComponentFinder; import abbot.finder.ComponentNotFoundException; import abbot.finder.Hierarchy; import abbot.finder.Matcher; import abbot.finder.MultiMatcher; import abbot.finder.MultipleComponentsFoundException; /** Provides basic component lookup, examining each component in turn. Searches all components of interest in a given hierarchy. */ public class BasicFinder2 implements ComponentFinder { private Hierarchy hierarchy; private static final ComponentFinder DEFAULT = new BasicFinder2(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 BasicFinder2() { this(AWTHierarchy.getDefault()); } public BasicFinder2(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) { throw new ComponentNotFoundException("finder.not_found"); } else if (found.size() > 1) { Component[] list = (Component[]) found.toArray(new Component[found.size()]); if (!(m instanceof MultiMatcher)) { throw new MultipleComponentsFoundException("finder.multiple_found", 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); } } /** 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 int findAll(Matcher m){ return findAll(getHierarchy(), m); } protected int findAll(Hierarchy h, Matcher m) { Set found = new HashSet(); Iterator iter = h.getRoots().iterator(); while (iter.hasNext()) { // 2/22/07 : kp check for match only in active window Component c = (Component)iter.next(); if (((Window)c).isActive()) findMatchesAll(h, m, c, found); } if (found.size() == 0) { // component not found ?? return 0; } else if (found.size() > 1) { // multiple components found for the locator return -1; } return 1; } protected void findMatchesAll(Hierarchy h, Matcher m, Component c, Set found) { Iterator iter = h.getComponents(c).iterator(); while (iter.hasNext()) { findMatchesAll(h, m, (Component)iter.next(), found); } if (m.matches(c)) { found.add(c); } } }