1 package org.apache.fulcrum.parser;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import javax.servlet.ServletException;
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.Part;
29
30 import org.apache.avalon.framework.configuration.Configurable;
31 import org.apache.avalon.framework.configuration.Configuration;
32 import org.apache.avalon.framework.configuration.ConfigurationException;
33 import org.apache.avalon.framework.logger.AbstractLogEnabled;
34 import org.apache.avalon.framework.logger.LogEnabled;
35 import org.apache.avalon.framework.service.ServiceException;
36 import org.apache.avalon.framework.service.ServiceManager;
37 import org.apache.avalon.framework.service.Serviceable;
38 import org.apache.commons.lang3.StringUtils;
39 import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
40 import org.apache.fulcrum.parser.ValueParser.URLCaseFolding;
41 import org.apache.fulcrum.parser.pool.BaseValueParserFactory;
42 import org.apache.fulcrum.parser.pool.BaseValueParserPool;
43 import org.apache.fulcrum.parser.pool.CookieParserFactory;
44 import org.apache.fulcrum.parser.pool.CookieParserPool;
45 import org.apache.fulcrum.parser.pool.DefaultParameterParserFactory;
46 import org.apache.fulcrum.parser.pool.DefaultParameterParserPool;
47 import org.apache.fulcrum.pool.PoolException;
48 import org.apache.fulcrum.pool.PoolService;
49
50
51
52
53
54
55
56
57
58 public class DefaultParserService
59 extends AbstractLogEnabled
60 implements ParserService,
61 Configurable, Serviceable
62 {
63
64
65 private URLCaseFolding folding = URLCaseFolding.NONE;
66
67
68 private boolean automaticUpload = AUTOMATIC_DEFAULT;
69
70
71
72
73 private String parameterEncoding = PARAMETER_ENCODING_DEFAULT;
74
75
76
77
78
79 private boolean useFulcrumPool = FULCRUM_POOL_DEFAULT;
80
81
82
83
84
85 private PoolService fulcrumPoolService = null;
86
87
88
89
90 private BaseValueParserPool valueParserPool;
91
92
93
94
95 private DefaultParameterParserPool parameterParserPool;
96
97
98
99
100 private CookieParserPool cookieParserPool;
101
102
103 public DefaultParserService()
104 {
105 }
106
107 public DefaultParserService(GenericObjectPoolConfig<?> config)
108 {
109
110 valueParserPool
111 = new BaseValueParserPool(new BaseValueParserFactory(), config);
112
113 parameterParserPool
114 = new DefaultParameterParserPool(new DefaultParameterParserFactory(), config);
115 }
116
117
118
119
120
121 @Override
122 public String getParameterEncoding()
123 {
124 return parameterEncoding;
125 }
126
127
128
129
130 public void setParameterEncoding(String encoding)
131 {
132 parameterEncoding = encoding;
133 }
134
135
136
137
138
139
140
141
142
143 @Override
144 public String convert(String value)
145 {
146 return convertAndTrim(value);
147 }
148
149
150
151
152
153
154
155
156
157 @Override
158 public String convertAndTrim(String value)
159 {
160 return convertAndTrim(value, getUrlFolding());
161 }
162
163
164
165
166
167
168
169
170
171
172 @Override
173 public String convertAndTrim(String value, URLCaseFolding fold)
174 {
175 if (value == null)
176 {
177 return "";
178 }
179
180 String tmp = value.trim();
181
182 switch (fold)
183 {
184 case NONE:
185 {
186 break;
187 }
188
189 case LOWER:
190 {
191 tmp = tmp.toLowerCase();
192 break;
193 }
194
195 case UPPER:
196 {
197 tmp = tmp.toUpperCase();
198 break;
199 }
200
201 default:
202 {
203 getLogger().error("Passed " + fold + " as fold rule, which is illegal!");
204 break;
205 }
206 }
207 return tmp;
208 }
209
210
211
212
213
214
215 @Override
216 public URLCaseFolding getUrlFolding()
217 {
218 return folding;
219 }
220
221
222
223
224
225
226 @Override
227 public boolean getAutomaticUpload()
228 {
229 return automaticUpload;
230 }
231
232
233
234
235
236
237
238
239 @Override
240 public List<Part> parseUpload(HttpServletRequest request) throws ServiceException
241 {
242 try
243 {
244 return new ArrayList<Part>(request.getParts());
245 }
246 catch (IOException | ServletException e)
247 {
248 throw new ServiceException(ParserService.ROLE, "Could not parse upload request", e);
249 }
250 }
251
252
253
254
255
256
257
258
259
260 @SuppressWarnings("unchecked")
261 @Override
262 public <P extends ValueParser> P getParser(Class<P> ppClass) throws InstantiationException
263 {
264 P vp = null;
265
266 try
267 {
268 if (useFulcrumPool) {
269 try
270 {
271 P parserInstance = (P) fulcrumPoolService.getInstance(ppClass);
272 vp = parserInstance;
273 }
274 catch (PoolException pe)
275 {
276 throw new InstantiationException("Parser class '" + ppClass + "' is illegal. " + pe.getMessage());
277 }
278 } else if ( ppClass.equals(BaseValueParser.class) )
279 {
280 BaseValueParser parserInstance = null;
281 try {
282 parserInstance = valueParserPool.borrowObject();
283 vp = (P) parserInstance;
284 if (vp == null) {
285 throw new InstantiationException("Could not borrow object from pool: " + valueParserPool);
286 }
287 } catch (Exception e) {
288 try {
289 valueParserPool.invalidateObject(parserInstance);
290 parserInstance = null;
291 } catch (Exception e1) {
292 throw new InstantiationException("Could not invalidate object " + e1.getMessage() + " after exception: " + e.getMessage());
293 }
294 }
295 } else if ( ppClass.equals(DefaultParameterParser.class) )
296 {
297 DefaultParameterParser parserInstance = null;
298 try {
299 parserInstance = parameterParserPool.borrowObject();
300 vp = (P) parserInstance;
301 if (vp == null) {
302 throw new InstantiationException("Could not borrow object from pool: " + parameterParserPool);
303 }
304 } catch (Exception e) {
305 try {
306 parameterParserPool.invalidateObject(parserInstance);
307 parserInstance = null;
308 } catch (Exception e1) {
309 throw new InstantiationException("Could not invalidate object " + e1.getMessage() + " after exception: " + e.getMessage());
310 }
311 }
312 } else if ( ppClass.equals(DefaultCookieParser.class) )
313 {
314 DefaultCookieParser parserInstance = null;
315 try {
316 parserInstance = cookieParserPool.borrowObject();
317 vp = (P) parserInstance;
318 if (vp == null) {
319 throw new InstantiationException("Could not borrow object from pool: " + cookieParserPool);
320 }
321 } catch (Exception e) {
322 try {
323 cookieParserPool.invalidateObject(parserInstance);
324 parserInstance = null;
325 } catch (Exception e1) {
326 throw new InstantiationException("Could not invalidate object " + e1.getMessage() + " after exception: " + e.getMessage());
327 }
328 }
329 }
330
331 if (vp != null && vp instanceof ParserServiceSupport ) {
332 ((ParserServiceSupport)vp).setParserService(this);
333 } else {
334 throw new InstantiationException("Could not set parser");
335 }
336 if (vp instanceof LogEnabled)
337 {
338 ((LogEnabled)vp).enableLogging(getLogger().getChildLogger(ppClass.getSimpleName()));
339 }
340 }
341 catch (ClassCastException x)
342 {
343 throw new InstantiationException("Parser class '" + ppClass + "' is illegal. " + x.getMessage());
344 }
345
346 return vp;
347 }
348
349
350
351
352
353
354
355
356
357
358 @Override
359 public void putParser(ValueParser parser)
360 {
361 parser.clear();
362 parser.dispose();
363
364 if (useFulcrumPool) {
365
366 fulcrumPoolService.putInstance(parser);
367
368 } else if( parser.getClass().equals(BaseValueParser.class) )
369 {
370 valueParserPool.returnObject( (BaseValueParser) parser );
371
372 } else if ( parser.getClass().equals(DefaultParameterParser.class) ||
373 parser instanceof DefaultParameterParser)
374 {
375 parameterParserPool.returnObject( (DefaultParameterParser) parser );
376
377 } else if ( parser.getClass().equals(DefaultCookieParser.class) ||
378 parser instanceof DefaultCookieParser)
379 {
380 cookieParserPool.returnObject( (DefaultCookieParser) parser );
381
382 } else {
383
384 getLogger().warn(parser.getClass() + " could not be put back into any pool exhausting some pool");
385
386 }
387 }
388
389
390
391
392
393
394
395 @Override
396 public void configure(Configuration conf) throws ConfigurationException
397 {
398 String foldString = conf.getChild(URL_CASE_FOLDING_KEY).getValue(URLCaseFolding.NONE.name()).toLowerCase();
399
400 folding = URLCaseFolding.NONE;
401
402 getLogger().debug("Setting folding from " + foldString);
403
404 if (StringUtils.isNotEmpty(foldString))
405 {
406 try
407 {
408 folding = URLCaseFolding.valueOf(foldString.toUpperCase());
409 }
410 catch (IllegalArgumentException e)
411 {
412 getLogger().error("Got " + foldString + " from " + URL_CASE_FOLDING_KEY + " property, which is illegal!");
413 throw new ConfigurationException("Value " + foldString + " is illegal!", e);
414 }
415 }
416
417 parameterEncoding = conf.getChild(PARAMETER_ENCODING_KEY)
418 .getValue(PARAMETER_ENCODING_DEFAULT).toLowerCase();
419
420 automaticUpload = conf.getChild(AUTOMATIC_KEY).getValueAsBoolean(AUTOMATIC_DEFAULT);
421
422 useFulcrumPool = conf.getChild(FULCRUM_POOL_KEY).getValueAsBoolean(FULCRUM_POOL_DEFAULT);
423
424 if (useFulcrumPool) {
425 if (fulcrumPoolService == null)
426 {
427
428 throw new ConfigurationException("Fulcrum Pool is activated", new ServiceException(ParserService.ROLE,
429 "Fulcrum enabled Pool Service requires " +
430 PoolService.ROLE + " to be available"));
431 }
432 getLogger().info("Using Fulcrum Pool Service: "+ fulcrumPoolService);
433 } else {
434
435 fulcrumPoolService = null;
436
437
438 GenericObjectPoolConfig config = new GenericObjectPoolConfig();
439 config.setMaxIdle(DEFAULT_MAX_IDLE);
440 config.setMaxTotal(DEFAULT_POOL_CAPACITY);
441
442
443 valueParserPool
444 = new BaseValueParserPool(new BaseValueParserFactory(), config);
445
446
447 parameterParserPool
448 = new DefaultParameterParserPool(new DefaultParameterParserFactory(), config);
449
450
451 cookieParserPool
452 = new CookieParserPool(new CookieParserFactory(), config);
453
454 getLogger().info("Init Commons2 Pool Services.." );
455 getLogger().info(valueParserPool.getClass().getName());
456 getLogger().info(parameterParserPool.getClass().getName());
457 getLogger().info(cookieParserPool.getClass().getName());
458 }
459
460 Configuration[] poolChildren = conf.getChild(POOL_KEY).getChildren();
461 if (poolChildren.length > 0) {
462 GenericObjectPoolConfig genObjPoolConfig = new GenericObjectPoolConfig();
463 genObjPoolConfig.setMaxIdle(DEFAULT_MAX_IDLE);
464 genObjPoolConfig.setMaxTotal(DEFAULT_POOL_CAPACITY);
465 for (Configuration poolConf : poolChildren) {
466
467 switch (poolConf.getName()) {
468 case "maxTotal":
469 int defaultCapacity = poolConf.getValueAsInteger();
470 genObjPoolConfig.setMaxTotal(defaultCapacity);
471 break;
472 case "maxWaitMillis":
473 int maxWaitMillis = poolConf.getValueAsInteger();
474 genObjPoolConfig.setMaxWaitMillis(maxWaitMillis);
475 break;
476 case "blockWhenExhausted":
477 boolean blockWhenExhausted = poolConf.getValueAsBoolean();
478 genObjPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
479 break;
480 case "maxIdle":
481 int maxIdle = poolConf.getValueAsInteger();
482 genObjPoolConfig.setMaxIdle(maxIdle);
483 break;
484 case "minIdle":
485 int minIdle = poolConf.getValueAsInteger();
486 genObjPoolConfig.setMinIdle(minIdle);
487 break;
488 case "testOnReturn":
489 boolean testOnReturn = poolConf.getValueAsBoolean();
490 genObjPoolConfig.setTestOnReturn(testOnReturn);
491 break;
492 case "testOnBorrow":
493 boolean testOnBorrow = poolConf.getValueAsBoolean();
494 genObjPoolConfig.setTestOnBorrow(testOnBorrow);
495 break;
496 case "testOnCreate":
497 boolean testOnCreate = poolConf.getValueAsBoolean();
498 genObjPoolConfig.setTestOnCreate(testOnCreate);
499 break;
500 default:
501
502 break;
503 }
504 }
505
506 valueParserPool.setConfig(genObjPoolConfig);
507 parameterParserPool.setConfig(genObjPoolConfig);
508 cookieParserPool.setConfig(genObjPoolConfig);
509
510 getLogger().debug(valueParserPool.toString());
511 getLogger().debug(parameterParserPool.toString());
512 getLogger().debug(cookieParserPool.toString());
513 }
514
515 }
516
517
518
519
520
521
522
523
524
525 @Override
526 public void service(ServiceManager manager) throws ServiceException
527 {
528
529 if (manager.hasService(PoolService.ROLE))
530 {
531 fulcrumPoolService = (PoolService)manager.lookup(PoolService.ROLE);
532 }
533
534 }
535 }