package abbot.finder.matchers.swt; import org.eclipse.swt.widgets.Widget; import abbot.tester.swt.Robot; import abbot.tester.swt.RunnableWithResult; /* * I give inheritance from ClassMatcher a try to open discussion about matcher * API at all. Tests on a first glance show (on my machine) that combining * Class type check and name check is considerably faster if combined in the * way shown below. For performance it is necessary to have control * that the least cost check is done first, the class check seems to be extremely * cheap compared to the name check. This is not necessarily obvious * with CompositeMatcher. */ /** * Provides matching of Widgets by widget name and widget class (optional). * <p/> * The name of the widget has to be stored in the widget's data section * by using {@link Widget#setData(java.lang.String, java.lang.Object) * Widget.setData(String key, Object value)}. * The value must be of type String. The key used is the String which can be * obtained by {@link #getNameTag()} and defaults to key="name". * @author Richard Birenheide */ //TODO Offer support for mustbeShowing public class NameMatcher extends ClassMatcher { private static String abbotNameTag = "name"; /** * Provides the possibility to set the name tag globally. * <p/> * The default for the name tag is "name". If this is not allowable for * ones application under test one may change this key generally. * @param nameTag the key under which the names are stored with widgets. * @see Widget#setData(java.lang.String, java.lang.Object) */ public static synchronized void setNameTag(String nameTag) { abbotNameTag = nameTag; } /** * Retrieves the name tag. * <p/> * @return the current name tag used as name key in {@link Widget#getData(java.lang.String)}. * */ public static synchronized String getNameTag() { return abbotNameTag; } private final String name; private final Class clazz; private final String nameKey; /** * Constructs a name matcher with the name given. * <p/> * The name key will be the one valid at the time the constructor is called. * @param name the name to match. */ public NameMatcher(String name) { this(name, null); } /** * Constructs a name matcher with the name and the class given. * <p/> * The name key will be the one valid at the time the constructor is called. * @param name the name to match. * @param clazz the class to match. */ public NameMatcher(String name, Class clazz) { this(name, Widget.class, NameMatcher.getNameTag()); } /** * Constructs a name matcher with the name, class, and name key given. * <p/> * @param name the name to match. * @param clazz the class to match. * @param nameKey the key under which the name of the widget is stored using * {@link Widget#setData(java.lang.String, java.lang.Object)}. */ public NameMatcher(String name, Class clazz, String nameKey) { super(clazz); this.name = name; this.clazz = clazz; this.nameKey = nameKey; } /** * {@inheritDoc} * @param w {@inheritDoc} * @return {@inheritDoc} * @see abbot.finder.swt.Matcher#matches(org.eclipse.swt.widgets.Widget) */ public boolean matches(final Widget w) { if (this.clazz != null) { boolean superResult = super.matches(w); if (!superResult) { return false; } } String name = (String) Robot.syncExec(w.getDisplay(), new RunnableWithResult() { public Object runWithResult() { return w.getData(NameMatcher.this.nameKey); } }); if (name == null) { return false; } return stringsMatch(this.name, name); // foundName = null; // w.getDisplay().syncExec( new Runnable() { public void run() { // foundName = (String)(w.getData("name")); // }}); // if (name == null) // return foundName == null; // return stringsMatch(name, foundName); } public String toString() { return "Name matcher name =" + name + " : tag = " + this.nameKey; } }