![JAR search and dependency download from the Maven repository](/logo.png)
net.admin4j.deps.commons.lang3.time.FormatCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of admin4j Show documentation
Show all versions of admin4j Show documentation
Admin4J is a set of application administration utilities that will assist with providing alerts for
thread contention, memory issues, performance issues. In addition, it provides a console for changing log levels at runtime.
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 net.admin4j.deps.commons.lang3.time;
import java.text.DateFormat;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* FormatCache is a cache and factory for {@link Format}s.
*
* @since 3.0
* @version $Id: FormatCache 892161 2009-12-18 07:21:10Z $
*/
// TODO: Before making public move from getDateTimeInstance(Integer,...) to int; or some other approach.
abstract class FormatCache {
/**
* No date or no time. Used in same parameters as DateFormat.SHORT or DateFormat.LONG
*/
static final int NONE= -1;
private final ConcurrentMap cInstanceCache
= new ConcurrentHashMap(7);
private final ConcurrentMap cDateTimeInstanceCache
= new ConcurrentHashMap(7);
/**
* Gets a formatter instance using the default pattern in the
* default timezone and locale.
*
* @return a date/time formatter
*/
public F getInstance() {
return getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, TimeZone.getDefault(), Locale.getDefault());
}
/**
* Gets a formatter instance using the specified pattern, time zone
* and locale.
*
* @param pattern {@link java.text.SimpleDateFormat} compatible
* pattern
* @param timeZone the non-null time zone
* @param locale the non-null locale
* @return a pattern based date/time formatter
* @throws IllegalArgumentException if pattern is invalid
* or null
*/
public F getInstance(String pattern, TimeZone timeZone, Locale locale) {
if (pattern == null) {
throw new NullPointerException("pattern must not be null");
}
if (timeZone == null) {
timeZone = TimeZone.getDefault();
}
if (locale == null) {
locale = Locale.getDefault();
}
MultipartKey key = new MultipartKey(pattern, timeZone, locale);
F format = cInstanceCache.get(key);
if (format == null) {
format = createInstance(pattern, timeZone, locale);
F previousValue= cInstanceCache.putIfAbsent(key, format);
if (previousValue != null) {
// another thread snuck in and did the same work
// we should return the instance that is in ConcurrentMap
format= previousValue;
}
}
return format;
}
/**
* Create a format instance using the specified pattern, time zone
* and locale.
*
* @param pattern {@link java.text.SimpleDateFormat} compatible pattern, this will not be null.
* @param timeZone time zone, this will not be null.
* @param locale locale, this will not be null.
* @return a pattern based date/time formatter
* @throws IllegalArgumentException if pattern is invalid
* or null
*/
abstract protected F createInstance(String pattern, TimeZone timeZone, Locale locale);
/**
* Gets a date/time formatter instance using the specified style,
* time zone and locale.
*
* @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT
* @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT
* @param timeZone optional time zone, overrides time zone of
* formatted date
* @param locale optional locale, overrides system locale
* @return a localized standard date/time formatter
* @throws IllegalArgumentException if the Locale has no date/time
* pattern defined
*/
public F getDateTimeInstance(Integer dateStyle, Integer timeStyle, TimeZone timeZone, Locale locale) {
if (locale == null) {
locale = Locale.getDefault();
}
MultipartKey key = new MultipartKey(dateStyle, timeStyle, locale);
String pattern = cDateTimeInstanceCache.get(key);
if (pattern == null) {
try {
DateFormat formatter;
if (dateStyle == null) {
formatter = DateFormat.getTimeInstance(timeStyle, locale);
}
else if (timeStyle == null) {
formatter = DateFormat.getDateInstance(dateStyle, locale);
}
else {
formatter = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
}
pattern = ((SimpleDateFormat)formatter).toPattern();
String previous = cDateTimeInstanceCache.putIfAbsent(key, pattern);
if (previous != null) {
// even though it doesn't matter if another thread put the pattern
// it's still good practice to return the String instance that is
// actually in the ConcurrentMap
pattern= previous;
}
} catch (ClassCastException ex) {
throw new IllegalArgumentException("No date time pattern for locale: " + locale);
}
}
return getInstance(pattern, timeZone, locale);
}
// ----------------------------------------------------------------------
/**
* Helper class to hold multi-part Map keys
*/
private static class MultipartKey {
private final Object[] keys;
private int hashCode;
/**
* Constructs an instance of MultipartKey
to hold the specified objects.
* @param keys the set of objects that make up the key. Each key may be null.
*/
public MultipartKey(Object... keys) {
this.keys = keys;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if ( obj instanceof MultipartKey == false ) {
return false;
}
return Arrays.equals(keys, ((MultipartKey)obj).keys);
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
if(hashCode==0) {
int rc= 0;
for(Object key : keys) {
if(key!=null) {
rc= rc*7 + key.hashCode();
}
}
hashCode= rc;
}
return hashCode;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy