001: package com.flexive.war.webdav.catalina;
002:
003: import java.io.Serializable;
004: import java.text.DateFormat;
005: import java.text.ParseException;
006: import java.text.SimpleDateFormat;
007: import java.util.Date;
008: import java.util.HashMap;
009: import java.util.Locale;
010: import java.util.TimeZone;
011:
012: /**
013: * Catalina sources cloned for packaging issues to the flexive source tree.
014: * Refactored to JDK 1.5 compatibility.
015: * Licensed under the Apache License, Version 2.0
016: * <p/>
017: * Utility class to generate HTTP dates.
018: *
019: * @author Remy Maucherat
020: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
021: */
022: public final class FastHttpDateFormat {
023:
024: // -------------------------------------------------------------- Variables
025:
026: /**
027: * HTTP date format.
028: */
029: protected static final SimpleDateFormat format = new SimpleDateFormat(
030: "EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
031:
032: /**
033: * The set of SimpleDateFormat formats to use in getDateHeader().
034: */
035: protected static final SimpleDateFormat formats[] = {
036: new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz",
037: Locale.US),
038: new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz",
039: Locale.US),
040: new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };
041:
042: protected final static TimeZone gmtZone = TimeZone
043: .getTimeZone("GMT");
044:
045: /**
046: * GMT timezone - all HTTP dates are on GMT
047: */
048: static {
049:
050: format.setTimeZone(gmtZone);
051:
052: formats[0].setTimeZone(gmtZone);
053: formats[1].setTimeZone(gmtZone);
054: formats[2].setTimeZone(gmtZone);
055:
056: }
057:
058: /**
059: * Instant on which the currentDate object was generated.
060: */
061: protected static long currentDateGenerated = 0L;
062:
063: /**
064: * Current formatted date.
065: */
066: protected static String currentDate = null;
067:
068: /**
069: * Formatter cache.
070: */
071: protected static final HashMap<Long, String> formatCache = new HashMap<Long, String>();
072:
073: /**
074: * Parser cache.
075: */
076: protected static final HashMap parseCache = new HashMap();
077:
078: // --------------------------------------------------------- Public Methods
079:
080: /**
081: * Get the current date in HTTP format.
082: */
083: public static String getCurrentDate() {
084:
085: long now = System.currentTimeMillis();
086: if ((now - currentDateGenerated) > 1000) {
087: synchronized (format) {
088: if ((now - currentDateGenerated) > 1000) {
089: currentDateGenerated = now;
090: currentDate = format.format(new Date(now));
091: }
092: }
093: }
094: return currentDate;
095:
096: }
097:
098: /**
099: * Get the HTTP format of the specified date.
100: */
101: public static String formatDate(long value,
102: DateFormat threadLocalformat) {
103:
104: String cachedDate = null;
105: try {
106: cachedDate = (String) formatCache.get(value);
107: } catch (Exception e) {
108: //ignore
109: }
110: if (cachedDate != null)
111: return cachedDate;
112:
113: String newDate;
114: Date dateValue = new Date(value);
115: if (threadLocalformat != null) {
116: newDate = threadLocalformat.format(dateValue);
117: synchronized (formatCache) {
118: updateCache(formatCache, value, newDate);
119: }
120: } else {
121: synchronized (formatCache) {
122: synchronized (format) {
123: newDate = format.format(dateValue);
124: }
125: updateCache(formatCache, value, newDate);
126: }
127: }
128: return newDate;
129:
130: }
131:
132: /**
133: * Try to parse the given date as a HTTP date.
134: */
135: public static long parseDate(String value,
136: DateFormat[] threadLocalformats) {
137:
138: Long cachedDate = null;
139: try {
140: cachedDate = (Long) parseCache.get(value);
141: } catch (Exception e) {
142: //ignore
143: }
144: if (cachedDate != null)
145: return cachedDate;
146:
147: Long date;
148: if (threadLocalformats != null) {
149: date = internalParseDate(value, threadLocalformats);
150: synchronized (parseCache) {
151: updateCache(parseCache, value, date);
152: }
153: } else {
154: synchronized (parseCache) {
155: date = internalParseDate(value, formats);
156: updateCache(parseCache, value, date);
157: }
158: }
159: if (date == null) {
160: return (-1L);
161: } else {
162: return date;
163: }
164:
165: }
166:
167: /**
168: * Parse date with given formatters.
169: */
170: private static Long internalParseDate(String value,
171: DateFormat[] formats) {
172: Date date = null;
173: for (int i = 0; (date == null) && (i < formats.length); i++) {
174: try {
175: date = formats[i].parse(value);
176: } catch (ParseException e) {
177: //ignore
178: }
179: }
180: if (date == null) {
181: return null;
182: }
183: return date.getTime();
184: }
185:
186: /**
187: * Update cache.
188: */
189: private static void updateCache(HashMap cache, Serializable key,
190: Serializable value) {
191: if (value == null) {
192: return;
193: }
194: if (cache.size() > 1000) {
195: cache.clear();
196: }
197: cache.put(key, value);
198: }
199:
200: }
|