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