package abbot.script.swt;
import java.lang.reflect.Method;
import java.util.HashMap;
import abbot.script.InvalidScriptException;
import abbot.swt.Resolver;
/** Encapsulate an action. Usage:<br>
* <blockquote><code>
* <action method="..." args="..."><br>
* <action method="..." args="widget_id[,...]" class="..."><br>
* </code></blockquote>
* An Action reproduces a user semantic action (such as a mouse click, menu
* selection, or drag/drop action) on a particular Widget. The id of the
* Widget being operated on must be the first argument, and the class of
* that Widget must be identified by the class tag if the action is not
* provided by the base
* <a href="../tester/ComponentTester.html">ComponentTester</a> class.<p>
* Note that the method name is the name of the actionXXX method,
* e.g. to click a button (actionClick on
* AbstractButtonTester), the XML would appear thus:<p>
* <blockquote><code>
* <action method="actionClick" args="My Button" class=javax.swing.AbstractButton><br>
* </code></blockquote>
* Note that if the first argument is a Widget, the class tag is required.
* Note also that the specified class is the <i>tested</i> class, not the
* target class for the method invocation.
*/
// don't put tested class into target class
public class Action extends Call {
public static final String copyright = "Licensed Materials -- Property of IBM\n"+
"(c) Copyright International Business Machines Corporation, 2003\nUS Government "+
"Users Restricted Rights - Use, duplication or disclosure restricted by GSA "+
"ADP Schedule Contract with IBM Corp.";
private static final String USAGE =
"<action method=\"...\" args=\"...\" [class=\"...\"]/>";
/** Provide a default value for the target class name, so that the Call
* parent class won't choke.
*/
private static HashMap patchAttributes(HashMap map) {
if (map.get(TAG_CLASS) == null) {
map.put(TAG_CLASS, "org.eclipse.swt.widgets.Widget");
}
return map;
}
public Action(Resolver resolver, HashMap attributes) {
super(resolver, patchAttributes(attributes));
init();
}
/** Action for a method in the ComponentTester base class. */
public Action(Resolver resolver, String description,
String methodName, String[] args) {
super(resolver, description, "org.eclipse.swt.widgets.Widget", methodName, args);
init();
}
public Action(Resolver resolver, String description,
String methodName, String[] args, Class targetClass) {
super(resolver, description, targetClass.getName(), methodName, args);
init();
}
private void init() {
// account for deprecated usage
String mn = getMethodName();
if (!mn.startsWith("action"))
setMethodName("action" + mn);
}
/** Ensure the default class name is "org.eclipse.swt.widgets.Widget".
* The target class <i>must</i> be a subclass of org.eclipse.swt.widgets.Widget.
*/
public void setTargetClassName(String cn) {
if (cn == null || "".equals(cn))
cn = "org.eclipse.swt.widgets.Widget";
super.setTargetClassName(cn);
}
/** Return the XML tag for this step. */
public String getXMLTag() { return TAG_ACTION; }
/** Return custom attributes for an Action. */
public HashMap getAttributes() {
HashMap map = super.getAttributes();
// Only save the class attribute if it's not the default
map.remove(TAG_CLASS);
if (!getTargetClassName().equals("org.eclipse.swt.widgets.Widget"))
map.put(TAG_CLASS, getTargetClassName());
return map;
}
/** Return the proper XML usage for this step. */
public String getUsage() { return USAGE; }
/** Return a default description for this action. */
protected String getDefaultDescription() {
// strip off "action"
String name = getMethodName().substring(6);
return name + "(" + getEncodedArguments() + ")";
}
public Class getTargetClass() throws InvalidScriptException {
return getTarget().getClass();
}
/** Return the target of the invocation. */
protected Object getTarget() throws InvalidScriptException {
return resolveTester(getTargetClassName());
}
/** Resolve the method name into its final form. */
protected Method getMethod() throws InvalidScriptException {
return resolveMethod(getMethodName(), getTargetClass(), void.class);
}
}