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 **** /* ! * Copyright (c) 1997, 2006, 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 --- 1,7 ---- /* ! * 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,53 **** * */ package java.text; 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; /** * The <code>Collator</code> class performs locale-sensitive * <code>String</code> comparison. You use this class to build --- 36,53 ---- * */ package java.text; + import java.lang.ref.SoftReference; import java.text.spi.CollatorProvider; import java.util.Locale; import java.util.ResourceBundle; ! 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,293 **** * @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, desiredLocale); ! if (providersInstance != null) { ! return providersInstance; } } - - // 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 ); } ! catch(ParseException foo) ! { ! // predefined tables should contain correct grammar ! try { ! result = new RuleBasedCollator( CollationRules.DEFAULTRULES ); ! } catch (ParseException bar) { ! // do nothing } } - // 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(); } /** * 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 --- 229,274 ---- * @param desiredLocale the desired locale. * @return the Collator for the desired locale. * @see java.util.Locale * @see java.util.ResourceBundle */ ! 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); ! 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 + ")"); } } ! while (true) { ! if (ref != null) { ! // Remove the empty SoftReference if any ! cache.remove(desiredLocale, ref); } ! ref = cache.putIfAbsent(desiredLocale, new SoftReference<>(result)); ! if (ref == null) { ! break; } + Collator cachedColl = ref.get(); + if (cachedColl != null) { + result = cachedColl; + break; } } + } + 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,330 **** --- 302,312 ---- * 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,396 **** */ public synchronized void setStrength(int newStrength) { if ((newStrength != PRIMARY) && (newStrength != SECONDARY) && (newStrength != TERTIARY) && ! (newStrength != IDENTICAL)) throw new IllegalArgumentException("Incorrect comparison level."); strength = newStrength; } /** * Get the decomposition mode of this Collator. Decomposition mode --- 367,379 ---- */ public synchronized void setStrength(int newStrength) { if ((newStrength != PRIMARY) && (newStrength != SECONDARY) && (newStrength != TERTIARY) && ! (newStrength != IDENTICAL)) { throw new IllegalArgumentException("Incorrect comparison level."); + } strength = newStrength; } /** * Get the decomposition mode of this Collator. Decomposition mode
*** 427,438 **** * mode. */ public synchronized void setDecomposition(int decompositionMode) { if ((decompositionMode != NO_DECOMPOSITION) && (decompositionMode != CANONICAL_DECOMPOSITION) && ! (decompositionMode != FULL_DECOMPOSITION)) throw new IllegalArgumentException("Wrong decomposition mode."); decmp = decompositionMode; } /** * Returns an array of all locales for which the --- 410,422 ---- * mode. */ public synchronized void setDecomposition(int decompositionMode) { if ((decompositionMode != NO_DECOMPOSITION) && (decompositionMode != CANONICAL_DECOMPOSITION) && ! (decompositionMode != FULL_DECOMPOSITION)) { throw new IllegalArgumentException("Wrong decomposition mode."); + } decmp = decompositionMode; } /** * Returns an array of all locales for which the
*** 454,463 **** --- 438,448 ---- } /** * Overrides Cloneable */ + @Override public Object clone() { try { return (Collator)super.clone(); } catch (CloneNotSupportedException e) {
*** 469,491 **** * 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. */ public boolean equals(Object that) { ! 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. */ abstract public int hashCode(); /** * Default constructor. This constructor is * protected so subclasses can get access to it. Users typically create --- 454,484 ---- * 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; ! } 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,508 **** decmp = CANONICAL_DECOMPOSITION; } private int strength = 0; private int decmp = 0; ! private static SoftCache cache = new SoftCache(); // // FIXME: These three constants should be removed. // /** --- 491,502 ---- decmp = CANONICAL_DECOMPOSITION; } private int strength = 0; private int decmp = 0; ! private static final ConcurrentMap<Locale, SoftReference<Collator>> cache ! = new ConcurrentHashMap<>(); // // FIXME: These three constants should be removed. // /**
*** 521,553 **** * 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; - } - } } --- 515,520 ----