1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package junitx.ddtunit.data.processing;
39
40 import java.io.IOException;
41 import java.util.HashMap;
42 import java.util.Map;
43
44 import junitx.ddtunit.data.DDTTestDataException;
45 import junitx.ddtunit.data.DDTDataRepository;
46 import junitx.ddtunit.data.ExceptionAsserter;
47 import junitx.ddtunit.data.IDataSet;
48 import junitx.ddtunit.data.ObjectAsserter;
49 import junitx.ddtunit.data.TestDataSet;
50 import junitx.ddtunit.data.TestGroupDataSet;
51
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.xml.sax.Attributes;
55
56
57
58
59
60
61
62 public class Engine {
63 final static int LEVEL_CLUSTER_GLOBAL_OBJ = 4;
64
65 final static int LEVEL_RESOURCE_OBJ = 3;
66
67 final static int LEVEL_SINGLE_OBJ = 1;
68
69 final static int LEVEL_GROUP = 3;
70
71 final static int LEVEL_GROUP_GLOBAL = 3;
72
73 final static int LEVEL_TEST = 4;
74
75 final static int LEVEL_TEST_OBJS = 5;
76
77 final static int LEVEL_TEST_OBJ = 6;
78
79 private Logger log = LoggerFactory.getLogger(Engine.class);
80
81 private IDataSet clusterDataSet;
82
83
84
85
86
87 private boolean processCluster = false;
88
89 private boolean processResource = false;
90
91 private String clusterId;
92
93 private String groupId;
94
95 private IDataSet actualDataSet;
96
97 private ActionStack actionStack;
98
99 private boolean cdataProcessing;
100
101 private ReferenceProcessor refProcessor;
102
103
104
105
106
107
108 public Engine(IDataSet clusterDataSet) {
109 this.cdataProcessing = false;
110 this.clusterDataSet = clusterDataSet;
111 }
112
113
114
115
116
117
118
119
120
121 public void processStartElement(String qName, Attributes attribs, int level) {
122 Map<String, String> attrMap = getAttrMap(attribs);
123 if (ParserConstants.XML_ELEM_RESOURCES.equals(qName)
124 && level == (LEVEL_RESOURCE_OBJ - 1)) {
125 this.refProcessor = new ReferenceProcessor(this.clusterDataSet);
126 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
127 && level == LEVEL_SINGLE_OBJ) {
128 this.processCluster = true;
129 this.actionStack = new ActionStack();
130 pushAction(qName, attrMap);
131 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
132 && level == LEVEL_RESOURCE_OBJ) {
133 this.processResource = true;
134 this.actionStack = new ActionStack();
135 pushAction(qName, attrMap);
136 } else if (ParserConstants.XML_ELEM_CLUSTER.equals(qName)
137 && this.clusterId.equals(attrMap
138 .get(ParserConstants.XML_ATTR_ID))) {
139 log.debug("Found clusterid=" + this.clusterId);
140 processCluster = true;
141 this.actualDataSet = this.clusterDataSet;
142 } else if (processCluster) {
143 log.debug("Process Start Element <" + qName + "> Level " + level
144 + " Attrs " + attrMap.size());
145
146 if (ParserConstants.XML_ELEM_OBJS.equals(qName)
147 && level == (LEVEL_CLUSTER_GLOBAL_OBJ - 1)) {
148 if (this.refProcessor == null) {
149 this.refProcessor = new ReferenceProcessor(
150 this.clusterDataSet);
151 }
152 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
153 && (level == LEVEL_CLUSTER_GLOBAL_OBJ || level == LEVEL_TEST_OBJ)) {
154 this.actionStack = new ActionStack();
155 pushAction(qName, attrMap);
156 } else if (ParserConstants.XML_ELEM_EXCEPTION.equals(qName)
157 && level == LEVEL_TEST_OBJ) {
158 this.actionStack = new ActionStack();
159 IAction action = pushAction(qName, attrMap);
160 String type = (String) attrMap
161 .get(ParserConstants.XML_ATTR_TYPE);
162 String id = (String) attrMap.get(ParserConstants.XML_ATTR_ID);
163 String actionAttr = (String) attrMap
164 .get(ParserConstants.XML_ATTR_ACTION);
165
166 action.setObject(new ExceptionAsserter(id, type, actionAttr));
167 } else if (ParserConstants.XML_ELEM_ASSERT.equals(qName)
168 && level == LEVEL_TEST_OBJ) {
169 this.actionStack = new ActionStack();
170 IAction action = pushAction(qName, attrMap);
171 String type = (String) attrMap
172 .get(ParserConstants.XML_ATTR_TYPE);
173 String id = (String) attrMap.get(ParserConstants.XML_ATTR_ID);
174 String actionAttr = (String) attrMap
175 .get(ParserConstants.XML_ATTR_ACTION);
176 action.setObject(new ObjectAsserter(id, type, actionAttr));
177 } else if (ParserConstants.XML_ELEM_TEST.equals(qName)
178 && level == LEVEL_TEST) {
179
180 TestGroupDataSet methodDataSet = (TestGroupDataSet) this.clusterDataSet
181 .get(groupId);
182 String testName = (String) attrMap
183 .get(ParserConstants.XML_ATTR_ID);
184
185 this.actualDataSet = new TestDataSet(testName, methodDataSet);
186 methodDataSet.put(testName, (TestDataSet) actualDataSet);
187 methodDataSet.addSubKey(testName);
188 this.refProcessor.setTestId(testName);
189 } else if (ParserConstants.XML_ELEM_GROUP.equals(qName)
190 && level == LEVEL_GROUP) {
191 this.groupId = (String) attrMap
192 .get(ParserConstants.XML_ATTR_ID);
193 if (this.refProcessor == null) {
194 this.refProcessor = new ReferenceProcessor(
195 this.clusterDataSet);
196 }
197 this.refProcessor.setGroupId(this.groupId);
198 this.actualDataSet = new TestGroupDataSet(this.groupId,
199 this.clusterDataSet);
200 this.clusterDataSet.put(this.groupId,
201 (TestGroupDataSet) this.actualDataSet);
202
203
204 } else if (!contains(ParserConstants.XML_IGNORE_ELEM, qName)) {
205
206
207 pushAction(qName, attrMap);
208 }
209 } else {
210 log.debug("Ignore Start Element <" + qName + "> Level " + level
211 + " Attrs " + attrMap.size());
212 }
213
214 }
215
216
217
218
219
220 private IAction pushAction(String qName, Map<String, String> attrMap) {
221 IAction action;
222 String id = (String) attrMap.get(ParserConstants.XML_ATTR_ID);
223 if (id == null) {
224 attrMap.put("id", qName);
225 }
226 String hint = (String) attrMap.get(ParserConstants.XML_ATTR_HINT);
227 if (HintTypes.COLLECTION.equals(hint)) {
228 action = push(attrMap, ActionState.COLLECTION_CREATION);
229 } else if (HintTypes.ARRAY.equals(hint)) {
230 action = push(attrMap, ActionState.ARRAY_CREATION);
231 } else if (HintTypes.MAP.equals(hint)) {
232 action = push(attrMap, ActionState.MAP_CREATION);
233 } else if (HintTypes.BEAN.equals(hint)) {
234 action = push(attrMap, ActionState.BEAN_CREATION);
235 } else if (HintTypes.CONSTRUCTOR.equals(hint)
236 || HintTypes.CALL.equals(hint)) {
237 action = push(attrMap, ActionState.CALL_CREATION);
238 } else if (HintTypes.CONTENT.equals(hint)) {
239 action = push(attrMap, ActionState.CONTENT_CREATION);
240 } else if (HintTypes.CONSTANT.equals(hint)) {
241 action = push(attrMap, ActionState.CONSTANT_CREATION);
242 } else if (HintTypes.DATE.equals(hint)) {
243 action = push(attrMap, ActionState.DATE_CREATION);
244 } else {
245
246
247 action = push(attrMap, ActionState.SUBELEMENT_CREATION);
248 }
249 return action;
250 }
251
252
253
254
255 private IAction push(Map attrMap, ActionState processState) {
256 IAction action = ActionFactory.getAction(processState, attrMap);
257 this.actionStack.push(action);
258 action.registerReferenceListener(this.refProcessor);
259 log.debug("push(" + action.toString() + ") - END");
260 return action;
261 }
262
263
264
265
266
267 private Map<String, String> getAttrMap(Attributes attribs) {
268 Map<String, String> attrMap = new HashMap<String, String>();
269 for (int count = 0; count < attribs.getLength(); count++) {
270 String key = attribs.getQName(count);
271 String value = attribs.getValue(count);
272 if (ParserConstants.XML_ATTR_TYPE.equals(key)
273 || ParserConstants.XML_ATTR_VALUETYPE.equals(key)
274 || ParserConstants.XML_ATTR_KEYTYPE.equals(key)) {
275 try {
276 value = TypeAbbreviator.getInstance().resolve(value);
277 } catch (IOException ex) {
278 throw new DDTTestDataException(
279 "Problem using TypeAbbreviator.", ex);
280 }
281 }
282 attrMap.put(key, value);
283 }
284 if (!attrMap.containsKey(ParserConstants.XML_ATTR_HINT)) {
285 attrMap.put(ParserConstants.XML_ATTR_HINT, HintTypes.FIELDS
286 .toString());
287 }
288 return attrMap;
289 }
290
291
292
293
294
295
296
297
298 private boolean contains(String[] array, String searchText) {
299 boolean found = false;
300 for (int i = 0; i < array.length; i++) {
301 if (array[i].equals(searchText)) {
302 found = true;
303 break;
304 }
305 }
306 return found;
307 }
308
309
310
311
312
313
314
315 public void processEndElement(String qName, long level) {
316 if (processCluster || processResource) {
317 log.debug("process End Element <" + qName + "> Level " + level
318 + " - START");
319 if ((ParserConstants.XML_ELEM_RESOURCES.equals(qName)
320 && level == (LEVEL_RESOURCE_OBJ - 1) || (ParserConstants.XML_ELEM_OBJS
321 .equals(qName) && level == (LEVEL_CLUSTER_GLOBAL_OBJ - 1)))) {
322 this.refProcessor.resolve();
323 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
324 && level == LEVEL_SINGLE_OBJ) {
325 IAction action = null;
326 while (!this.actionStack.isEmpty()) {
327 action = this.actionStack.process();
328 }
329 this.clusterDataSet.putObject("singleton", action.getObject());
330 this.processResource = false;
331 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
332 && level == LEVEL_RESOURCE_OBJ) {
333 IAction action = null;
334 while (!this.actionStack.isEmpty()) {
335 action = this.actionStack.process();
336 }
337
338 DDTDataRepository.getInstance().putObject(action.getId(),
339 action.getObject());
340 this.processResource = false;
341 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
342 && level == LEVEL_CLUSTER_GLOBAL_OBJ) {
343 IAction action = null;
344 while (!this.actionStack.isEmpty()) {
345 action = this.actionStack.process();
346 }
347
348 this.clusterDataSet.putObject(action.getId(), action
349 .getObject());
350 } else if (ParserConstants.XML_ELEM_OBJ.equals(qName)
351 && level == LEVEL_TEST_OBJ) {
352 IAction action = null;
353 while (!this.actionStack.isEmpty()) {
354 action = this.actionStack.process();
355 }
356
357 this.actualDataSet
358 .putObject(action.getId(), action.getObject());
359 } else if ((ParserConstants.XML_ELEM_ASSERT.equals(qName) || ParserConstants.XML_ELEM_EXCEPTION
360 .equals(qName))
361 && level == LEVEL_TEST_OBJ) {
362 IAction action = null;
363 while (!this.actionStack.isEmpty()) {
364 action = this.actionStack.process();
365 }
366
367 ((TestDataSet) this.actualDataSet).getAssertMap().put(
368 action.getId(), action.getObject());
369 } else if (ParserConstants.XML_ELEM_TEST.equals(qName)
370 && level == LEVEL_TEST && this.processCluster) {
371 this.refProcessor.resolve();
372 this.refProcessor.setTestId(null);
373 } else if (ParserConstants.XML_ELEM_GROUP.equals(qName)
374 && level == LEVEL_GROUP && this.processCluster) {
375 this.groupId = null;
376 this.refProcessor.resolve();
377 } else if (ParserConstants.XML_ELEM_CLUSTER.equals(qName)
378 && this.processCluster) {
379 this.refProcessor.resolve();
380 processCluster = false;
381 } else if (!ParserConstants.XML_ELEM_TEST.equals(qName)
382 && !contains(ParserConstants.XML_IGNORE_ELEM, qName)) {
383
384 log.debug("Process generic tag <" + qName + ">");
385 this.actionStack.process();
386 }
387 } else {
388 log.debug("Ignore End Element </" + qName + "> Level " + level);
389 }
390 StringBuffer sb = new StringBuffer("process End Element <").append(
391 qName).append("> Level ").append(level).append(" - END");
392 if (this.actionStack != null) {
393 sb.append(", ").append(this.actionStack.infoOf());
394 }
395 log.debug(sb.toString());
396 }
397
398
399
400
401
402
403
404
405
406
407 public void processCharacters(char[] buffer, int offset, int length) {
408 if ((processCluster || processResource) && this.actionStack != null) {
409 StringBuffer sb = new StringBuffer();
410 sb.append(buffer, offset, length);
411 if (!"".equals(sb.toString().trim()) || this.cdataProcessing) {
412 log.debug("Process content <\"" + sb.toString() + "\">");
413 Map<String, String> attrMap = new HashMap<String, String>();
414 attrMap.put(ParserConstants.XML_ATTR_CONTENT, sb.toString());
415 attrMap.put(ParserConstants.XML_ATTR_ID,
416 ParserConstants.XML_ATTR_CONTENT);
417 attrMap.put(ParserConstants.XML_ATTR_HINT,
418 ParserConstants.XML_ATTR_CONTENT);
419 attrMap.put(ParserConstants.XML_ATTR_TYPE,
420 "java.lang.StringBuffer");
421 attrMap.put(ParserConstants.XML_ATTR_PICDATA, Boolean
422 .toString(this.cdataProcessing));
423 pushAction("content", attrMap);
424 }
425 }
426 }
427
428 public String getClusterId() {
429 return clusterId;
430 }
431
432 public void setClusterId(String classId) {
433 this.clusterId = classId;
434 }
435
436
437
438
439 public void endCDATA() {
440 this.cdataProcessing = false;
441 }
442
443
444
445
446 public void startCDATA() {
447 this.cdataProcessing = true;
448 }
449
450 }