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.lang.reflect.Constructor;
41  import java.lang.reflect.Method;
42  import java.lang.reflect.Modifier;
43  import java.util.HashMap;
44  import java.util.List;
45  import java.util.Map;
46  import java.util.Vector;
47  
48  import junitx.ddtunit.DDTException;
49  import junitx.ddtunit.data.DDTTestDataException;
50  import junitx.ddtunit.data.TypedObject;
51  import junitx.ddtunit.util.ClassAnalyser;
52  import junitx.ddtunit.util.PrivilegedAccessor;
53  
54  
55  
56  
57  
58  
59  
60  public class CallCreatorAction extends ActionBase {
61      
62  
63  
64  
65  
66  
67  
68      public CallCreatorAction(Map<String, String> attrMap) {
69          super(attrMap);
70      }
71  
72      
73  
74  
75  
76  
77      public IAction process() {
78          log.debug("process CallCreator - START");
79          if (!this.successorProcessed) {
80              processNoSuccessor();
81          }
82          IAction rootAction = this.getPrevious();
83          if (rootAction != null) {
84              String hintValue = rootAction.getHint();
85  
86              if (HintTypes.COLLECTION.equals(hintValue)) {
87                  rootAction.processSuccessor(this);
88              } else if (HintTypes.MAP.equals(hintValue)) {
89                  rootAction.processSuccessor(this);
90              } else if (HintTypes.ATTRLIST.equals(hintValue)) {
91                  rootAction.processSuccessor(this);
92              } else if (HintTypes.FIELDS.equals(hintValue)) {
93                  rootAction.processSuccessor(this);
94              } else if (HintTypes.CONSTRUCTOR.equals(hintValue)
95                      || HintTypes.CALL.equals(hintValue)) {
96                  rootAction.processSuccessor(this);
97              } else if (HintTypes.BEAN.equals(hintValue)) {
98                  rootAction.processSuccessor(this);
99              } else if (HintTypes.ARRAY.equals(hintValue)) {
100                 rootAction.processSuccessor(this);
101             } else if (HintTypes.INTERNAL_MAPENTRY.equals(hintValue)) {
102                 rootAction.processSuccessor(this);
103             } else {
104                 throw new DDTException("Unknown hint (" + hintValue
105                         + ")- stop processing.");
106             }
107         } else {
108             rootAction = this;
109         }
110         this.pop();
111         return this;
112     }
113 
114     public void processNoSuccessor() {
115         
116         IAction action = new AttributeListCreatorAction(
117                 new HashMap<String, String>());
118         action.inject();
119         action.setValue(new Vector());
120         this.insert(action);
121         action.process();
122     }
123 
124     
125 
126 
127 
128 
129     public IAction inject() {
130         String type = (String) this.attrMap.get(ParserConstants.XML_ATTR_TYPE);
131         String id = (String) this.attrMap.get(ParserConstants.XML_ATTR_ID);
132         this.injectedObject = new TypedObject(id, type);
133         return this;
134     }
135 
136     public void processSuccessor(IAction successor) {
137         log.debug("processSuccessor(" + successor + ") - START");
138         
139         if (HintTypes.ATTRLIST.equals(successor.getHint())) {
140             String rootType = this.getType();
141             if (TypedObject.UNKNOWN_TYPE.equals(rootType)) {
142                 rootType = successor.getTypeFromRoot();
143             }
144             
145             
146             
147             Class[] sigClasses = getClassesFrom((List) successor.getValue());
148             Object[] sigObjects = getObjectsFrom((List) successor.getValue());
149             String methodName = this.getAttribute("method");
150             Object obj = null;
151             if (methodName == null || "".equals(methodName)
152                     || "constructor".equals(methodName)) {
153                 Constructor constructor = (Constructor) ClassAnalyser
154                     .findMethodByParams(rootType,
155                         ClassAnalyser.CLASS_CONSTRUCTOR, sigClasses);
156                 checkForValidMethod(constructor, sigClasses, "constructor");
157                 try {
158                     obj = constructor.newInstance(sigObjects);
159                 } catch (Exception ex) {
160                     throw new DDTException(
161                             "Error on object creation by constructor", ex);
162                 }
163             } else {
164                 String callType = this.getAttribute("calltype");
165                 if (callType == null || "".equals(callType)) {
166                     callType = rootType;
167                 }
168                 Method method = (Method) ClassAnalyser.findMethodByParams(
169                     callType, methodName, sigClasses);
170                 checkForValidMethod(method, sigClasses, methodName);
171                 try {
172                     if (Modifier.isStatic(method.getModifiers())) {
173                         obj = method.invoke(null, sigObjects);
174                     } else {
175                         Class callClazz = Class.forName(callType);
176                         Object callObj = callClazz.newInstance();
177                         obj = method.invoke(callObj, sigObjects);
178                     }
179                 } catch (Exception ex) {
180                     throw new DDTException(
181                             "Error on object creation by method call", ex);
182                 }
183             }
184             this.setValue(obj);
185             this.successorProcessed = true;
186         } else if (HintTypes.INTERNAL_MAPENTRY.equals(this.getHint())) {
187             try {
188                 PrivilegedAccessor.setFieldValue(this.getValue(), successor
189                     .getId(), successor.getObject());
190             } catch (Exception ex) {
191                 throw new DDTTestDataException("Error filling map entry "
192                         + this.getId(), ex);
193             }
194         } else {
195             
196             Map attribMap = new HashMap();
197             IAction attribListAction = ActionFactory.getAction(
198                 ActionState.ATTRLIST_CREATION, attribMap);
199             this.insert(attribListAction);
200             try {
201                 
202                 attribListAction.createObject();
203                 
204                 ((List<TypedObject>) attribListAction.getValue()).add(successor
205                     .getObject());
206             } catch (Exception ex) {
207                 throw new DDTException("Error on action processing", ex);
208             }
209         }
210     }
211 
212     
213 
214 
215 
216     private void checkForValidMethod(Object caller, Class[] sigClasses,
217             String type) {
218         if (caller == null) {
219             StringBuffer sb = new StringBuffer("No method found! Expected ")
220                 .append(this.getType()).append(".").append(type).append("(");
221             for (int count = 0; count < sigClasses.length; count++) {
222                 sb.append(sigClasses[count].getName());
223                 if (count < sigClasses.length) {
224                     sb.append(", ");
225                 }
226             }
227             sb.append(")");
228             throw new DDTException(sb.toString());
229         }
230     }
231 
232     
233 
234 
235 
236 
237 
238 
239     private Class[] getClassesFrom(List recordList) {
240         int max = recordList.size();
241         Class[] sigClasses;
242         sigClasses = new Class[max];
243         for (int pos = 0; pos < max; pos++) {
244             TypedObject tObject = (TypedObject) recordList.get(pos);
245             String objectType = tObject.getType();
246             try {
247 
248                 sigClasses[pos] = Class.forName(objectType);
249             } catch (ClassNotFoundException ex) {
250                 throw new DDTException("Could not instanciate class for "
251                         + objectType, ex);
252             }
253         }
254         return sigClasses;
255     }
256 
257     
258 
259 
260 
261 
262 
263 
264     private Object[] getObjectsFrom(List objectList) {
265         int max = objectList.size();
266         Object[] sigObjects;
267         sigObjects = new Object[max];
268         for (int pos = 0; pos < max; pos++) {
269             TypedObject tObject = (TypedObject) objectList.get(pos);
270             sigObjects[pos] = tObject.getValue();
271         }
272         return sigObjects;
273     }
274 
275 }