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.digester.AbstractObjectCreationFactory;
24 import org.apache.commons.digester.Digester;
25 import org.apache.commons.digester.Rule;
26 import org.apache.commons.digester.RuleSetBase;
27 import org.apache.commons.digester.SetPropertyRule;
28 import org.apache.struts.util.RequestUtils;
29 import org.xml.sax.Attributes;
30
31 /**
32 * <p>The set of Digester rules required to parse a Struts configuration file
33 * (<code>struts-config.xml</code>).</p>
34 *
35 * @version $Rev: 471754 $ $Date: 2005-08-16 15:53:27 -0400 (Tue, 16 Aug 2005)
36 * $
37 * @since Struts 1.1
38 */
39 public class ConfigRuleSet extends RuleSetBase {
40
41
42 /**
43 * <p>Add the set of Rule instances defined in this RuleSet to the
44 * specified <code>Digester</code> instance, associating them with our
45 * namespace URI (if any). This method should only be called by a
46 * Digester instance. These rules assume that an instance of
47 * <code>org.apache.struts.config.ModuleConfig</code> is pushed onto the
48 * evaluation stack before parsing begins.</p>
49 *
50 * @param digester Digester instance to which the new Rule instances
51 * should be added.
52 */
53 public void addRuleInstances(Digester digester) {
54 ClassLoader cl = digester.getClassLoader();
55
56 digester.addRule("struts-config/action-mappings",
57 new SetActionMappingClassRule());
58
59 digester.addFactoryCreate("struts-config/action-mappings/action",
60 new ActionMappingFactory(cl));
61 digester.addSetProperties("struts-config/action-mappings/action");
62 digester.addSetNext("struts-config/action-mappings/action",
63 "addActionConfig", "org.apache.struts.config.ActionConfig");
64
65 digester.addRule("struts-config/action-mappings/action/set-property",
66 new BaseConfigSetPropertyRule());
67
68 digester.addObjectCreate("struts-config/action-mappings/action/exception",
69 "org.apache.struts.config.ExceptionConfig", "className");
70 digester.addSetProperties(
71 "struts-config/action-mappings/action/exception");
72 digester.addSetNext("struts-config/action-mappings/action/exception",
73 "addExceptionConfig", "org.apache.struts.config.ExceptionConfig");
74
75 digester.addRule("struts-config/action-mappings/action/exception/set-property",
76 new BaseConfigSetPropertyRule());
77
78 digester.addFactoryCreate("struts-config/action-mappings/action/forward",
79 new ActionForwardFactory(cl));
80 digester.addSetProperties(
81 "struts-config/action-mappings/action/forward");
82 digester.addSetNext("struts-config/action-mappings/action/forward",
83 "addForwardConfig", "org.apache.struts.config.ForwardConfig");
84
85 digester.addRule("struts-config/action-mappings/action/forward/set-property",
86 new BaseConfigSetPropertyRule());
87
88 digester.addObjectCreate("struts-config/controller",
89 "org.apache.struts.config.ControllerConfig", "className");
90 digester.addSetProperties("struts-config/controller");
91 digester.addSetNext("struts-config/controller", "setControllerConfig",
92 "org.apache.struts.config.ControllerConfig");
93
94 digester.addRule("struts-config/controller/set-property",
95 new BaseConfigSetPropertyRule());
96
97 digester.addRule("struts-config/form-beans",
98 new SetActionFormBeanClassRule());
99
100 digester.addFactoryCreate("struts-config/form-beans/form-bean",
101 new ActionFormBeanFactory(cl));
102 digester.addSetProperties("struts-config/form-beans/form-bean");
103 digester.addSetNext("struts-config/form-beans/form-bean",
104 "addFormBeanConfig", "org.apache.struts.config.FormBeanConfig");
105
106 digester.addObjectCreate("struts-config/form-beans/form-bean/form-property",
107 "org.apache.struts.config.FormPropertyConfig", "className");
108 digester.addSetProperties(
109 "struts-config/form-beans/form-bean/form-property");
110 digester.addSetNext("struts-config/form-beans/form-bean/form-property",
111 "addFormPropertyConfig",
112 "org.apache.struts.config.FormPropertyConfig");
113
114 digester.addRule("struts-config/form-beans/form-bean/form-property/set-property",
115 new BaseConfigSetPropertyRule());
116
117 digester.addRule("struts-config/form-beans/form-bean/set-property",
118 new BaseConfigSetPropertyRule());
119
120 digester.addObjectCreate("struts-config/global-exceptions/exception",
121 "org.apache.struts.config.ExceptionConfig", "className");
122 digester.addSetProperties("struts-config/global-exceptions/exception");
123 digester.addSetNext("struts-config/global-exceptions/exception",
124 "addExceptionConfig", "org.apache.struts.config.ExceptionConfig");
125
126 digester.addRule("struts-config/global-exceptions/exception/set-property",
127 new BaseConfigSetPropertyRule());
128
129 digester.addRule("struts-config/global-forwards",
130 new SetActionForwardClassRule());
131
132 digester.addFactoryCreate("struts-config/global-forwards/forward",
133 new GlobalForwardFactory(cl));
134 digester.addSetProperties("struts-config/global-forwards/forward");
135 digester.addSetNext("struts-config/global-forwards/forward",
136 "addForwardConfig", "org.apache.struts.config.ForwardConfig");
137
138 digester.addRule("struts-config/global-forwards/forward/set-property",
139 new BaseConfigSetPropertyRule());
140
141 digester.addObjectCreate("struts-config/message-resources",
142 "org.apache.struts.config.MessageResourcesConfig", "className");
143 digester.addSetProperties("struts-config/message-resources");
144 digester.addSetNext("struts-config/message-resources",
145 "addMessageResourcesConfig",
146 "org.apache.struts.config.MessageResourcesConfig");
147
148 digester.addRule("struts-config/message-resources/set-property",
149 new BaseConfigSetPropertyRule());
150
151 digester.addObjectCreate("struts-config/plug-in",
152 "org.apache.struts.config.PlugInConfig");
153 digester.addSetProperties("struts-config/plug-in");
154 digester.addSetNext("struts-config/plug-in", "addPlugInConfig",
155 "org.apache.struts.config.PlugInConfig");
156
157 digester.addRule("struts-config/plug-in/set-property",
158 new PlugInSetPropertyRule());
159
160
161 }
162 }
163
164
165 /**
166 * <p> Class that records the name and value of a configuration property to be
167 * used in configuring a <code>PlugIn</code> instance when instantiated. </p>
168 */
169 final class PlugInSetPropertyRule extends Rule {
170 public PlugInSetPropertyRule() {
171 super();
172 }
173
174 public void begin(String namespace, String names, Attributes attributes)
175 throws Exception {
176 PlugInConfig plugInConfig = (PlugInConfig) digester.peek();
177
178 plugInConfig.addProperty(attributes.getValue("property"),
179 attributes.getValue("value"));
180 }
181 }
182
183
184 /**
185 * <p> Class that sets the name of the class to use when creating action form
186 * bean instances. The value is set on the object on the top of the stack,
187 * which must be a <code>org.apache.struts.config.ModuleConfig</code>. </p>
188 */
189 final class SetActionFormBeanClassRule extends Rule {
190 public SetActionFormBeanClassRule() {
191 super();
192 }
193
194 public void begin(String namespace, String name, Attributes attributes)
195 throws Exception {
196 String className = attributes.getValue("type");
197
198 if (className != null) {
199 ModuleConfig mc = (ModuleConfig) digester.peek();
200
201 mc.setActionFormBeanClass(className);
202 }
203 }
204 }
205
206
207 /**
208 * <p> A variant of the standard Digester <code>SetPropertyRule</code>. If
209 * the element being processed has a "key" attribute, then the value will be
210 * used to call <code>setProperty(key,value)</code> on the object on top of
211 * the stack, which will be assumed to be of type <code>ActionConfig</code>.
212 * Otherwise, the standard <code>SetPropertyRule</code> behavior is invoked,
213 * and the value will be used to set a bean property on the object on top of
214 * the Digester stack. In that case, the element being processed is assumed to
215 * have attributes "property" and "value". </p>
216 */
217 final class BaseConfigSetPropertyRule extends SetPropertyRule {
218 public BaseConfigSetPropertyRule() {
219 super("property", "value");
220 }
221
222 public void begin(Attributes attributes)
223 throws Exception {
224 if (attributes.getIndex("key") == -1) {
225 super.begin(attributes);
226
227 return;
228 }
229
230 if (attributes.getIndex("property") != -1) {
231 throw new IllegalArgumentException(
232 "<set-property> accepts only one of 'key' or 'property' attributes.");
233 }
234
235 Object topOfStack = digester.peek();
236
237 if (topOfStack instanceof BaseConfig) {
238 BaseConfig config = (BaseConfig) topOfStack;
239
240 config.setProperty(attributes.getValue("key"),
241 attributes.getValue("value"));
242 } else {
243 throw new IllegalArgumentException(
244 "'key' attribute of <set-property> only applicable to subclasses of BaseConfig; "
245 + "object on top of stack is " + topOfStack + " [key: "
246 + attributes.getValue("key") + ", value: "
247 + attributes.getValue("value") + "]");
248 }
249 }
250 }
251
252
253 /**
254 * <p> An object creation factory which creates action form bean instances,
255 * taking into account the default class name, which may have been specified
256 * on the parent element and which is made available through the object on the
257 * top of the stack, which must be a <code>org.apache.struts.config.ModuleConfig</code>.
258 * </p>
259 */
260 final class ActionFormBeanFactory extends AbstractObjectCreationFactory {
261 private ClassLoader cl;
262
263 public ActionFormBeanFactory(ClassLoader cl) {
264 super();
265 this.cl = cl;
266 }
267
268 public Object createObject(Attributes attributes) {
269
270 String className = attributes.getValue("className");
271
272 if (className == null) {
273 ModuleConfig mc = (ModuleConfig) digester.peek();
274
275 className = mc.getActionFormBeanClass();
276 }
277
278
279 Object actionFormBean = null;
280
281 try {
282 actionFormBean = RequestUtils.applicationInstance(className, cl);
283 } catch (Exception e) {
284 digester.getLogger().error("ActionFormBeanFactory.createObject: ", e);
285 }
286
287 return actionFormBean;
288 }
289 }
290
291
292 /**
293 * <p> Class that sets the name of the class to use when creating action
294 * mapping instances. The value is set on the object on the top of the stack,
295 * which must be a <code>org.apache.struts.config.ModuleConfig</code>. </p>
296 */
297 final class SetActionMappingClassRule extends Rule {
298 public SetActionMappingClassRule() {
299 super();
300 }
301
302 public void begin(String namespace, String name, Attributes attributes)
303 throws Exception {
304 String className = attributes.getValue("type");
305
306 if (className != null) {
307 ModuleConfig mc = (ModuleConfig) digester.peek();
308
309 mc.setActionMappingClass(className);
310 }
311 }
312 }
313
314
315 /**
316 * <p> An object creation factory which creates action mapping instances,
317 * taking into account the default class name, which may have been specified
318 * on the parent element and which is made available through the object on the
319 * top of the stack, which must be a <code>org.apache.struts.config.ModuleConfig</code>.
320 * </p>
321 */
322 final class ActionMappingFactory extends AbstractObjectCreationFactory {
323 private ClassLoader cl;
324
325 public ActionMappingFactory(ClassLoader cl) {
326 super();
327 this.cl = cl;
328 }
329
330 public Object createObject(Attributes attributes) {
331
332 String className = attributes.getValue("className");
333
334 if (className == null) {
335 ModuleConfig mc = (ModuleConfig) digester.peek();
336
337 className = mc.getActionMappingClass();
338 }
339
340
341 Object actionMapping = null;
342
343 try {
344 actionMapping = RequestUtils.applicationInstance(className, cl);
345 } catch (Exception e) {
346 digester.getLogger().error("ActionMappingFactory.createObject: ", e);
347 }
348
349 return actionMapping;
350 }
351 }
352
353
354 /**
355 * <p> Class that sets the name of the class to use when creating global
356 * forward instances. The value is set on the object on the top of the stack,
357 * which must be a <code>org.apache.struts.config.ModuleConfig</code>. </p>
358 */
359 final class SetActionForwardClassRule extends Rule {
360 public SetActionForwardClassRule() {
361 super();
362 }
363
364 public void begin(String namespace, String name, Attributes attributes)
365 throws Exception {
366 String className = attributes.getValue("type");
367
368 if (className != null) {
369 ModuleConfig mc = (ModuleConfig) digester.peek();
370
371 mc.setActionForwardClass(className);
372 }
373 }
374 }
375
376
377 /**
378 * <p> An object creation factory which creates global forward instances,
379 * taking into account the default class name, which may have been specified
380 * on the parent element and which is made available through the object on the
381 * top of the stack, which must be a <code>org.apache.struts.config.ModuleConfig</code>.
382 * </p>
383 */
384 final class GlobalForwardFactory extends AbstractObjectCreationFactory {
385 private ClassLoader cl;
386
387 public GlobalForwardFactory(ClassLoader cl) {
388 super();
389 this.cl = cl;
390 }
391
392 public Object createObject(Attributes attributes) {
393
394 String className = attributes.getValue("className");
395
396 if (className == null) {
397 ModuleConfig mc = (ModuleConfig) digester.peek();
398
399 className = mc.getActionForwardClass();
400 }
401
402
403 Object globalForward = null;
404
405 try {
406 globalForward = RequestUtils.applicationInstance(className, cl);
407 } catch (Exception e) {
408 digester.getLogger().error("GlobalForwardFactory.createObject: ", e);
409 }
410
411 return globalForward;
412 }
413 }
414
415
416 /**
417 * <p> An object creation factory which creates action forward instances,
418 * taking into account the default class name, which may have been specified
419 * on the parent element and which is made available through the object on the
420 * top of the stack, which must be a <code>org.apache.struts.config.ModuleConfig</code>.
421 * </p>
422 */
423 final class ActionForwardFactory extends AbstractObjectCreationFactory {
424 private ClassLoader cl;
425
426 public ActionForwardFactory(ClassLoader cl) {
427 super();
428 this.cl = cl;
429 }
430
431 public Object createObject(Attributes attributes) {
432
433 String className = attributes.getValue("className");
434
435 if (className == null) {
436 ModuleConfig mc = (ModuleConfig) digester.peek(1);
437
438 className = mc.getActionForwardClass();
439 }
440
441
442 Object actionForward = null;
443
444 try {
445 actionForward = RequestUtils.applicationInstance(className, cl);
446 } catch (Exception e) {
447 digester.getLogger().error("ActionForwardFactory.createObject: ", e);
448 }
449
450 return actionForward;
451 }
452 }