src/share/classes/java/text/Collator.java
Print this page
rev 5615 : 6336885: RFE: Locale Data Deployment Enhancements
4609153: Provide locale data for Indic locales
5104387: Support for gl_ES locale (galician language)
6337471: desktop/system locale preferences support
7056139: (cal) SPI support for locale-dependent Calendar parameters
7058206: Provide CalendarData SPI for week params and display field value names
7073852: Support multiple scripts for digits and decimal symbols per locale
7079560: [Fmt-Da] Context dependent month names support in SimpleDateFormat
7171324: getAvailableLocales() of locale sensitive services should return the actual availability of locales
7151414: (cal) Support calendar type identification
7168528: LocaleServiceProvider needs to be aware of Locale extensions
7171372: (cal) locale's default Calendar should be created if unknown calendar is specified
Summary: JEP 127: Improve Locale Data Packaging and Adopt Unicode CLDR Data (part 1 w/o Jigsaw. by Naoto Sato and Masayoshi Okutsu)
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
@@ -36,18 +36,18 @@
*
*/
package java.text;
+import java.lang.ref.SoftReference;
import java.text.spi.CollatorProvider;
import java.util.Locale;
-import java.util.MissingResourceException;
import java.util.ResourceBundle;
-import java.util.spi.LocaleServiceProvider;
-import sun.misc.SoftCache;
-import sun.util.resources.LocaleData;
-import sun.util.LocaleServiceProviderPool;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import sun.util.locale.provider.LocaleProviderAdapter;
+import sun.util.locale.provider.LocaleServiceProviderPool;
/**
* The <code>Collator</code> class performs locale-sensitive
* <code>String</code> comparison. You use this class to build
@@ -229,65 +229,46 @@
* @param desiredLocale the desired locale.
* @return the Collator for the desired locale.
* @see java.util.Locale
* @see java.util.ResourceBundle
*/
- public static synchronized
- Collator getInstance(Locale desiredLocale)
- {
- Collator result = (Collator) cache.get(desiredLocale);
- if (result != null) {
- return (Collator)result.clone(); // make the world safe
- }
-
- // Check whether a provider can provide an implementation that's closer
- // to the requested locale than what the Java runtime itself can provide.
- LocaleServiceProviderPool pool =
- LocaleServiceProviderPool.getPool(CollatorProvider.class);
- if (pool.hasProviders()) {
- Collator providersInstance = pool.getLocalizedObject(
- CollatorGetter.INSTANCE,
- desiredLocale,
+ public static Collator getInstance(Locale desiredLocale) {
+ SoftReference<Collator> ref = cache.get(desiredLocale);
+ Collator result = (ref != null) ? ref.get() : null;
+ if (result == null) {
+ LocaleProviderAdapter adapter = LocaleProviderAdapter.getAdapter(CollatorProvider.class,
desiredLocale);
- if (providersInstance != null) {
- return providersInstance;
+ CollatorProvider provider = adapter.getCollatorProvider();
+ result = provider.getInstance(desiredLocale);
+ if (result == null) {
+ if (adapter.getAdapterType() != LocaleProviderAdapter.Type.JRE) {
+ result = LocaleProviderAdapter.forJRE()
+ .getCollatorProvider().getInstance(desiredLocale);
}
+ if (result == null) {
+ throw new InternalError("Collator instance creation failed. (provider="
+ + provider + ")");
}
-
- // Load the resource of the desired locale from resource
- // manager.
- String colString = "";
- try {
- ResourceBundle resource = LocaleData.getCollationData(desiredLocale);
-
- colString = resource.getString("Rule");
- } catch (MissingResourceException e) {
- // Use default values
}
- try
- {
- result = new RuleBasedCollator( CollationRules.DEFAULTRULES +
- colString,
- CANONICAL_DECOMPOSITION );
+ while (true) {
+ if (ref != null) {
+ // Remove the empty SoftReference if any
+ cache.remove(desiredLocale, ref);
}
- catch(ParseException foo)
- {
- // predefined tables should contain correct grammar
- try {
- result = new RuleBasedCollator( CollationRules.DEFAULTRULES );
- } catch (ParseException bar) {
- // do nothing
+ ref = cache.putIfAbsent(desiredLocale, new SoftReference<>(result));
+ if (ref == null) {
+ break;
}
+ Collator cachedColl = ref.get();
+ if (cachedColl != null) {
+ result = cachedColl;
+ break;
}
- // Now that RuleBasedCollator adds expansions for pre-composed characters
- // into their decomposed equivalents, the default collators don't need
- // to have decomposition turned on. Laura, 5/5/98, bug 4114077
- result.setDecomposition(NO_DECOMPOSITION);
-
- cache.put(desiredLocale,result);
- return (Collator)result.clone();
}
+ }
+ return (Collator) result.clone(); // make the world safe
+ }
/**
* Compares the source string to the target string according to the
* collation rules for this Collator. Returns an integer less than,
* equal to or greater than zero depending on whether the source String is
@@ -321,10 +302,11 @@
* second.
* @exception ClassCastException the arguments cannot be cast to Strings.
* @see java.util.Comparator
* @since 1.2
*/
+ @Override
public int compare(Object o1, Object o2) {
return compare((String)o1, (String)o2);
}
/**
@@ -385,12 +367,13 @@
*/
public synchronized void setStrength(int newStrength) {
if ((newStrength != PRIMARY) &&
(newStrength != SECONDARY) &&
(newStrength != TERTIARY) &&
- (newStrength != IDENTICAL))
+ (newStrength != IDENTICAL)) {
throw new IllegalArgumentException("Incorrect comparison level.");
+ }
strength = newStrength;
}
/**
* Get the decomposition mode of this Collator. Decomposition mode
@@ -427,12 +410,13 @@
* mode.
*/
public synchronized void setDecomposition(int decompositionMode) {
if ((decompositionMode != NO_DECOMPOSITION) &&
(decompositionMode != CANONICAL_DECOMPOSITION) &&
- (decompositionMode != FULL_DECOMPOSITION))
+ (decompositionMode != FULL_DECOMPOSITION)) {
throw new IllegalArgumentException("Wrong decomposition mode.");
+ }
decmp = decompositionMode;
}
/**
* Returns an array of all locales for which the
@@ -454,10 +438,11 @@
}
/**
* Overrides Cloneable
*/
+ @Override
public Object clone()
{
try {
return (Collator)super.clone();
} catch (CloneNotSupportedException e) {
@@ -469,23 +454,31 @@
* Compares the equality of two Collators.
* @param that the Collator to be compared with this.
* @return true if this Collator is the same as that Collator;
* false otherwise.
*/
+ @Override
public boolean equals(Object that)
{
- if (this == that) return true;
- if (that == null) return false;
- if (getClass() != that.getClass()) return false;
+ if (this == that) {
+ return true;
+ }
+ if (that == null) {
+ return false;
+ }
+ if (getClass() != that.getClass()) {
+ return false;
+ }
Collator other = (Collator) that;
return ((strength == other.strength) &&
(decmp == other.decmp));
}
/**
* Generates the hash code for this Collator.
*/
+ @Override
abstract public int hashCode();
/**
* Default constructor. This constructor is
* protected so subclasses can get access to it. Users typically create
@@ -498,11 +491,12 @@
decmp = CANONICAL_DECOMPOSITION;
}
private int strength = 0;
private int decmp = 0;
- private static SoftCache cache = new SoftCache();
+ private static final ConcurrentMap<Locale, SoftReference<Collator>> cache
+ = new ConcurrentHashMap<>();
//
// FIXME: These three constants should be removed.
//
/**
@@ -521,33 +515,6 @@
* GREATER is returned if source string is compared to be greater than
* target string in the compare() method.
* @see java.text.Collator#compare
*/
final static int GREATER = 1;
-
- /**
- * Obtains a Collator instance from a CollatorProvider
- * implementation.
- */
- private static class CollatorGetter
- implements LocaleServiceProviderPool.LocalizedObjectGetter<CollatorProvider, Collator> {
- private static final CollatorGetter INSTANCE = new CollatorGetter();
-
- public Collator getObject(CollatorProvider collatorProvider,
- Locale locale,
- String key,
- Object... params) {
- assert params.length == 1;
- Collator result = collatorProvider.getInstance(locale);
- if (result != null) {
- // put this Collator instance in the cache for two locales, one
- // is for the desired locale, and the other is for the actual
- // locale where the provider is found, which may be a fall back locale.
- cache.put((Locale)params[0], result);
- cache.put(locale, result);
- return (Collator)result.clone();
- }
-
- return null;
- }
- }
}