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.extras.plugins;
22
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.net.URLConnection;
30
31 import jakarta.servlet.ServletException;
32
33 import org.apache.commons.digester.Digester;
34 import org.apache.commons.digester.RuleSet;
35 import org.apache.commons.digester.xmlrules.DigesterLoader;
36 import org.apache.struts.action.ActionServlet;
37 import org.apache.struts.action.PlugIn;
38 import org.apache.struts.config.ModuleConfig;
39 import org.apache.struts.util.RequestUtils;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 import org.xml.sax.SAXException;
43
44
45
46
47
48
49
50
51
52
53 public class DigestingPlugIn implements PlugIn {
54
55
56
57
58 private final Logger log =
59 LoggerFactory.getLogger(DigestingPlugIn.class);
60
61 protected static final String SOURCE_CLASSPATH = "classpath";
62 protected static final String SOURCE_FILE = "file";
63 protected static final String SOURCE_SERVLET = "servlet";
64 protected String configPath = null;
65 protected String configSource = SOURCE_SERVLET;
66 protected String digesterPath = null;
67 protected String digesterSource = SOURCE_SERVLET;
68 protected String key = null;
69 protected ModuleConfig moduleConfig = null;
70 protected String rulesets = null;
71 protected ActionServlet servlet = null;
72 protected boolean push = false;
73
74
75
76
77 public DigestingPlugIn() {
78 super();
79 }
80
81
82
83
84 public void destroy() {
85 this.servlet = null;
86 this.moduleConfig = null;
87 }
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public void init(ActionServlet servlet, ModuleConfig config)
102 throws ServletException {
103 this.servlet = servlet;
104 this.moduleConfig = config;
105
106 Object obj = null;
107
108 Digester digester = this.initializeDigester();
109
110 if (this.push) {
111 log.debug("push == true; pushing plugin onto digester stack");
112 digester.push(this);
113 }
114
115 try {
116 log.debug("XML data file: [path: {}, source: {}]",
117 this.configPath, this.configSource);
118
119 URL configURL =
120 this.getConfigURL(this.configPath, this.configSource);
121
122 if (configURL == null) {
123 throw new ServletException(
124 "Unable to locate XML data file at [path: "
125 + this.configPath + ", source: " + this.configSource + "]");
126 }
127
128 URLConnection conn = configURL.openConnection();
129
130 conn.setUseCaches(false);
131 conn.connect();
132 try (InputStream is = conn.getInputStream()) {
133 obj = digester.parse(is);
134 }
135 } catch (IOException e) {
136
137 log.error("Exception processing config", e);
138 throw new ServletException(e);
139 } catch (SAXException e) {
140
141 log.error("Exception processing config", e);
142 throw new ServletException(e);
143 }
144
145 this.storeGeneratedObject(obj);
146 }
147
148
149
150
151
152
153
154
155 protected Digester initializeDigester()
156 throws ServletException {
157 Digester digester = null;
158
159 if ((this.digesterPath != null) && (this.digesterSource != null)) {
160 try {
161 log.debug("Initialize digester from XML [path: {}; source: {}]",
162 this.digesterPath, this.digesterSource);
163 digester =
164 this.digesterFromXml(this.digesterPath, this.digesterSource);
165 } catch (IOException e) {
166
167 log.error("Exception instantiating digester from XML", e);
168 throw new ServletException(e);
169 }
170 } else {
171 log.debug("No XML rules for digester; call newDigesterInstance()");
172 digester = this.newDigesterInstance();
173 }
174
175 try {
176 digester.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
177 } catch (Exception e) {
178 log.error("Exception configuring Digester instance", e);
179 throw new ServletException(e);
180 }
181
182 this.applyRuleSets(digester);
183
184 return digester;
185 }
186
187
188
189
190
191
192
193
194 protected Digester newDigesterInstance() {
195 return new Digester();
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 protected Digester digesterFromXml(String path, String source)
212 throws IOException {
213 URL configURL = this.getConfigURL(path, source);
214
215 if (configURL == null) {
216 throw new NullPointerException("No resource '" + path
217 + "' found in '" + source + "'");
218 }
219
220
221
222
223
224
225
226
227
228 return DigesterLoader.createDigester(configURL);
229 }
230
231
232
233
234
235
236
237
238
239 protected void applyRuleSets(Digester digester)
240 throws ServletException {
241 if ((this.rulesets == null) || (this.rulesets.trim().length() == 0)) {
242 return;
243 }
244
245 rulesets = rulesets.trim();
246
247 String ruleSet = null;
248
249 while (rulesets.length() > 0) {
250 int comma = rulesets.indexOf(",");
251
252 if (comma < 0) {
253 ruleSet = rulesets.trim();
254 rulesets = "";
255 } else {
256 ruleSet = rulesets.substring(0, comma).trim();
257 rulesets = rulesets.substring(comma + 1).trim();
258 }
259
260
261 log.debug("Configuring custom Digester Ruleset of type {}"
262 , ruleSet);
263
264 try {
265 RuleSet instance =
266 (RuleSet) RequestUtils.applicationInstance(ruleSet);
267
268 digester.addRuleSet(instance);
269 } catch (Exception e) {
270
271 log.error("Exception configuring custom Digester RuleSet", e);
272 throw new ServletException(e);
273 }
274 }
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 protected URL getConfigURL(String path, String source)
302 throws IOException {
303 if (SOURCE_CLASSPATH.equals(source)) {
304 return this.getClassPathURL(path);
305 }
306
307 if (SOURCE_FILE.equals(source)) {
308 return this.getFileURL(path);
309 }
310
311 if (SOURCE_SERVLET.equals(source)) {
312 return this.getServletContextURL(path);
313 }
314
315
316 throw new IllegalArgumentException("ConfigSource " + source
317 + " is not recognized");
318 }
319
320
321
322
323
324
325
326
327 protected URL getClassPathURL(String path) {
328 return getClass().getClassLoader().getResource(path);
329 }
330
331
332
333
334
335
336
337
338
339 protected URL getServletContextURL(String path)
340 throws IOException {
341 return this.servlet.getServletContext().getResource(path);
342 }
343
344
345
346
347
348
349
350
351
352 protected URL getFileURL(String path)
353 throws IOException {
354 File file = new File(path);
355
356 return file.toURI().toURL();
357 }
358
359
360
361
362
363
364 public void setConfigPath(String configPath) {
365 this.configPath = configPath;
366 }
367
368
369
370
371
372 public String getConfigPath() {
373 return configPath;
374 }
375
376
377
378
379
380
381
382
383
384
385
386 public void setConfigSource(String configSource) {
387 this.configSource = configSource;
388 }
389
390
391
392
393
394
395 public String getConfigSource() {
396 return configSource;
397 }
398
399
400
401
402
403
404
405
406
407 protected void storeGeneratedObject(Object obj) {
408 log.debug("Put [{}] into application context [key:{}]",
409 obj, this.key);
410 this.servlet.getServletContext().setAttribute(this.getKey(), obj);
411 }
412
413
414
415
416
417 public void setKey(String key) {
418 this.key = key;
419 }
420
421
422
423
424
425 public String getKey() {
426 return key;
427 }
428
429
430
431
432
433 public void setRulesets(String ruleSets) {
434 this.rulesets = ruleSets;
435 }
436
437
438
439
440 public String getRulesets() {
441 return this.rulesets;
442 }
443
444
445
446
447
448
449
450
451 public void setDigesterPath(String digesterPath) {
452 this.digesterPath = digesterPath;
453 }
454
455
456
457
458
459
460 public String getDigesterPath() {
461 return digesterPath;
462 }
463
464
465
466
467
468
469
470
471 public void setDigesterSource(String digesterSource) {
472 this.digesterSource = digesterSource;
473 }
474
475
476
477
478
479
480 public String getDigesterSource() {
481 return this.digesterSource;
482 }
483
484
485
486
487
488
489
490
491 public void setPush(boolean push) {
492 this.push = push;
493 }
494
495
496
497
498
499
500 public boolean getPush() {
501 return this.push;
502 }
503 }