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

(-)src/org/apache/taglibs/standard/lang/jstl/Constants.java (+12 lines)
Lines 33-38 Link Here
33
public class Constants
33
public class Constants
34
{
34
{
35
  //-------------------------------------
35
  //-------------------------------------
36
  // SPI extensions
37
38
  public static final String ELEVALUATOR_EXPECTED_STRINGS_CACHE = 
39
      "org.apache.taglibs.standard.elevalutor.expected.strings.cache";
40
  public static final String ELEVALUATOR_EXPECTED_TYPES_CACHE = 
41
      "org.apache.taglibs.standard.elevalutor.expected.types.cache";
42
  public static final String MESSAGEFORMAT_CACHE = 
43
      "org.apache.taglibs.standard.messageformat.cache";
44
  public static final String DATEFORMAT_CACHE = 
45
      "org.apache.taglibs.standard.dateformat.cache";
46
47
  //-------------------------------------
36
  // Resources
48
  // Resources
37
49
38
  static ResourceBundle sResources =
50
  static ResourceBundle sResources =
(-)src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (-33 / +14 lines)
Lines 28-33 Link Here
28
import org.apache.taglibs.standard.lang.jstl.parser.Token;
28
import org.apache.taglibs.standard.lang.jstl.parser.Token;
29
import org.apache.taglibs.standard.lang.jstl.parser.TokenMgrError;
29
import org.apache.taglibs.standard.lang.jstl.parser.TokenMgrError;
30
30
31
import org.apache.taglibs.standard.util.*;
32
31
/**
33
/**
32
 *
34
 *
33
 * <p>This is the main class for evaluating expression Strings.  An
35
 * <p>This is the main class for evaluating expression Strings.  An
Lines 91-102 Link Here
91
93
92
  /** The mapping from expression String to its parsed form (String,
94
  /** The mapping from expression String to its parsed form (String,
93
      Expression, or ExpressionString) **/
95
      Expression, or ExpressionString) **/
94
  static Map sCachedExpressionStrings = 
96
  static StandardTaglibCache sCachedExpressionStrings =
95
    Collections.synchronizedMap (new HashMap ());
97
    StandardTaglibCacheFactory.createCache(
98
    Constants.ELEVALUATOR_EXPECTED_STRINGS_CACHE, 
99
    ForeverStandardTaglibCache.class
100
    );
96
101
97
  /** The mapping from ExpectedType to Maps mapping literal String to
102
  /** The mapping from ExpectedType to Maps mapping literal String to
98
      parsed value **/
103
      parsed value **/
99
  static Map sCachedExpectedTypes = new HashMap ();
104
  static StandardTaglibCache sCachedExpectedTypes = 
105
    StandardTaglibCacheFactory.createCache(
106
    Constants.ELEVALUATOR_EXPECTED_TYPES_CACHE, 
107
    ForeverStandardTaglibCache.class
108
    );
100
109
101
  /** The static Logger **/
110
  /** The static Logger **/
102
  static Logger sLogger = new Logger (System.out);
111
  static Logger sLogger = new Logger (System.out);
Lines 104-112 Link Here
104
  /** The VariableResolver **/
113
  /** The VariableResolver **/
105
  VariableResolver mResolver;
114
  VariableResolver mResolver;
106
115
107
  /** Flag if the cache should be bypassed **/
108
  boolean mBypassCache;
109
110
  //-------------------------------------
116
  //-------------------------------------
111
  /**
117
  /**
112
   *
118
   *
Lines 124-148 Link Here
124
  //-------------------------------------
130
  //-------------------------------------
125
  /**
131
  /**
126
   *
132
   *
127
   * Constructor
128
   *
129
   * @param pResolver the object that should be used to resolve
130
   * variable names encountered in expressions.  If null, all variable
131
   * references will resolve to null.
132
   *
133
   * @param pBypassCache flag indicating if the cache should be
134
   * bypassed
135
   **/
136
  public ELEvaluator (VariableResolver pResolver,
137
		      boolean pBypassCache)
138
  {
139
    mResolver = pResolver;
140
    mBypassCache = pBypassCache;
141
  }
142
143
  //-------------------------------------
144
  /**
145
   *
146
   * Evaluates the given expression String
133
   * Evaluates the given expression String
147
   *
134
   *
148
   * @param pExpressionString the expression String to be evaluated
135
   * @param pExpressionString the expression String to be evaluated
Lines 248-257 Link Here
248
    }
235
    }
249
236
250
    // See if it's in the cache
237
    // See if it's in the cache
251
    Object ret = 
238
    Object ret = sCachedExpressionStrings.get (pExpressionString);
252
      mBypassCache ?
253
      null :
254
      sCachedExpressionStrings.get (pExpressionString);
255
239
256
    if (ret == null) {
240
    if (ret == null) {
257
      // Parse the expression
241
      // Parse the expression
Lines 311-318 Link Here
311
295
312
    // Find the cached value
296
    // Find the cached value
313
    Map valueByString = getOrCreateExpectedTypeMap (pExpectedType);
297
    Map valueByString = getOrCreateExpectedTypeMap (pExpectedType);
314
    if (!mBypassCache &&
298
    if (valueByString.containsKey (pValue)) {
315
	valueByString.containsKey (pValue)) {
316
      return valueByString.get (pValue);
299
      return valueByString.get (pValue);
317
    }
300
    }
318
    else {
301
    else {
Lines 331-344 Link Here
331
   **/
314
   **/
332
  static Map getOrCreateExpectedTypeMap (Class pExpectedType)
315
  static Map getOrCreateExpectedTypeMap (Class pExpectedType)
333
  {
316
  {
334
    synchronized (sCachedExpectedTypes) {
335
      Map ret = (Map) sCachedExpectedTypes.get (pExpectedType);
317
      Map ret = (Map) sCachedExpectedTypes.get (pExpectedType);
336
      if (ret == null) {
318
      if (ret == null) {
337
	ret = Collections.synchronizedMap (new HashMap ());
319
	ret = Collections.synchronizedMap (new HashMap ());
338
	sCachedExpectedTypes.put (pExpectedType, ret);
320
	sCachedExpectedTypes.put (pExpectedType, ret);
339
      }
321
      }
340
      return ret;
322
      return ret;
341
    }
342
  }
323
  }
343
324
344
  //-------------------------------------
325
  //-------------------------------------
(-)src/org/apache/taglibs/standard/resources/Resources.java (-1 / +12 lines)
Lines 20-25 Link Here
20
import java.util.MissingResourceException;
20
import java.util.MissingResourceException;
21
import java.util.ResourceBundle;
21
import java.util.ResourceBundle;
22
22
23
import org.apache.taglibs.standard.util.*;
24
import org.apache.taglibs.standard.lang.jstl.Constants;
25
23
/**
26
/**
24
 * <p>Provides locale-neutral access to string resources.  Only the
27
 * <p>Provides locale-neutral access to string resources.  Only the
25
 * documentation and code are in English. :-)
28
 * documentation and code are in English. :-)
Lines 52-58 Link Here
52
    private static ResourceBundle rb =
55
    private static ResourceBundle rb =
53
	ResourceBundle.getBundle(RESOURCE_LOCATION);
56
	ResourceBundle.getBundle(RESOURCE_LOCATION);
54
57
58
    private static StandardTaglibCache messageFormatCache = 
59
        StandardTaglibCacheFactory.createCache(Constants.MESSAGEFORMAT_CACHE);
55
60
61
56
    //*********************************************************************
62
    //*********************************************************************
57
    // Public static methods
63
    // Public static methods
58
64
Lines 66-72 Link Here
66
    public static String getMessage(String name, Object[] a)
72
    public static String getMessage(String name, Object[] a)
67
	    throws MissingResourceException {
73
	    throws MissingResourceException {
68
	String res = rb.getString(name);
74
	String res = rb.getString(name);
69
	return MessageFormat.format(res, a);
75
        MessageFormat msgFormat = (MessageFormat) messageFormatCache.get(res);
76
        if(msgFormat == null) {
77
            msgFormat = new MessageFormat(res);
78
            messageFormatCache.put(res, msgFormat);
79
        }
80
	return msgFormat.format(res, a);
70
    }
81
    }
71
82
72
    /** Retrieves a message with one argument. */
83
    /** Retrieves a message with one argument. */
(-)src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (-14 / +32 lines)
Lines 31-36 Link Here
31
import org.apache.taglibs.standard.resources.Resources;
31
import org.apache.taglibs.standard.resources.Resources;
32
import org.apache.taglibs.standard.tag.common.core.Util;
32
import org.apache.taglibs.standard.tag.common.core.Util;
33
33
34
import org.apache.taglibs.standard.util.*;
35
import org.apache.taglibs.standard.lang.jstl.Constants;
36
34
/**
37
/**
35
 * Support for tag handlers for &lt;formatDate&gt;, the date and time
38
 * Support for tag handlers for &lt;formatDate&gt;, the date and time
36
 * formatting tag in JSTL 1.0.
39
 * formatting tag in JSTL 1.0.
Lines 65-70 Link Here
65
    private String var;                          // 'var' attribute
68
    private String var;                          // 'var' attribute
66
    private int scope;                           // 'scope' attribute
69
    private int scope;                           // 'scope' attribute
67
70
71
    private static StandardTaglibCache dateFormatCache = 
72
        StandardTaglibCacheFactory.createCache(Constants.DATEFORMAT_CACHE);
68
73
69
    //*********************************************************************
74
    //*********************************************************************
70
    // Constructor and initialization
75
    // Constructor and initialization
Lines 183-202 Link Here
183
    private DateFormat createFormatter(Locale loc) throws JspException {
188
    private DateFormat createFormatter(Locale loc) throws JspException {
184
	DateFormat formatter = null;
189
	DateFormat formatter = null;
185
190
186
	if ((type == null) || DATE.equalsIgnoreCase(type)) {
191
    if ((type == null) || DATE.equalsIgnoreCase(type)) {
187
	    formatter = DateFormat.getDateInstance(
192
        int style = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE");
188
	        Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
193
        String key = DATE + style + loc;
189
		loc);
194
        formatter = (DateFormat) dateFormatCache.get(key);
190
	} else if (TIME.equalsIgnoreCase(type)) {
195
        if(formatter == null) {
191
	    formatter = DateFormat.getTimeInstance(
196
            formatter = DateFormat.getDateInstance(style, loc);
192
	        Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
197
            dateFormatCache.put(key, formatter);
193
		loc);
198
        }
194
	} else if (DATETIME.equalsIgnoreCase(type)) {
199
    } else if (TIME.equalsIgnoreCase(type)) {
195
	    formatter = DateFormat.getDateTimeInstance(
200
        int style = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE");
196
	        Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
201
        String key = TIME + style + loc;
197
		Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
202
        formatter = (DateFormat) dateFormatCache.get(key);
198
		loc);
203
        if(formatter == null) {
199
	} else {
204
            formatter = DateFormat.getTimeInstance(style, loc);
205
            dateFormatCache.put(key, formatter);
206
        }
207
    } else if (DATETIME.equalsIgnoreCase(type)) {
208
        int style1 = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE");
209
        int style2 = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE");
210
        String key = DATETIME + style1 + loc + style2;
211
        formatter = (DateFormat) dateFormatCache.get(key);
212
        if(formatter == null) {
213
            formatter = DateFormat.getDateTimeInstance(style1, style2, loc);
214
            dateFormatCache.put(key, formatter);
215
        }
216
    } else {
200
	    throw new JspException(
217
	    throw new JspException(
201
                    Resources.getMessage("FORMAT_DATE_INVALID_TYPE", 
218
                    Resources.getMessage("FORMAT_DATE_INVALID_TYPE", 
202
					 type));
219
					 type));
Lines 204-207 Link Here
204
221
205
	return formatter;
222
	return formatter;
206
    }
223
    }
224
207
}
225
}
(-)src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java (+44 lines)
Line 0 Link Here
1
package org.apache.taglibs.standard.util;
2
3
public class StandardTaglibCacheFactory {
4
5
	/**
6
     * @throws ClassNotFoundException
7
     * @throws InstantiationException 
8
	 * @throws IllegalAccessException
9
     */
10
    public static StandardTaglibCache createCache(String key) {
11
        return createCache(key, null);
12
    }
13
14
	/**
15
     * @throws ClassNotFoundException
16
     * @throws InstantiationException 
17
	 * @throws IllegalAccessException
18
     */
19
    public static StandardTaglibCache createCache(String key, Class defaultClass) {
20
21
        String className = System.getProperty(key);
22
23
        try {
24
            if(className == null) {
25
                if(defaultClass == null) {
26
                    return null;
27
                } else {
28
                    return (StandardTaglibCache) defaultClass.newInstance();
29
                }
30
            }
31
32
            return (StandardTaglibCache) Class.forName(className, true, 
33
                Thread.currentThread().getContextClassLoader()
34
                ).newInstance();
35
        } catch(ClassNotFoundException cnfe) {
36
            throw new RuntimeException("Unable to create cache: " + cnfe);
37
        } catch(IllegalAccessException iae) {
38
            throw new RuntimeException("Unable to create cache: " + iae);
39
        } catch(InstantiationException ie) {
40
            throw new RuntimeException("Unable to create cache: " + ie);
41
        }
42
    }
43
44
}
0
  + native
