Source Code Cross Referenced for Step.java in  » Testing » abbot-1.0.1 » abbot » script » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » abbot 1.0.1 » abbot.script 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package abbot.script;
002:
003:        import java.awt.Component;
004:        import java.io.*;
005:        import java.lang.reflect.*;
006:        import java.util.*;
007:
008:        import org.jdom.*;
009:        import org.jdom.input.SAXBuilder;
010:        import org.jdom.output.XMLOutputter;
011:
012:        import abbot.Log;
013:        import abbot.i18n.Strings;
014:        import abbot.tester.ComponentTester;
015:
016:        /**
017:         * Provides access to one step (line) from a script.  A Step is the basic
018:         * unit of execution.  
019:         * <b>Custom Step classes</b><p>
020:         * All custom {@link Step} classes must supply a {@link Constructor} with the
021:         * signature <code>&lt;init&gt;(${link Resolver}, {@link Map})</code>.  If 
022:         * the step has contents (e.g. {@link Sequence}), then it should also
023:         * provide a {@link Constructor} with the signature
024:         * <code>&lt;init&gt;({@link Resolver}, {@link Element}, {@link Map})</code>.
025:         * <p>
026:         * The XML tag for a given {@link Step} will be used to auto-generate the
027:         * {@link Step} class name, e.g. the tag &lt;aphrodite/&gt; causes the
028:         * parser to create an instance of class <code>abbot.script.Aphrodite</code>,
029:         * using one of the {@link Constructor}s described above. 
030:         * <p>
031:         * All derived classes should include an entry in the
032:         * <a href={@docRoot}/../abbot.xsd>schema</a>, or validation must be turned
033:         * off by setting the System property
034:         * <code>abbot.script.validate=false</code>. 
035:         * <p>
036:         * You can make the custom <code>Aphrodite</code> step do just about anything
037:         * by overriding the {@link #runStep()} method.  
038:         * <p>
039:         * See the source for any {@link Step} implementation in this package for
040:         * examples. 
041:         */
042:        public abstract class Step implements  XMLConstants, XMLifiable,
043:                Serializable {
044:
045:            private String description = null;
046:            private Resolver resolver;
047:            /** Error encountered on parse. */
048:            private Throwable invalidScriptError = null;
049:
050:            public Step(Resolver resolver, Map attributes) {
051:                this (resolver, "");
052:                Log.debug("Instantiating " + getClass());
053:                if (Log.isClassDebugEnabled(Step.class)) {
054:                    Iterator iter = attributes.keySet().iterator();
055:                    while (iter.hasNext()) {
056:                        String key = (String) iter.next();
057:                        Log.debug(key + "=" + attributes.get(key));
058:                    }
059:                }
060:                parseStepAttributes(attributes);
061:            }
062:
063:            public Step(Resolver resolver, String description) {
064:                // Kind of a hack; a Script is its own resolver
065:                if (resolver == null) {
066:                    if (!(this  instanceof  Resolver)) {
067:                        throw new Error("Resolver must be provided");
068:                    }
069:                    resolver = (Resolver) this ;
070:                } else if (this  instanceof  Resolver) {
071:                    resolver = (Resolver) this ;
072:                }
073:                this .resolver = resolver;
074:                if ("".equals(description))
075:                    description = null;
076:                this .description = description;
077:            }
078:
079:            /** Only exposed so that Script may invoke it on load from disk. */
080:            protected final void parseStepAttributes(Map attributes) {
081:                Log.debug("Parsing attributes for " + getClass());
082:                description = (String) attributes.get(TAG_DESC);
083:            }
084:
085:            /** Main run method.  Should <b>never</b> be run on the event dispatch
086:             * thread, although no check is explicitly done here.
087:             */
088:            public final void run() throws Throwable {
089:                if (invalidScriptError != null)
090:                    throw invalidScriptError;
091:                Log.debug("Running " + toString());
092:                runStep();
093:            }
094:
095:            /** Implement the step's behavior here. */
096:            protected abstract void runStep() throws Throwable;
097:
098:            public String getDescription() {
099:                return description != null ? description
100:                        : getDefaultDescription();
101:            }
102:
103:            public void setDescription(String desc) {
104:                description = desc;
105:            }
106:
107:            /** Define the XML tag to use for this script step. */
108:            public abstract String getXMLTag();
109:
110:            /** Provide a usage String for this step. */
111:            public abstract String getUsage();
112:
113:            /** Return a reasonable default description for this script step.
114:                This value is used in the absence of an explicit description. 
115:             */
116:            public abstract String getDefaultDescription();
117:
118:            /** For use by subclasses when an error is encountered during parsing. 
119:             * Should only be used by the XML parsing ctors.
120:             */
121:            protected void setScriptError(Throwable thr) {
122:                if (invalidScriptError == null) {
123:                    invalidScriptError = thr;
124:                } else {
125:                    Log.warn("More than one script error encountered: " + thr);
126:                    Log.warn("Already have: " + invalidScriptError);
127:                }
128:            }
129:
130:            /** Throw an invalid script exception describing the proper script
131:             * usage.  This should be used by derived classes whenever parsing
132:             * indicates invalid input.
133:             */
134:            protected void usage() {
135:                usage(null);
136:            }
137:
138:            /** Store an invalid script exception describing the proper script
139:             * usage.  This should be used by derived classes whenever parsing
140:             * indicates invalid input.  
141:             */
142:            protected void usage(String details) {
143:                String msg = getUsage();
144:                if (details != null) {
145:                    msg = Strings.get("step.usage",
146:                            new Object[] { msg, details });
147:                }
148:                setScriptError(new InvalidScriptException(msg));
149:            }
150:
151:            /** Attributes to save in script. */
152:            public Map getAttributes() {
153:                Map map = new HashMap();
154:                if (description != null
155:                        && !description.equals(getDefaultDescription()))
156:                    map.put(TAG_DESC, description);
157:                return map;
158:            }
159:
160:            public Resolver getResolver() {
161:                return resolver;
162:            }
163:
164:            /** Override if the step actually has some contents.  In most cases, it
165:             * won't.
166:             */
167:            protected Element addContent(Element el) {
168:                return el;
169:            }
170:
171:            /** Add an attribute to the given XML Element.  Attributes are kept in
172:                alphabetical order. */
173:            protected Element addAttributes(Element el) {
174:                // Use a TreeMap to keep the attributes sorted on output
175:                Map atts = new TreeMap(getAttributes());
176:                Iterator iter = atts.keySet().iterator();
177:                while (iter.hasNext()) {
178:                    String key = (String) iter.next();
179:                    String value = (String) atts.get(key);
180:                    if (value == null) {
181:                        Log.warn("Attribute '" + key
182:                                + "' value was null in step " + getXMLTag());
183:                        value = "";
184:                    }
185:                    el.setAttribute(key, value);
186:                }
187:                return el;
188:            }
189:
190:            /** Convert this Step into a String suitable for editing.  The default is
191:                the XML representation of the Step. */
192:            public String toEditableString() {
193:                return toXMLString(this );
194:            }
195:
196:            /** Provide a one-line XML string representation. */
197:            public static String toXMLString(XMLifiable obj) {
198:                // Comments are the only things that aren't actually elements...
199:                if (obj instanceof  Comment) {
200:                    return "<!-- " + ((Comment) obj).getDescription() + " -->";
201:                }
202:                Element el = obj.toXML();
203:                StringWriter writer = new StringWriter();
204:                try {
205:                    XMLOutputter outputter = new XMLOutputter();
206:                    outputter.output(el, writer);
207:                } catch (IOException io) {
208:                    Log.warn(io);
209:                }
210:                return writer.toString();
211:            }
212:
213:            /** Convert the object to XML.  */
214:            public Element toXML() {
215:                return addAttributes(addContent(new Element(getXMLTag())));
216:            }
217:
218:            /** Create a new step from an in-line XML string. */
219:            public static Step createStep(Resolver resolver, String str)
220:                    throws InvalidScriptException, IOException {
221:                StringReader reader = new StringReader(str);
222:                try {
223:                    SAXBuilder builder = new SAXBuilder();
224:                    Document doc = builder.build(reader);
225:                    Element el = doc.getRootElement();
226:                    return createStep(resolver, el);
227:                } catch (JDOMException e) {
228:                    throw new InvalidScriptException(e.getMessage());
229:                }
230:            }
231:
232:            /** Convert the attributes in the given XML Element into a Map of
233:                name/value pairs. */
234:            protected static Map createAttributeMap(Element el) {
235:                Log.debug("Creating attribute map for " + el);
236:                Map attributes = new HashMap();
237:                Iterator iter = el.getAttributes().iterator();
238:                while (iter.hasNext()) {
239:                    Attribute att = (Attribute) iter.next();
240:                    attributes.put(att.getName(), att.getValue());
241:                }
242:                return attributes;
243:            }
244:
245:            /**
246:             * Factory method, equivalent to a "fromXML" for step creation.  Looks for
247:             * a class with the same name as the XML tag, with the first letter
248:             * capitalized.  For example, &lt;call /&gt; is abbot.script.Call.
249:             */
250:            public static Step createStep(Resolver resolver, Element el)
251:                    throws InvalidScriptException {
252:                String tag = el.getName();
253:                Map attributes = createAttributeMap(el);
254:                String name = tag.substring(0, 1).toUpperCase()
255:                        + tag.substring(1);
256:                if (tag.equals(TAG_WAIT)) {
257:                    attributes.put(TAG_WAIT, "true");
258:                    name = "Assert";
259:                }
260:                try {
261:                    name = "abbot.script." + name;
262:                    Log.debug("Instantiating " + name);
263:                    Class cls = Class.forName(name);
264:                    try {
265:                        // Steps with contents require access to the XML element
266:                        Class[] argTypes = new Class[] { Resolver.class,
267:                                Element.class, Map.class };
268:                        Constructor ctor = cls.getConstructor(argTypes);
269:                        return (Step) ctor.newInstance(new Object[] { resolver,
270:                                el, attributes });
271:                    } catch (NoSuchMethodException nsm) {
272:                        // All steps must support this ctor
273:                        Class[] argTypes = new Class[] { Resolver.class,
274:                                Map.class };
275:                        Constructor ctor = cls.getConstructor(argTypes);
276:                        return (Step) ctor.newInstance(new Object[] { resolver,
277:                                attributes });
278:                    }
279:                } catch (ClassNotFoundException cnf) {
280:                    String msg = Strings.get("step.unknown_tag",
281:                            new Object[] { tag });
282:                    throw new InvalidScriptException(msg);
283:                } catch (InvocationTargetException ite) {
284:                    Log.warn(ite);
285:                    throw new InvalidScriptException(ite.getTargetException()
286:                            .getMessage());
287:                } catch (Exception exc) {
288:                    Log.warn(exc);
289:                    throw new InvalidScriptException(exc.getMessage());
290:                }
291:            }
292:
293:            protected String simpleClassName(Class cls) {
294:                return ComponentTester.simpleClassName(cls);
295:            }
296:
297:            /** Return a description of this script step. */
298:            public String toString() {
299:                return getDescription();
300:            }
301:
302:            /** Returns the Class corresponding to the given class name.  Provides
303:             * just-in-time classname resolution to ensure loading by the proper class
304:             * loader. <p>
305:             */
306:            public Class resolveClass(String className)
307:                    throws ClassNotFoundException {
308:                ClassLoader cl = getResolver().getContextClassLoader();
309:                return Class.forName(className, true, cl);
310:            }
311:
312:            /** Look up an appropriate ComponentTester given an arbitrary
313:             * Component-derived class.
314:             * If the class is derived from abbot.tester.ComponentTester, instantiate
315:             * one; if it is derived from java.awt.Component, return a matching Tester.
316:             * Otherwise return abbot.tester.ComponentTester.<p>
317:             * @throws ClassNotFoundException If the given class can't be found.
318:             * @throws IllegalArgumentException If the tester cannot be instantiated.
319:             */
320:            protected ComponentTester resolveTester(String className)
321:                    throws ClassNotFoundException {
322:                Class testedClass = resolveClass(className);
323:                if (Component.class.isAssignableFrom(testedClass))
324:                    return ComponentTester.getTester(testedClass);
325:                else if (ComponentTester.class.isAssignableFrom(testedClass)) {
326:                    try {
327:                        return (ComponentTester) testedClass.newInstance();
328:                    } catch (Exception e) {
329:                        String msg = "Custom ComponentTesters must provide "
330:                                + "an accessible no-args Constructor: "
331:                                + e.getMessage();
332:                        throw new IllegalArgumentException(msg);
333:                    }
334:                }
335:                String msg = "The given class '" + className
336:                        + "' is neither a Component nor a ComponentTester";
337:                throw new IllegalArgumentException(msg);
338:            }
339:
340:            private void writeObject(ObjectOutputStream out) {
341:                // NOTE: this is only to avoid drag/drop errors
342:                out = null;
343:            }
344:
345:            private void readObject(ObjectInputStream in) {
346:                // NOTE: this is only to avoid drag/drop errors
347:                in = null;
348:            }
349:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.