- Updated API status of java.lang.Object method overrides (equals/hashCode/toString/clone) to match status of declaring class. There are some API comments that is insufficient, or incorrect, or not appropriate after the change. Most of these issues were fixed.
- APIStatusConsistencyChecker and ant tasks invoking the check, designed for checking this requirement. For now, Normalizer#clone() does not satisfy the requirement, but unchanged on purpose. The tool can accept exception.
- DeprecatedAPIChecker had a problem for handling non-static inner class's constructor. CodePointMap$StringIterator is the very first instance of such class in ICU4J. The problem was fixed by removing the implicit param scanned by reflection.
- This commit includes a lot of changes made by Eclipse project configuration - removing spaces in blank lines/end of statement, and removeal of redundant generics type declaration.
</java>
</target>
+ <target name="checkAPIStatusConsistency" depends="info, build-tools, gatherapi"
+ description="Check consistency between API class status and methods overriding java.lang.Object">
+ <!--
+ If you need classes excluded from this check, define followig property in build-local.properties.
+ e.g. checkAPIStatusConsistency.skip.classes=com.ibm.icu.text.Normalizer;com.ibm.icu.util.ULocale
+ -->
+ <property name="checkAPIStatusConsistency.skip.classes" value=""/>
+ <java classname="com.ibm.icu.dev.tool.docs.APIStatusConsistencyChecker"
+ failonerror="true">
+ <arg value="${out.dir}/icu4j${api.report.version}.api3.gz" />
+ <arg value="${checkAPIStatusConsistency.skip.classes}" />
+ <classpath>
+ <pathelement location="${icu4j.build-tools.jar}"/>
+ <pathelement location="${icu4j.core.jar}"/>
+ <pathelement location="${icu4j.collate.jar}"/>
+ <pathelement location="${icu4j.charset.jar}"/>
+ <pathelement location="${icu4j.currdata.jar}"/>
+ <pathelement location="${icu4j.langdata.jar}"/>
+ <pathelement location="${icu4j.regiondata.jar}"/>
+ <pathelement location="${icu4j.translit.jar}"/>
+ </classpath>
+ </java>
+ </target>
+
+ <target name="checkAPIStatus" depends="checkAPIStatusConsistency, checkDeprecated"/>
+
<target name="draftAPIs" depends="info, gatherapi" description="Run API collector tool and generate draft API report in html">
<java classname="com.ibm.icu.dev.tool.docs.CollectAPI"
classpath="${icu4j.build-tools.jar}"
}
static final Map<Integer, Integer> computeMaxExpansions(CollationData data) {
- Map<Integer, Integer> maxExpansions = new HashMap<Integer, Integer>();
+ Map<Integer, Integer> maxExpansions = new HashMap<>();
MaxExpSink sink = new MaxExpSink(maxExpansions);
new ContractionsAndExpansions(null, null, sink, true).forData(data);
return maxExpansions;
/**
* Mock implementation of hashCode(). This implementation always returns a constant
* value. When Java assertion is enabled, this method triggers an assertion failure.
- * @internal
- * @deprecated This API is ICU internal only.
+ * @stable ICU 2.8
*/
@Override
- @Deprecated
public int hashCode() {
assert false : "hashCode not designed";
return 42;
* Subclasses should override this implementation.
*
* @return a hash code value.
- * @stable ICU 58
+ * @stable ICU 2.8
*/
@Override
public int hashCode() {
/**
* Clones the collator.
- * @stable ICU 2.6
+ * @stable ICU 2.8
* @return a clone of this collator.
*/
@Override
}
private static final class KeywordsSink extends UResource.Sink {
- LinkedList<String> values = new LinkedList<String>();
+ LinkedList<String> values = new LinkedList<>();
boolean hasDefault = false;
@Override
* @return the property as a set
* @see UProperty
* @see UCharacter#hasBinaryProperty
+ * @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
*/
public static final UnicodeSet getBinaryPropertySet(int property) {
if (property < 0 || UProperty.BINARY_LIMIT <= property) {
* @return the property as a map
* @see UProperty
* @see UCharacter#getIntPropertyValue
+ * @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
*/
public static final CodePointMap getIntPropertyMap(int property) {
if (property < UProperty.INT_START || UProperty.INT_LIMIT <= property) {
*
* @return An {@link UnlocalizedNumberRangeFormatter}, to be used for chaining.
* @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
*/
public static UnlocalizedNumberRangeFormatter with() {
return BASE;
* The locale from which to load formats and symbols for number range formatting.
* @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
* @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
*/
public static LocalizedNumberRangeFormatter withLocale(Locale locale) {
return BASE.locale(locale);
* The locale from which to load formats and symbols for number range formatting.
* @return A {@link LocalizedNumberRangeFormatter}, to be used for chaining.
* @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
*/
public static LocalizedNumberRangeFormatter withLocale(ULocale locale) {
return BASE.locale(locale);
}
+ /**
+ * Private constructor - this class is not designed for instantiation
+ */
+ private NumberRangeFormatter() {
+ }
}
}
/**
- * @internal
- * @deprecated This API is ICU internal only.
+ * {@inheritDoc}
+ * @draft ICU 62
+ * @provisional This API might change or be removed in a future release.
*/
- @Deprecated
@Override
public Object clone() {
try {
}
/**
- * @internal
- * @deprecated This API is ICU internal only.
+ * @draft ICU 60
+ * @provisional This API might change or be removed in a future release.
*/
- @Deprecated
@Override
public Object clone() {
try {
//other.pluralRules = pluralRules;
// clone content
//other.pluralCountToCurrencyUnitPattern = pluralCountToCurrencyUnitPattern;
- other.pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
+ other.pluralCountToCurrencyUnitPattern = new HashMap<>();
for (String pluralCount : pluralCountToCurrencyUnitPattern.keySet()) {
String currencyPattern = pluralCountToCurrencyUnitPattern.get(pluralCount);
other.pluralCountToCurrencyUnitPattern.put(pluralCount, currencyPattern);
/**
* Override hashCode
*
- * @internal
- * @deprecated This API is ICU internal only.
+ * @stable ICU 4.2
*/
@Override
- @Deprecated
public int hashCode() {
return pluralCountToCurrencyUnitPattern.hashCode()
^ pluralRules.hashCode()
}
private void setupCurrencyPluralPattern(ULocale uloc) {
- pluralCountToCurrencyUnitPattern = new HashMap<String, String>();
+ pluralCountToCurrencyUnitPattern = new HashMap<>();
String numberStylePattern = NumberFormat.getPattern(uloc, NumberFormat.NUMBERSTYLE);
// Split the number style pattern into pos and neg if applicable
/**
* {@inheritDoc}
- * @internal
- * @deprecated This API is ICU internal only.
+ * @stable ICU 4.0
*/
- @Deprecated
@Override
public String toString() {
return "{first=«" + fIntervalPatternFirstPart + "», second=«" + fIntervalPatternSecondPart + "», reversed:" + fFirstDateInPtnIsLaterDate + "}";
/**
* A string representation of the current edit represented by the iterator for debugging. You
* should not depend on the contents of the return string; it may change over time.
- * @internal
+ * @return a string representation of the object.
+ * @stable ICU 59
*/
@Override
public String toString() {
private final transient LocalizedNumberFormatter numberFormatter;
- private static final SimpleCache<ULocale, NumericFormatters> localeToNumericDurationFormatters = new SimpleCache<ULocale, NumericFormatters>();
+ private static final SimpleCache<ULocale, NumericFormatters> localeToNumericDurationFormatters = new SimpleCache<>();
- private static final Map<MeasureUnit, Integer> hmsTo012 = new HashMap<MeasureUnit, Integer>();
+ private static final Map<MeasureUnit, Integer> hmsTo012 = new HashMap<>();
static {
hmsTo012.put(MeasureUnit.HOUR, 0);
* Two MeasureFormats, a and b, are equal if and only if they have the same formatWidth, locale, and
* equal number formats.
*
- * @stable ICU 53
+ * @stable ICU 3.0
*/
@Override
public final boolean equals(Object other) {
/**
* {@inheritDoc}
*
- * @stable ICU 53
+ * @stable ICU 3.0
*/
@Override
public final int hashCode() {
this.formatWidth = width;
this.numberFormat = numberFormat;
this.subClass = subClass;
- this.keyValues = new HashMap<Object, Object>();
+ this.keyValues = new HashMap<>();
}
// Must have public constructor, to enable Externalizable
return values[ordinal];
}
- private static final Map<ULocale, String> localeIdToRangeFormat = new ConcurrentHashMap<ULocale, String>();
+ private static final Map<ULocale, String> localeIdToRangeFormat = new ConcurrentHashMap<>();
/**
* Return a formatter (compiled SimpleFormatter pattern) for a range, such as "{0}–{1}".
SampleType sampleType2;
boolean bounded2 = true;
boolean haveBound = false;
- Set<FixedDecimalRange> samples2 = new LinkedHashSet<FixedDecimalRange>();
+ Set<FixedDecimalRange> samples2 = new LinkedHashSet<>();
if (source.startsWith("integer")) {
sampleType2 = SampleType.INTEGER;
static final UnicodeSet BREAK_AND_KEEP = new UnicodeSet('!', '!', '%', '%', ',', ',', '.', '.', '=', '=').freeze();
static String[] split(String source) {
int last = -1;
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (int i = 0; i < source.length(); ++i) {
char ch = source.charAt(i);
if (BREAK_AND_IGNORE.contains(ch)) {
t = nextToken(tokens, x++, condition);
}
- List<Long> valueList = new ArrayList<Long>();
+ List<Long> valueList = new ArrayList<>();
// the token t is always one item ahead
while (true) {
}
/**
- * @internal
- * @deprecated This API is ICU internal only.
+ * {@inheritDoc}
+ * @stable ICU 3.8
*/
- @Deprecated
@Override
public int hashCode() {
return keyword.hashCode() ^ constraint.hashCode();
private static class RuleList implements Serializable {
private boolean hasExplicitBoundingInfo = false;
private static final long serialVersionUID = 1;
- private final List<Rule> rules = new ArrayList<Rule>();
+ private final List<Rule> rules = new ArrayList<>();
public RuleList addRule(Rule nextRule) {
String keyword = nextRule.getKeyword();
}
public Set<String> getKeywords() {
- Set<String> result = new LinkedHashSet<String>();
+ Set<String> result = new LinkedHashSet<>();
for (Rule rule : rules) {
result.add(rule.getKeyword());
}
}
/**
- * @internal
- * @deprecated This API is ICU internal only.
+ * {@inheritDoc}
+ * @stable ICU 3.8
*/
- @Deprecated
@Override
public int hashCode() {
return rules.hashCode();
if (!keywords.contains(keyword)) {
return null;
}
- Set<Double> result = new TreeSet<Double>();
+ Set<Double> result = new TreeSet<>();
if (rules.hasExplicitBoundingInfo) {
FixedDecimalSamples samples = rules.getDecimalSamples(keyword, sampleType);
// Compute if the quick test is insufficient.
- HashSet<Double> subtractedSet = new HashSet<Double>(values);
+ HashSet<Double> subtractedSet = new HashSet<>(values);
for (Double explicit : explicits) {
subtractedSet.remove(explicit - offset);
}
}
/**
- * Mock implementation of hashCode(). This implementation always returns a constant
- * value. When Java assertion is enabled, this method triggers an assertion failure.
- * @internal
- * @deprecated This API is ICU internal only.
+ * {@inheritDoc}
+ * @stable ICU 2.0
*/
@Override
- @Deprecated
public int hashCode() {
return super.hashCode();
}
// our rule list is an array of the appropriate size
ruleSets = new NFRuleSet[numRuleSets];
- ruleSetsMap = new HashMap<String, NFRuleSet>(numRuleSets * 2 + 1);
+ ruleSetsMap = new HashMap<>(numRuleSets * 2 + 1);
defaultRuleSet = null;
// Used to count the number of public rule sets
if (localizations != null) {
publicRuleSetNames = localizations[0].clone();
- Map<String, String[]> m = new HashMap<String, String[]>();
+ Map<String, String[]> m = new HashMap<>();
for (int i = 1; i < localizations.length; ++i) {
String[] data = localizations[i];
String loc = data[0];
SpoofData fSpoofData;
final UnicodeSet fAllowedCharsSet = new UnicodeSet(0, 0x10ffff); // The UnicodeSet of allowed characters.
// for this Spoof Checker. Defaults to all chars.
- final Set<ULocale> fAllowedLocales = new LinkedHashSet<ULocale>(); // The list of allowed locales.
+ final Set<ULocale> fAllowedLocales = new LinkedHashSet<>(); // The list of allowed locales.
private RestrictionLevel fRestrictionLevel;
/**
result.fSpoofData = this.fSpoofData;
result.fAllowedCharsSet = (UnicodeSet) (this.fAllowedCharsSet.clone());
result.fAllowedCharsSet.freeze();
- result.fAllowedLocales = new HashSet<ULocale>(this.fAllowedLocales);
+ result.fAllowedLocales = new HashSet<>(this.fAllowedLocales);
result.fRestrictionLevel = this.fRestrictionLevel;
return result;
}
* @stable ICU 54
*/
public Builder setAllowedJavaLocales(Set<Locale> locales) {
- HashSet<ULocale> ulocales = new HashSet<ULocale>(locales.size());
+ HashSet<ULocale> ulocales = new HashSet<>(locales.size());
for (Locale locale : locales) {
ulocales.add(ULocale.forLocale(locale));
}
private int fLineNum;
ConfusabledataBuilder() {
- fTable = new Hashtable<Integer, SPUString>();
+ fTable = new Hashtable<>();
fKeySet = new UnicodeSet();
- fKeyVec = new ArrayList<Integer>();
- fValueVec = new ArrayList<Integer>();
+ fKeyVec = new ArrayList<>();
+ fValueVec = new ArrayList<>();
stringPool = new SPUStringPool();
}
// combination of a uhash and a Vector.
private static class SPUStringPool {
public SPUStringPool() {
- fVec = new Vector<SPUString>();
- fHash = new Hashtable<String, SPUString>();
+ fVec = new Vector<>();
+ fHash = new Hashtable<>();
}
public int size() {
* @stable ICU 54
*/
public Set<Locale> getAllowedJavaLocales() {
- HashSet<Locale> locales = new HashSet<Locale>(fAllowedLocales.size());
+ HashSet<Locale> locales = new HashSet<>(fAllowedLocales.size());
for (ULocale uloc : fAllowedLocales) {
locales.add(uloc.toLocale());
}
* @param other
* the SpoofChecker being compared with.
* @return true if the two SpoofCheckers are equal.
- * @stable ICU 58
+ * @stable ICU 4.6
*/
@Override
public boolean equals(Object other) {
/**
* Overrides {@link Object#hashCode()}.
- * @stable ICU 58
+ * @stable ICU 4.6
*/
@Override
public int hashCode() {
/**
* Mock implementation of hashCode(). This implementation always returns a constant
* value. When Java assertion is enabled, this method triggers an assertion failure.
- * @internal
- * @deprecated This API is ICU internal only.
+ * @return a hash code value for this object.
+ * @stable ICU 2.8
*/
@Override
- @Deprecated
public int hashCode() {
assert false : "hashCode not designed";
return 42;
format = NumberFormat.getNumberInstance(locale);
}
pluralRules = PluralRules.forLocale(locale);
- timeUnitToCountToPatterns = new HashMap<TimeUnit, Map<String, Object[]>>();
+ timeUnitToCountToPatterns = new HashMap<>();
Set<String> pluralKeywords = pluralRules.getKeywords();
setup("units/duration", timeUnitToCountToPatterns, FULL_NAME, pluralKeywords);
setup("unitsShort/duration", timeUnitToCountToPatterns, ABBREVIATED_NAME, pluralKeywords);
Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
if (countToPatterns == null) {
- countToPatterns = new TreeMap<String, Object[]>();
+ countToPatterns = new TreeMap<>();
timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
}
final TimeUnit timeUnit = timeUnits[i];
Map<String, Object[]> countToPatterns = timeUnitToCountToPatterns.get(timeUnit);
if (countToPatterns == null) {
- countToPatterns = new TreeMap<String, Object[]>();
+ countToPatterns = new TreeMap<>();
timeUnitToCountToPatterns.put(timeUnit, countToPatterns);
}
for (String pluralCount : keywords) {
// MeasureFormat
/**
- * @internal
- * @deprecated This API is ICU internal only.
+ * @deprecated ICU 53 see {@link MeasureFormat}
*/
@Deprecated
@Override
public class ByteArrayWrapper implements Comparable<ByteArrayWrapper>
{
// public data member ------------------------------------------------
-
+
/**
* Internal byte array.
* @stable ICU 2.8
public byte[] bytes;
/**
- * Size of the internal byte array used.
- * Different from bytes.length, size will be <= bytes.length.
+ * Size of the internal byte array used.
+ * Different from bytes.length, size will be <= bytes.length.
* Semantics of size is similar to java.util.Vector.size().
* @stable ICU 2.8
*/
public int size;
-
+
// public constructor ------------------------------------------------
- /**
+ /**
* Construct a new ByteArrayWrapper with no data.
* @stable ICU 2.8
*/
// public methods ----------------------------------------------------
/**
- * Ensure that the internal byte array is at least of length capacity.
- * If the byte array is null or its length is less than capacity, a new
- * byte array of length capacity will be allocated.
- * The contents of the array (between 0 and size) remain unchanged.
+ * Ensure that the internal byte array is at least of length capacity.
+ * If the byte array is null or its length is less than capacity, a new
+ * byte array of length capacity will be allocated.
+ * The contents of the array (between 0 and size) remain unchanged.
* @param capacity minimum length of internal byte array.
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
- public ByteArrayWrapper ensureCapacity(int capacity)
+ public ByteArrayWrapper ensureCapacity(int capacity)
{
if (bytes == null || bytes.length < capacity) {
byte[] newbytes = new byte[capacity];
}
return this;
}
-
+
/**
- * Set the internal byte array from offset 0 to (limit - start) with the
- * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new
- * byte array of length (limit - start) will be allocated.
+ * Set the internal byte array from offset 0 to (limit - start) with the
+ * contents of src from offset start to limit. If the byte array is null or its length is less than capacity, a new
+ * byte array of length (limit - start) will be allocated.
* This resets the size of the internal byte array to (limit - start).
* @param src source byte array to copy from
* @param start start offset of src to copy from
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
- public final ByteArrayWrapper set(byte[] src, int start, int limit)
+ public final ByteArrayWrapper set(byte[] src, int start, int limit)
{
size = 0;
append(src, start, limit);
return this;
}
-
+
/*
- public final ByteArrayWrapper get(byte[] target, int start, int limit)
+ public final ByteArrayWrapper get(byte[] target, int start, int limit)
{
int len = limit - start;
if (len > size) throw new IllegalArgumentException("limit too long");
*/
/**
- * Appends the internal byte array from offset size with the
+ * Appends the internal byte array from offset size with the
* contents of src from offset start to limit. This increases the size of
* the internal byte array to (size + limit - start).
* @param src source byte array to copy from
* @return this ByteArrayWrapper
* @stable ICU 3.2
*/
- public final ByteArrayWrapper append(byte[] src, int start, int limit)
+ public final ByteArrayWrapper append(byte[] src, int start, int limit)
{
int len = limit - start;
ensureCapacity(size + len);
}
/*
- public final ByteArrayWrapper append(ByteArrayWrapper other)
+ public final ByteArrayWrapper append(ByteArrayWrapper other)
{
return append(other.bytes, 0, other.size);
}
size = 0;
return result;
}
-
+
// Boilerplate ----------------------------------------------------
-
+
/**
* Returns string value for debugging
- * @stable ICU 3.2
+ * @stable ICU 2.8
*/
+ @Override
public String toString() {
StringBuilder result = new StringBuilder();
for (int i = 0; i < size; ++i) {
* Return true if the bytes in each wrapper are equal.
* @param other the object to compare to.
* @return true if the two objects are equal.
- * @stable ICU 3.2
+ * @stable ICU 2.8
*/
+ @Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null) return false;
/**
* Return the hashcode.
* @return the hashcode.
- * @stable ICU 3.2
+ * @stable ICU 2.8
*/
+ @Override
public int hashCode() {
int result = bytes.length;
for (int i = 0; i < size; ++i) {
* @throws ClassCastException if the other object is not a ByteArrayWrapper
* @stable ICU 4.4
*/
+ @Override
public int compareTo(ByteArrayWrapper other) {
if (this == other) return 0;
int minSize = size < other.size ? size : other.size;
}
return size - other.size;
}
-
+
// private methods -----------------------------------------------------
-
+
/**
- * Copies the contents of src byte array from offset srcoff to the
+ * Copies the contents of src byte array from offset srcoff to the
* target of tgt byte array at the offset tgtoff.
* @param src source byte array to copy from
* @param srcoff start offset of src to copy from
* @param tgtoff start offset of tgt to copy to
* @param length size of contents to copy
*/
- private static final void copyBytes(byte[] src, int srcoff, byte[] tgt,
+ private static final void copyBytes(byte[] src, int srcoff, byte[] tgt,
int tgtoff, int length) {
if (length < 64) {
for (int i = srcoff, n = tgtoff; -- length >= 0; ++ i, ++ n) {
tgt[n] = src[i];
}
- }
+ }
else {
System.arraycopy(src, srcoff, tgt, tgtoff, length);
}
- }
+ }
}
* @stable ICU 2.0
*/
public class CaseInsensitiveString {
-
+
private String string;
private int hash = 0;
-
+
private String folded = null;
-
+
private static String foldCase(String foldee)
{
return UCharacter.foldCase(foldee, true);
}
-
+
private void getFolded()
{
if (folded == null) {
folded = foldCase(string);
}
}
-
+
/**
* Constructs an CaseInsentiveString object from the given string
- * @param s The string to construct this object from
+ * @param s The string to construct this object from
* @stable ICU 2.0
*/
public CaseInsensitiveString(String s) {
string = s;
}
/**
- * returns the underlying string
+ * returns the underlying string
* @return String
* @stable ICU 2.0
*/
return string;
}
/**
- * Compare the object with this
- * @param o Object to compare this object with
+ * Compare the object with this
+ * @param o Object to compare this object with
* @stable ICU 2.0
*/
+ @Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
return false;
}
-
+
/**
* Returns the hashCode of this object
* @return int hashcode
* @stable ICU 2.0
*/
+ @Override
public int hashCode() {
getFolded();
-
+
if (hash == 0) {
hash = folded.hashCode();
}
-
+
return hash;
}
-
+
/**
* Overrides superclass method
- * @stable ICU 3.6
+ * @return a string representation of the object.
+ * @stable ICU 2.0
*/
+ @Override
public String toString() {
return string;
}
public final int getValue() { return value; }
}
+ /**
+ * Protected no-args constructor.
+ *
+ * @draft ICU 63
+ * @provisional This API might change or be removed in a future release.
+ */
+ protected CodePointMap() {
+ }
+
/**
* Returns the value for a code point as stored in the map, with range checking.
* Returns an implementation-defined error value if c is not in the range 0..U+10FFFF.
// All access to the cache or cacheIsPopulated flag must be synchronized on class MeasureUnit,
// i.e. from synchronized static methods. Beware of non-static methods.
private static final Map<String, Map<String,MeasureUnit>> cache
- = new HashMap<String, Map<String,MeasureUnit>>();
+ = new HashMap<>();
private static boolean cacheIsPopulated = false;
/**
/**
* {@inheritDoc}
*
- * @stable ICU 53
+ * @stable ICU 3.0
*/
@Override
public int hashCode() {
/**
* {@inheritDoc}
*
- * @stable ICU 53
+ * @stable ICU 3.0
*/
@Override
public boolean equals(Object rhs) {
/**
* {@inheritDoc}
*
- * @stable ICU 53
+ * @stable ICU 3.0
*/
@Override
public String toString() {
// flexibility for implementation.
// Use CollectionSet instead of HashSet for better performance.
return units == null ? Collections.<MeasureUnit>emptySet()
- : Collections.unmodifiableSet(new CollectionSet<MeasureUnit>(units.values()));
+ : Collections.unmodifiableSet(new CollectionSet<>(units.values()));
}
/**
* @stable ICU 53
*/
public synchronized static Set<MeasureUnit> getAvailable() {
- Set<MeasureUnit> result = new HashSet<MeasureUnit>();
- for (String type : new HashSet<String>(MeasureUnit.getAvailableTypes())) {
+ Set<MeasureUnit> result = new HashSet<>();
+ for (String type : new HashSet<>(MeasureUnit.getAvailableTypes())) {
for (MeasureUnit unit : MeasureUnit.getAvailable(type)) {
result.add(unit);
}
protected synchronized static MeasureUnit addUnit(String type, String unitName, Factory factory) {
Map<String, MeasureUnit> tmp = cache.get(type);
if (tmp == null) {
- cache.put(type, tmp = new HashMap<String, MeasureUnit>());
+ cache.put(type, tmp = new HashMap<>());
} else {
// "intern" the type by setting to first item's type.
type = tmp.entrySet().iterator().next().getValue().type;
public static final MeasureUnit TEASPOON = MeasureUnit.internalGetInstance("volume", "teaspoon");
private static HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>unitPerUnitToSingleUnit =
- new HashMap<Pair<MeasureUnit, MeasureUnit>, MeasureUnit>();
+ new HashMap<>();
static {
unitPerUnitToSingleUnit.put(Pair.<MeasureUnit, MeasureUnit>of(MeasureUnit.LITER, MeasureUnit.KILOMETER), MeasureUnit.LITER_PER_KILOMETER);
/**
* Returns a string representation of this object.
* @return a string representation of this object
- * @stable ICU 3.6
+ * @stable ICU 2.0
*/
@Override
public String toString() {
/**
* Overrides equals.
* @return true if obj is a SimpleTimeZone equivalent to this
- * @stable ICU 3.6
+ * @stable ICU 2.0
*/
@Override
public boolean equals(Object obj){
/**
* Overrides hashCode.
- * @stable ICU 3.6
+ * @return a hash code value for this object.
+ * @stable ICU 2.0
*/
@Override
public int hashCode(){
/**
* Overrides clone.
- * @stable ICU 3.6
+ * @stable ICU 2.0
*/
@Override
public Object clone() {
/**
* Overrides equals.
- * @stable ICU 3.6
+ * @return <code>true</code> if this object is the same as the obj argument; <code>false</code> otherwise.
+ * @stable ICU 2.0
*/
@Override
public boolean equals(Object obj){
/**
* Overrides hashCode.
- * @stable ICU 3.6
+ * @return a hash code value for this object.
+ * @stable ICU 2.0
*/
@Override
public int hashCode(){
/**
* This is for compatibility with Locale-- in actuality, since ULocale is
* immutable, there is no reason to clone it, so this API returns 'this'.
- * @stable ICU 3.0
+ * @stable ICU 2.8
*/
@Override
public Object clone() {
/**
* Returns the hashCode.
- * @stable ICU 3.0
+ * @return a hash code value for this object.
+ * @stable ICU 2.8
*/
@Override
public int hashCode() {
* function identically might not compare equal.
*
* @return true if this Locale is equal to the specified object.
- * @stable ICU 3.0
+ * @stable ICU 2.8
*/
@Override
public boolean equals(Object obj) {
/**
* Returns a string representation of this object.
- * @stable ICU 3.0
+ * @return a string representation of the object.
+ * @stable ICU 2.8
*/
@Override
public String toString() {
*
* @return the hash code value for this set.
* @see java.lang.Object#hashCode()
- * @stable ICU 58
+ * @stable ICU 2.6
*/
@Override
public int hashCode() {
/**
* Map of singletons
*/
- private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<Integer, VersionInfo>();
+ private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<>();
/**
* Last byte mask
*/
/**
* Returns true if this Position is equal to the given object.
- * @stable ICU 2.6
+ * @stable ICU 2.0
*/
@Override
public boolean equals(Object obj) {
}
/**
- * @draft ICU 63
+ * {@inheritDoc}
+ * @stable ICU 2.0
*/
@Override
public int hashCode() {
/**
* Returns a string representation of this Position.
- * @stable ICU 2.6
+ * @return a string representation of the object.
+ * @stable ICU 2.0
*/
@Override
public String toString() {
public static Transliterator getInstance(String ID,
int dir) {
StringBuffer canonID = new StringBuffer();
- List<SingleID> list = new ArrayList<SingleID>();
+ List<SingleID> list = new ArrayList<>();
UnicodeSet[] globalFilter = new UnicodeSet[1];
if (!TransliteratorIDParser.parseCompoundID(ID, dir, canonID, list, globalFilter)) {
throw new IllegalArgumentException("Invalid ID " + ID);
}
}
else {
- List<Transliterator> transliterators = new ArrayList<Transliterator>();
+ List<Transliterator> transliterators = new ArrayList<>();
int passNumber = 1;
int limit = Math.max(parser.idBlockVector.size(), parser.dataVector.size());
--- /dev/null
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.dev.tool.docs;
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Checks if API status of equals/hashCode is same with its containing class.
+ *
+ * @author Yoshito
+ */
+public class APIStatusConsistencyChecker {
+ public static void main(String[] args) {
+ // args[0] API signature file path
+ // args[1] (Optional) List of classes to be skipped, separated by semicolon
+ if (args.length < 1) {
+ System.err.println("Missing API signature file path.");
+ } else if (args.length > 2) {
+ System.err.println("Too many command arguments");
+ }
+
+ List<String> skipClasses = Collections.emptyList();
+ if (args.length == 2) {
+ String[] classes = args[1].split(";");
+ skipClasses = Arrays.asList(classes);
+ }
+
+ // Load the ICU4J API signature file
+ Set<APIInfo> apiInfoSet = APIData.read(new File(args[0]), true).getAPIInfoSet();
+ APIStatusConsistencyChecker checker = new APIStatusConsistencyChecker(apiInfoSet, skipClasses, new PrintWriter(System.err, true));
+ checker.checkConsistency();
+ System.exit(checker.errCount);
+ }
+
+ private int errCount = 0;
+ private Set<APIInfo> apiInfoSet;
+ private PrintWriter pw;
+ private List<String> skipClasses;
+
+ public APIStatusConsistencyChecker(Set<APIInfo> apiInfoSet, List<String> skipClasses, PrintWriter pw) {
+ this.apiInfoSet = apiInfoSet;
+ this.skipClasses = skipClasses;
+ this.pw = pw;
+ }
+
+ public int errorCount() {
+ return errCount;
+ }
+
+ // Methods that should have same API status with a containing class
+ static final String[][] METHODS = {
+ //{"<method name>", "<method signature in APIInfo data>"},
+ {"equals", "boolean(java.lang.Object)"},
+ {"hashCode", "int()"},
+ {"toString", "java.lang.String()"},
+ {"clone", "java.lang.Object()"},
+ };
+
+ public void checkConsistency() {
+ Map<String, APIInfo> classMap = new TreeMap<>();
+ // Build a map of APIInfo for classes, indexed by class name
+ for (APIInfo api : apiInfoSet) {
+ if (!api.isPublic() && !api.isProtected()) {
+ continue;
+ }
+ if (!api.isClass() && !api.isEnum()) {
+ continue;
+ }
+ String fullClassName = api.getPackageName() + "." + api.getName();
+ classMap.put(fullClassName, api);
+ }
+
+ // Walk through methods
+ for (APIInfo api : apiInfoSet) {
+ if (!api.isMethod()) {
+ continue;
+ }
+
+ String fullClassName = api.getPackageName() + "." + api.getClassName();
+ if (skipClasses.contains(fullClassName)) {
+ continue;
+ }
+
+ boolean checkWithClass = false;
+ String methodName = api.getName();
+ String methodSig = api.getSignature();
+
+ for (String[] method : METHODS) {
+ if (method[0].equals(methodName) && method[1].equals(methodSig)) {
+ checkWithClass = true;
+ }
+ }
+
+ if (!checkWithClass) {
+ continue;
+ }
+
+ // Check if this method has same API status with the containing class
+ APIInfo clsApi = classMap.get(fullClassName);
+ if (clsApi == null) {
+ pw.println("## Error ## Class " + fullClassName + " is not found.");
+ errCount++;
+ }
+
+ int methodStatus = api.getVal(APIInfo.STA);
+ String methodVer = api.getStatusVersion();
+ int classStatus = clsApi.getVal(APIInfo.STA);
+ String classVer = clsApi.getStatusVersion();
+
+ if (methodStatus != classStatus || !Objects.equals(methodVer, classVer)) {
+ pw.println("## Error ## " + methodName + " in " + fullClassName);
+ errCount++;
+ }
+ }
+ }
+}
public void checkDeprecated() {
// Gather API class/enum names and its names that can be
// used for Class.forName()
- Map<String, String> apiClassNameMap = new TreeMap<String, String>();
+ Map<String, String> apiClassNameMap = new TreeMap<>();
for (APIInfo api : apiInfoSet) {
if (!api.isPublic() && !api.isProtected()) {
continue;
}
List<String> paramNames = getParamNames(ctor);
+
+ Class<?> declClass = cls.getDeclaringClass();
+ if (declClass != null && !Modifier.isStatic(cls.getModifiers())) {
+ // This is non-static inner class's constructor.
+ // javac automatically injects instance of declaring class
+ // as the first param of the constructor, but ICU's API
+ // signature is based on javadoc and it generates signature
+ // without the implicit parameter.
+ assert paramNames.get(0).equals(declClass.getName());
+ paramNames.remove(0);
+ }
+
api = findConstructorInfo(apiInfoSet, clsName, paramNames);
if (api == null) {
throw new IllegalArgumentException(api.toString() + " is not a constructor or a method.");
}
- List<String> nameList = new ArrayList<String>();
+ List<String> nameList = new ArrayList<>();
String signature = api.getSignature();
int start = signature.indexOf('(');
int end = signature.indexOf(')');
private static char[] PRIMITIVE_SIGNATURES = { 'B', 'S', 'I', 'J', 'F', 'D', 'Z', 'C' };
private static List<String> toTypeNameList(Type[] types) {
- List<String> nameList = new ArrayList<String>();
+ List<String> nameList = new ArrayList<>();
for (Type t : types) {
StringBuilder s = new StringBuilder();