Lines 102-114
Link Here
|
102 |
* growth. |
102 |
* growth. |
103 |
* <p>NOTE: use LinkedHashmap if a dependency on J2SE 1.4+ is ok |
103 |
* <p>NOTE: use LinkedHashmap if a dependency on J2SE 1.4+ is ok |
104 |
*/ |
104 |
*/ |
105 |
static Map sCachedExpressionStrings = null; |
105 |
private static Map sCachedExpressionStrings = null; |
106 |
|
106 |
|
107 |
/** |
107 |
/** |
108 |
* The mapping from ExpectedType to Maps mapping literal String to |
108 |
* The mapping from ExpectedType to Maps mapping literal String to |
109 |
* parsed value * |
109 |
* parsed value * |
110 |
*/ |
110 |
*/ |
111 |
static Map sCachedExpectedTypes = new HashMap(); |
111 |
private static final Map sCachedExpectedTypes = new HashMap(); |
112 |
|
112 |
|
113 |
/** |
113 |
/** |
114 |
* The static Logger * |
114 |
* The static Logger * |
Lines 123-129
Link Here
|
123 |
/** |
123 |
/** |
124 |
* Flag if the cache should be bypassed * |
124 |
* Flag if the cache should be bypassed * |
125 |
*/ |
125 |
*/ |
126 |
boolean mBypassCache; |
126 |
private volatile boolean mBypassCache; |
127 |
|
127 |
|
128 |
/** |
128 |
/** |
129 |
* The PageContext * |
129 |
* The PageContext * |
Lines 256-295
Link Here
|
256 |
return ""; |
256 |
return ""; |
257 |
} |
257 |
} |
258 |
|
258 |
|
259 |
if (!(mBypassCache) && (sCachedExpressionStrings == null)) { |
259 |
if (mBypassCache) { |
260 |
createExpressionStringMap(); |
260 |
return parseExpressionUncached(pExpressionString); |
261 |
} |
261 |
} |
262 |
|
262 |
|
|
|
263 |
Map cache = getOrCreateExpressionStringMap(pageContext); |
264 |
|
263 |
// See if it's in the cache |
265 |
// See if it's in the cache |
264 |
Object ret = |
266 |
Object ret = cache.get(pExpressionString); |
265 |
mBypassCache ? |
267 |
if (ret != null) { |
266 |
null : |
268 |
return ret; |
267 |
sCachedExpressionStrings.get(pExpressionString); |
269 |
} |
268 |
|
270 |
|
269 |
if (ret == null) { |
271 |
ret = parseExpressionUncached(pExpressionString); |
270 |
// Parse the expression |
272 |
cache.put(pExpressionString, ret); |
|
|
273 |
return ret; |
274 |
} |
275 |
|
276 |
/** |
277 |
* Parse an expression string bypassing the cache. |
278 |
* |
279 |
* This allows expressions to be validated at translation time without polluting the cache. |
280 |
* |
281 |
* @param pExpressionString the text to parse |
282 |
* @return the parse result |
283 |
* @throws ELException if there was a problem parsing the expression text |
284 |
*/ |
285 |
public Object parseExpressionUncached(String pExpressionString) throws ELException { |
286 |
try { |
271 |
Reader r = new StringReader(pExpressionString); |
287 |
Reader r = new StringReader(pExpressionString); |
272 |
ELParser parser = new ELParser(r); |
288 |
ELParser parser = new ELParser(r); |
273 |
try { |
289 |
return parser.ExpressionString(); |
274 |
ret = parser.ExpressionString(); |
290 |
} catch (ParseException exc) { |
275 |
if (!mBypassCache) { |
291 |
throw new ELException(formatParseException(pExpressionString, exc)); |
276 |
sCachedExpressionStrings.put(pExpressionString, ret); |
292 |
} catch (TokenMgrError exc) { |
277 |
} |
293 |
// Note - this should never be reached, since the parser is |
278 |
} |
294 |
// constructed to tokenize any input (illegal inputs get |
279 |
catch (ParseException exc) { |
295 |
// parsed to <BADLY_ESCAPED_STRING_LITERAL> or |
280 |
throw new ELException |
296 |
// <ILLEGAL_CHARACTER> |
281 |
(formatParseException(pExpressionString, |
297 |
throw new ELException(exc.getMessage()); |
282 |
exc)); |
|
|
283 |
} |
284 |
catch (TokenMgrError exc) { |
285 |
// Note - this should never be reached, since the parser is |
286 |
// constructed to tokenize any input (illegal inputs get |
287 |
// parsed to <BADLY_ESCAPED_STRING_LITERAL> or |
288 |
// <ILLEGAL_CHARACTER> |
289 |
throw new ELException(exc.getMessage()); |
290 |
} |
291 |
} |
298 |
} |
292 |
return ret; |
|
|
293 |
} |
299 |
} |
294 |
|
300 |
|
295 |
//------------------------------------- |
301 |
//------------------------------------- |
Lines 358-388
Link Here
|
358 |
* Creates LRU map of expression strings. If context parameter |
364 |
* Creates LRU map of expression strings. If context parameter |
359 |
* specifying cache size is present use that as the maximum size |
365 |
* specifying cache size is present use that as the maximum size |
360 |
* of the LRU map otherwise use default. |
366 |
* of the LRU map otherwise use default. |
|
|
367 |
* |
368 |
* TODO: Using the context parameter means the cache is sized based on the configuration |
369 |
* of the first web application that calls this. This might be a problem if this jar is |
370 |
* installed in the application server's classpath rather than the application's. |
361 |
*/ |
371 |
*/ |
362 |
private synchronized void createExpressionStringMap() { |
372 |
private static synchronized Map getOrCreateExpressionStringMap(PageContext pageContext) { |
363 |
if (sCachedExpressionStrings != null) { |
373 |
if (sCachedExpressionStrings == null) { |
364 |
return; |
|
|
365 |
} |
366 |
|
374 |
|
367 |
final int maxSize; |
375 |
final int maxSize; |
368 |
if ((pageContext != null) && (pageContext.getServletContext() != null)) { |
376 |
if ((pageContext != null) && (pageContext.getServletContext() != null)) { |
369 |
String value = pageContext.getServletContext().getInitParameter(EXPR_CACHE_PARAM); |
377 |
String value = pageContext.getServletContext().getInitParameter(EXPR_CACHE_PARAM); |
370 |
if (value != null) { |
378 |
if (value != null) { |
371 |
maxSize = Integer.valueOf(value); |
379 |
maxSize = Integer.valueOf(value); |
|
|
380 |
} else { |
381 |
maxSize = MAX_SIZE; |
382 |
} |
372 |
} else { |
383 |
} else { |
373 |
maxSize = MAX_SIZE; |
384 |
maxSize = MAX_SIZE; |
374 |
} |
385 |
} |
375 |
} else { |
386 |
|
376 |
maxSize = MAX_SIZE; |
387 |
// fall through if it couldn't find the parameter |
|
|
388 |
sCachedExpressionStrings = Collections.synchronizedMap(new LinkedHashMap() { |
389 |
@Override |
390 |
protected boolean removeEldestEntry(Map.Entry eldest) { |
391 |
return size() > maxSize; |
392 |
} |
393 |
}); |
377 |
} |
394 |
} |
378 |
|
395 |
return sCachedExpressionStrings; |
379 |
// fall through if it couldn't find the parameter |
|
|
380 |
sCachedExpressionStrings = Collections.synchronizedMap(new LinkedHashMap() { |
381 |
@Override |
382 |
protected boolean removeEldestEntry(Map.Entry eldest) { |
383 |
return size() > maxSize; |
384 |
} |
385 |
}); |
386 |
} |
396 |
} |
387 |
|
397 |
|
388 |
//------------------------------------- |
398 |
//------------------------------------- |