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.ArrayList;
25 import java.util.HashMap;
26
27 import org.apache.commons.beanutils.BeanUtils;
28 import org.apache.struts.util.RequestUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35
36
37
38
39
40 public class ActionConfig extends BaseConfig {
41 private static final long serialVersionUID = -7821814205678644815L;
42
43
44
45
46 private transient final Logger log =
47 LoggerFactory.getLogger(ActionConfig.class);
48
49
50
51
52
53
54
55 protected HashMap<String, ExceptionConfig> exceptions = new HashMap<>();
56
57
58
59
60
61 protected HashMap<String, ForwardConfig> forwards = new HashMap<>();
62
63
64
65
66
67
68 protected ModuleConfig moduleConfig = null;
69
70
71
72
73
74
75 protected String attribute = null;
76
77
78
79
80
81
82
83 protected String actionId = null;
84
85
86
87
88
89 protected String inherit = null;
90
91
92
93
94 private boolean cancellableSet = false;
95
96
97
98
99
100
101
102
103 protected boolean cancellable = false;
104
105
106
107
108 protected boolean extensionProcessed = false;
109
110
111
112
113
114
115
116
117 protected String forward = null;
118
119
120
121
122
123
124
125
126 protected String include = null;
127
128
129
130
131
132
133 protected String input = null;
134
135
136
137
138
139
140 protected String multipartClass = null;
141
142
143
144
145 protected String name = null;
146
147
148
149
150
151
152 protected String parameter = null;
153
154
155
156
157
158
159 protected String path = null;
160
161
162
163
164
165 protected String prefix = null;
166
167
168
169
170
171 protected String roles = null;
172
173
174
175
176
177 protected String[] roleNames = new String[0];
178
179
180
181
182
183 protected String scope = "session";
184
185
186
187
188
189 private boolean singleton = true;
190
191
192
193
194 protected String reset = PopulateEvent.ALL;
195
196 private String[] resetNames = { PopulateEvent.ALL };
197
198
199
200
201
202 protected String populate = PopulateEvent.ALL;
203
204 private String[] populateNames = { PopulateEvent.ALL };
205
206
207
208
209
210 protected String suffix = null;
211
212
213
214
215
216
217
218
219 protected String type = null;
220
221
222
223
224
225 protected boolean unknown = false;
226
227
228
229
230 private boolean validateSet = false;
231
232
233
234
235
236 protected boolean validate = true;
237
238
239
240
241
242
243
244 protected String command = null;
245
246
247
248
249
250
251
252
253
254
255
256 protected String catalog = null;
257
258
259
260
261
262
263
264 protected String dispatcher;
265
266
267
268
269
270
271
272
273
274 protected Integer acceptPage = null;
275
276
277
278
279
280
281
282
283
284
285 public String getActionId() {
286 return this.actionId;
287 }
288
289
290
291
292
293
294
295
296
297
298 public void setActionId(String actionId) {
299 if (configured) {
300 throw new IllegalStateException("Configuration is frozen");
301 }
302
303 if ((actionId != null) && (actionId.indexOf("/") > -1)) {
304 throw new IllegalArgumentException("actionId '" + actionId + "' may not contain a forward slash");
305 }
306
307 this.actionId = actionId;
308 }
309
310
311
312
313 public ModuleConfig getModuleConfig() {
314 return (this.moduleConfig);
315 }
316
317
318
319
320 public void setModuleConfig(ModuleConfig moduleConfig) {
321 if (configured) {
322 throw new IllegalStateException("Configuration is frozen");
323 }
324
325 this.moduleConfig = moduleConfig;
326 }
327
328
329
330
331
332
333
334
335 public String getAttribute() {
336 if (this.attribute == null) {
337 return (this.name);
338 } else {
339 return (this.attribute);
340 }
341 }
342
343
344
345
346
347
348
349
350
351 public void setAttribute(String attribute) {
352 if (configured) {
353 throw new IllegalStateException("Configuration is frozen");
354 }
355
356 this.attribute = attribute;
357 }
358
359
360
361
362
363
364 public boolean getCancellable() {
365 return (this.cancellable);
366 }
367
368
369
370
371
372
373 public void setCancellable(boolean cancellable) {
374 if (configured) {
375 throw new IllegalStateException("Configuration is frozen");
376 }
377
378 this.cancellable = cancellable;
379 this.cancellableSet = true;
380 }
381
382
383
384
385
386
387
388
389
390 public String getExtends() {
391 return (this.inherit);
392 }
393
394
395
396
397
398
399
400
401
402 public void setExtends(String inherit) {
403 if (configured) {
404 throw new IllegalStateException("Configuration is frozen");
405 }
406
407 this.inherit = inherit;
408 }
409
410 public boolean isExtensionProcessed() {
411 return extensionProcessed;
412 }
413
414
415
416
417
418
419
420
421 public String getForward() {
422 return (this.forward);
423 }
424
425
426
427
428
429
430
431
432
433 public void setForward(String forward) {
434 if (configured) {
435 throw new IllegalStateException("Configuration is frozen");
436 }
437
438 this.forward = forward;
439 }
440
441
442
443
444
445
446
447
448 public String getInclude() {
449 return (this.include);
450 }
451
452
453
454
455
456
457
458
459
460 public void setInclude(String include) {
461 if (configured) {
462 throw new IllegalStateException("Configuration is frozen");
463 }
464
465 this.include = include;
466 }
467
468
469
470
471
472
473
474
475 public String getInput() {
476 return (this.input);
477 }
478
479
480
481
482
483
484
485
486
487 public void setInput(String input) {
488 if (configured) {
489 throw new IllegalStateException("Configuration is frozen");
490 }
491
492 this.input = input;
493 }
494
495
496
497
498
499
500 public String getMultipartClass() {
501 return (this.multipartClass);
502 }
503
504
505
506
507
508
509
510
511
512
513 public void setMultipartClass(String multipartClass) {
514 if (configured) {
515 throw new IllegalStateException("Configuration is frozen");
516 }
517
518 this.multipartClass = multipartClass;
519 }
520
521
522
523
524 public String getName() {
525 return (this.name);
526 }
527
528
529
530
531 public void setName(String name) {
532 if (configured) {
533 throw new IllegalStateException("Configuration is frozen");
534 }
535
536 this.name = name;
537 }
538
539
540
541
542
543
544 public String getParameter() {
545 return (this.parameter);
546 }
547
548
549
550
551
552
553
554
555 public void setParameter(String parameter) {
556 if (configured) {
557 throw new IllegalStateException("Configuration is frozen");
558 }
559
560 this.parameter = parameter;
561 }
562
563
564
565
566
567
568 public String getPath() {
569 return (this.path);
570 }
571
572
573
574
575
576
577
578
579 public void setPath(String path) {
580 if (configured) {
581 throw new IllegalStateException("Configuration is frozen");
582 }
583
584 this.path = path;
585 }
586
587
588
589
590
591 public String getPrefix() {
592 return (this.prefix);
593 }
594
595
596
597
598
599 public void setPrefix(String prefix) {
600 if (configured) {
601 throw new IllegalStateException("Configuration is frozen");
602 }
603
604 this.prefix = prefix;
605 }
606
607 public String getRoles() {
608 return (this.roles);
609 }
610
611 public void setRoles(String roles) {
612 if (configured) {
613 throw new IllegalStateException("Configuration is frozen");
614 }
615
616 this.roles = roles;
617
618 if (roles == null) {
619 roleNames = new String[0];
620
621 return;
622 }
623
624 ArrayList<String> list = new ArrayList<>();
625
626 while (true) {
627 int comma = roles.indexOf(',');
628
629 if (comma < 0) {
630 break;
631 }
632
633 list.add(roles.substring(0, comma).trim());
634 roles = roles.substring(comma + 1);
635 }
636
637 roles = roles.trim();
638
639 if (roles.length() > 0) {
640 list.add(roles);
641 }
642
643 roleNames = list.toArray(new String[list.size()]);
644 }
645
646
647
648
649
650 public String[] getRoleNames() {
651 return (this.roleNames);
652 }
653
654
655
656
657
658 public String getScope() {
659 return (this.scope);
660 }
661
662
663
664
665
666 public void setScope(String scope) {
667 if (configured) {
668 throw new IllegalStateException("Configuration is frozen");
669 }
670
671 this.scope = scope;
672 }
673
674
675
676
677
678
679
680
681
682 public final String getReset() {
683 return (this.reset);
684 }
685
686
687
688
689
690
691
692
693
694 public final String[] getResetNames() {
695 return (this.resetNames);
696 }
697
698
699
700
701
702
703
704
705 public final void setReset(String reset) {
706 if (configured) {
707 throw new IllegalStateException("Configuration is frozen");
708 }
709
710 this.reset = reset;
711 this.resetNames = reset.split(",");
712 }
713
714
715
716
717
718
719
720
721
722 public final String getPopulate() {
723 return (this.populate);
724 }
725
726
727
728
729
730
731
732
733
734 public final String[] getPopulateNames() {
735 return (this.populateNames);
736 }
737
738
739
740
741
742
743
744
745 public final void setPopulate(String populate) {
746 if (configured) {
747 throw new IllegalStateException("Configuration is frozen");
748 }
749
750 this.populate = populate;
751 this.populateNames = populate.split(",");
752 }
753
754
755
756
757
758
759
760
761
762
763 public final boolean isSingleton() {
764 return this.singleton;
765 }
766
767
768
769
770
771
772
773
774 public final void setSingleton(boolean singleton) {
775 this.singleton = singleton;
776 }
777
778
779
780
781
782 public String getSuffix() {
783 return (this.suffix);
784 }
785
786
787
788
789
790 public void setSuffix(String suffix) {
791 if (configured) {
792 throw new IllegalStateException("Configuration is frozen");
793 }
794
795 this.suffix = suffix;
796 }
797
798 public String getType() {
799 return (this.type);
800 }
801
802 public void setType(String type) {
803 if (configured) {
804 throw new IllegalStateException("Configuration is frozen");
805 }
806
807 this.type = type;
808 }
809
810
811
812
813
814 public boolean getUnknown() {
815 return (this.unknown);
816 }
817
818
819
820
821
822 public void setUnknown(boolean unknown) {
823 if (configured) {
824 throw new IllegalStateException("Configuration is frozen");
825 }
826
827 this.unknown = unknown;
828 }
829
830 public boolean getValidate() {
831 return (this.validate);
832 }
833
834 public void setValidate(boolean validate) {
835 if (configured) {
836 throw new IllegalStateException("Configuration is frozen");
837 }
838
839 this.validate = validate;
840 this.validateSet = true;
841 }
842
843
844
845
846
847
848
849
850
851 public String getCommand() {
852 return (this.command);
853 }
854
855
856
857
858
859
860
861
862
863
864
865 public String getCatalog() {
866 return (this.catalog);
867 }
868
869
870
871
872
873
874
875
876
877
878 public void setCommand(String command) {
879 if (configured) {
880 throw new IllegalStateException("Configuration is frozen");
881 }
882
883 this.command = command;
884 }
885
886
887
888
889
890
891
892
893
894
895
896 public void setCatalog(String catalog) {
897 if (configured) {
898 throw new IllegalStateException("Configuration is frozen");
899 }
900
901 this.catalog = catalog;
902 }
903
904
905
906
907
908
909
910
911
912
913 public final String getDispatcher() {
914 return dispatcher;
915 }
916
917
918
919
920
921
922
923
924
925
926
927 public final void setDispatcher(String dispatcher) {
928 if (configured) {
929 throw new IllegalStateException("Configuration is frozen");
930 }
931 this.dispatcher = dispatcher;
932 }
933
934
935
936
937
938
939
940
941
942 public Integer getAcceptPage() {
943 return acceptPage;
944 }
945
946
947
948
949
950
951
952 public void setAcceptPage(Integer acceptPage) {
953 this.acceptPage = acceptPage;
954 }
955
956
957
958
959
960
961
962
963
964
965 protected boolean checkCircularInheritance(ModuleConfig moduleConfig) {
966 String ancestor = getExtends();
967
968 while (ancestor != null) {
969
970 if (getPath().equals(ancestor) || ancestor.equals(getActionId())) {
971 return true;
972 }
973
974
975 ActionConfig baseConfig = moduleConfig.findActionConfig(ancestor);
976 if (baseConfig == null) {
977 baseConfig = moduleConfig.findActionConfigId(ancestor);
978 }
979
980 if (baseConfig != null) {
981 ancestor = baseConfig.getExtends();
982 } else {
983 ancestor = null;
984 }
985 }
986
987 return false;
988 }
989
990
991
992
993
994
995
996
997 protected void inheritExceptionHandlers(ActionConfig baseConfig)
998 throws ClassNotFoundException, IllegalAccessException,
999 InstantiationException, InvocationTargetException {
1000 if (configured) {
1001 throw new IllegalStateException("Configuration is frozen");
1002 }
1003
1004
1005 ExceptionConfig[] baseHandlers = baseConfig.findExceptionConfigs();
1006
1007 for (int i = 0; i < baseHandlers.length; i++) {
1008 ExceptionConfig baseHandler = baseHandlers[i];
1009
1010
1011 ExceptionConfig copy =
1012 this.findExceptionConfig(baseHandler.getType());
1013
1014 if (copy == null) {
1015
1016 copy =
1017 (ExceptionConfig) RequestUtils.applicationInstance(baseHandler.getClass()
1018 .getName());
1019
1020 BeanUtils.copyProperties(copy, baseHandler);
1021 this.addExceptionConfig(copy);
1022 copy.setProperties(baseHandler.copyProperties());
1023 } else {
1024
1025 copy.processExtends(getModuleConfig(), this);
1026 }
1027 }
1028 }
1029
1030
1031
1032
1033
1034
1035
1036
1037 protected void inheritForwards(ActionConfig baseConfig)
1038 throws ClassNotFoundException, IllegalAccessException,
1039 InstantiationException, InvocationTargetException {
1040 if (configured) {
1041 throw new IllegalStateException("Configuration is frozen");
1042 }
1043
1044
1045 ForwardConfig[] baseForwards = baseConfig.findForwardConfigs();
1046
1047 for (ForwardConfig baseForward : baseForwards) {
1048
1049 ForwardConfig copy = this.findForwardConfig(baseForward.getName());
1050
1051 if (copy == null) {
1052
1053 copy =
1054 (ForwardConfig) RequestUtils.applicationInstance(baseForward.getClass()
1055 .getName());
1056 BeanUtils.copyProperties(copy, baseForward);
1057
1058 this.addForwardConfig(copy);
1059 copy.setProperties(baseForward.copyProperties());
1060 } else {
1061
1062 copy.processExtends(getModuleConfig(), this);
1063 }
1064 }
1065 }
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 public void addExceptionConfig(ExceptionConfig config) {
1078 if (configured) {
1079 throw new IllegalStateException("Configuration is frozen");
1080 }
1081
1082 exceptions.put(config.getType(), config);
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 public void addForwardConfig(ForwardConfig config) {
1094 if (configured) {
1095 throw new IllegalStateException("Configuration is frozen");
1096 }
1097
1098 forwards.put(config.getName(), config);
1099 }
1100
1101
1102
1103
1104
1105
1106
1107 public ExceptionConfig findExceptionConfig(String type) {
1108 return (exceptions.get(type));
1109 }
1110
1111
1112
1113
1114
1115 public ExceptionConfig[] findExceptionConfigs() {
1116 ExceptionConfig[] results = new ExceptionConfig[exceptions.size()];
1117
1118 return (exceptions.values().toArray(results));
1119 }
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135 public ExceptionConfig findException(Class<?> type) {
1136
1137 ExceptionConfig config;
1138
1139 while (true) {
1140
1141 String name = type.getName();
1142
1143 log.debug("findException: look locally for {}", name);
1144 config = findExceptionConfig(name);
1145
1146 if (config != null) {
1147 return (config);
1148 }
1149
1150
1151 log.debug("findException: look globally for {}", name);
1152 config = getModuleConfig().findExceptionConfig(name);
1153
1154 if (config != null) {
1155 return (config);
1156 }
1157
1158
1159 type = type.getSuperclass();
1160
1161 if (type == null) {
1162 break;
1163 }
1164 }
1165
1166 return (null);
1167 }
1168
1169
1170
1171
1172
1173
1174
1175 public ForwardConfig findForwardConfig(String name) {
1176 return (forwards.get(name));
1177 }
1178
1179
1180
1181
1182
1183 public ForwardConfig[] findForwardConfigs() {
1184 ForwardConfig[] results = new ForwardConfig[forwards.size()];
1185
1186 return (forwards.values().toArray(results));
1187 }
1188
1189
1190
1191
1192 public void freeze() {
1193 super.freeze();
1194
1195 ExceptionConfig[] econfigs = findExceptionConfigs();
1196
1197 for (int i = 0; i < econfigs.length; i++) {
1198 econfigs[i].freeze();
1199 }
1200
1201 ForwardConfig[] fconfigs = findForwardConfigs();
1202
1203 for (int i = 0; i < fconfigs.length; i++) {
1204 fconfigs[i].freeze();
1205 }
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233 public void inheritFrom(ActionConfig config)
1234 throws ClassNotFoundException, IllegalAccessException,
1235 InstantiationException, InvocationTargetException {
1236 if (configured) {
1237 throw new IllegalStateException("Configuration is frozen");
1238 }
1239
1240
1241 if (getAttribute() == null) {
1242 setAttribute(config.getAttribute());
1243 }
1244
1245 if (!cancellableSet) {
1246 setCancellable(config.getCancellable());
1247 }
1248
1249 if (getCatalog() == null) {
1250 setCatalog(config.getCatalog());
1251 }
1252
1253 if (getCommand() == null) {
1254 setCommand(config.getCommand());
1255 }
1256
1257 if (getForward() == null) {
1258 setForward(config.getForward());
1259 }
1260
1261 if (getInclude() == null) {
1262 setInclude(config.getInclude());
1263 }
1264
1265 if (getInput() == null) {
1266 setInput(config.getInput());
1267 }
1268
1269 if (getMultipartClass() == null) {
1270 setMultipartClass(config.getMultipartClass());
1271 }
1272
1273 if (getName() == null) {
1274 setName(config.getName());
1275 }
1276
1277 if (getParameter() == null) {
1278 setParameter(config.getParameter());
1279 }
1280
1281 if (getPath() == null) {
1282 setPath(config.getPath());
1283 }
1284
1285 if (getPrefix() == null) {
1286 setPrefix(config.getPrefix());
1287 }
1288
1289 if (getRoles() == null) {
1290 setRoles(config.getRoles());
1291 }
1292
1293 if (getScope().equals("session")) {
1294 setScope(config.getScope());
1295 }
1296
1297 if (getSuffix() == null) {
1298 setSuffix(config.getSuffix());
1299 }
1300
1301 if (getType() == null) {
1302 setType(config.getType());
1303 }
1304
1305 if (!getUnknown()) {
1306 setUnknown(config.getUnknown());
1307 }
1308
1309 if (!validateSet) {
1310 setValidate(config.getValidate());
1311 }
1312
1313
1314
1315 if (getAcceptPage() == null) {
1316 setAcceptPage(config.getAcceptPage());
1317 }
1318
1319 inheritExceptionHandlers(config);
1320 inheritForwards(config);
1321 inheritProperties(config);
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333 public void processExtends(ModuleConfig moduleConfig)
1334 throws ClassNotFoundException, IllegalAccessException,
1335 InstantiationException, InvocationTargetException {
1336 if (configured) {
1337 throw new IllegalStateException("Configuration is frozen");
1338 }
1339
1340 String ancestor = getExtends();
1341
1342 if ((!extensionProcessed) && (ancestor != null)) {
1343 ActionConfig baseConfig =
1344 moduleConfig.findActionConfig(ancestor);
1345 if (baseConfig == null) {
1346 baseConfig = moduleConfig.findActionConfigId(ancestor);
1347 }
1348
1349 if (baseConfig == null) {
1350 throw new NullPointerException("Unable to find "
1351 + "action for '" + ancestor + "' to extend.");
1352 }
1353
1354
1355
1356 if (checkCircularInheritance(moduleConfig)) {
1357 throw new IllegalArgumentException(
1358 "Circular inheritance detected for action " + getPath());
1359 }
1360
1361
1362 if (!baseConfig.isExtensionProcessed()) {
1363 baseConfig.processExtends(moduleConfig);
1364 }
1365
1366
1367 inheritFrom(baseConfig);
1368 }
1369
1370 extensionProcessed = true;
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380 public void removeExceptionConfig(ExceptionConfig config) {
1381 if (configured) {
1382 throw new IllegalStateException("Configuration is frozen");
1383 }
1384
1385 exceptions.remove(config.getType());
1386 }
1387
1388
1389
1390
1391
1392
1393
1394
1395 public void removeForwardConfig(ForwardConfig config) {
1396 if (configured) {
1397 throw new IllegalStateException("Configuration is frozen");
1398 }
1399
1400 forwards.remove(config.getName());
1401 }
1402
1403
1404
1405
1406 public String toString() {
1407 StringBuilder sb = new StringBuilder("ActionConfig[");
1408
1409 sb.append("cancellable=");
1410 sb.append(cancellable);
1411
1412 sb.append(",path=");
1413 sb.append(path);
1414
1415 sb.append(",validate=");
1416 sb.append(validate);
1417
1418 if (actionId != null) {
1419 sb.append(",actionId=");
1420 sb.append(actionId);
1421 }
1422
1423 if (attribute != null) {
1424 sb.append(",attribute=");
1425 sb.append(attribute);
1426 }
1427
1428 if (catalog != null) {
1429 sb.append(",catalog=");
1430 sb.append(catalog);
1431 }
1432
1433 if (command != null) {
1434 sb.append(",command=");
1435 sb.append(command);
1436 }
1437
1438 if (dispatcher != null) {
1439 sb.append(",dispatcher=");
1440 sb.append(dispatcher);
1441 }
1442
1443 if (forward != null) {
1444 sb.append(",forward=");
1445 sb.append(forward);
1446 }
1447
1448 if (include != null) {
1449 sb.append(",include=");
1450 sb.append(include);
1451 }
1452
1453 if (inherit != null) {
1454 sb.append(",extends=");
1455 sb.append(inherit);
1456 }
1457
1458 if (input != null) {
1459 sb.append(",input=");
1460 sb.append(input);
1461 }
1462
1463 if (multipartClass != null) {
1464 sb.append(",multipartClass=");
1465 sb.append(multipartClass);
1466 }
1467
1468 if (name != null) {
1469 sb.append(",name=");
1470 sb.append(name);
1471 }
1472
1473 if (parameter != null) {
1474 sb.append(",parameter=");
1475 sb.append(parameter);
1476 }
1477
1478 if (prefix != null) {
1479 sb.append(",prefix=");
1480 sb.append(prefix);
1481 }
1482
1483 if (roles != null) {
1484 sb.append(",roles=");
1485 sb.append(roles);
1486 }
1487
1488 if (scope != null) {
1489 sb.append(",scope=");
1490 sb.append(scope);
1491 }
1492
1493 if (reset != null) {
1494 sb.append(",reset=");
1495 sb.append(reset);
1496 }
1497
1498 if (populate != null) {
1499 sb.append(",populate=");
1500 sb.append(populate);
1501 }
1502
1503 sb.append(",singleton=");
1504 sb.append(singleton);
1505
1506 if (suffix != null) {
1507 sb.append(",suffix=");
1508 sb.append(suffix);
1509 }
1510
1511 if (type != null) {
1512 sb.append(",type=");
1513 sb.append(type);
1514 }
1515
1516
1517
1518 if (acceptPage != null) {
1519 sb.append(",acceptPage=");
1520 sb.append(acceptPage);
1521 }
1522
1523 sb.append("]");
1524 return (sb.toString());
1525 }
1526 }