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 }