Index: test/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.java
===================================================================
--- test/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.java (revision 0)
+++ test/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.java (revision 0)
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1999,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.taglibs.standard.tag.el.fmt;
+
+import javax.servlet.jsp.*;
+import org.apache.cactus.*;
+import org.apache.taglibs.standard.testutil.TestUtil;
+
+public class TestDateTag extends JspTestCase {
+
+ public TestDateTag(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testDateTag() throws Exception {
+ String var = "varDate";
+ String toInclude = TestUtil.getTestJsp(this);
+ pageContext.include(toInclude);
+ String actual = (String) pageContext.getAttribute(var, PageContext.APPLICATION_SCOPE);
+ assertEquals("yyyy-MM-dd".length(), actual.length());
+ }
+}
Property changes on: test/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.java
___________________________________________________________________
Name: svn:eol-style
+ native
Index: test/web/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.jsp
===================================================================
--- test/web/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.jsp (revision 0)
+++ test/web/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.jsp (revision 0)
@@ -0,0 +1,7 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+
+
+
+
+
Property changes on: test/web/org/apache/taglibs/standard/tag/el/fmt/TestDateTag.jsp
___________________________________________________________________
Name: svn:eol-style
+ native
Index: src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java
===================================================================
--- src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (revision 580679)
+++ src/org/apache/taglibs/standard/tag/common/fmt/FormatDateSupport.java (working copy)
@@ -22,6 +22,8 @@
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
+import java.util.Collections;
+import java.util.Map;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
@@ -31,6 +33,8 @@
import org.apache.taglibs.standard.resources.Resources;
import org.apache.taglibs.standard.tag.common.core.Util;
+import org.apache.taglibs.standard.extra.commons.collections.map.LRUMap;
+
/**
* Support for tag handlers for <formatDate>, the date and time
* formatting tag in JSTL 1.0.
@@ -43,11 +47,25 @@
//*********************************************************************
// Private constants
+ /**
+ * Name of configuration setting for maximum number of entries in the
+ * cached dateformat map
+ */
+ private static final String DATE_CACHE_PARAM =
+ "org.apache.taglibs.standard.tag.common.fmt.dateFormatCacheSize";
+
private static final String DATE = "date";
private static final String TIME = "time";
private static final String DATETIME = "both";
+ private static Map dateFormatCache = null;
+ /**
+ * Default maximum cache size
+ */
+ private static final int MAX_SIZE = 100;
+
+
//*********************************************************************
// Protected state
@@ -120,17 +138,8 @@
DateFormat.getAvailableLocales());
if (locale != null) {
- DateFormat formatter = createFormatter(locale);
+ DateFormat formatter = createFormatter(locale, pattern);
- // Apply pattern, if present
- if (pattern != null) {
- try {
- ((SimpleDateFormat) formatter).applyPattern(pattern);
- } catch (ClassCastException cce) {
- formatter = new SimpleDateFormat(pattern, locale);
- }
- }
-
// Set time zone
TimeZone tz = null;
if ((timeZone instanceof String)
@@ -180,22 +189,75 @@
//*********************************************************************
// Private utility methods
- private DateFormat createFormatter(Locale loc) throws JspException {
+ private DateFormat createFormatter(Locale loc, String pattern) throws JspException {
DateFormat formatter = null;
+ // lazy initialization of cache
+ if (dateFormatCache == null) {
+ String value = pageContext.getServletContext().getInitParameter(DATE_CACHE_PARAM);
+ if (value != null) {
+ dateFormatCache = Collections.synchronizedMap(new LRUMap(Integer.parseInt(value)));
+ } else {
+ dateFormatCache = Collections.synchronizedMap(new LRUMap(MAX_SIZE));
+ }
+ }
+
+ // Apply pattern, if present
+ if (pattern != null) {
+ if ((type == null) || DATE.equalsIgnoreCase(type)) {
+ String key = DATE + pattern + loc;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = new SimpleDateFormat(pattern, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else if (TIME.equalsIgnoreCase(type)) {
+ String key = TIME + pattern + loc;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = new SimpleDateFormat(pattern, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else if (DATETIME.equalsIgnoreCase(type)) {
+ String key = DATETIME + pattern + loc;
+ formatter = (DateFormat) dateFormatCache.get(key);
+ if(formatter == null) {
+ formatter = new SimpleDateFormat(pattern, loc);
+ dateFormatCache.put(key, formatter);
+ }
+ } else {
+ throw new JspException(
+ Resources.getMessage("FORMAT_DATE_INVALID_TYPE",
+ type));
+ }
+ return formatter;
+ }
+
if ((type == null) || DATE.equalsIgnoreCase(type)) {
- formatter = DateFormat.getDateInstance(
- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
- loc);
+ 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)) {
- formatter = DateFormat.getTimeInstance(
- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
- loc);
+ 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)) {
- formatter = DateFormat.getDateTimeInstance(
- Util.getStyle(dateStyle, "FORMAT_DATE_INVALID_DATE_STYLE"),
- Util.getStyle(timeStyle, "FORMAT_DATE_INVALID_TIME_STYLE"),
- loc);
+ 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",