/** * Factory method, equivalent to a "fromXML" for step creation. Looks for a class with the same * name as the XML tag, with the first letter capitalized. For example, <call /> is * abbot.script.Call. */ public static Step createStep(Resolver resolver, Element el) throws InvalidScriptException { String tag = el.getName(); Map attributes = createAttributeMap(el); String name = tag.substring(0, 1).toUpperCase() + tag.substring(1); if (tag.equals(TAG_WAIT)) { attributes.put(TAG_WAIT, "true"); name = "Assert"; } try { name = "abbot.script." + name; Log.debug("Instantiating " + name); Class cls = Class.forName(name); try { // Steps with contents require access to the XML element Class[] argTypes = new Class[] {Resolver.class, Element.class, Map.class}; Constructor ctor = cls.getConstructor(argTypes); return (Step) ctor.newInstance(new Object[] {resolver, el, attributes}); } catch (NoSuchMethodException nsm) { // All steps must support this ctor Class[] argTypes = new Class[] {Resolver.class, Map.class}; Constructor ctor = cls.getConstructor(argTypes); return (Step) ctor.newInstance(new Object[] {resolver, attributes}); } } catch (ClassNotFoundException cnf) { String msg = Strings.get("step.unknown_tag", new Object[] {tag}); throw new InvalidScriptException(msg); } catch (InvocationTargetException ite) { Log.warn(ite); throw new InvalidScriptException(ite.getTargetException().getMessage()); } catch (Exception exc) { Log.warn(exc); throw new InvalidScriptException(exc.getMessage()); } }
/** * For use by subclasses when an error is encountered during parsing. Should only be used by the * XML parsing ctors. */ protected void setScriptError(Throwable thr) { if (invalidScriptError == null) { invalidScriptError = thr; } else { Log.warn("More than one script error encountered: " + thr); Log.warn("Already have: " + invalidScriptError); } }
/** Provide a one-line XML string representation. */ public static String toXMLString(XMLifiable obj) { // Comments are the only things that aren't actually elements... if (obj instanceof Comment) { return "<!-- " + ((Comment) obj).getDescription() + " -->"; } Element el = obj.toXML(); StringWriter writer = new StringWriter(); try { XMLOutputter outputter = new XMLOutputter(); outputter.output(el, writer); } catch (IOException io) { Log.warn(io); } return writer.toString(); }
/** Add an attribute to the given XML Element. Attributes are kept in alphabetical order. */ protected Element addAttributes(Element el) { // Use a TreeMap to keep the attributes sorted on output Map atts = new TreeMap(getAttributes()); Iterator iter = atts.keySet().iterator(); while (iter.hasNext()) { String key = (String) iter.next(); String value = (String) atts.get(key); if (value == null) { Log.warn("Attribute '" + key + "' value was null in step " + getXMLTag()); value = ""; } el.setAttribute(key, value); } return el; }
/** Return the semantic recorder for the given component class. */ protected SemanticRecorder getSemanticRecorder(Class cls) { // System.out.println("getting recorder for: " + cls); if (!(Component.class.isAssignableFrom(cls))) { throw new IllegalArgumentException("Class (" + cls + ") must derive from " + "Component"); } SemanticRecorder sr = (SemanticRecorder) semanticRecorders.get(cls); if (sr == null) { Class ccls = Robot.getCanonicalClass(cls); if (ccls != cls) { sr = getSemanticRecorder(ccls); // Additionally cache the mapping from the non-canonical class semanticRecorders.put(cls, sr); return sr; } String cname = Robot.simpleClassName(cls); try { // cname = "abbot.editor.recorder." + cname + "Recorder"; cname = getRecoderName(cname); Class recorderClass = Class.forName(cname); Constructor ctor = recorderClass.getConstructor( new Class[] { Resolver.class, }); sr = (SemanticRecorder) ctor.newInstance(new Object[] {getResolver()}); sr.addActionListener(getListener()); } catch (InvocationTargetException e) { Log.warn(e); } catch (NoSuchMethodException e) { sr = getSemanticRecorder(cls.getSuperclass()); } catch (InstantiationException e) { sr = getSemanticRecorder(cls.getSuperclass()); } catch (IllegalAccessException iae) { sr = getSemanticRecorder(cls.getSuperclass()); } catch (ClassNotFoundException cnf) { sr = getSemanticRecorder(cls.getSuperclass()); } // Cache the results for future reference semanticRecorders.put(cls, sr); } return sr; }
/** Capture the given event as a raw event. */ private void captureRawEvent(AWTEvent event) { // FIXME maybe measure time delay between events and insert delay // events? int id = event.getID(); boolean capture = false; switch (id) { case MouseEvent.MOUSE_PRESSED: case MouseEvent.MOUSE_RELEASED: capture = true; break; case KeyEvent.KEY_PRESSED: case KeyEvent.KEY_RELEASED: KeyEvent e = (KeyEvent) event; capture = e.getKeyCode() != KeyEvent.VK_UNDEFINED; if (!capture) { Log.warn( "VM bug: no valid keycode on key " + (id == KeyEvent.KEY_PRESSED ? "press" : "release")); } break; case MouseEvent.MOUSE_ENTERED: case MouseEvent.MOUSE_EXITED: // case MouseEvent.MOUSE_MOVED: case MouseEvent.MOUSE_DRAGGED: capture = captureMotion; break; default: break; } if (capture) { Event step = new Event(getResolver(), null, event); capturedEvent = event; insertStep(step); setStatus("Added event " + step); } }