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.action;
22
23 import java.lang.reflect.Array;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.StringTokenizer;
28
29 import jakarta.servlet.ServletRequest;
30 import jakarta.servlet.http.HttpServletRequest;
31
32 import org.apache.commons.beanutils.ConversionException;
33 import org.apache.commons.beanutils.DynaBean;
34 import org.apache.commons.beanutils.DynaClass;
35 import org.apache.commons.beanutils.DynaProperty;
36 import org.apache.struts.config.FormBeanConfig;
37 import org.apache.struts.config.FormPropertyConfig;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class DynaActionForm extends ActionForm implements DynaBean {
56 private static final long serialVersionUID = 1726775935544475430L;
57
58
59
60
61
62
63
64 protected DynaActionFormClass dynaClass = null;
65
66
67
68
69
70 protected HashMap<String, Object> dynaValues = new HashMap<>();
71
72
73
74
75
76
77
78
79
80
81 public void initialize(ActionMapping mapping) {
82 String name = mapping.getName();
83
84 if (name == null) {
85 return;
86 }
87
88 FormBeanConfig config =
89 mapping.getModuleConfig().findFormBeanConfig(name);
90
91 if (config == null) {
92 return;
93 }
94
95 initialize(config);
96 }
97
98
99
100
101
102
103 public void initialize(FormBeanConfig config) {
104 FormPropertyConfig[] props = config.findFormPropertyConfigs();
105
106 for (int i = 0; i < props.length; i++) {
107 set(props[i].getName(), props[i].initial());
108 }
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 public void reset(ActionMapping mapping, ServletRequest request) {
125 super.reset(mapping, request);
126 }
127
128
129
130
131
132
133
134
135
136
137 public void reset(ActionMapping mapping, HttpServletRequest request) {
138 String name = getDynaClass().getName();
139
140 if (name == null) {
141 return;
142 }
143
144 FormBeanConfig config =
145 mapping.getModuleConfig().findFormBeanConfig(name);
146
147 if (config == null) {
148 return;
149 }
150
151
152 FormPropertyConfig[] props = config.findFormPropertyConfigs();
153
154 for (int i = 0; i < props.length; i++) {
155 String resetValue = props[i].getReset();
156
157
158 if ((resetValue == null) || (resetValue.length() <= 0)) {
159 continue;
160 }
161
162 boolean reset = Boolean.valueOf(resetValue).booleanValue();
163
164 if (!reset) {
165
166
167 StringTokenizer st =
168 new StringTokenizer(resetValue, ", \t\n\r\f");
169
170 while (st.hasMoreTokens()) {
171 String token = st.nextToken();
172
173 if (token.equalsIgnoreCase(request.getMethod())) {
174 reset = true;
175
176 break;
177 }
178 }
179 }
180
181 if (reset) {
182 set(props[i].getName(), props[i].initial());
183 }
184 }
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 public boolean contains(String name, String key) {
204 Object value = dynaValues.get(name);
205
206 if (value == null) {
207 throw new NullPointerException("No mapped value for '" + name + "("
208 + key + ")'");
209 } else if (value instanceof Map) {
210 return (((Map<?, ?>) value).containsKey(key));
211 } else {
212 throw new IllegalArgumentException("Non-mapped property for '"
213 + name + "(" + key + ")'");
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227 public Object get(String name) {
228
229 Object value = dynaValues.get(name);
230
231 if (value != null) {
232 return (value);
233 }
234
235
236 Class<?> type = getDynaProperty(name).getType();
237
238 if (type == null) {
239 throw new NullPointerException("The type for property " + name
240 + " is invalid");
241 }
242
243 if (!type.isPrimitive()) {
244 return (value);
245 }
246
247
248 if (type == Boolean.TYPE) {
249 return (Boolean.FALSE);
250 } else if (type == Byte.TYPE) {
251 return (Byte.valueOf((byte) 0));
252 } else if (type == Character.TYPE) {
253 return (Character.valueOf((char) 0));
254 } else if (type == Double.TYPE) {
255 return (Double.valueOf(0.0));
256 } else if (type == Float.TYPE) {
257 return (Float.valueOf((float) 0.0));
258 } else if (type == Integer.TYPE) {
259 return (Integer.valueOf(0));
260 } else if (type == Long.TYPE) {
261 return (Long.valueOf(0));
262 } else if (type == Short.TYPE) {
263 return (Short.valueOf((short) 0));
264 } else {
265 return (null);
266 }
267 }
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 public Object get(String name, int index) {
284 Object value = dynaValues.get(name);
285
286 if (value == null) {
287 throw new NullPointerException("No indexed value for '" + name
288 + "[" + index + "]'");
289 } else if (value.getClass().isArray()) {
290 return (Array.get(value, index));
291 } else if (value instanceof List) {
292 return ((List<?>) value).get(index);
293 } else {
294 throw new IllegalArgumentException("Non-indexed property for '"
295 + name + "[" + index + "]'");
296 }
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 public Object get(String name, String key) {
313 Object value = dynaValues.get(name);
314
315 if (value == null) {
316 throw new NullPointerException("No mapped value for '" + name + "("
317 + key + ")'");
318 } else if (value instanceof Map) {
319 return (((Map<?, ?>) value).get(key));
320 } else {
321 throw new IllegalArgumentException("Non-mapped property for '"
322 + name + "(" + key + ")'");
323 }
324 }
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341 public String getString(String name) {
342 return (String) this.get(name);
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360 public String[] getStrings(String name) {
361 return (String[]) this.get(name);
362 }
363
364
365
366
367
368
369
370
371 public DynaClass getDynaClass() {
372 return (this.dynaClass);
373 }
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394 public Map<String, Object> getMap() {
395 return (dynaValues);
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409 public void remove(String name, String key) {
410 Object value = dynaValues.get(name);
411
412 if (value == null) {
413 throw new NullPointerException("No mapped value for '" + name + "("
414 + key + ")'");
415 } else if (value instanceof Map) {
416 ((Map<?, ?>) value).remove(key);
417 } else {
418 throw new IllegalArgumentException("Non-mapped property for '"
419 + name + "(" + key + ")'");
420 }
421 }
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438 public void set(String name, Object value) {
439 DynaProperty descriptor = getDynaProperty(name);
440
441 if (descriptor.getType() == null) {
442 throw new NullPointerException("The type for property " + name
443 + " is invalid");
444 }
445
446 if (value == null) {
447 if (descriptor.getType().isPrimitive()) {
448 throw new NullPointerException("Primitive value for '" + name
449 + "'");
450 }
451 } else if (!isDynaAssignable(descriptor.getType(), value.getClass())) {
452 throw new ConversionException("Cannot assign value of type '"
453 + value.getClass().getName() + "' to property '" + name
454 + "' of type '" + descriptor.getType().getName() + "'");
455 }
456
457 dynaValues.put(name, value);
458 }
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476 public void set(String name, int index, Object value) {
477 Object prop = dynaValues.get(name);
478
479 if (prop == null) {
480 throw new NullPointerException("No indexed value for '" + name
481 + "[" + index + "]'");
482 } else if (prop.getClass().isArray()) {
483 Array.set(prop, index, value);
484 } else if (prop instanceof List) {
485 try {
486 @SuppressWarnings("unchecked")
487 List<Object> list = (List<Object>)prop;
488 list.set(index, value);
489 } catch (ClassCastException e) {
490 throw new ConversionException(e.getMessage(), e);
491 }
492 } else {
493 throw new IllegalArgumentException("Non-indexed property for '"
494 + name + "[" + index + "]'");
495 }
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509 public void set(String name, String key, Object value) {
510 Object prop = dynaValues.get(name);
511
512 if (prop == null) {
513 throw new NullPointerException("No mapped value for '" + name + "("
514 + key + ")'");
515 } else if (prop instanceof Map) {
516 @SuppressWarnings("unchecked")
517 Map<String, Object> map = (Map<String, Object>)prop;
518 map.put(key, value);
519 } else {
520 throw new IllegalArgumentException("Non-mapped property for '"
521 + name + "(" + key + ")'");
522 }
523 }
524
525
526
527
528
529
530
531
532 public String toString() {
533 StringBuilder sb = new StringBuilder("DynaActionForm[dynaClass=");
534 DynaClass dynaClass = getDynaClass();
535
536 if (dynaClass == null) {
537 return sb.append("null]").toString();
538 }
539
540 sb.append(dynaClass.getName());
541
542 DynaProperty[] props = dynaClass.getDynaProperties();
543
544 if (props == null) {
545 props = new DynaProperty[0];
546 }
547
548 for (int i = 0; i < props.length; i++) {
549 sb.append(',');
550 sb.append(props[i].getName());
551 sb.append('=');
552
553 Object value = get(props[i].getName());
554
555 if (value == null) {
556 sb.append("<NULL>");
557 } else if (value.getClass().isArray()) {
558 int n = Array.getLength(value);
559
560 sb.append("{");
561
562 for (int j = 0; j < n; j++) {
563 if (j > 0) {
564 sb.append(',');
565 }
566
567 sb.append(Array.get(value, j));
568 }
569
570 sb.append("}");
571 } else if (value instanceof List) {
572 int n = ((List<?>) value).size();
573
574 sb.append("{");
575
576 for (int j = 0; j < n; j++) {
577 if (j > 0) {
578 sb.append(',');
579 }
580
581 sb.append(((List<?>) value).get(j));
582 }
583
584 sb.append("}");
585 } else if (value instanceof Map) {
586 boolean first = true;
587
588 sb.append("{");
589
590 for (Map.Entry<?, ?> entry : ((Map<?, ?>) value).entrySet()) {
591 if (first) {
592 first = false;
593 } else {
594 sb.append(',');
595 }
596
597 sb.append(entry.getKey());
598 sb.append('=');
599 sb.append(entry.getValue());
600 }
601
602 sb.append("}");
603 } else {
604 sb.append(value);
605 }
606 }
607
608 sb.append("]");
609
610 return (sb.toString());
611 }
612
613
614
615
616
617
618
619
620
621 void setDynaActionFormClass(DynaActionFormClass dynaClass) {
622 this.dynaClass = dynaClass;
623 }
624
625
626
627
628
629
630
631
632
633
634
635 protected DynaProperty getDynaProperty(String name) {
636 DynaProperty descriptor = getDynaClass().getDynaProperty(name);
637
638 if (descriptor == null) {
639 throw new IllegalArgumentException("Invalid property name '" + name
640 + "'");
641 }
642
643 return (descriptor);
644 }
645
646
647
648
649
650
651
652
653
654
655 protected boolean isDynaAssignable(Class<?> dest, Class<?> source) {
656 if (dest.isAssignableFrom(source)
657 || ((dest == Boolean.TYPE) && (source == Boolean.class))
658 || ((dest == Byte.TYPE) && (source == Byte.class))
659 || ((dest == Character.TYPE) && (source == Character.class))
660 || ((dest == Double.TYPE) && (source == Double.class))
661 || ((dest == Float.TYPE) && (source == Float.class))
662 || ((dest == Integer.TYPE) && (source == Integer.class))
663 || ((dest == Long.TYPE) && (source == Long.class))
664 || ((dest == Short.TYPE) && (source == Short.class))) {
665 return (true);
666 } else {
667 return (false);
668 }
669 }
670 }