com.ibm.icu.impl.number.range.StandardPluralRanges Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.number.range;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.impl.UResource;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;
import com.ibm.icu.util.UResourceTypeMismatchException;
/**
* @author sffc
*
*/
public class StandardPluralRanges {
StandardPlural[] flatTriples;
int numTriples = 0;
/**
* An immutable map from language codes to set IDs.
* Pre-computed and cached in Java since it is used as a cache key for PluralRules.
*/
private static volatile Map languageToSet;
/** An empty StandardPluralRanges instance. */
public static final StandardPluralRanges DEFAULT = new StandardPluralRanges();
////////////////////
private static final class PluralRangeSetsDataSink extends UResource.Sink {
Map output;
PluralRangeSetsDataSink(Map output) {
this.output = output;
}
@Override
public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
UResource.Table table = value.getTable();
for (int i = 0; table.getKeyAndValue(i, key, value); ++i) {
// The data has only languages; no regions/scripts. If this changes, this
// code and languageToSet will need to change.
assert key.toString().equals(new ULocale(key.toString()).getLanguage());
output.put(key.toString(), value.toString());
}
}
}
private static Map getLanguageToSet() {
Map candidate = languageToSet;
if (candidate == null) {
Map map = new HashMap();
PluralRangeSetsDataSink sink = new PluralRangeSetsDataSink(map);
ICUResourceBundle resource = (ICUResourceBundle)
UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "pluralRanges");
resource.getAllItemsWithFallback("locales", sink);
candidate = Collections.unmodifiableMap(map);
}
// Check if another thread set languageToSet in the mean time
if (languageToSet == null) {
languageToSet = candidate;
}
return languageToSet;
}
private static final class PluralRangesDataSink extends UResource.Sink {
StandardPluralRanges output;
PluralRangesDataSink(StandardPluralRanges output) {
this.output = output;
}
@Override
public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
UResource.Array entriesArray = value.getArray();
output.setCapacity(entriesArray.getSize());
for (int i = 0; entriesArray.getValue(i, value); ++i) {
UResource.Array pluralFormsArray = value.getArray();
if (pluralFormsArray.getSize() != 3) {
throw new UResourceTypeMismatchException(
"Expected 3 elements in pluralRanges.txt array");
}
pluralFormsArray.getValue(0, value);
StandardPlural first = StandardPlural.fromString(value.getString());
pluralFormsArray.getValue(1, value);
StandardPlural second = StandardPlural.fromString(value.getString());
pluralFormsArray.getValue(2, value);
StandardPlural result = StandardPlural.fromString(value.getString());
output.addPluralRange(first, second, result);
}
}
}
private static void getPluralRangesData(
String set,
StandardPluralRanges out) {
StringBuilder sb = new StringBuilder();
ICUResourceBundle resource;
resource = (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, "pluralRanges");
sb.setLength(0);
sb.append("rules/");
sb.append(set);
String key = sb.toString();
PluralRangesDataSink sink = new PluralRangesDataSink(out);
resource.getAllItemsWithFallback(key, sink);
}
////////////////////
/** Create a StandardPluralRanges based on locale. */
public static StandardPluralRanges forLocale(ULocale locale) {
return forSet(getSetForLocale(locale));
}
/** Create a StandardPluralRanges based on set name. */
public static StandardPluralRanges forSet(String set) {
StandardPluralRanges result = new StandardPluralRanges();
if (set == null) {
// Not all languages are covered: fail gracefully
return DEFAULT;
}
getPluralRangesData(set, result);
return result;
}
/** Get the set name from the locale. */
public static String getSetForLocale(ULocale locale) {
return getLanguageToSet().get(locale.getLanguage());
}
private StandardPluralRanges() {
}
/** Used for data loading. */
private void addPluralRange(StandardPlural first, StandardPlural second, StandardPlural result) {
flatTriples[3 * numTriples] = first;
flatTriples[3 * numTriples + 1] = second;
flatTriples[3 * numTriples + 2] = result;
numTriples++;
}
/** Used for data loading. */
private void setCapacity(int length) {
flatTriples = new StandardPlural[length*3];
}
public StandardPlural resolve(StandardPlural first, StandardPlural second) {
for (int i = 0; i < numTriples; i++) {
if (first == flatTriples[3 * i] && second == flatTriples[3 * i + 1]) {
return flatTriples[3 * i + 2];
}
}
// Default fallback
return StandardPlural.OTHER;
}
}