1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.jameleon.data;
21
22 import java.util.Collection;
23
24 import org.apache.log4j.Logger;
25
26 /***
27 * Iterates over all nested tags one time per object in a Collection.
28 * Sometimes you want to data-drive your test, but based on data that is defined
29 * in the application itself. This is a more generic way to data-drive your tags,
30 * based on a Collection of Objects that may be populated into the context via some
31 * other tag.
32 *
33 * For example:
34 * <pre><source>
35 * <testcase xmlns="jelly:jameleon">
36 * <get-data-from-somewhere toVar="listOfAccounts"/>
37 * <iterate varName="someVar" items="${listOfAccounts}">
38 * <some-session application="someApp" beginSession="true">
39 * <some-tag-that-uses-context-variables
40 * functionId="Verify successful navigation, using a different variable."
41 * attribute="${someVar}"/>
42 * </some-session>
43 * </iterate>
44 * </testcase>
45 * </source></pre>
46 *
47 * @author Andrey Chernyshov
48 * @author Christian Hargraves
49 * @jameleon.function name="iterate"
50 */
51 public class IterateTag extends AbstractDataDrivableTag {
52
53 protected CollectionDataDriver dataDriver;
54 protected Collection items;
55 protected String varName;
56 protected String id = "-";
57
58 /***
59 * Gets the logger used for this tag
60 *
61 * @return the logger used for this tag.
62 */
63 protected Logger getLogger() {
64 return Logger.getLogger(IterateTag.class.getName());
65 }
66
67 /***
68 * Gets the DataDriver used for this tag.
69 *
70 * @return the DataDriver used for this tag.
71 */
72 protected DataDriver getDataDriver() {
73 if(dataDriver == null) {
74 dataDriver = new CollectionDataDriver();
75 }
76 return dataDriver;
77 }
78
79 /***
80 * Sets up the DataDriver by calling any implementation-dependent
81 * methods.
82 */
83 protected void setupDataDriver() {
84 dataDriver.setItems(items);
85 dataDriver.setKey(varName);
86 }
87
88 /***
89 * Gets the trace message when the execution is beginning and ending.
90 * The message displayed will already start with BEGIN: or END:
91 *
92 * @return the trace message when the execution is just beginning and ending.
93 */
94 protected String getTagTraceMsg() {
95 StringBuffer msg = new StringBuffer("Iterating over the collection of size ");
96 int size = 0;
97 if(items != null) {
98 size = items.size();
99 }
100 msg.append(size);
101 return msg.toString();
102 }
103
104 /***
105 * Describe the tag when error messages occur.
106 * The most appropriate message might be the tag name itself.
107 *
108 * @return A brief description of the tag or the tag name itself.
109 */
110 public String getTagDescription() {
111 return "iterate tag";
112 }
113
114 /***
115 * Gets an error message to be displayed when a error occurs due to the DataDriver.
116 *
117 * @return an error message to be displayed when a error occurs due to the DataDriver.
118 */
119 protected String getDataExceptionMessage() {
120 return "Trouble iterating over the collection.";
121 }
122
123 /***
124 * Calculates the location of the state to be stored for any tags under this tag.
125 * The result should be a relative path that simply has the row number in it along
126 * with some unique indentifier for this tag like the handle name or something.
127 *
128 * @return the location of the state to be stored for any tags under this tag minus the baseDir calculation stuff.
129 */
130 protected String getNewStateStoreLocation(int rowNum) {
131 return "iterate-"+id+"-"+rowNum;
132 }
133
134 /***
135 * @jameleon.attribute required="true"
136 */
137 public void setItems(Collection items) {
138 this.items = items;
139 }
140
141 /***
142 * @jameleon.attribute required="true"
143 */
144 public void setVarName(String varName) {
145 this.varName = varName;
146 }
147
148 /***
149 * This is primarily used for debugging.
150 * It also provides a means to distinguish between nested <code>IterateTag</code> tags.
151 * @jameleon.attribute required="false"
152 */
153 public void setId(String id) {
154 this.id = id;
155 }
156 }