1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts.config;
22
23 import org.apache.commons.beanutils.BeanUtils;
24 import org.apache.commons.beanutils.DynaBean;
25 import org.apache.commons.beanutils.MutableDynaClass;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.struts.action.ActionForm;
29 import org.apache.struts.action.ActionServlet;
30 import org.apache.struts.action.DynaActionForm;
31 import org.apache.struts.action.DynaActionFormClass;
32 import org.apache.struts.chain.commands.util.ClassUtils;
33 import org.apache.struts.chain.contexts.ActionContext;
34 import org.apache.struts.chain.contexts.ServletActionContext;
35 import org.apache.struts.util.RequestUtils;
36 import org.apache.struts.validator.BeanValidatorForm;
37
38 import java.lang.reflect.InvocationTargetException;
39
40 import java.util.HashMap;
41
42
43
44
45
46
47
48
49
50 public class FormBeanConfig extends BaseConfig {
51 private static final Log log = LogFactory.getLog(FormBeanConfig.class);
52
53
54
55
56
57
58
59 protected HashMap formProperties = new HashMap();
60
61
62
63
64
65 protected String lock = "";
66
67
68
69
70
71
72 protected transient DynaActionFormClass dynaActionFormClass;
73
74
75
76
77
78 protected boolean dynamic = false;
79
80
81
82
83
84 protected String inherit = null;
85
86
87
88
89 protected boolean extensionProcessed = false;
90
91
92
93
94
95
96
97 protected String name = null;
98
99
100
101
102
103 protected String type = null;
104
105
106
107
108
109 protected boolean restricted = false;
110
111
112
113
114
115
116
117 public DynaActionFormClass getDynaActionFormClass() {
118 if (dynamic == false) {
119 throw new IllegalArgumentException("ActionForm is not dynamic");
120 }
121
122 synchronized (lock) {
123 if (dynaActionFormClass == null) {
124 dynaActionFormClass = new DynaActionFormClass(this);
125 }
126 }
127
128 return dynaActionFormClass;
129 }
130
131 public boolean getDynamic() {
132 return (this.dynamic);
133 }
134
135 public String getExtends() {
136 return (this.inherit);
137 }
138
139 public void setExtends(String extend) {
140 throwIfConfigured();
141 this.inherit = extend;
142 }
143
144 public boolean isExtensionProcessed() {
145 return extensionProcessed;
146 }
147
148 public String getName() {
149 return (this.name);
150 }
151
152 public void setName(String name) {
153 throwIfConfigured();
154 this.name = name;
155 }
156
157 public String getType() {
158 return (this.type);
159 }
160
161 public void setType(String type) {
162 throwIfConfigured();
163 this.type = type;
164
165 Class dynaBeanClass = DynaActionForm.class;
166 Class formBeanClass = formBeanClass();
167
168 if (formBeanClass != null) {
169 if (dynaBeanClass.isAssignableFrom(formBeanClass)) {
170 this.dynamic = true;
171 } else {
172 this.dynamic = false;
173 }
174 } else {
175 this.dynamic = false;
176 }
177 }
178
179
180
181
182
183
184 public boolean isRestricted() {
185 return restricted;
186 }
187
188
189
190
191
192
193 public void setRestricted(boolean restricted) {
194 this.restricted = restricted;
195 }
196
197
198
199
200
201
202
203
204
205
206 protected boolean checkCircularInheritance(ModuleConfig moduleConfig) {
207 String ancestorName = getExtends();
208
209 while (ancestorName != null) {
210
211 if (getName().equals(ancestorName)) {
212 return true;
213 }
214
215
216 FormBeanConfig ancestor =
217 moduleConfig.findFormBeanConfig(ancestorName);
218
219 ancestorName = ancestor.getExtends();
220 }
221
222 return false;
223 }
224
225
226
227
228
229
230
231
232 protected void inheritFormProperties(FormBeanConfig config)
233 throws ClassNotFoundException, IllegalAccessException,
234 InstantiationException, InvocationTargetException {
235 throwIfConfigured();
236
237
238 FormPropertyConfig[] baseFpcs = config.findFormPropertyConfigs();
239
240 for (int i = 0; i < baseFpcs.length; i++) {
241 FormPropertyConfig baseFpc = baseFpcs[i];
242
243
244 FormPropertyConfig prop =
245 this.findFormPropertyConfig(baseFpc.getName());
246
247 if (prop == null) {
248
249 prop =
250 (FormPropertyConfig) RequestUtils.applicationInstance(baseFpc.getClass()
251 .getName());
252
253 BeanUtils.copyProperties(prop, baseFpc);
254 this.addFormPropertyConfig(prop);
255 prop.setProperties(baseFpc.copyProperties());
256 }
257 }
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 public ActionForm createActionForm(ActionServlet servlet)
282 throws IllegalAccessException, InstantiationException {
283 Object obj = null;
284
285
286 if (getDynamic()) {
287 obj = getDynaActionFormClass().newInstance();
288 } else {
289 obj = formBeanClass().newInstance();
290 }
291
292 ActionForm form = null;
293
294 if (obj instanceof ActionForm) {
295 form = (ActionForm) obj;
296 } else {
297 form = new BeanValidatorForm(obj);
298 }
299
300 form.setServlet(servlet);
301
302 if (form instanceof DynaBean
303 && ((DynaBean) form).getDynaClass() instanceof MutableDynaClass) {
304 DynaBean dynaBean = (DynaBean) form;
305 MutableDynaClass dynaClass =
306 (MutableDynaClass) dynaBean.getDynaClass();
307
308
309 dynaClass.setRestricted(false);
310
311 FormPropertyConfig[] props = findFormPropertyConfigs();
312
313 for (int i = 0; i < props.length; i++) {
314 dynaClass.add(props[i].getName(), props[i].getTypeClass());
315 dynaBean.set(props[i].getName(), props[i].initial());
316 }
317
318 dynaClass.setRestricted(isRestricted());
319 }
320
321 if (form instanceof BeanValidatorForm) {
322 ((BeanValidatorForm)form).initialize(this);
323 }
324
325 return form;
326 }
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347 public ActionForm createActionForm(ActionContext context)
348 throws IllegalAccessException, InstantiationException {
349 ActionServlet actionServlet = null;
350
351 if (context instanceof ServletActionContext) {
352 ServletActionContext saContext = (ServletActionContext) context;
353
354 actionServlet = saContext.getActionServlet();
355 }
356
357 return createActionForm(actionServlet);
358 }
359
360
361
362
363
364
365
366
367
368
369 public boolean canReuse(ActionForm form) {
370 if (form != null) {
371 if (this.getDynamic()) {
372 String className = ((DynaBean) form).getDynaClass().getName();
373
374 if (className.equals(this.getName())) {
375 log.debug("Can reuse existing instance (dynamic)");
376
377 return (true);
378 }
379 } else {
380 try {
381
382
383 Class formClass = form.getClass();
384
385 if (form instanceof BeanValidatorForm) {
386 BeanValidatorForm beanValidatorForm =
387 (BeanValidatorForm) form;
388
389 if (beanValidatorForm.getInstance() instanceof DynaBean) {
390 String formName = beanValidatorForm.getStrutsConfigFormName();
391 if (getName().equals(formName)) {
392 log.debug("Can reuse existing instance (BeanValidatorForm)");
393 return true;
394 } else {
395 return false;
396 }
397 }
398 formClass = beanValidatorForm.getInstance().getClass();
399 }
400
401 Class configClass =
402 ClassUtils.getApplicationClass(this.getType());
403
404 if (configClass.isAssignableFrom(formClass)) {
405 log.debug("Can reuse existing instance (non-dynamic)");
406
407 return (true);
408 }
409 } catch (Exception e) {
410 log.debug("Error testing existing instance for reusability; just create a new instance",
411 e);
412 }
413 }
414 }
415
416 return false;
417 }
418
419
420
421
422
423
424
425
426
427 public void addFormPropertyConfig(FormPropertyConfig config) {
428 throwIfConfigured();
429
430 if (formProperties.containsKey(config.getName())) {
431 throw new IllegalArgumentException("Property " + config.getName()
432 + " already defined");
433 }
434
435 formProperties.put(config.getName(), config);
436 }
437
438
439
440
441
442
443
444 public FormPropertyConfig findFormPropertyConfig(String name) {
445 return ((FormPropertyConfig) formProperties.get(name));
446 }
447
448
449
450
451
452 public FormPropertyConfig[] findFormPropertyConfigs() {
453 FormPropertyConfig[] results =
454 new FormPropertyConfig[formProperties.size()];
455
456 return ((FormPropertyConfig[]) formProperties.values().toArray(results));
457 }
458
459
460
461
462 public void freeze() {
463 super.freeze();
464
465 FormPropertyConfig[] fpconfigs = findFormPropertyConfigs();
466
467 for (int i = 0; i < fpconfigs.length; i++) {
468 fpconfigs[i].freeze();
469 }
470 }
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497 public void inheritFrom(FormBeanConfig config)
498 throws ClassNotFoundException, IllegalAccessException,
499 InstantiationException, InvocationTargetException {
500 throwIfConfigured();
501
502
503 if (getName() == null) {
504 setName(config.getName());
505 }
506
507 if (!isRestricted()) {
508 setRestricted(config.isRestricted());
509 }
510
511 if (getType() == null) {
512 setType(config.getType());
513 }
514
515 inheritFormProperties(config);
516 inheritProperties(config);
517 }
518
519
520
521
522
523
524
525
526
527
528 public void processExtends(ModuleConfig moduleConfig)
529 throws ClassNotFoundException, IllegalAccessException,
530 InstantiationException, InvocationTargetException {
531 if (configured) {
532 throw new IllegalStateException("Configuration is frozen");
533 }
534
535 String ancestor = getExtends();
536
537 if ((!extensionProcessed) && (ancestor != null)) {
538 FormBeanConfig baseConfig =
539 moduleConfig.findFormBeanConfig(ancestor);
540
541 if (baseConfig == null) {
542 throw new NullPointerException("Unable to find "
543 + "form bean '" + ancestor + "' to extend.");
544 }
545
546
547
548 if (checkCircularInheritance(moduleConfig)) {
549 throw new IllegalArgumentException(
550 "Circular inheritance detected for form bean " + getName());
551 }
552
553
554 if (!baseConfig.isExtensionProcessed()) {
555 baseConfig.processExtends(moduleConfig);
556 }
557
558
559 inheritFrom(baseConfig);
560 }
561
562 extensionProcessed = true;
563 }
564
565
566
567
568
569
570 public void removeFormPropertyConfig(FormPropertyConfig config) {
571 if (configured) {
572 throw new IllegalStateException("Configuration is frozen");
573 }
574
575 formProperties.remove(config.getName());
576 }
577
578
579
580
581 public String toString() {
582 StringBuffer sb = new StringBuffer("FormBeanConfig[");
583
584 sb.append("name=");
585 sb.append(this.name);
586 sb.append(",type=");
587 sb.append(this.type);
588 sb.append(",extends=");
589 sb.append(this.inherit);
590 sb.append("]");
591
592 return (sb.toString());
593 }
594
595
596
597
598
599
600
601
602
603 protected Class formBeanClass() {
604 ClassLoader classLoader =
605 Thread.currentThread().getContextClassLoader();
606
607 if (classLoader == null) {
608 classLoader = this.getClass().getClassLoader();
609 }
610
611 try {
612 return (classLoader.loadClass(getType()));
613 } catch (Exception e) {
614 return (null);
615 }
616 }
617 }