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 }