com.ibm.icu.text.PluralRanges 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
// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
* Copyright (C) 2008-2015, Google, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.text;
import java.util.Arrays;
import java.util.EnumSet;
import com.ibm.icu.impl.StandardPlural;
import com.ibm.icu.util.Freezable;
import com.ibm.icu.util.Output;
/**
* Utility class for returning the plural category for a range of numbers, such as 1–5, so that appropriate messages can
* be chosen. The rules for determining this value vary widely across locales.
*
* @author markdavis
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public final class PluralRanges implements Freezable, Comparable {
private volatile boolean isFrozen;
private Matrix matrix = new Matrix();
private boolean[] explicit = new boolean[StandardPlural.COUNT];
/**
* Constructor
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public PluralRanges() {
}
/**
* Internal class for mapping from two StandardPluralCategories values to another.
*/
private static final class Matrix implements Comparable, Cloneable {
private byte[] data = new byte[StandardPlural.COUNT * StandardPlural.COUNT];
{
for (int i = 0; i < data.length; ++i) {
data[i] = -1;
}
}
Matrix() {
}
/**
* Internal method for setting.
*/
@SuppressWarnings("unused")
void set(StandardPlural start, StandardPlural end, StandardPlural result) {
data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
: (byte) result.ordinal();
}
/**
* Internal method for setting; throws exception if already set.
*/
void setIfNew(StandardPlural start, StandardPlural end,
StandardPlural result) {
byte old = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
if (old >= 0) {
throw new IllegalArgumentException("Previously set value for <" + start + ", " + end + ", "
+ StandardPlural.VALUES.get(old) + ">");
}
data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
: (byte) result.ordinal();
}
/**
* Internal method for getting.
*/
StandardPlural get(StandardPlural start, StandardPlural end) {
byte result = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
return result < 0 ? null : StandardPlural.VALUES.get(result);
}
/**
* Internal method to see if <*,end> values are all the same.
*/
@SuppressWarnings("unused")
StandardPlural endSame(StandardPlural end) {
StandardPlural first = null;
for (StandardPlural start : StandardPlural.VALUES) {
StandardPlural item = get(start, end);
if (item == null) {
continue;
}
if (first == null) {
first = item;
continue;
}
if (first != item) {
return null;
}
}
return first;
}
/**
* Internal method to see if values are all the same.
*/
@SuppressWarnings("unused")
StandardPlural startSame(StandardPlural start,
EnumSet endDone, Output emit) {
emit.value = false;
StandardPlural first = null;
for (StandardPlural end : StandardPlural.VALUES) {
StandardPlural item = get(start, end);
if (item == null) {
continue;
}
if (first == null) {
first = item;
continue;
}
if (first != item) {
return null;
}
// only emit if we didn't cover with the 'end' values
if (!endDone.contains(end)) {
emit.value = true;
}
}
return first;
}
@Override
public int hashCode() {
int result = 0;
for (int i = 0; i < data.length; ++i) {
result = result * 37 + data[i];
}
return result;
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Matrix)) {
return false;
}
return 0 == compareTo((Matrix) other);
}
@Override
public int compareTo(Matrix o) {
for (int i = 0; i < data.length; ++i) {
int diff = data[i] - o.data[i];
if (diff != 0) {
return diff;
}
}
return 0;
}
@Override
public Matrix clone() {
Matrix result = new Matrix();
result.data = data.clone();
return result;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (StandardPlural i : StandardPlural.values()) {
for (StandardPlural j : StandardPlural.values()) {
StandardPlural x = get(i, j);
if (x != null) {
result.append(i + " & " + j + " → " + x + ";\n");
}
}
}
return result.toString();
}
}
/**
* Internal method for building. If the start or end are null, it means everything of that type.
*
* @param rangeStart
* plural category for the start of the range
* @param rangeEnd
* plural category for the end of the range
* @param result
* the resulting plural category
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public void add(StandardPlural rangeStart, StandardPlural rangeEnd,
StandardPlural result) {
if (isFrozen) {
throw new UnsupportedOperationException();
}
explicit[result.ordinal()] = true;
if (rangeStart == null) {
for (StandardPlural rs : StandardPlural.values()) {
if (rangeEnd == null) {
for (StandardPlural re : StandardPlural.values()) {
matrix.setIfNew(rs, re, result);
}
} else {
explicit[rangeEnd.ordinal()] = true;
matrix.setIfNew(rs, rangeEnd, result);
}
}
} else if (rangeEnd == null) {
explicit[rangeStart.ordinal()] = true;
for (StandardPlural re : StandardPlural.values()) {
matrix.setIfNew(rangeStart, re, result);
}
} else {
explicit[rangeStart.ordinal()] = true;
explicit[rangeEnd.ordinal()] = true;
matrix.setIfNew(rangeStart, rangeEnd, result);
}
}
/**
* Returns the appropriate plural category for a range from start to end. If there is no available data, then
* 'end' is returned as an implicit value. (Such an implicit value can be tested for with {@link #isExplicit}.)
*
* @param start
* plural category for the start of the range
* @param end
* plural category for the end of the range
* @return the resulting plural category, or 'end' if there is no data.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public StandardPlural get(StandardPlural start, StandardPlural end) {
StandardPlural result = matrix.get(start, end);
return result == null ? end : result;
}
/**
* Returns whether the appropriate plural category for a range from start to end
* is explicitly in the data (vs given an implicit value). See also {@link #get}.
*
* @param start
* plural category for the start of the range
* @param end
* plural category for the end of the range
* @return whether the value for (start,end) is explicit or not.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public boolean isExplicit(StandardPlural start, StandardPlural end) {
return matrix.get(start, end) != null;
}
/**
* Internal method to determines whether the StandardPluralCategories was explicitly used in any add statement.
*
* @param count
* plural category to test
* @return true if set
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public boolean isExplicitlySet(StandardPlural count) {
return explicit[count.ordinal()];
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof PluralRanges)) {
return false;
}
PluralRanges otherPR = (PluralRanges)other;
return matrix.equals(otherPR.matrix) && Arrays.equals(explicit, otherPR.explicit);
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public int hashCode() {
return matrix.hashCode();
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public int compareTo(PluralRanges that) {
return matrix.compareTo(that.matrix);
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public boolean isFrozen() {
return isFrozen;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public PluralRanges freeze() {
isFrozen = true;
return this;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public PluralRanges cloneAsThawed() {
PluralRanges result = new PluralRanges();
result.explicit = explicit.clone();
result.matrix = matrix.clone();
return result;
}
/**
* {@inheritDoc}
* @internal
* @deprecated This API is ICU internal only.
*/
@Override
@Deprecated
public String toString() {
return matrix.toString();
}
}