45
  + native
(-)src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java (+22 lines)
Line 0 Link Here
1
package org.apache.taglibs.standard.util;
2
3
import java.util.Collections;
4
import java.util.HashMap;
5
import java.util.Map;
6
7
/**
8
 * Objects are cached forever in a Forever cache.
9
 */
10
public class ForeverStandardTaglibCache implements StandardTaglibCache {
11
12
    private Map map = Collections.synchronizedMap( new HashMap() );
13
14
    public Object get(Object key) {
15
        return map.get(key);
16
    }
17
18
    public void put(Object key, Object value) {
19
        map.put(key, value);
20
    }
21
22
}
0
  + native
23
  + native
(-)src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java (+15 lines)
Line 0 Link Here
1
package org.apache.taglibs.standard.util;
2
3
/**
4
 * Objects are never cached.
5
 */
6
public class NullStandardTaglibCache implements StandardTaglibCache {
7
8
    public Object get(Object key) {
9
        return null;
10
    }
11
12
    public void put(Object key, Object value) {
13
    }
14
15
}
0
  + native
16
  + native
(-)src/org/apache/taglibs/standard/util/StandardTaglibCache.java (+26 lines)
Line 0 Link Here
1
package org.apache.taglibs.standard.util;
2
3
/**
4
 * There are various places in the Standard taglib that 
5
 * can really benefit from some caching, however implementing 
6
 * a cache with enough options to keep each user happy it 
7
 * beyond the scope of the Standard taglib. This interface 
8
 * is provided as a plugin point for different cache 
9
 * implementations. 
10
 */
11
public interface StandardTaglibCache {
12
13
    /**
14
     * Get an object out of the cache. 
15
     * <code>null</code> is returned if there is nothing 
16
     * registered under the specified key.
17
     */
18
    Object get(Object key);
19
20
    /**
21
     * Register an object in the cache for a specified key.
22
     * Passing in a value of <code>null</code> unregisters a key. 
23
     */
24
    void put(Object key, Object value);
25
26
}
0
  + native
27
  + native

Return to bug 31789