Source Code Cross Referenced for Step.java in  » Testing » webtest » com » canoo » webtest » steps » 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 » webtest » com.canoo.webtest.steps 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Copyright © 2002-2007 Canoo Engineering AG, Switzerland.
002:        package com.canoo.webtest.steps;
003:
004:        import java.io.Serializable;
005:        import java.util.Date;
006:        import java.util.HashMap;
007:        import java.util.Iterator;
008:        import java.util.Map;
009:        import java.util.TreeMap;
010:
011:        import org.apache.commons.lang.ClassUtils;
012:        import org.apache.commons.lang.StringUtils;
013:        import org.apache.log4j.Logger;
014:        import org.apache.tools.ant.BuildListener;
015:        import org.apache.tools.ant.Task;
016:
017:        import com.canoo.webtest.ant.WebtestTask;
018:        import com.canoo.webtest.engine.Context;
019:        import com.canoo.webtest.engine.EqualsStringVerfier;
020:        import com.canoo.webtest.engine.IStringVerifier;
021:        import com.canoo.webtest.engine.RegExStringVerifier;
022:        import com.canoo.webtest.engine.StepExecutionException;
023:        import com.canoo.webtest.interfaces.IComputeValue;
024:        import com.canoo.webtest.reporting.IStepResultListener;
025:        import com.canoo.webtest.util.Checker;
026:        import com.canoo.webtest.util.MapUtil;
027:        import com.gargoylesoftware.htmlunit.Page;
028:
029:        /**
030:         * Abstract superclass for all test steps. Provides generic services for all subclasses.
031:         *
032:         * @author Carsten Seibert
033:         * @author Marc Guillemot
034:         * @author Paul King, ASERT
035:         * @webtest.step
036:         */
037:        public abstract class Step extends Task implements  Serializable,
038:                Cloneable {
039:            private static final Logger LOG = Logger.getLogger(Step.class);
040:            public static final String ELEMENT_ATTRIBUTE_NAME = "name";
041:            public static final String ELEMENT_ATTRIBUTE_ID = "id";
042:            /**
043:             * @deprecated The default is now not to set  the value at all.
044:             */
045:            public static final String DEFAULT_DESCRIPTION = "<unknown>";
046:
047:            private Date fStarted;
048:            private Date fCompleted;
049:            private boolean fSuccessful;
050:
051:            /**
052:             * The property type is set according to webtest's <em>defaultPropertyType</em>.
053:             */
054:            public static final String PROPERTY_TYPE_DEFAULT = null;
055:            /**
056:             * The property is a <em>dynamic</em> property.
057:             */
058:            public static final String PROPERTY_TYPE_DYNAMIC = "dynamic";
059:            /**
060:             * The property is an <em>ant</em> property.
061:             */
062:            public static final String PROPERTY_TYPE_ANT = "ant";
063:            /**
064:             * The property is an <em>ant</em> property that must not overwrite an existing property.
065:             */
066:            public static final String PROPERTY_TYPE_ANT_STRICT = "antstrict";
067:
068:            /**
069:             * This is the abstract base class for all test step specifications.
070:             */
071:            protected Step() {
072:            }
073:
074:            private void checkSetup() {
075:                Checker.assertNonNull(getProject(), "Project cannot be null");
076:            }
077:
078:            public Context getContext() {
079:                return WebtestTask.getThreadContext();
080:            }
081:
082:            /**
083:             * Called to perform the step's functionality.
084:             * Before calling this method, the step has been completely initialized (including expanding and verifying the parameters)
085:             * and the environment notified of the start.
086:             *
087:             * @throws Exception
088:             */
089:            public abstract void doExecute() throws Exception;
090:
091:            /**
092:             * Ant calls this method to invoke this task's functionality.
093:             * We expand and verify the steps parameters then call doExecute()
094:             * as well as handle lifecycle notifications.
095:             */
096:            public void execute() {
097:                //expandProperties(); FIXME: use PropertyHelper!
098:                checkContextDefined();
099:                notifyStarted();
100:                try {
101:                    verifyParameters();
102:                    doExecute();
103:
104:                    // give time for background js tasks to finish when needed
105:                    final Page currentPage = getContext().getCurrentResponse();
106:                    if (currentPage != null
107:                            && getContext().getConfig().isEasyAjax())
108:                        currentPage.getEnclosingWindow().getThreadManager()
109:                                .joinAll(2000);
110:                } catch (final Exception ex) {
111:                    handleException(ex);
112:                } finally {
113:                    notifyCompleted();
114:                    notifyStepResultsListeners();
115:                }
116:                notifySuccess();
117:            }
118:
119:            private void checkContextDefined() {
120:                if (WebtestTask.getThreadContext() == null) {
121:                    throw new StepExecutionException(
122:                            "Step not inside a webtest", this );
123:                }
124:            }
125:
126:            /**
127:             * Notifies the interested project build listeners (typically only the {@link com.canoo.webtest.reporting.StepExecutionListener})
128:             * that this step has produced results
129:             */
130:            protected void notifyStepResultsListeners() {
131:                final Map results = getComputedParameters();
132:                if (results.isEmpty()) {
133:                    LOG
134:                            .debug("Step didn't produce results, no need to notifying listeners");
135:                    return;
136:                }
137:
138:                for (final Iterator iter = getProject().getBuildListeners()
139:                        .iterator(); iter.hasNext();) {
140:                    final BuildListener listener = (BuildListener) iter.next();
141:                    if (listener instanceof  IStepResultListener) {
142:                        LOG.debug("Notifying " + listener + " of "
143:                                + results.size() + " results");
144:                        ((IStepResultListener) listener).stepResults(results);
145:                    }
146:                }
147:            }
148:
149:            /**
150:             * Called to let the step's implementation validate its parameters.
151:             * The method is called after parameter extensions but before {@link #doExecute()}.
152:             * This implementation does nothing, overwrite as needed.
153:             */
154:            protected void verifyParameters() {
155:                // default is do nothing
156:            }
157:
158:            public boolean hasDescription() {
159:                return StringUtils.isNotEmpty(getDescription());
160:            }
161:
162:            /**
163:             * Gets the description with a prefix and suffix if the description is set.
164:             *
165:             * @param prefix A string to display before the description.
166:             * @param suffix A string to display after the description.
167:             * @return the concatenation of prefix, description and suffix.
168:             */
169:            public String getDescription(final String prefix,
170:                    final String suffix) {
171:                final String description = getDescription();
172:                if (!StringUtils.isNotEmpty(description)) {
173:                    return "";
174:                }
175:                return prefix + description + suffix;
176:            }
177:
178:            /**
179:             * Gets the execution time for a completed step.
180:             *
181:             * @return the execution time in ms
182:             */
183:            public long getDuration() {
184:                return fCompleted.getTime() - fStarted.getTime();
185:            }
186:
187:            protected String getStepLabel() {
188:                return "Step[" + getStepLabelBrief() + "]";
189:            }
190:
191:            private String getStepLabelBrief() {
192:                final StringBuffer message = new StringBuffer();
193:                message.append(getTaskName());
194:                message.append(getDescription(" \"", "\""));
195:                message.append(" (")
196:                        .append(getContext().getCurrentStepNumber())
197:                        .append("/");
198:                message.append(getContext().getNumberOfSteps()).append(")");
199:
200:                return message.toString();
201:            }
202:
203:            public boolean isCompleted() {
204:                return fStarted != null && fCompleted != null;
205:            }
206:
207:            public boolean isStarted() {
208:                return fStarted != null;
209:            }
210:
211:            public boolean isSuccessful() {
212:                return fSuccessful;
213:            }
214:
215:            /**
216:             * Called after {@link #doExecute()} has completed (successfully or not)
217:             */
218:            public void notifyCompleted() {
219:                fCompleted = new Date();
220:                LOG.debug("Completed Step: " + getStepLabelBrief());
221:            }
222:
223:            /**
224:             * Called before calling {@link #doExecute()}
225:             */
226:            public void notifyStarted() {
227:                fStarted = new Date();
228:                LOG.info(">>>> Start Step: " + getStepLabelBrief());
229:            }
230:
231:            public void notifySuccess() {
232:                fSuccessful = true;
233:                LOG.debug("<<<< Successful Step: " + getStepLabelBrief());
234:            }
235:
236:            /**
237:             * @param description
238:             * @deprecated since June 10 2005. Use {@link Task#setDescription(String)}
239:             *             (setter should not be removed for compatibility with existing test sequences)
240:             */
241:            public void setStepid(final String description) {
242:                LOG.warn("'stepid' is deprecated - use 'description' instead");
243:                setDescription(description);
244:            }
245:
246:            public String toString() {
247:                final StringBuffer sb = new StringBuffer(64);
248:
249:                sb.append(ClassUtils.getShortClassName(getClass()));
250:                sb.append(" at ");
251:                sb.append(getLocation().toString());
252:                sb.append(" with (");
253:
254:                final Map parms = getParameterDictionary();
255:
256:                for (final Iterator iter = parms.keySet().iterator(); iter
257:                        .hasNext(); sb.append(", ")) {
258:                    final Object param = iter.next();
259:                    sb.append(param).append("=\"").append(parms.get(param))
260:                            .append("\"");
261:                }
262:                if (!parms.isEmpty()) {
263:                    sb.setLength(sb.length() - 2);
264:                }
265:                sb.append(")");
266:                return sb.toString();
267:            }
268:
269:            protected String getDefaultPropertyType() {
270:                return getContext().getConfig().getDefaultPropertyType();
271:            }
272:
273:            /**
274:             * Sets a property of the default type.
275:             *
276:             * @param name  The name of the property.
277:             * @param value The value of the property.
278:             */
279:            public void setWebtestProperty(final String name, final String value) {
280:                setWebtestProperty(name, value, null);
281:            }
282:
283:            /**
284:             * Sets a property of the default type.
285:             *
286:             * @param name		 The name of the property.
287:             * @param value		The value of the property.
288:             * @param propertyType The kind of property desired. One of {@link #PROPERTY_TYPE_ANT},
289:             *                     {@link #PROPERTY_TYPE_ANT_STRICT}, {@link #PROPERTY_TYPE_DYNAMIC} or {@link #PROPERTY_TYPE_DEFAULT}.
290:             */
291:            public void setWebtestProperty(final String name,
292:                    final String value, final String propertyType) {
293:                final String this PropType = propertyType == PROPERTY_TYPE_DEFAULT ? getDefaultPropertyType()
294:                        : propertyType;
295:
296:                LOG.debug("setWebtestProperty: " + name + "=" + value + " ["
297:                        + this PropType + "]");
298:                if (StringUtils.isEmpty(this PropType)
299:                        || PROPERTY_TYPE_DYNAMIC.equals(this PropType)) {
300:                    getContext().getWebtest().setDynamicProperty(name, value);
301:                    return;
302:                }
303:
304:                if (PROPERTY_TYPE_ANT.equals(this PropType)) {
305:                    checkSetup();
306:                    getProject().setProperty(name, value);
307:                    return;
308:                }
309:
310:                if (PROPERTY_TYPE_ANT_STRICT.equals(this PropType)) {
311:                    checkSetup();
312:                    getProject().setNewProperty(name, value);
313:                    return;
314:                }
315:
316:                throw new StepExecutionException("Unknown propertyType: "
317:                        + this PropType, this );
318:            }
319:
320:            /**
321:             * Gets a property of the default type.
322:             *
323:             * @param name The name of the property.
324:             * @return The value of the property.
325:             */
326:            public String getWebtestProperty(final String name) {
327:                return getWebtestProperty(name, PROPERTY_TYPE_DEFAULT);
328:            }
329:
330:            /**
331:             * Gets a property of the specified type
332:             *
333:             * @param name		 The name of the property.
334:             * @param propertyType The kind of property desired. One of {@link #PROPERTY_TYPE_ANT},
335:             *                     {@link #PROPERTY_TYPE_DYNAMIC} or {@link #PROPERTY_TYPE_DEFAULT}.
336:             * @return The value of the property.
337:             */
338:            public String getWebtestProperty(final String name,
339:                    final String propertyType) {
340:                final String this PropType = propertyType == PROPERTY_TYPE_DEFAULT ? getDefaultPropertyType()
341:                        : propertyType;
342:
343:                LOG.debug("getWebtestProperty(" + name + ") [" + this PropType
344:                        + "]");
345:                if (StringUtils.isEmpty(this PropType)
346:                        || PROPERTY_TYPE_DYNAMIC.equals(this PropType)) {
347:                    return getContext().getWebtest().getDynamicProperty(name);
348:                }
349:
350:                if (this PropType.startsWith(PROPERTY_TYPE_ANT)) {
351:                    checkSetup();
352:                    return getProject().getProperty(name);
353:                }
354:                throw new StepExecutionException("Unknown propertyType: "
355:                        + this PropType, this );
356:            }
357:
358:            public Map getWebtestProperties() {
359:                return getWebtestProperties(null);
360:            }
361:
362:            public Map getWebtestProperties(final String propertyType) {
363:                final String this PropType = propertyType == null ? getDefaultPropertyType()
364:                        : propertyType;
365:
366:                if (StringUtils.isEmpty(this PropType)
367:                        || PROPERTY_TYPE_DYNAMIC.equals(this PropType)) {
368:                    return getContext().getWebtest().getDynamicProperties();
369:                }
370:
371:                if (this PropType.startsWith(PROPERTY_TYPE_ANT)) {
372:                    checkSetup();
373:                    return getProject().getProperties();
374:                }
375:                throw new StepExecutionException("Unknown propertyType: "
376:                        + this PropType, this );
377:            }
378:
379:            /**
380:             * This creates a bitwise copy of the receiver. Since we do not reference
381:             * any complex objects as attributes, the default implementation of
382:             * object will do.
383:             * The mere relay to the super implementation is left in the code as a
384:             * reminder that this needs to be updated as soon as complex objects
385:             * are aggregated right here or in a subclass.
386:             */
387:            public Object clone() throws CloneNotSupportedException {
388:                return super .clone();
389:            }
390:
391:            protected static IStringVerifier getVerifier(final boolean useRegex) {
392:                return useRegex ? RegExStringVerifier.INSTANCE
393:                        : EqualsStringVerfier.INSTANCE;
394:            }
395:
396:            /**
397:             * Called if {@link #doExecute()} throws an exception
398:             * @param t the thrown exception
399:             */
400:            protected void handleException(final Throwable t) {
401:                LOG.debug("Handling exception " + t.getClass().getName() + ": "
402:                        + t.getMessage(), t);
403:                StepUtil.handleException(t);
404:            }
405:
406:            /**
407:             * Throw an exception if the condition holds.
408:             *
409:             * @param condition If true, throws the exception.
410:             * @param message   The error message.
411:             */
412:            protected void paramCheck(final boolean condition,
413:                    final String message) {
414:                if (condition) {
415:                    throw new StepExecutionException(message, this );
416:                }
417:            }
418:
419:            protected void nullParamCheck(final Object param,
420:                    final String paramName) {
421:                paramCheck(param == null, "Required parameter \"" + paramName
422:                        + "\" not set!");
423:            }
424:
425:            protected void emptyParamCheck(final String param,
426:                    final String paramName) {
427:                paramCheck(StringUtils.isEmpty(param), "Required parameter \""
428:                        + paramName + "\" not set or set to empty string!");
429:            }
430:
431:            /**
432:             * Checks that the parameter's value is non negative
433:             *
434:             * @param paramName the name of the parameter
435:             * @param value	 the parameter value
436:             * @throws StepExecutionException if the value is negative
437:             */
438:            protected void positiveOrZeroParamCheck(final int value,
439:                    final String paramName) {
440:                if (value < 0) {
441:                    throw new StepExecutionException(paramName
442:                            + " parameter with value '" + value
443:                            + "' must not be negative", this );
444:                }
445:            }
446:
447:            protected void integerParamCheck(final String param,
448:                    final String paramName, final boolean nonNegative) {
449:                try {
450:                    final int value = Integer.parseInt(param);
451:                    if (nonNegative && value < 0) {
452:                        throw new StepExecutionException(paramName
453:                                + " parameter with value '" + param
454:                                + "' must not be negative", this );
455:                    }
456:                } catch (NumberFormatException e) {
457:                    throw new StepExecutionException("Can't parse " + paramName
458:                            + " parameter with value '" + param
459:                            + "' as an integer.", this );
460:                }
461:            }
462:
463:            protected void optionalIntegerParamCheck(final String param,
464:                    final String paramName, final boolean nonNegative) {
465:                if (!StringUtils.isEmpty(param)) {
466:                    integerParamCheck(param, paramName, nonNegative);
467:                }
468:            }
469:
470:            protected void nullResponseCheck() {
471:                paramCheck(getContext() == null
472:                        || getContext().getCurrentResponse() == null,
473:                        "No current response available! Is previous invoke missing?");
474:            }
475:
476:            /**
477:             * Gets a snapshot of the values.
478:             * As the value of the attributes can change over time,
479:             * it is not possible to fill and cache the Map.
480:             * Either fill the Map everytime, or skip the fields and use only the Map.
481:             * <p>This method returns all the parameters that were discovered at build time and stored in the <em>.attributes</em> resource.
482:             * Overwrite this method if your step doesn't have a  <em>.attributes</em> resource
483:             *
484:             * @return A Map of (attribute name, attribute value) for this step.
485:             */
486:            public Map getParameterDictionary() {
487:                final Map parameterDictionary = new TreeMap(); // to ensure order and make report comparison easier
488:
489:                addComputedParameters(parameterDictionary);
490:                addInternalParameters(parameterDictionary);
491:
492:                return parameterDictionary;
493:            }
494:
495:            /**
496:             * Adds parameters that are not issued from the config file but computed at runtime by the step
497:             *
498:             * @param map the map in which the parameters should be added
499:             */
500:            protected void addComputedParameters(final Map map) {
501:                if (this  instanceof  IComputeValue) {
502:                    final String value = ((IComputeValue) this )
503:                            .getComputedValue();
504:                    MapUtil.putIfNotNull(map, "=> value", value);
505:                }
506:            }
507:
508:            /**
509:             * TODO: would be cleaner to notify the result listener and to give him this information
510:             *
511:             * @return the "results" parameter of the step
512:             */
513:            protected Map getComputedParameters() {
514:                final Map map = new HashMap();
515:                addComputedParameters(map);
516:                return map;
517:            }
518:
519:            private void addInternalParameters(final Map map) {
520:                // add internal parameters
521:                MapUtil.putIfNotNull(map, "taskName", getTaskName());
522:            }
523:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.