001: package abbot.script;
002:
003: import java.awt.*;
004: import java.awt.event.*;
005: import java.util.*;
006:
007: import abbot.*;
008: import abbot.finder.*;
009: import abbot.tester.ComponentTester;
010: import abbot.util.AWT;
011:
012: /** Script step to generate a single AWT event to a component. Currently
013: * used for key down/up and mouse motion.
014: */
015: // TODO: Save mouse motion/enter/leave as relative to containing window/frame,
016: // in case frame moves
017: public class Event extends Step {
018: private static final String USAGE = "<event type=\"...\" kind=\"...\" [...]/>";
019:
020: private String componentID = null;
021: private String type = null;
022: private String kind = null;
023: private Map eventAttributes = new HashMap();
024:
025: public Event(Resolver resolver, Map attributes) {
026: super (resolver, attributes);
027: componentID = (String) attributes.get(TAG_COMPONENT);
028: // can't create events without a component, so creation of the event
029: // is deferred. we do check for validity, though.
030: parseEvent(attributes);
031: }
032:
033: /** Create one based on the given event. */
034: public Event(Resolver resolver, String desc, AWTEvent event) {
035: super (resolver, desc);
036: int id = event.getID();
037: type = simpleClassName(event.getClass());
038: kind = ComponentTester.getEventID(event);
039: Component comp = ((ComponentEvent) event).getComponent();
040: if (event instanceof MouseEvent) {
041: MouseEvent me = (MouseEvent) event;
042: ComponentReference ref = resolver.addComponent(comp);
043: componentID = ref.getID();
044: eventAttributes.put(TAG_X, String.valueOf(me.getX()));
045: eventAttributes.put(TAG_Y, String.valueOf(me.getY()));
046: // Convert enter/exit to mouse moved
047: if (id == MouseEvent.MOUSE_ENTERED
048: || id == MouseEvent.MOUSE_EXITED
049: || id == MouseEvent.MOUSE_DRAGGED)
050: kind = "MOUSE_MOVED";
051: // No need to include modifiers in a captured event; it is assumed
052: // that the modifiers are captured separately
053: if (me.isPopupTrigger())
054: eventAttributes.put(TAG_TRIGGER, "true");
055: } else if (event instanceof KeyEvent) {
056: KeyEvent ke = (KeyEvent) event;
057: ComponentReference ref = resolver.addComponent(comp);
058: componentID = ref.getID();
059: if (ke.getModifiers() != 0) {
060: eventAttributes
061: .put(TAG_MODIFIERS, AWT.getModifiers(ke));
062: }
063: if (id == KeyEvent.KEY_TYPED) {
064: // Must encode keychars (e.g. '<')
065: eventAttributes.put(TAG_KEYCHAR, String.valueOf(ke
066: .getKeyChar()));
067: } else {
068: eventAttributes.put(TAG_KEYCODE, AWT.getKeyCode(ke
069: .getKeyCode()));
070: }
071: } else {
072: throw new IllegalArgumentException(
073: "Unimplemented event type " + event);
074: }
075: }
076:
077: public String getDefaultDescription() {
078: String desc = type + "." + kind;
079: if (type.equals("KeyEvent"))
080: desc += " (" + eventAttributes.get(TAG_KEYCODE) + ")";
081: if (componentID != null)
082: desc += " on ${" + componentID + "}";
083: return desc;
084: }
085:
086: public String getXMLTag() {
087: return TAG_EVENT;
088: }
089:
090: public String getUsage() {
091: return USAGE;
092: }
093:
094: public Map getAttributes() {
095: Map map = super .getAttributes();
096: map.put(TAG_COMPONENT, componentID);
097: map.put(TAG_TYPE, type);
098: if (kind != null)
099: map.put(TAG_KIND, kind);
100: map.putAll(eventAttributes);
101: return map;
102: }
103:
104: /** Send our event to the component's event queue. */
105: public void runStep() throws Throwable {
106: ComponentTester.getTester(java.awt.Component.class).sendEvent(
107: createEvent(System.currentTimeMillis()));
108: }
109:
110: /** Validate the attributes are sufficient to construct an event. */
111: private void parseEvent(Map map) {
112: type = (String) map.get(TAG_TYPE);
113: componentID = (String) map.get(TAG_COMPONENT);
114: kind = (String) map.get(TAG_KIND);
115: if (type == null)
116: usage("AWT event type missing");
117: if (type.endsWith("MouseEvent")) {
118: String modifiers = (String) map.get(TAG_MODIFIERS);
119: String x = (String) map.get(TAG_X);
120: String y = (String) map.get(TAG_Y);
121: String count = (String) map.get(TAG_COUNT);
122: String trigger = (String) map.get(TAG_TRIGGER);
123: if (kind == null)
124: usage("MouseEvent must specify a kind");
125: if (modifiers != null)
126: eventAttributes.put(TAG_MODIFIERS, modifiers);
127: if (x != null)
128: eventAttributes.put(TAG_X, x);
129: if (y != null)
130: eventAttributes.put(TAG_Y, y);
131: if (count != null)
132: eventAttributes.put(TAG_COUNT, count);
133: if (trigger != null)
134: eventAttributes.put(TAG_TRIGGER, trigger);
135: if (type.equals("MenuDragMouseEvent")) {
136: // FIXME
137: }
138: } else if (type.equals("KeyEvent")) {
139: if (kind == null)
140: usage("KeyEvent must specify a kind");
141: String keyCode = (String) map.get(TAG_KEYCODE);
142: String modifiers = (String) map.get(TAG_MODIFIERS);
143: // Saved characters might be XML-encoded
144: String keyChar = (String) map.get(TAG_KEYCHAR);
145: if (keyCode == null) {
146: if (!kind.equals("KEY_TYPED"))
147: usage("KeyPress/Release require a keyCode");
148: } else if (!kind.equals("KEY_TYPED"))
149: eventAttributes.put(TAG_KEYCODE, keyCode);
150: if (keyChar == null) {
151: if (kind.equals("KEY_TYPED"))
152: usage("KeyTyped requires a keyChar");
153: } else if (kind.equals("KEY_TYPED")) {
154: eventAttributes.put(TAG_KEYCHAR, keyChar);
155: }
156: if (modifiers != null && !"".equals(modifiers)) {
157: eventAttributes.put(TAG_MODIFIERS, modifiers);
158: }
159: }
160: // FIXME what others are important? window events?
161: else {
162: Log.warn("Unimplemented event type '" + type
163: + "', placeholder");
164: //usage("Unimplemented event type '" + type + "'");
165: }
166: }
167:
168: /** Resolve the given name into a component. */
169: protected java.awt.Component resolve(String name)
170: throws NoSuchReferenceException,
171: ComponentNotFoundException,
172: MultipleComponentsFoundException {
173: ComponentReference ref = getResolver().getComponentReference(
174: name);
175: if (ref != null) {
176: return ref.getComponent();
177: }
178: throw new NoSuchReferenceException(name);
179: }
180:
181: /** Create an event based on the parameters we've collected */
182: private AWTEvent createEvent(long timestamp)
183: throws ComponentSearchException, NoSuchReferenceException {
184: Component comp = null;
185: if (componentID != null) {
186: comp = resolve(componentID);
187: }
188: long when = timestamp;
189: if (type.endsWith("MouseEvent")) {
190: int x = (comp.getSize().width + 1) / 2;
191: int y = (comp.getSize().height + 1) / 2;
192: int count = 1;
193: boolean trigger = false;
194: String modifiers = (String) eventAttributes
195: .get(TAG_MODIFIERS);
196: int mods = modifiers != null ? AWT.getModifiers(modifiers)
197: : 0;
198: try {
199: x = Integer.parseInt((String) eventAttributes
200: .get(TAG_X));
201: } catch (Exception exc) {
202: }
203: try {
204: y = Integer.parseInt((String) eventAttributes
205: .get(TAG_Y));
206: } catch (Exception exc) {
207: }
208: try {
209: count = Integer.parseInt((String) eventAttributes
210: .get(TAG_COUNT));
211: } catch (Exception exc) {
212: }
213: try {
214: trigger = Boolean.getBoolean((String) eventAttributes
215: .get(TAG_TRIGGER));
216: } catch (Exception exc) {
217: }
218: int id = ComponentTester.getEventID(MouseEvent.class, kind);
219: return new MouseEvent(comp, id, when, mods, x, y, count,
220: trigger);
221: } else if (type.equals("KeyEvent")) {
222: String modifiers = (String) eventAttributes
223: .get(TAG_MODIFIERS);
224: int mods = modifiers != null ? AWT.getModifiers(modifiers)
225: : 0;
226: int code = AWT.getKeyCode((String) eventAttributes
227: .get(TAG_KEYCODE));
228: String ch = (String) eventAttributes.get(TAG_KEYCHAR);
229: char keyChar = ch != null ? ch.charAt(0) : (char) code;
230: int id = ComponentTester.getEventID(KeyEvent.class, kind);
231: return new KeyEvent(comp, id, when, mods, code, keyChar);
232: }
233: throw new IllegalArgumentException("Bad event type " + type);
234: }
235:
236: public String getType() {
237: return type;
238: }
239:
240: public void setType(String type) {
241: this .type = type;
242: }
243:
244: public String getKind() {
245: return kind;
246: }
247:
248: public void setKind(String kind) {
249: this .kind = kind;
250: }
251:
252: public String getComponentID() {
253: return componentID;
254: }
255:
256: public void setComponentID(String id) {
257: componentID = id;
258: }
259:
260: public String getAttribute(String tag) {
261: return (String) eventAttributes.get(tag);
262: }
263:
264: public void setAttribute(String tag, String value) {
265: eventAttributes.put(tag, value);
266: }
267: }
|