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 org.apache.commons.beanutils.BeanUtils;
24 import org.apache.commons.beanutils.ConvertUtils;
25 import org.apache.commons.beanutils.PropertyUtils;
26 import org.apache.commons.beanutils.converters.BigDecimalConverter;
27 import org.apache.commons.beanutils.converters.BigIntegerConverter;
28 import org.apache.commons.beanutils.converters.BooleanConverter;
29 import org.apache.commons.beanutils.converters.ByteConverter;
30 import org.apache.commons.beanutils.converters.CharacterConverter;
31 import org.apache.commons.beanutils.converters.DoubleConverter;
32 import org.apache.commons.beanutils.converters.FloatConverter;
33 import org.apache.commons.beanutils.converters.IntegerConverter;
34 import org.apache.commons.beanutils.converters.LongConverter;
35 import org.apache.commons.beanutils.converters.ShortConverter;
36 import org.apache.commons.chain.CatalogFactory;
37 import org.apache.commons.chain.config.ConfigParser;
38 import org.apache.commons.digester.Digester;
39 import org.apache.commons.digester.RuleSet;
40 import org.apache.commons.logging.Log;
41 import org.apache.commons.logging.LogFactory;
42 import org.apache.struts.Globals;
43 import org.apache.struts.config.ActionConfig;
44 import org.apache.struts.config.ConfigRuleSet;
45 import org.apache.struts.config.ExceptionConfig;
46 import org.apache.struts.config.FormBeanConfig;
47 import org.apache.struts.config.FormPropertyConfig;
48 import org.apache.struts.config.ForwardConfig;
49 import org.apache.struts.config.MessageResourcesConfig;
50 import org.apache.struts.config.ModuleConfig;
51 import org.apache.struts.config.ModuleConfigFactory;
52 import org.apache.struts.config.PlugInConfig;
53 import org.apache.struts.util.MessageResources;
54 import org.apache.struts.util.MessageResourcesFactory;
55 import org.apache.struts.util.ModuleUtils;
56 import org.apache.struts.util.RequestUtils;
57 import org.xml.sax.InputSource;
58 import org.xml.sax.SAXException;
59
60 import javax.servlet.ServletContext;
61 import javax.servlet.ServletException;
62 import javax.servlet.UnavailableException;
63 import javax.servlet.http.HttpServlet;
64 import javax.servlet.http.HttpServletRequest;
65 import javax.servlet.http.HttpServletResponse;
66
67 import java.io.IOException;
68 import java.io.InputStream;
69
70 import java.math.BigDecimal;
71 import java.math.BigInteger;
72
73 import java.net.MalformedURLException;
74 import java.net.URL;
75 import java.net.URLConnection;
76
77 import java.util.ArrayList;
78 import java.util.Enumeration;
79 import java.util.Iterator;
80 import java.util.List;
81 import java.util.MissingResourceException;
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public class ActionServlet extends HttpServlet {
207
208
209
210
211
212 protected static Log log = LogFactory.getLog(ActionServlet.class);
213
214
215
216
217
218
219
220 protected String config = "/WEB-INF/struts-config.xml";
221
222
223
224
225
226
227 protected String chainConfig = "org/apache/struts/chain/chain-config.xml";
228
229
230
231
232
233
234
235 protected Digester configDigester = null;
236
237
238
239
240
241
242
243 protected boolean convertNull = false;
244
245
246
247
248 protected MessageResources internal = null;
249
250
251
252
253
254
255 protected String internalName = "org.apache.struts.action.ActionResources";
256
257
258
259
260
261
262 protected String[] registrations =
263 {
264 "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",
265 "/org/apache/struts/resources/struts-config_1_0.dtd",
266 "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN",
267 "/org/apache/struts/resources/struts-config_1_1.dtd",
268 "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN",
269 "/org/apache/struts/resources/struts-config_1_2.dtd",
270 "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN",
271 "/org/apache/struts/resources/struts-config_1_3.dtd",
272 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
273 "/org/apache/struts/resources/web-app_2_3.dtd"
274 };
275
276
277
278
279
280 protected String servletMapping = null;
281
282
283
284
285
286 protected String servletName = null;
287
288
289
290
291
292
293
294 public void destroy() {
295 if (log.isDebugEnabled()) {
296 log.debug(internal.getMessage("finalizing"));
297 }
298
299 destroyModules();
300 destroyInternal();
301 getServletContext().removeAttribute(Globals.ACTION_SERVLET_KEY);
302
303 CatalogFactory.clear();
304 PropertyUtils.clearDescriptors();
305
306
307 ClassLoader classLoader =
308 Thread.currentThread().getContextClassLoader();
309
310 if (classLoader == null) {
311 classLoader = ActionServlet.class.getClassLoader();
312 }
313
314 try {
315 LogFactory.release(classLoader);
316 } catch (Throwable t) {
317 ;
318
319
320
321
322
323
324
325
326
327
328
329 }
330 }
331
332
333
334
335
336
337
338
339 public void init() throws ServletException {
340 final String configPrefix = "config/";
341 final int configPrefixLength = configPrefix.length() - 1;
342
343
344
345
346 try {
347 initInternal();
348 initOther();
349 initServlet();
350 initChain();
351
352 getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
353 initModuleConfigFactory();
354
355
356 ModuleConfig moduleConfig = initModuleConfig("", config);
357
358 initModuleMessageResources(moduleConfig);
359 initModulePlugIns(moduleConfig);
360 initModuleFormBeans(moduleConfig);
361 initModuleForwards(moduleConfig);
362 initModuleExceptionConfigs(moduleConfig);
363 initModuleActions(moduleConfig);
364 moduleConfig.freeze();
365
366 Enumeration names = getServletConfig().getInitParameterNames();
367
368 while (names.hasMoreElements()) {
369 String name = (String) names.nextElement();
370
371 if (!name.startsWith(configPrefix)) {
372 continue;
373 }
374
375 String prefix = name.substring(configPrefixLength);
376
377 moduleConfig =
378 initModuleConfig(prefix,
379 getServletConfig().getInitParameter(name));
380 initModuleMessageResources(moduleConfig);
381 initModulePlugIns(moduleConfig);
382 initModuleFormBeans(moduleConfig);
383 initModuleForwards(moduleConfig);
384 initModuleExceptionConfigs(moduleConfig);
385 initModuleActions(moduleConfig);
386 moduleConfig.freeze();
387 }
388
389 this.initModulePrefixes(this.getServletContext());
390
391 this.destroyConfigDigester();
392 } catch (UnavailableException ex) {
393 throw ex;
394 } catch (Throwable t) {
395
396
397
398 log.error("Unable to initialize Struts ActionServlet due to an "
399 + "unexpected exception or error thrown, so marking the "
400 + "servlet as unavailable. Most likely, this is due to an "
401 + "incorrect or missing library dependency.", t);
402 throw new UnavailableException(t.getMessage());
403 }
404 }
405
406
407
408
409
410
411
412
413
414 protected void initModulePrefixes(ServletContext context) {
415 ArrayList prefixList = new ArrayList();
416
417 Enumeration names = context.getAttributeNames();
418
419 while (names.hasMoreElements()) {
420 String name = (String) names.nextElement();
421
422 if (!name.startsWith(Globals.MODULE_KEY)) {
423 continue;
424 }
425
426 String prefix = name.substring(Globals.MODULE_KEY.length());
427
428 if (prefix.length() > 0) {
429 prefixList.add(prefix);
430 }
431 }
432
433 String[] prefixes =
434 (String[]) prefixList.toArray(new String[prefixList.size()]);
435
436 context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
437 }
438
439
440
441
442
443
444
445
446
447 public void doGet(HttpServletRequest request, HttpServletResponse response)
448 throws IOException, ServletException {
449 process(request, response);
450 }
451
452
453
454
455
456
457
458
459
460 public void doPost(HttpServletRequest request, HttpServletResponse response)
461 throws IOException, ServletException {
462 process(request, response);
463 }
464
465
466
467
468
469
470
471
472
473
474 public void addServletMapping(String servletName, String urlPattern) {
475 if (servletName == null) {
476 return;
477 }
478
479 if (servletName.equals(this.servletName)) {
480 if (log.isDebugEnabled()) {
481 log.debug("Process servletName=" + servletName
482 + ", urlPattern=" + urlPattern);
483 }
484
485 this.servletMapping = urlPattern;
486 }
487 }
488
489
490
491
492
493
494
495
496
497 public MessageResources getInternal() {
498 return (this.internal);
499 }
500
501
502
503
504
505
506
507
508
509 protected void destroyModules() {
510 ArrayList values = new ArrayList();
511 Enumeration names = getServletContext().getAttributeNames();
512
513 while (names.hasMoreElements()) {
514 values.add(names.nextElement());
515 }
516
517 Iterator keys = values.iterator();
518
519 while (keys.hasNext()) {
520 String name = (String) keys.next();
521 Object value = getServletContext().getAttribute(name);
522
523 if (!(value instanceof ModuleConfig)) {
524 continue;
525 }
526
527 ModuleConfig config = (ModuleConfig) value;
528
529 if (this.getProcessorForModule(config) != null) {
530 this.getProcessorForModule(config).destroy();
531 }
532
533 getServletContext().removeAttribute(name);
534
535 PlugIn[] plugIns =
536 (PlugIn[]) getServletContext().getAttribute(Globals.PLUG_INS_KEY
537 + config.getPrefix());
538
539 if (plugIns != null) {
540 for (int i = 0; i < plugIns.length; i++) {
541 int j = plugIns.length - (i + 1);
542
543 plugIns[j].destroy();
544 }
545
546 getServletContext().removeAttribute(Globals.PLUG_INS_KEY
547 + config.getPrefix());
548 }
549 }
550 }
551
552
553
554
555
556
557
558 protected void destroyConfigDigester() {
559 configDigester = null;
560 }
561
562
563
564
565 protected void destroyInternal() {
566 internal = null;
567 }
568
569
570
571
572
573
574
575
576
577
578 protected ModuleConfig getModuleConfig(HttpServletRequest request) {
579 ModuleConfig config =
580 (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);
581
582 if (config == null) {
583 config =
584 (ModuleConfig) getServletContext().getAttribute(Globals.MODULE_KEY);
585 }
586
587 return (config);
588 }
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604 protected synchronized RequestProcessor getRequestProcessor(
605 ModuleConfig config) throws ServletException {
606 RequestProcessor processor = this.getProcessorForModule(config);
607
608 if (processor == null) {
609 try {
610 processor =
611 (RequestProcessor) RequestUtils.applicationInstance(config.getControllerConfig()
612 .getProcessorClass());
613 } catch (Exception e) {
614 throw new UnavailableException(
615 "Cannot initialize RequestProcessor of class "
616 + config.getControllerConfig().getProcessorClass() + ": "
617 + e);
618 }
619
620 processor.init(this, config);
621
622 String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
623
624 getServletContext().setAttribute(key, processor);
625 }
626
627 return (processor);
628 }
629
630
631
632
633
634
635
636
637
638 private RequestProcessor getProcessorForModule(ModuleConfig config) {
639 String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
640
641 return (RequestProcessor) getServletContext().getAttribute(key);
642 }
643
644
645
646
647
648
649 protected void initModuleConfigFactory() {
650 String configFactory =
651 getServletConfig().getInitParameter("configFactory");
652
653 if (configFactory != null) {
654 ModuleConfigFactory.setFactoryClass(configFactory);
655 }
656 }
657
658
659
660
661
662
663
664
665
666
667
668
669 protected ModuleConfig initModuleConfig(String prefix, String paths)
670 throws ServletException {
671 if (log.isDebugEnabled()) {
672 log.debug("Initializing module path '" + prefix
673 + "' configuration from '" + paths + "'");
674 }
675
676
677 ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();
678 ModuleConfig config = factoryObject.createModuleConfig(prefix);
679
680
681 Digester digester = initConfigDigester();
682
683 List urls = splitAndResolvePaths(paths);
684 URL url;
685
686 for (Iterator i = urls.iterator(); i.hasNext();) {
687 url = (URL) i.next();
688 digester.push(config);
689 this.parseModuleConfigFile(digester, url);
690 }
691
692 getServletContext().setAttribute(Globals.MODULE_KEY
693 + config.getPrefix(), config);
694
695 return config;
696 }
697
698
699
700
701
702
703
704
705
706
707
708 protected void parseModuleConfigFile(Digester digester, String path)
709 throws UnavailableException {
710 try {
711 List paths = splitAndResolvePaths(path);
712
713 if (paths.size() > 0) {
714
715 URL url = (URL) paths.get(0);
716
717 parseModuleConfigFile(digester, url);
718 } else {
719 throw new UnavailableException("Cannot locate path " + path);
720 }
721 } catch (UnavailableException ex) {
722 throw ex;
723 } catch (ServletException ex) {
724 handleConfigException(path, ex);
725 }
726 }
727
728
729
730
731
732
733
734
735
736 protected void parseModuleConfigFile(Digester digester, URL url)
737 throws UnavailableException {
738
739 try {
740 digester.parse(url);
741 } catch (IOException e) {
742 handleConfigException(url.toString(), e);
743 } catch (SAXException e) {
744 handleConfigException(url.toString(), e);
745 }
746 }
747
748
749
750
751
752
753
754
755
756 private void handleConfigException(String path, Exception e)
757 throws UnavailableException {
758 String msg = internal.getMessage("configParse", path);
759
760 log.error(msg, e);
761 throw new UnavailableException(msg);
762 }
763
764
765
766
767
768
769
770
771
772 private void handleCreationException(String className, Exception e)
773 throws ServletException {
774 String errorMessage =
775 internal.getMessage("configExtends.creation", className);
776
777 log.error(errorMessage, e);
778 throw new UnavailableException(errorMessage);
779 }
780
781
782
783
784
785
786
787
788
789
790 private void handleGeneralExtensionException(String configType,
791 String configName, Exception e)
792 throws ServletException {
793 String errorMessage =
794 internal.getMessage("configExtends", configType, configName);
795
796 log.error(errorMessage, e);
797 throw new UnavailableException(errorMessage);
798 }
799
800
801
802
803
804
805
806
807
808
809
810 private void handleValueRequiredException(String field, String configType,
811 String configName) throws ServletException {
812 String errorMessage =
813 internal.getMessage("configFieldRequired", field, configType,
814 configName);
815
816 log.error(errorMessage);
817 throw new UnavailableException(errorMessage);
818 }
819
820
821
822
823
824
825
826
827 protected void initModulePlugIns(ModuleConfig config)
828 throws ServletException {
829 if (log.isDebugEnabled()) {
830 log.debug("Initializing module path '" + config.getPrefix()
831 + "' plug ins");
832 }
833
834 PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
835 PlugIn[] plugIns = new PlugIn[plugInConfigs.length];
836
837 getServletContext().setAttribute(Globals.PLUG_INS_KEY
838 + config.getPrefix(), plugIns);
839
840 for (int i = 0; i < plugIns.length; i++) {
841 try {
842 plugIns[i] =
843 (PlugIn) RequestUtils.applicationInstance(plugInConfigs[i]
844 .getClassName());
845 BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties());
846
847
848
849
850 try {
851 PropertyUtils.setProperty(plugIns[i],
852 "currentPlugInConfigObject", plugInConfigs[i]);
853 } catch (Exception e) {
854 ;
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869 }
870
871 plugIns[i].init(this, config);
872 } catch (ServletException e) {
873 throw e;
874 } catch (Exception e) {
875 String errMsg =
876 internal.getMessage("plugIn.init",
877 plugInConfigs[i].getClassName());
878
879 log(errMsg, e);
880 throw new UnavailableException(errMsg);
881 }
882 }
883 }
884
885
886
887
888
889
890
891
892 protected void initModuleFormBeans(ModuleConfig config)
893 throws ServletException {
894 if (log.isDebugEnabled()) {
895 log.debug("Initializing module path '" + config.getPrefix()
896 + "' form beans");
897 }
898
899
900 FormBeanConfig[] formBeans = config.findFormBeanConfigs();
901
902 for (int i = 0; i < formBeans.length; i++) {
903 FormBeanConfig beanConfig = formBeans[i];
904
905 processFormBeanExtension(beanConfig, config);
906 }
907
908 for (int i = 0; i < formBeans.length; i++) {
909 FormBeanConfig formBean = formBeans[i];
910
911
912 if (formBean.getType() == null) {
913 handleValueRequiredException("type", formBean.getName(),
914 "form bean");
915 }
916
917
918 FormPropertyConfig[] fpcs = formBean.findFormPropertyConfigs();
919
920 for (int j = 0; j < fpcs.length; j++) {
921 FormPropertyConfig property = fpcs[j];
922
923 if (property.getType() == null) {
924 handleValueRequiredException("type", property.getName(),
925 "form property");
926 }
927 }
928
929
930
931 if (formBean.getDynamic()) {
932 formBean.getDynaActionFormClass();
933 }
934 }
935 }
936
937
938
939
940
941
942
943
944 protected void processFormBeanExtension(FormBeanConfig beanConfig,
945 ModuleConfig moduleConfig)
946 throws ServletException {
947 try {
948 if (!beanConfig.isExtensionProcessed()) {
949 if (log.isDebugEnabled()) {
950 log.debug("Processing extensions for '"
951 + beanConfig.getName() + "'");
952 }
953
954 beanConfig =
955 processFormBeanConfigClass(beanConfig, moduleConfig);
956
957 beanConfig.processExtends(moduleConfig);
958 }
959 } catch (ServletException e) {
960 throw e;
961 } catch (Exception e) {
962 handleGeneralExtensionException("FormBeanConfig",
963 beanConfig.getName(), e);
964 }
965 }
966
967
968
969
970
971
972
973
974
975
976
977
978
979 protected FormBeanConfig processFormBeanConfigClass(
980 FormBeanConfig beanConfig, ModuleConfig moduleConfig)
981 throws ServletException {
982 String ancestor = beanConfig.getExtends();
983
984 if (ancestor == null) {
985
986 return beanConfig;
987 }
988
989
990 FormBeanConfig baseConfig = moduleConfig.findFormBeanConfig(ancestor);
991
992 if (baseConfig == null) {
993 throw new UnavailableException("Unable to find " + "form bean '"
994 + ancestor + "' to extend.");
995 }
996
997
998 if (beanConfig.getClass().equals(FormBeanConfig.class)) {
999
1000 if (!baseConfig.getClass().equals(beanConfig.getClass())) {
1001
1002 FormBeanConfig newBeanConfig = null;
1003 String baseConfigClassName = baseConfig.getClass().getName();
1004
1005 try {
1006 newBeanConfig =
1007 (FormBeanConfig) RequestUtils.applicationInstance(baseConfigClassName);
1008
1009
1010 BeanUtils.copyProperties(newBeanConfig, beanConfig);
1011
1012 FormPropertyConfig[] fpc =
1013 beanConfig.findFormPropertyConfigs();
1014
1015 for (int i = 0; i < fpc.length; i++) {
1016 newBeanConfig.addFormPropertyConfig(fpc[i]);
1017 }
1018 } catch (Exception e) {
1019 handleCreationException(baseConfigClassName, e);
1020 }
1021
1022
1023 moduleConfig.removeFormBeanConfig(beanConfig);
1024 moduleConfig.addFormBeanConfig(newBeanConfig);
1025 beanConfig = newBeanConfig;
1026 }
1027 }
1028
1029 return beanConfig;
1030 }
1031
1032
1033
1034
1035
1036
1037
1038 protected void initModuleForwards(ModuleConfig config)
1039 throws ServletException {
1040 if (log.isDebugEnabled()) {
1041 log.debug("Initializing module path '" + config.getPrefix()
1042 + "' forwards");
1043 }
1044
1045
1046 ForwardConfig[] forwards = config.findForwardConfigs();
1047
1048 for (int i = 0; i < forwards.length; i++) {
1049 ForwardConfig forward = forwards[i];
1050
1051 processForwardExtension(forward, config, null);
1052 }
1053
1054 for (int i = 0; i < forwards.length; i++) {
1055 ForwardConfig forward = forwards[i];
1056
1057
1058 if (forward.getPath() == null) {
1059 handleValueRequiredException("path", forward.getName(),
1060 "global forward");
1061 }
1062 }
1063 }
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076 protected void processForwardExtension(ForwardConfig forwardConfig,
1077 ModuleConfig moduleConfig, ActionConfig actionConfig)
1078 throws ServletException {
1079 try {
1080 if (!forwardConfig.isExtensionProcessed()) {
1081 if (log.isDebugEnabled()) {
1082 log.debug("Processing extensions for '"
1083 + forwardConfig.getName() + "'");
1084 }
1085
1086 forwardConfig =
1087 processForwardConfigClass(forwardConfig, moduleConfig,
1088 actionConfig);
1089
1090 forwardConfig.processExtends(moduleConfig, actionConfig);
1091 }
1092 } catch (ServletException e) {
1093 throw e;
1094 } catch (Exception e) {
1095 handleGeneralExtensionException("Forward", forwardConfig.getName(),
1096 e);
1097 }
1098 }
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 protected ForwardConfig processForwardConfigClass(
1117 ForwardConfig forwardConfig, ModuleConfig moduleConfig,
1118 ActionConfig actionConfig)
1119 throws ServletException {
1120 String ancestor = forwardConfig.getExtends();
1121
1122 if (ancestor == null) {
1123
1124 return forwardConfig;
1125 }
1126
1127
1128 ForwardConfig baseConfig = null;
1129 if (actionConfig != null) {
1130
1131 baseConfig = actionConfig.findForwardConfig(ancestor);
1132 }
1133
1134 if (baseConfig == null) {
1135
1136
1137 baseConfig = moduleConfig.findForwardConfig(ancestor);
1138 }
1139
1140 if (baseConfig == null) {
1141 throw new UnavailableException("Unable to find " + "forward '"
1142 + ancestor + "' to extend.");
1143 }
1144
1145
1146 if (forwardConfig.getClass().equals(ActionForward.class)) {
1147
1148 if (!baseConfig.getClass().equals(forwardConfig.getClass())) {
1149
1150 ForwardConfig newForwardConfig = null;
1151 String baseConfigClassName = baseConfig.getClass().getName();
1152
1153 try {
1154 newForwardConfig =
1155 (ForwardConfig) RequestUtils.applicationInstance(
1156 baseConfigClassName);
1157
1158
1159 BeanUtils.copyProperties(newForwardConfig, forwardConfig);
1160 } catch (Exception e) {
1161 handleCreationException(baseConfigClassName, e);
1162 }
1163
1164
1165 if (actionConfig != null) {
1166 actionConfig.removeForwardConfig(forwardConfig);
1167 actionConfig.addForwardConfig(newForwardConfig);
1168 } else {
1169
1170 moduleConfig.removeForwardConfig(forwardConfig);
1171 moduleConfig.addForwardConfig(newForwardConfig);
1172 }
1173 forwardConfig = newForwardConfig;
1174 }
1175 }
1176
1177 return forwardConfig;
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187 protected void initModuleExceptionConfigs(ModuleConfig config)
1188 throws ServletException {
1189 if (log.isDebugEnabled()) {
1190 log.debug("Initializing module path '" + config.getPrefix()
1191 + "' forwards");
1192 }
1193
1194
1195 ExceptionConfig[] exceptions = config.findExceptionConfigs();
1196
1197 for (int i = 0; i < exceptions.length; i++) {
1198 ExceptionConfig exception = exceptions[i];
1199
1200 processExceptionExtension(exception, config, null);
1201 }
1202
1203 for (int i = 0; i < exceptions.length; i++) {
1204 ExceptionConfig exception = exceptions[i];
1205
1206
1207 if (exception.getKey() == null) {
1208 handleValueRequiredException("key", exception.getType(),
1209 "global exception config");
1210 }
1211 }
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 protected void processExceptionExtension(ExceptionConfig exceptionConfig,
1226 ModuleConfig moduleConfig, ActionConfig actionConfig)
1227 throws ServletException {
1228 try {
1229 if (!exceptionConfig.isExtensionProcessed()) {
1230 if (log.isDebugEnabled()) {
1231 log.debug("Processing extensions for '"
1232 + exceptionConfig.getType() + "'");
1233 }
1234
1235 exceptionConfig =
1236 processExceptionConfigClass(exceptionConfig, moduleConfig,
1237 actionConfig);
1238
1239 exceptionConfig.processExtends(moduleConfig, actionConfig);
1240 }
1241 } catch (ServletException e) {
1242 throw e;
1243 } catch (Exception e) {
1244 handleGeneralExtensionException("Exception",
1245 exceptionConfig.getType(), e);
1246 }
1247 }
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 protected ExceptionConfig processExceptionConfigClass(
1265 ExceptionConfig exceptionConfig, ModuleConfig moduleConfig,
1266 ActionConfig actionConfig)
1267 throws ServletException {
1268 String ancestor = exceptionConfig.getExtends();
1269
1270 if (ancestor == null) {
1271
1272 return exceptionConfig;
1273 }
1274
1275
1276 ExceptionConfig baseConfig = null;
1277 if (actionConfig != null) {
1278 baseConfig = actionConfig.findExceptionConfig(ancestor);
1279 }
1280
1281 if (baseConfig == null) {
1282
1283
1284 baseConfig = moduleConfig.findExceptionConfig(ancestor);
1285 }
1286
1287 if (baseConfig == null) {
1288 throw new UnavailableException("Unable to find "
1289 + "exception config '" + ancestor + "' to extend.");
1290 }
1291
1292
1293 if (exceptionConfig.getClass().equals(ExceptionConfig.class)) {
1294
1295 if (!baseConfig.getClass().equals(exceptionConfig.getClass())) {
1296
1297 ExceptionConfig newExceptionConfig = null;
1298 String baseConfigClassName = baseConfig.getClass().getName();
1299
1300 try {
1301 newExceptionConfig =
1302 (ExceptionConfig) RequestUtils.applicationInstance(
1303 baseConfigClassName);
1304
1305
1306 BeanUtils.copyProperties(newExceptionConfig,
1307 exceptionConfig);
1308 } catch (Exception e) {
1309 handleCreationException(baseConfigClassName, e);
1310 }
1311
1312
1313 if (actionConfig != null) {
1314 actionConfig.removeExceptionConfig(exceptionConfig);
1315 actionConfig.addExceptionConfig(newExceptionConfig);
1316 } else {
1317 moduleConfig.removeExceptionConfig(exceptionConfig);
1318 moduleConfig.addExceptionConfig(newExceptionConfig);
1319 }
1320 exceptionConfig = newExceptionConfig;
1321 }
1322 }
1323
1324 return exceptionConfig;
1325 }
1326
1327
1328
1329
1330
1331
1332
1333
1334 protected void initModuleActions(ModuleConfig config)
1335 throws ServletException {
1336 if (log.isDebugEnabled()) {
1337 log.debug("Initializing module path '" + config.getPrefix()
1338 + "' action configs");
1339 }
1340
1341
1342 ActionConfig[] actionConfigs = config.findActionConfigs();
1343
1344 for (int i = 0; i < actionConfigs.length; i++) {
1345 ActionConfig actionConfig = actionConfigs[i];
1346
1347 processActionConfigExtension(actionConfig, config);
1348 }
1349
1350 for (int i = 0; i < actionConfigs.length; i++) {
1351 ActionConfig actionConfig = actionConfigs[i];
1352
1353
1354
1355 ForwardConfig[] forwards = actionConfig.findForwardConfigs();
1356
1357 for (int j = 0; j < forwards.length; j++) {
1358 ForwardConfig forward = forwards[j];
1359
1360 if (forward.getPath() == null) {
1361 handleValueRequiredException("path", forward.getName(),
1362 "action forward");
1363 }
1364 }
1365
1366
1367 ExceptionConfig[] exceptions = actionConfig.findExceptionConfigs();
1368
1369 for (int j = 0; j < exceptions.length; j++) {
1370 ExceptionConfig exception = exceptions[j];
1371
1372 if (exception.getKey() == null) {
1373 handleValueRequiredException("key", exception.getType(),
1374 "action exception config");
1375 }
1376 }
1377 }
1378 }
1379
1380
1381
1382
1383
1384
1385
1386
1387 protected void processActionConfigExtension(ActionConfig actionConfig,
1388 ModuleConfig moduleConfig)
1389 throws ServletException {
1390 try {
1391 if (!actionConfig.isExtensionProcessed()) {
1392 if (log.isDebugEnabled()) {
1393 log.debug("Processing extensions for '"
1394 + actionConfig.getPath() + "'");
1395 }
1396
1397 actionConfig =
1398 processActionConfigClass(actionConfig, moduleConfig);
1399
1400 actionConfig.processExtends(moduleConfig);
1401 }
1402
1403
1404 ForwardConfig[] forwards = actionConfig.findForwardConfigs();
1405 for (int i = 0; i < forwards.length; i++) {
1406 ForwardConfig forward = forwards[i];
1407 processForwardExtension(forward, moduleConfig, actionConfig);
1408 }
1409
1410
1411 ExceptionConfig[] exceptions = actionConfig.findExceptionConfigs();
1412 for (int i = 0; i < exceptions.length; i++) {
1413 ExceptionConfig exception = exceptions[i];
1414 processExceptionExtension(exception, moduleConfig,
1415 actionConfig);
1416 }
1417 } catch (ServletException e) {
1418 throw e;
1419 } catch (Exception e) {
1420 handleGeneralExtensionException("Action", actionConfig.getPath(), e);
1421 }
1422 }
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435 protected ActionConfig processActionConfigClass(ActionConfig actionConfig,
1436 ModuleConfig moduleConfig)
1437 throws ServletException {
1438 String ancestor = actionConfig.getExtends();
1439
1440 if (ancestor == null) {
1441
1442 return actionConfig;
1443 }
1444
1445
1446 ActionConfig baseConfig = moduleConfig.findActionConfig(ancestor);
1447
1448 if (baseConfig == null) {
1449 throw new UnavailableException("Unable to find "
1450 + "action config for '" + ancestor + "' to extend.");
1451 }
1452
1453
1454 if (actionConfig.getClass().equals(ActionMapping.class)) {
1455
1456 if (!baseConfig.getClass().equals(actionConfig.getClass())) {
1457
1458 ActionConfig newActionConfig = null;
1459 String baseConfigClassName = baseConfig.getClass().getName();
1460
1461 try {
1462 newActionConfig =
1463 (ActionConfig) RequestUtils.applicationInstance(baseConfigClassName);
1464
1465
1466 BeanUtils.copyProperties(newActionConfig, actionConfig);
1467
1468
1469 ForwardConfig[] forwards =
1470 actionConfig.findForwardConfigs();
1471
1472 for (int i = 0; i < forwards.length; i++) {
1473 newActionConfig.addForwardConfig(forwards[i]);
1474 }
1475
1476 ExceptionConfig[] exceptions =
1477 actionConfig.findExceptionConfigs();
1478
1479 for (int i = 0; i < exceptions.length; i++) {
1480 newActionConfig.addExceptionConfig(exceptions[i]);
1481 }
1482 } catch (Exception e) {
1483 handleCreationException(baseConfigClassName, e);
1484 }
1485
1486
1487 moduleConfig.removeActionConfig(actionConfig);
1488 moduleConfig.addActionConfig(newActionConfig);
1489 actionConfig = newActionConfig;
1490 }
1491 }
1492
1493 return actionConfig;
1494 }
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504 protected void initModuleMessageResources(ModuleConfig config)
1505 throws ServletException {
1506 MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();
1507
1508 for (int i = 0; i < mrcs.length; i++) {
1509 if ((mrcs[i].getFactory() == null)
1510 || (mrcs[i].getParameter() == null)) {
1511 continue;
1512 }
1513
1514 if (log.isDebugEnabled()) {
1515 log.debug("Initializing module path '" + config.getPrefix()
1516 + "' message resources from '" + mrcs[i].getParameter()
1517 + "'");
1518 }
1519
1520 String factory = mrcs[i].getFactory();
1521
1522 MessageResourcesFactory.setFactoryClass(factory);
1523
1524 MessageResourcesFactory factoryObject =
1525 MessageResourcesFactory.createFactory();
1526
1527 factoryObject.setConfig(mrcs[i]);
1528
1529 MessageResources resources =
1530 factoryObject.createResources(mrcs[i].getParameter());
1531
1532 resources.setReturnNull(mrcs[i].getNull());
1533 resources.setEscape(mrcs[i].isEscape());
1534 getServletContext().setAttribute(mrcs[i].getKey()
1535 + config.getPrefix(), resources);
1536 }
1537 }
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549 protected Digester initConfigDigester()
1550 throws ServletException {
1551
1552
1553 if (configDigester != null) {
1554 return (configDigester);
1555 }
1556
1557
1558 configDigester = new Digester();
1559 configDigester.setNamespaceAware(true);
1560 configDigester.setValidating(this.isValidating());
1561 configDigester.setUseContextClassLoader(true);
1562 configDigester.addRuleSet(new ConfigRuleSet());
1563
1564 for (int i = 0; i < registrations.length; i += 2) {
1565 URL url = this.getClass().getResource(registrations[i + 1]);
1566
1567 if (url != null) {
1568 configDigester.register(registrations[i], url.toString());
1569 }
1570 }
1571
1572 this.addRuleSets();
1573
1574
1575 return (configDigester);
1576 }
1577
1578
1579
1580
1581
1582
1583
1584 private void addRuleSets()
1585 throws ServletException {
1586 String rulesets = getServletConfig().getInitParameter("rulesets");
1587
1588 if (rulesets == null) {
1589 rulesets = "";
1590 }
1591
1592 rulesets = rulesets.trim();
1593
1594 String ruleset;
1595
1596 while (rulesets.length() > 0) {
1597 int comma = rulesets.indexOf(",");
1598
1599 if (comma < 0) {
1600 ruleset = rulesets.trim();
1601 rulesets = "";
1602 } else {
1603 ruleset = rulesets.substring(0, comma).trim();
1604 rulesets = rulesets.substring(comma + 1).trim();
1605 }
1606
1607 if (log.isDebugEnabled()) {
1608 log.debug("Configuring custom Digester Ruleset of type "
1609 + ruleset);
1610 }
1611
1612 try {
1613 RuleSet instance =
1614 (RuleSet) RequestUtils.applicationInstance(ruleset);
1615
1616 this.configDigester.addRuleSet(instance);
1617 } catch (Exception e) {
1618 log.error("Exception configuring custom Digester RuleSet", e);
1619 throw new ServletException(e);
1620 }
1621 }
1622 }
1623
1624
1625
1626
1627
1628
1629
1630 private boolean isValidating() {
1631 boolean validating = true;
1632 String value = getServletConfig().getInitParameter("validating");
1633
1634 if ("false".equalsIgnoreCase(value) || "no".equalsIgnoreCase(value)
1635 || "n".equalsIgnoreCase(value) || "0".equalsIgnoreCase(value)) {
1636 validating = false;
1637 }
1638
1639 return validating;
1640 }
1641
1642
1643
1644
1645
1646
1647
1648 protected void initInternal()
1649 throws ServletException {
1650 try {
1651 internal = MessageResources.getMessageResources(internalName);
1652 } catch (MissingResourceException e) {
1653 log.error("Cannot load internal resources from '" + internalName
1654 + "'", e);
1655 throw new UnavailableException(
1656 "Cannot load internal resources from '" + internalName + "'");
1657 }
1658 }
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668 protected void initChain()
1669 throws ServletException {
1670
1671 try {
1672 String value;
1673
1674 value = getServletConfig().getInitParameter("chainConfig");
1675
1676 if (value != null) {
1677 chainConfig = value;
1678 }
1679
1680 ConfigParser parser = new ConfigParser();
1681 List urls = splitAndResolvePaths(chainConfig);
1682 URL resource;
1683
1684 for (Iterator i = urls.iterator(); i.hasNext();) {
1685 resource = (URL) i.next();
1686 log.info("Loading chain catalog from " + resource);
1687 parser.parse(resource);
1688 }
1689 } catch (Exception e) {
1690 log.error("Exception loading resources", e);
1691 throw new ServletException(e);
1692 }
1693 }
1694
1695
1696
1697
1698
1699
1700
1701 protected void initOther()
1702 throws ServletException {
1703 String value;
1704
1705 value = getServletConfig().getInitParameter("config");
1706
1707 if (value != null) {
1708 config = value;
1709 }
1710
1711
1712
1713 value = getServletConfig().getInitParameter("convertNull");
1714
1715 if ("true".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
1716 || "on".equalsIgnoreCase(value) || "y".equalsIgnoreCase(value)
1717 || "1".equalsIgnoreCase(value)) {
1718 convertNull = true;
1719 }
1720
1721 if (convertNull) {
1722 ConvertUtils.deregister();
1723 ConvertUtils.register(new BigDecimalConverter(null),
1724 BigDecimal.class);
1725 ConvertUtils.register(new BigIntegerConverter(null),
1726 BigInteger.class);
1727 ConvertUtils.register(new BooleanConverter(null), Boolean.class);
1728 ConvertUtils.register(new ByteConverter(null), Byte.class);
1729 ConvertUtils.register(new CharacterConverter(null), Character.class);
1730 ConvertUtils.register(new DoubleConverter(null), Double.class);
1731 ConvertUtils.register(new FloatConverter(null), Float.class);
1732 ConvertUtils.register(new IntegerConverter(null), Integer.class);
1733 ConvertUtils.register(new LongConverter(null), Long.class);
1734 ConvertUtils.register(new ShortConverter(null), Short.class);
1735 }
1736 }
1737
1738
1739
1740
1741
1742
1743
1744
1745 protected void initServlet()
1746 throws ServletException {
1747
1748 this.servletName = getServletConfig().getServletName();
1749
1750
1751 Digester digester = new Digester();
1752
1753 digester.push(this);
1754 digester.setNamespaceAware(true);
1755 digester.setValidating(false);
1756
1757
1758 for (int i = 0; i < registrations.length; i += 2) {
1759 URL url = this.getClass().getResource(registrations[i + 1]);
1760
1761 if (url != null) {
1762 digester.register(registrations[i], url.toString());
1763 }
1764 }
1765
1766
1767 digester.addCallMethod("web-app/servlet-mapping", "addServletMapping", 2);
1768 digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
1769 digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
1770
1771
1772 if (log.isDebugEnabled()) {
1773 log.debug("Scanning web.xml for controller servlet mapping");
1774 }
1775
1776 InputStream input =
1777 getServletContext().getResourceAsStream("/WEB-INF/web.xml");
1778
1779 if (input == null) {
1780 log.error(internal.getMessage("configWebXml"));
1781 throw new ServletException(internal.getMessage("configWebXml"));
1782 }
1783
1784 try {
1785 digester.parse(input);
1786 } catch (IOException e) {
1787 log.error(internal.getMessage("configWebXml"), e);
1788 throw new ServletException(e);
1789 } catch (SAXException e) {
1790 log.error(internal.getMessage("configWebXml"), e);
1791 throw new ServletException(e);
1792 } finally {
1793 try {
1794 input.close();
1795 } catch (IOException e) {
1796 log.error(internal.getMessage("configWebXml"), e);
1797 throw new ServletException(e);
1798 }
1799 }
1800
1801
1802 if (log.isDebugEnabled()) {
1803 log.debug("Mapping for servlet '" + servletName + "' = '"
1804 + servletMapping + "'");
1805 }
1806
1807 if (servletMapping != null) {
1808 getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);
1809 }
1810 }
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823 protected List splitAndResolvePaths(String paths)
1824 throws ServletException {
1825 ClassLoader loader = Thread.currentThread().getContextClassLoader();
1826
1827 if (loader == null) {
1828 loader = this.getClass().getClassLoader();
1829 }
1830
1831 ArrayList resolvedUrls = new ArrayList();
1832
1833 URL resource;
1834 String path = null;
1835
1836 try {
1837
1838 while (paths.length() > 0) {
1839 resource = null;
1840
1841 int comma = paths.indexOf(',');
1842
1843 if (comma >= 0) {
1844 path = paths.substring(0, comma).trim();
1845 paths = paths.substring(comma + 1);
1846 } else {
1847 path = paths.trim();
1848 paths = "";
1849 }
1850
1851 if (path.length() < 1) {
1852 break;
1853 }
1854
1855 if (path.charAt(0) == '/') {
1856 resource = getServletContext().getResource(path);
1857 }
1858
1859 if (resource == null) {
1860 if (log.isDebugEnabled()) {
1861 log.debug("Unable to locate " + path
1862 + " in the servlet context, "
1863 + "trying classloader.");
1864 }
1865
1866 Enumeration e = loader.getResources(path);
1867
1868 if (!e.hasMoreElements()) {
1869 String msg = internal.getMessage("configMissing", path);
1870
1871 log.error(msg);
1872 throw new UnavailableException(msg);
1873 } else {
1874 while (e.hasMoreElements()) {
1875 resolvedUrls.add(e.nextElement());
1876 }
1877 }
1878 } else {
1879 resolvedUrls.add(resource);
1880 }
1881 }
1882 } catch (MalformedURLException e) {
1883 handleConfigException(path, e);
1884 } catch (IOException e) {
1885 handleConfigException(path, e);
1886 }
1887
1888 return resolvedUrls;
1889 }
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900 protected void process(HttpServletRequest request,
1901 HttpServletResponse response)
1902 throws IOException, ServletException {
1903 ModuleUtils.getInstance().selectModule(request, getServletContext());
1904
1905 ModuleConfig config = getModuleConfig(request);
1906
1907 RequestProcessor processor = getProcessorForModule(config);
1908
1909 if (processor == null) {
1910 processor = getRequestProcessor(config);
1911 }
1912
1913 processor.process(request, response);
1914 }
1915 }