spring security FastHttpDateFormat 源码

  • 2022-08-13
  • 浏览 (388)

spring security FastHttpDateFormat 代码

文件路径:/web/src/main/java/org/springframework/security/web/savedrequest/FastHttpDateFormat.java

/*
 * Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 *
 * 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
 *
 *      https://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.springframework.security.web.savedrequest;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Utility class to generate HTTP dates.
 * <p>
 * This class is based on code in Apache Tomcat.
 *
 * @author Remy Maucherat
 * @author Andrey Grebnev
 */
public final class FastHttpDateFormat {

	/**
	 * HTTP date format.
	 */
	protected static final SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);

	/**
	 * The set of SimpleDateFormat formats to use in <code>getDateHeader()</code>.
	 */
	protected static final SimpleDateFormat[] formats = {
			new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
			new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
			new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US) };

	/**
	 * GMT time zone - all HTTP dates are on GMT
	 */
	protected static final TimeZone gmtZone = TimeZone.getTimeZone("GMT");

	static {
		format.setTimeZone(gmtZone);
		formats[0].setTimeZone(gmtZone);
		formats[1].setTimeZone(gmtZone);
		formats[2].setTimeZone(gmtZone);
	}

	/**
	 * Instant on which the currentDate object was generated.
	 */
	protected static long currentDateGenerated = 0L;

	/**
	 * Current formatted date.
	 */
	protected static String currentDate = null;

	/**
	 * Formatter cache.
	 */
	protected static final HashMap<Long, String> formatCache = new HashMap<>();

	/**
	 * Parser cache.
	 */
	protected static final HashMap<String, Long> parseCache = new HashMap<>();

	private FastHttpDateFormat() {
	}

	/**
	 * Formats a specified date to HTTP format. If local format is not <code>null</code>,
	 * it's used instead.
	 * @param value Date value to format
	 * @param threadLocalformat The format to use (or <code>null</code> -- then HTTP
	 * format will be used)
	 * @return Formatted date
	 */
	public static String formatDate(long value, DateFormat threadLocalformat) {
		String cachedDate = null;
		Long longValue = value;
		try {
			cachedDate = formatCache.get(longValue);
		}
		catch (Exception ex) {
		}
		if (cachedDate != null) {
			return cachedDate;
		}
		String newDate;
		Date dateValue = new Date(value);
		if (threadLocalformat != null) {
			newDate = threadLocalformat.format(dateValue);
			synchronized (formatCache) {
				updateCache(formatCache, longValue, newDate);
			}
		}
		else {
			synchronized (formatCache) {
				newDate = format.format(dateValue);
				updateCache(formatCache, longValue, newDate);
			}
		}
		return newDate;
	}

	/**
	 * Gets the current date in HTTP format.
	 * @return Current date in HTTP format
	 */
	public static String getCurrentDate() {
		long now = System.currentTimeMillis();
		if ((now - currentDateGenerated) > 1000) {
			synchronized (format) {
				if ((now - currentDateGenerated) > 1000) {
					currentDateGenerated = now;
					currentDate = format.format(new Date(now));
				}
			}
		}
		return currentDate;
	}

	/**
	 * Parses date with given formatters.
	 * @param value The string to parse
	 * @param formats Array of formats to use
	 * @return Parsed date (or <code>null</code> if no formatter mached)
	 */
	private static Long internalParseDate(String value, DateFormat[] formats) {
		Date date = null;
		for (int i = 0; (date == null) && (i < formats.length); i++) {
			try {
				date = formats[i].parse(value);
			}
			catch (ParseException ex) {
			}
		}
		if (date == null) {
			return null;
		}
		return date.getTime();
	}

	/**
	 * Tries to parse the given date as an HTTP date. If local format list is not
	 * <code>null</code>, it's used instead.
	 * @param value The string to parse
	 * @param threadLocalformats Array of formats to use for parsing. If <code>null</code>
	 * , HTTP formats are used.
	 * @return Parsed date (or -1 if error occurred)
	 */
	public static long parseDate(String value, DateFormat[] threadLocalformats) {
		Long cachedDate = null;
		try {
			cachedDate = parseCache.get(value);
		}
		catch (Exception ex) {
		}
		if (cachedDate != null) {
			return cachedDate;
		}
		Long date;
		if (threadLocalformats != null) {
			date = internalParseDate(value, threadLocalformats);
			synchronized (parseCache) {
				updateCache(parseCache, value, date);
			}
		}
		else {
			synchronized (parseCache) {
				date = internalParseDate(value, formats);
				updateCache(parseCache, value, date);
			}
		}
		return (date != null) ? date : -1L;
	}

	/**
	 * Updates cache.
	 * @param cache Cache to be updated
	 * @param key Key to be updated
	 * @param value New value
	 */
	@SuppressWarnings("unchecked")
	private static void updateCache(HashMap cache, Object key, Object value) {
		if (value == null) {
			return;
		}
		if (cache.size() > 1000) {
			cache.clear();
		}
		cache.put(key, value);
	}

}

相关信息

spring security 源码目录

相关文章

spring security CookieRequestCache 源码

spring security DefaultSavedRequest 源码

spring security Enumerator 源码

spring security HttpSessionRequestCache 源码

spring security NullRequestCache 源码

spring security RequestCache 源码

spring security RequestCacheAwareFilter 源码

spring security SavedCookie 源码

spring security SavedRequest 源码

spring security SavedRequestAwareWrapper 源码

0  赞