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.lang.reflect.Array;
42 import java.lang.reflect.Field;
43 import java.lang.reflect.Method;
44 import java.util.HashMap;
45 import java.util.List;
46 import java.util.Map;
47 import java.util.Vector;
48
49 import junitx.ddtunit.DDTException;
50 import junitx.ddtunit.data.DDTTestDataException;
51 import junitx.ddtunit.data.IDataSet;
52 import junitx.ddtunit.data.TestDataSet;
53 import junitx.ddtunit.data.TypedObject;
54 import junitx.ddtunit.util.ClassAnalyser;
55
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
58
59
60
61
62
63
64 abstract class ActionBase implements IAction {
65 protected Logger log = LoggerFactory.getLogger(ActionBase.class);
66
67 private List<ILinkChangeListener> changeListeners;
68
69 private List<IReferenceListener> referenceListeners;
70
71 protected Map<String, String> attrMap;
72
73 protected TypedObject injectedObject;
74
75 protected IAction previous;
76
77 protected IAction next;
78
79 protected static final String LF = System.getProperty("line.separator");
80
81
82
83
84
85 boolean successorProcessed = false;
86
87
88
89
90
91
92
93
94
95 public ActionBase(Map<String, String> attrMap) {
96 if (this.attrMap == null) {
97 this.attrMap = new HashMap<String, String>();
98 }
99 this.attrMap.putAll(attrMap);
100 this.changeListeners = new Vector<ILinkChangeListener>();
101 this.referenceListeners = new Vector<IReferenceListener>();
102 }
103
104 public void processNoSuccessor() {
105
106 }
107
108 public void registerLinkChangeListener(ILinkChangeListener listener) {
109 this.changeListeners.add(listener);
110 }
111
112 public void removeLinkChangeListener(ILinkChangeListener listener) {
113 this.changeListeners.remove(listener);
114 }
115
116 public void pop() {
117 for (int count = 0; count < this.changeListeners.size(); count++) {
118 ((ILinkChangeListener) this.changeListeners.get(count)).pop();
119 }
120 this.removeFromLinkChangeListener(this);
121 }
122
123 private void removeFromLinkChangeListener(IAction action) {
124 for (int count = 0; count < this.changeListeners.size(); count++) {
125 action
126 .removeLinkChangeListener(((ILinkChangeListener) this.changeListeners
127 .get(count)));
128 }
129 }
130
131 public void promoteLinkChangeListener(IAction action) {
132 for (int count = 0; count < this.changeListeners.size(); count++) {
133 ActionStack actionStack = (ActionStack) this.changeListeners
134 .get(count);
135 action.registerLinkChangeListener(actionStack);
136 if (actionStack.last == this) {
137 actionStack.last = action;
138 }
139 }
140 }
141
142 public void registerReferenceListener(IReferenceListener listener) {
143 this.referenceListeners.add(listener);
144 }
145
146 public void add(IReferenceInfo info) {
147 for (int count = 0; count < this.referenceListeners.size(); count++) {
148 ((IReferenceListener) this.referenceListeners.get(count)).add(info);
149 }
150 }
151
152 public void removeReferenceListener(IReferenceListener listener) {
153 this.referenceListeners.remove(listener);
154 }
155
156 protected void desintegrate() {
157 this.attrMap.clear();
158 this.injectedObject = null;
159 }
160
161 public TypedObject getInjectedObject() {
162 return injectedObject;
163 }
164
165 public String getHint() {
166 String hint = (String) this.attrMap.get(ParserConstants.XML_ATTR_HINT);
167 if (hint == null) {
168 hint = HintTypes.FIELDS.toString();
169 }
170 return hint;
171 }
172
173 public String getId() {
174 String id = null;
175 if (this.injectedObject != null) {
176 id = this.injectedObject.getId();
177 }
178 return id;
179 }
180
181 public String getType() {
182 String type = null;
183 if (this.injectedObject != null) {
184 type = this.injectedObject.getType();
185 if (TypedObject.UNKNOWN_TYPE.equals(type)) {
186 type = getTypeFromRoot();
187 if (type == null) {
188 throw new DDTTestDataException(
189 "Could not specify type of object");
190 }
191 this.injectedObject.setType(type);
192 }
193 } else {
194 type = getTypeFromRoot();
195 }
196 return type;
197 }
198
199 public void setType(String type) {
200 if (this.injectedObject != null) {
201 this.injectedObject.setType(type);
202 }
203 }
204
205 public Object getValue() {
206 Object obj = null;
207 if (this.injectedObject != null) {
208 obj = this.injectedObject.getValue();
209 }
210 return obj;
211 }
212
213 public TypedObject getObject() {
214 return this.injectedObject;
215 }
216
217 public void setObject(TypedObject newObject) {
218 this.injectedObject = newObject;
219 }
220
221 public void setValue(Object obj) {
222 if (this.injectedObject != null) {
223 this.injectedObject.setValue(obj);
224 }
225 }
226
227
228
229
230
231
232
233
234 public String getTypeFromRoot() {
235 String mapEntryType = "junitx.ddtunit.data.processing.MapEntry";
236 log.debug("getTypeFromRoot() - START " + this);
237
238 String objectType = null;
239 IAction rootAction = this.getPrevious();
240
241 if (rootAction == null) {
242 throw new DDTException("Corrupt internal Action structure");
243 }
244
245 String hintValue = rootAction.getHint();
246 String rootTypeValue = rootAction.getType();
247 if (HintTypes.ATTRLIST.equals(hintValue)) {
248 rootAction = rootAction.getPrevious();
249 hintValue = rootAction.getHint();
250 rootTypeValue = rootAction.getType();
251 }
252 if (HintTypes.INTERNAL_MAPENTRY.equals(hintValue)
253 || mapEntryType.equals(rootTypeValue)) {
254 rootAction.createObject();
255 if ("key".equals(this.injectedObject.getId())) {
256 objectType = rootAction
257 .getAttribute(ParserConstants.XML_ATTR_KEYTYPE);
258 } else if ("value".equals(this.injectedObject.getId())) {
259 objectType = rootAction
260 .getAttribute(ParserConstants.XML_ATTR_VALUETYPE);
261 }
262
263
264
265
266 } else if (HintTypes.MAP.equals(hintValue)) {
267 String keyType = rootAction
268 .getAttribute(ParserConstants.XML_ATTR_KEYTYPE);
269 String valueType = rootAction
270 .getAttribute(ParserConstants.XML_ATTR_VALUETYPE);
271 if (keyType != null && !keyType.equals("")) {
272 this.setAttribute(ParserConstants.XML_ATTR_KEYTYPE, keyType);
273 }
274 if (valueType != null && !valueType.equals("")) {
275 this
276 .setAttribute(ParserConstants.XML_ATTR_VALUETYPE, valueType);
277 }
278 objectType = mapEntryType;
279 this.setAttribute(ParserConstants.XML_ATTR_HINT,
280 HintTypes.INTERNAL_MAPENTRY.toString());
281 this.setType(objectType);
282 } else if (HintTypes.COLLECTION.equals(hintValue)) {
283 objectType = rootAction
284 .getAttribute(ParserConstants.XML_ATTR_VALUETYPE);
285 } else if (HintTypes.ARRAY.equals(hintValue)) {
286 objectType = rootAction.getType();
287 if (objectType.startsWith("[L")) {
288 objectType = objectType.substring(2, objectType.length() - 1);
289 }
290 } else if (HintTypes.BEAN.equals(hintValue)){
291
292 StringBuffer setterName = new StringBuffer("set").append(getId().substring(0,1).toUpperCase())
293 .append(getId().substring(1));
294 Method setter = ClassAnalyser.findMethodByName(rootTypeValue, setterName.toString());
295 objectType = setter.getParameterTypes()[0].getName();
296 try {
297 objectType = TypeAbbreviator.getInstance().resolve(objectType);
298 } catch (IOException e) {
299
300 e.printStackTrace();
301 }
302 } else {
303 objectType = rootAction.extractFieldType(getId());
304 }
305 log.debug("getTypeFromRoot() - END (" + objectType + ")");
306 return objectType;
307 }
308
309 private void setAttribute(String key, String value) {
310 this.attrMap.put(key, value);
311 }
312
313
314
315
316
317
318
319
320
321
322 public String extractFieldType(String fieldName) {
323 log.debug("extractFieldType(" + fieldName + ") - START");
324 String fieldType = null;
325 String rootType = null;
326 IAction rootAction = getPrevious();
327 if ("java.util.Vector".equals(getType()) && "attrlist".equals(getId())) {
328 rootType = rootAction.getType();
329 } else {
330 rootType = getType();
331 }
332
333 if (rootAction != null && TypedObject.UNKNOWN_TYPE.equals(rootType)
334 && HintTypes.INTERNAL_MAPENTRY.equals(rootAction.getHint())) {
335 fieldType = rootAction.getAttribute(fieldName + "type");
336 } else {
337 Field field = ClassAnalyser.getSelectedField(rootType, fieldName);
338 if (field != null) {
339 fieldType = field.getType().getName();
340
341 try {
342 fieldType = TypeAbbreviator.getInstance()
343 .resolve(fieldType);
344 } catch (IOException ex) {
345 throw new DDTTestDataException(
346 "could not identify field of type " + fieldType);
347 }
348 }
349 }
350 log
351 .debug("extractFieldType(" + fieldName + ")=" + fieldType
352 + " - END");
353 return fieldType;
354 }
355
356
357
358
359
360
361
362
363
364
365 public TypedObject createObject() {
366 log.debug("Instanciate TypedObject ...");
367 if (getInjectedObject() == null) {
368 inject();
369 }
370 if (this.getValue() == null) {
371 String recordType = getType();
372 if (TypedObject.UNKNOWN_TYPE.equals(recordType)) {
373 recordType = getTypeFromRoot();
374 }
375 Class clazz;
376 Object obj = null;
377 try {
378 clazz = Class.forName(recordType);
379 if (HintTypes.ARRAY.equals(this.getHint())) {
380 obj = Array.newInstance(clazz, 1);
381 } else {
382 obj = clazz.newInstance();
383 }
384 } catch (Exception ex) {
385 throw new DDTException("Error on object creation of class "
386 + recordType, ex);
387 }
388 setValue(obj);
389 setType(recordType);
390 }
391 return this.getInjectedObject();
392 }
393
394 public IAction getNext() {
395 return next;
396 }
397
398 public void setNext(IAction next) {
399 this.next = next;
400 }
401
402 public IAction getPrevious() {
403 return previous;
404 }
405
406 public void setPrevious(IAction previous) {
407 this.previous = previous;
408 }
409
410
411
412
413
414
415 public void insert(IAction action) {
416 IAction nextAction = this.getNext();
417 this.setNext(action);
418 if (nextAction != null) {
419 action.setNext(nextAction);
420 nextAction.setPrevious(action);
421 }
422 action.setPrevious(this);
423 promoteLinkChangeListener(action);
424 }
425
426 public String toString() {
427 StringBuffer buffer = new StringBuffer();
428 buffer.append("[").append(this.getClass().getName());
429 if (this.injectedObject != null) {
430 buffer.append(" id: ");
431 buffer.append(this.injectedObject.getId());
432 buffer.append(" type: ");
433 buffer.append(this.injectedObject.getType());
434 }
435 buffer.append("]");
436 return buffer.toString();
437 }
438
439 public String getAttribute(String id) {
440 String attrValue = (String) this.attrMap.get(id);
441 return attrValue;
442 }
443
444 public boolean hasReferenceInfo() {
445 boolean check = false;
446 String refid = this.getAttribute(ParserConstants.XML_ATTR_REFID);
447 if (refid != null) {
448 check = true;
449 }
450 return check;
451 }
452
453 class ObjectReferenceInfo extends ReferenceInfoBase {
454
455
456
457
458
459 public ObjectReferenceInfo(TypedObject source, TypedObject destination) {
460 super(source, destination);
461 }
462
463 public void resolve(IDataSet dataSet, String groupId, String testId) {
464 if (ParserConstants.UNKNOWN.equals(groupId)) {
465 if (ParserConstants.UNKNOWN.equals(testId)) {
466 TypedObject dest = dataSet.findObject(this.getDestId(),
467 this.getDestType());
468 TypedObject source = dataSet.getObject(this.getSourceId(),
469 this.getSourceType());
470 if (source == null && dataSet instanceof TestDataSet) {
471 source = ((TestDataSet) dataSet).getAssert(this
472 .getSourceId(), this.getSourceType());
473 }
474 if (dest != null && source != null) {
475 source.setValue(dest.getValue());
476 source.setType(dest.getType());
477 } else {
478 throw new DDTTestDataException(
479 "Error on processing references on testdata.");
480 }
481 } else {
482 throw new DDTTestDataException(
483 "No testId expected because groupId is unspecified");
484 }
485 } else {
486 if (!ParserConstants.UNKNOWN.equals(testId)) {
487 IDataSet groupSet = dataSet.get(groupId);
488 IDataSet testDataSet = null;
489 if (groupSet != null) {
490 testDataSet = groupSet.get(testId);
491 }
492 TypedObject dest = testDataSet.findObject(this.getDestId(),
493 this.getDestType());
494 TypedObject source = testDataSet.getObject(this
495 .getSourceId(), this.getSourceType());
496 if (source == null && testDataSet instanceof TestDataSet) {
497 source = ((TestDataSet) testDataSet).getAssert(this
498 .getSourceId(), this.getSourceType());
499 }
500 if (dest != null && source != null) {
501 source.setValue(dest.getValue());
502 source.setType(dest.getType());
503 } else {
504 throw new DDTTestDataException(
505 "Error on processing references on testdata.");
506 }
507 } else {
508 throw new DDTTestDataException(
509 "Do not process group data without testId");
510 }
511 }
512 }
513
514
515
516
517
518
519
520
521
522 public void raiseRankOf(IReferenceInfo info) {
523 if (this.getDestId().equals(info.getSourceId())
524 && (this.getDestType().equals(info.getSourceType()) || TypedObject.UNKNOWN_TYPE
525 .equals(info.getDestType()))) {
526 if (this.getRank() >= info.getRank()) {
527 info.setRank(this.getRank() + 1);
528 }
529 }
530 }
531 }
532
533 }