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