View | Details | Raw Unified | Return to bug 57434
Collapse All | Expand All

(-)jstlel/src/main/java/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (-49 / +59 lines)
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
    //-------------------------------------
(-)jstlel/src/main/java/org/apache/taglibs/standard/lang/jstl/Evaluator.java (-3 / +1 lines)
Lines 67-75 Link Here
67
    public String validate(String pAttributeName,
67
    public String validate(String pAttributeName,
68
                           String pAttributeValue) {
68
                           String pAttributeValue) {
69
        try {
69
        try {
70
            sEvaluator.setBypassCache(true);
70
            sEvaluator.parseExpressionUncached(pAttributeValue);
71
            sEvaluator.parseExpressionString(pAttributeValue);
72
            sEvaluator.setBypassCache(false);
73
            return null;
71
            return null;
74
        }
72
        }
75
        catch (ELException exc) {
73
        catch (ELException exc) {

Return to bug 57434