1 package org.textensor.xml;
2
3
4 import java.lang.reflect.Field;
5 import java.lang.reflect.Modifier;
6 import java.util.ArrayList;
7 import java.util.StringTokenizer;
8
9 import org.textensor.report.E;
10 import org.textensor.stochdiff.inter.AddableTo;
11 import org.textensor.stochdiff.inter.XMLContainer;
12
13
14
15 public class ReflectionInstantiator {
16
17 ArrayList search = new ArrayList();
18
19 int npkg;
20 String[] pkgs;
21
22 String wkpkg;
23
24
25 public ReflectionInstantiator() {
26 pkgs = new String[100];
27 npkg = 0;
28 }
29
30
31 public ReflectionInstantiator(String path) {
32 this();
33 addSearchPackage(path);
34 }
35
36
37
38
39 public void addSearchPackage(String s) {
40 wkpkg = s;
41 pkgs[npkg++] = s;
42 }
43
44
45 public void appendContent(Object obj, String s) {
46 if (obj instanceof XMLContainer) {
47 ((XMLContainer)obj).appendContent(s);
48 } else {
49 E.error(" - reflection instantiator doesn't do appendContent on " +
50 obj + "(" + obj.getClass() + ") while trying to append " + s);
51 }
52 }
53
54
55 public void checkAddPackage(Object oret) {
56 String scl = oret.getClass().getName();
57 if (scl.startsWith("java")) {
58 return;
59 }
60
61 int ild = scl.lastIndexOf(".");
62 String pkg = scl.substring(0, ild);
63 if (pkg.equals(wkpkg)) {
64
65
66 } else {
67 boolean got = false;
68 for (int i = 0; i < npkg; i++) {
69 if (pkgs[i].equals(pkg)) {
70 got = true;
71 break;
72 }
73 }
74 if (!got) {
75 pkgs[npkg++] = pkg;
76
77
78
79 }
80 }
81 }
82
83
84
85 public Object newInstance(String scl) {
86 Object oret = null;
87 Class<?> c = null;
88
89
90 if (scl.indexOf(":") > 0) {
91 scl = scl.substring(0, scl.indexOf(":"));
92 }
93
94 if (scl.indexOf(".") > 0) {
95 try {
96 c = Class.forName(scl);
97 } catch (Exception e) {
98 }
99 }
100
101 if (c == null) {
102 for (int i = 0; i < npkg && c == null; i++) {
103 try {
104 c = Class.forName(pkgs[i] + "." + scl);
105 } catch (Exception e) {
106 }
107 }
108 }
109
110 if (c == null) {
111 E.error("cant instantiate (class not found): " + scl);
112 E.reportCached();
113
114 for (int i = 0; i < npkg; i++) {
115 E.info("tried package " + pkgs[i]);
116 }
117
118 if (scl.endsWith("ing")) {
119 (new Exception()).printStackTrace();
120 }
121
122
123 } else {
124 int imod = c.getModifiers();
125 if (Modifier.isAbstract(imod)) {
126 E.error("cant instantiatie " + c + ": it is an abstract class");
127 } else {
128
129 try {
130 oret = c.newInstance();
131 } catch (Exception e) {
132 E.error(" " + e + " instantiating " + c);
133 e.printStackTrace();
134 }
135 }
136 }
137
138 if (oret != null) {
139 checkAddPackage(oret);
140 }
141
142 return oret;
143 }
144
145
146
147 public Object getField(Object ob, String fnm) {
148 Object ret = null;
149
150 boolean hasField = false;
151
152
153 Field[] flds = ob.getClass().getFields();
154 for (int i = 0; i < flds.length; i++) {
155 if (flds[i].getName().equals(fnm)) {
156 hasField = true;
157 break;
158 }
159 }
160
161 if (hasField) {
162 try {
163 Field f = ob.getClass().getField(fnm);
164
165 Class fcl = f.getType();
166
167 if (fcl.equals(String[].class)) {
168 ret = new String[0];
169
170 } else if (fcl.isArray()) {
171 ret = new ArrayList();
172 } else {
173 ret = f.get(ob);
174 }
175
176 if (ret == null) {
177 Class<?> cl = f.getType();
178 ret = cl.newInstance();
179 }
180
181 } catch (Exception e) {
182 E.error("cant get field " + fnm + " on " + ob + " " + "excception= " + e);
183 }
184 }
185
186
187
188
189
190
191
192
193
194 if (!hasField) {
195 if (ob instanceof ArrayList) {
196
197
198 } else {
199
200
201
202
203
204
205
206 }
207 }
208 return ret;
209 }
210
211
212
213 public Object getChildObject(Object parent, String name, Attribute[] atta) {
214 Object child = null;
215
216 if (parent != null) {
217 checkAddPackage(parent);
218 }
219
220
221
222
223
224
225
226 if (atta == null) {
227 atta = new Attribute[0];
228 }
229
230
231
232
233 String classname = null;
234 for (int i = 0; i < atta.length; i++) {
235 Attribute att = atta[i];
236 String attName = att.getName();
237 String attValue = att.getValue();
238
239 if (attName.equals("package")) {
240 StringTokenizer stok = new StringTokenizer(attValue, ", ");
241 while (stok.hasMoreTokens()) {
242 addSearchPackage(stok.nextToken());
243 }
244
245 } else if (attName.equals("archive-hash")) {
246
247 E.debugError("xmlreader found reference to archive file "
248 + " but has no importContext to retrieve object");
249
250
251 } else if (attName.equals("class")) {
252 classname = attValue;
253 }
254 }
255
256
257
258 if (child == null && classname != null) {
259 child = newInstance(classname);
260 }
261
262
263
264 if (child == null && parent != null) {
265 child = getField(parent, name);
266 }
267
268
269
270
271 if (child == null) {
272 child = newInstance(name);
273
274 }
275
276
277 if (child == null) {
278 E.warning("ReflectionInstantiator failed to get field " + name + " on " + parent + " "
279 + (parent != null ? parent.getClass().toString() : ""));
280 }
281
282
283
284
285
286
287
288
289 return child;
290 }
291
292
293
294 public void applyAttributes(Object target, Attribute[] atta) {
295
296 for (int i = 0; i < atta.length; i++) {
297 Attribute att = atta[i];
298 setAttributeField(target, att.getName(), att.getValue());
299 }
300 }
301
302
303
304 public boolean setAttributeField(Object target, String name, String arg) {
305 boolean bret = false;
306 if (name.equals("class") || name.equals("package") || name.equals("provides")
307 || name.equals("archive-hash")) {
308
309
310 } else {
311 bret = setField(target, name, arg);
312 }
313
314 return bret;
315 }
316
317
318
319 @SuppressWarnings( { "unchecked" })
320 public boolean setField(Object ob, String sf, Object arg) {
321
322
323 if (ob == null) {
324 E.error("null parent for " + sf + " (" + arg + ")");
325 return true;
326 }
327
328 if (arg == null) {
329 E.error("reflection instantiator has null arg setting " + sf + " in " + ob);
330 return true;
331 }
332
333 if (arg.equals(ob)) {
334 E.error("ReflectionInstantiator setField: " + "the child is the same as the parent " + ob);
335 return true;
336 }
337
338 int icolon = sf.indexOf(":");
339 if (icolon >= 0) {
340 sf = sf.substring(0, icolon) + "_" + sf.substring(icolon + 1, sf.length());
341 }
342
343 boolean ok = false;
344
345 Class c = ob.getClass();
346 Field f = null;
347 try {
348 f = c.getField(sf);
349 } catch (NoSuchFieldException e) {
350 }
351
352
353
354 if (f == null) {
355 if (ob instanceof ArrayList) {
356 ((ArrayList)ob).add(arg);
357 ok = true;
358
359
360
361
362
363
364
365 } else if (ob instanceof AddableTo && nonPrimitive(arg)) {
366 ((AddableTo)ob).add(arg);
367 ok = true;
368
369 } else {
370 E.oneLineWarning("no such field " + sf + " on " + ob + "while settting " + arg);
371 E.reportCached();
372 ok = false;
373 }
374
375 } else {
376
377 if (arg instanceof ArrayList && ((ArrayList)arg).size() == 1) {
378 for (Object sub : (ArrayList)arg) {
379 arg = sub;
380 }
381 }
382
383 try {
384 Class ftyp = f.getType();
385 if (ftyp == String.class && arg instanceof String) {
386 f.set(ob, arg);
387
388 } else if (ftyp == Double.TYPE && arg instanceof String) {
389 Double d = new Double((String)arg);
390 f.set(ob, d);
391
392 } else if (ftyp == Integer.TYPE && arg instanceof String) {
393 Integer ig = new Integer((String)arg);
394 f.set(ob, ig);
395
396
397
398 } else if (ftyp == Double.TYPE && arg instanceof Double) {
399 f.set(ob, arg);
400
401 } else if (ftyp == Boolean.TYPE && arg instanceof Boolean) {
402 f.set(ob, arg);
403
404 } else if (ftyp == Integer.TYPE && arg instanceof Integer) {
405 f.set(ob, arg);
406
407 } else if (f.getType().isArray() && arg instanceof ArrayList) {
408 setArrayField(ob, f, (ArrayList)arg);
409
410 } else {
411 Object onarg = Narrower.narrow(ftyp.getName(), arg);
412
413 if (onarg != null) {
414 f.set(ob, onarg);
415 } else {
416 f.set(ob, arg);
417 }
418 }
419 ok = true;
420 } catch (Exception e) {
421 ok = false;
422 E.error(" cant set field " + sf + " in " + ob + " from value " + arg + " " + e);
423 }
424 }
425
426
427 return ok;
428 }
429
430
431
432 public void setArrayField(Object obj, Field fld, ArrayList vals) {
433
434 E.missing();
435
436 System.out.println("setting array field of " + vals.size() + " in " + obj + " fnm="
437 + fld.getName());
438
439
440
441
442
443
444
445
446
447
448 }
449
450
451 private boolean nonPrimitive(Object arg) {
452 boolean ret = true;
453 if (arg instanceof String || arg instanceof Integer || arg instanceof Double) {
454 ret = false;
455 }
456 return ret;
457 }
458
459
460 public void setIntFromStatic(Object ret, String id, String sv) {
461 String svu = sv.toUpperCase();
462 Object obj = getField(ret, svu);
463 if (obj instanceof Integer) {
464 setField(ret, id, obj);
465 } else {
466 E.error("need an Integer, not " + obj);
467 }
468 }
469
470 }