Index: src/org/apache/taglibs/standard/lang/jstl/Constants.java =================================================================== --- src/org/apache/taglibs/standard/lang/jstl/Constants.java (revision 504759) +++ src/org/apache/taglibs/standard/lang/jstl/Constants.java (working copy) @@ -33,6 +33,18 @@ public class Constants { //------------------------------------- + // SPI extensions + + public static final String ELEVALUATOR_EXPECTED_STRINGS_CACHE = + "org.apache.taglibs.standard.elevalutor.expected.strings.cache"; + public static final String ELEVALUATOR_EXPECTED_TYPES_CACHE = + "org.apache.taglibs.standard.elevalutor.expected.types.cache"; + public static final String MESSAGEFORMAT_CACHE = + "org.apache.taglibs.standard.messageformat.cache"; + public static final String DATEFORMAT_CACHE = + "org.apache.taglibs.standard.dateformat.cache"; + + //------------------------------------- // Resources static ResourceBundle sResources = Index: src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java =================================================================== --- src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (revision 504759) +++ src/org/apache/taglibs/standard/lang/jstl/ELEvaluator.java (working copy) @@ -28,6 +28,8 @@ import org.apache.taglibs.standard.lang.jstl.parser.Token; import org.apache.taglibs.standard.lang.jstl.parser.TokenMgrError; +import org.apache.taglibs.standard.util.*; + /** * *
This is the main class for evaluating expression Strings. An @@ -91,12 +93,19 @@ /** The mapping from expression String to its parsed form (String, Expression, or ExpressionString) **/ - static Map sCachedExpressionStrings = - Collections.synchronizedMap (new HashMap ()); + static StandardTaglibCache sCachedExpressionStrings = + StandardTaglibCacheFactory.createCache( + Constants.ELEVALUATOR_EXPECTED_STRINGS_CACHE, + ForeverStandardTaglibCache.class + ); /** The mapping from ExpectedType to Maps mapping literal String to parsed value **/ - static Map sCachedExpectedTypes = new HashMap (); + static StandardTaglibCache sCachedExpectedTypes = + StandardTaglibCacheFactory.createCache( + Constants.ELEVALUATOR_EXPECTED_TYPES_CACHE, + ForeverStandardTaglibCache.class + ); /** The static Logger **/ static Logger sLogger = new Logger (System.out); @@ -104,9 +113,6 @@ /** The VariableResolver **/ VariableResolver mResolver; - /** Flag if the cache should be bypassed **/ - boolean mBypassCache; - //------------------------------------- /** * @@ -124,25 +130,6 @@ //------------------------------------- /** * - * Constructor - * - * @param pResolver the object that should be used to resolve - * variable names encountered in expressions. If null, all variable - * references will resolve to null. - * - * @param pBypassCache flag indicating if the cache should be - * bypassed - **/ - public ELEvaluator (VariableResolver pResolver, - boolean pBypassCache) - { - mResolver = pResolver; - mBypassCache = pBypassCache; - } - - //------------------------------------- - /** - * * Evaluates the given expression String * * @param pExpressionString the expression String to be evaluated @@ -248,10 +235,7 @@ } // See if it's in the cache - Object ret = - mBypassCache ? - null : - sCachedExpressionStrings.get (pExpressionString); + Object ret = sCachedExpressionStrings.get (pExpressionString); if (ret == null) { // Parse the expression @@ -311,8 +295,7 @@ // Find the cached value Map valueByString = getOrCreateExpectedTypeMap (pExpectedType); - if (!mBypassCache && - valueByString.containsKey (pValue)) { + if (valueByString.containsKey (pValue)) { return valueByString.get (pValue); } else { @@ -331,14 +314,12 @@ **/ static Map getOrCreateExpectedTypeMap (Class pExpectedType) { - synchronized (sCachedExpectedTypes) { Map ret = (Map) sCachedExpectedTypes.get (pExpectedType); if (ret == null) { ret = Collections.synchronizedMap (new HashMap ()); sCachedExpectedTypes.put (pExpectedType, ret); } return ret; - } } //------------------------------------- Index: src/org/apache/taglibs/standard/resources/Resources.java =================================================================== --- src/org/apache/taglibs/standard/resources/Resources.java (revision 504759) +++ src/org/apache/taglibs/standard/resources/Resources.java (working copy) @@ -20,6 +20,9 @@ import java.util.MissingResourceException; import java.util.ResourceBundle; +import org.apache.taglibs.standard.util.*; +import org.apache.taglibs.standard.lang.jstl.Constants; + /** *
Provides locale-neutral access to string resources. Only the
* documentation and code are in English. :-)
@@ -52,7 +55,10 @@
private static ResourceBundle rb =
ResourceBundle.getBundle(RESOURCE_LOCATION);
+ private static StandardTaglibCache messageFormatCache =
+ StandardTaglibCacheFactory.createCache(Constants.MESSAGEFORMAT_CACHE);
+
//*********************************************************************
// Public static methods
@@ -66,7 +72,12 @@
public static String getMessage(String name, Object[] a)
throws MissingResourceException {
String res = rb.getString(name);
- return MessageFormat.format(res, a);
+ MessageFormat msgFormat = (MessageFormat) messageFormatCache.get(res);
+ if(msgFormat == null) {
+ msgFormat = new MessageFormat(res);
+ messageFormatCache.put(res, msgFormat);
+ }
+ return msgFormat.format(res, a);
}
/** Retrieves a message with one argument. */
Index: src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java
===================================================================
--- src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (revision 504759)
+++ src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (working copy)
@@ -31,6 +31,9 @@
import org.apache.taglibs.standard.resources.Resources;
import org.apache.taglibs.standard.tag.common.core.Util;
+import org.apache.taglibs.standard.util.*;
+import org.apache.taglibs.standard.lang.jstl.Constants;
+
/**
* Support for tag handlers for <formatDate>, the date and time
* formatting tag in JSTL 1.0.
@@ -65,6 +68,8 @@
private String var; // 'var' attribute
private int scope; // 'scope' attribute
+ private static StandardTaglibCache dateFormatCache =
+ StandardTaglibCacheFactory.createCache(Constants.DATEFORMAT_CACHE);
//*********************************************************************
// Constructor and initialization
@@ -183,20 +188,32 @@
private DateFormat createFormatter(Locale loc) throws JspException {
DateFormat formatter = null;
- if ((type == null) || DATE.equalsIgnoreCase(type)) {
- formatter = DateFormat.getDateInstance(
- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
- loc);
- } else if (TIME.equalsIgnoreCase(type)) {
- formatter = DateFormat.getTimeInstance(
- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
- loc);
- } else if (DATETIME.equalsIgnoreCase(type)) {
- formatter = DateFormat.getDateTimeInstance(
- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
- loc);
- } else {
+ if ((type == null) || DATE.equalsIgnoreCase(type)) {
+ int style = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE");
+ String key = DATE + style + loc;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = DateFormat.getDateInstance(style, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else if (TIME.equalsIgnoreCase(type)) {
+ int style = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE");
+ String key = TIME + style + loc;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = DateFormat.getTimeInstance(style, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else if (DATETIME.equalsIgnoreCase(type)) {
+ int style1 = Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE");
+ int style2 = Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE");
+ String key = DATETIME + style1 + loc + style2;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = DateFormat.getDateTimeInstance(style1, style2, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else {
throw new JspException(
Resources.getMessage("FORMAT_DATE_INVALID_TYPE",
type));
@@ -204,4 +221,5 @@
return formatter;
}
+
}
Index: src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java
===================================================================
--- src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java (revision 0)
+++ src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java (revision 0)
@@ -0,0 +1,44 @@
+package org.apache.taglibs.standard.util;
+
+public class StandardTaglibCacheFactory {
+
+ /**
+ * @throws ClassNotFoundException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ public static StandardTaglibCache createCache(String key) {
+ return createCache(key, null);
+ }
+
+ /**
+ * @throws ClassNotFoundException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ public static StandardTaglibCache createCache(String key, Class defaultClass) {
+
+ String className = System.getProperty(key);
+
+ try {
+ if(className == null) {
+ if(defaultClass == null) {
+ return null;
+ } else {
+ return (StandardTaglibCache) defaultClass.newInstance();
+ }
+ }
+
+ return (StandardTaglibCache) Class.forName(className, true,
+ Thread.currentThread().getContextClassLoader()
+ ).newInstance();
+ } catch(ClassNotFoundException cnfe) {
+ throw new RuntimeException("Unable to create cache: " + cnfe);
+ } catch(IllegalAccessException iae) {
+ throw new RuntimeException("Unable to create cache: " + iae);
+ } catch(InstantiationException ie) {
+ throw new RuntimeException("Unable to create cache: " + ie);
+ }
+ }
+
+}
Property changes on: src/org/apache/taglibs/standard/util/StandardTaglibCacheFactory.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java
===================================================================
--- src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java (revision 0)
+++ src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java (revision 0)
@@ -0,0 +1,22 @@
+package org.apache.taglibs.standard.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Objects are cached forever in a Forever cache.
+ */
+public class ForeverStandardTaglibCache implements StandardTaglibCache {
+
+ private Map map = Collections.synchronizedMap( new HashMap() );
+
+ public Object get(Object key) {
+ return map.get(key);
+ }
+
+ public void put(Object key, Object value) {
+ map.put(key, value);
+ }
+
+}
Property changes on: src/org/apache/taglibs/standard/util/ForeverStandardTaglibCache.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java
===================================================================
--- src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java (revision 0)
+++ src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java (revision 0)
@@ -0,0 +1,15 @@
+package org.apache.taglibs.standard.util;
+
+/**
+ * Objects are never cached.
+ */
+public class NullStandardTaglibCache implements StandardTaglibCache {
+
+ public Object get(Object key) {
+ return null;
+ }
+
+ public void put(Object key, Object value) {
+ }
+
+}
Property changes on: src/org/apache/taglibs/standard/util/NullStandardTaglibCache.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/org/apache/taglibs/standard/util/StandardTaglibCache.java
===================================================================
--- src/org/apache/taglibs/standard/util/StandardTaglibCache.java (revision 0)
+++ src/org/apache/taglibs/standard/util/StandardTaglibCache.java (revision 0)
@@ -0,0 +1,26 @@
+package org.apache.taglibs.standard.util;
+
+/**
+ * There are various places in the Standard taglib that
+ * can really benefit from some caching, however implementing
+ * a cache with enough options to keep each user happy it
+ * beyond the scope of the Standard taglib. This interface
+ * is provided as a plugin point for different cache
+ * implementations.
+ */
+public interface StandardTaglibCache {
+
+ /**
+ * Get an object out of the cache.
+ * null
is returned if there is nothing
+ * registered under the specified key.
+ */
+ Object get(Object key);
+
+ /**
+ * Register an object in the cache for a specified key.
+ * Passing in a value of null
unregisters a key.
+ */
+ void put(Object key, Object value);
+
+}
Property changes on: src/org/apache/taglibs/standard/util/StandardTaglibCache.java
___________________________________________________________________
Name: svn:eol-style
+ native