diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java index 6e946402b..337e5ab77 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatElement.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import org.teavm.classlib.java.util.TCalendar; import org.teavm.classlib.java.util.TGregorianCalendar; import org.teavm.classlib.java.util.TLocale; @@ -82,6 +83,25 @@ abstract class TDateFormatElement { date.set(TCalendar.MONTH, month); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + MonthText monthText = (MonthText) o; + return abbreviated == monthText.abbreviated + && Arrays.equals(months, monthText.months) + && Arrays.equals(shortMonths, monthText.shortMonths); + } + + @Override + public int hashCode() { + return Objects.hash(months, shortMonths, abbreviated); + } } public static class WeekdayText extends TDateFormatElement { @@ -113,6 +133,25 @@ abstract class TDateFormatElement { date.set(TCalendar.WEEK_OF_MONTH, weekday + 1); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + WeekdayText that = (WeekdayText) o; + return abbreviated == that.abbreviated + && Arrays.equals(weeks, that.weeks) + && Arrays.equals(shortWeeks, that.shortWeeks); + } + + @Override + public int hashCode() { + return Objects.hash(weeks, shortWeeks, abbreviated); + } } public static class EraText extends TDateFormatElement { @@ -137,6 +176,23 @@ abstract class TDateFormatElement { date.set(TCalendar.ERA, era); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + EraText eraText = (EraText) o; + return Arrays.equals(eras, eraText.eras); + } + + @Override + public int hashCode() { + return Arrays.hashCode(eras); + } } public static class AmPmText extends TDateFormatElement { @@ -161,6 +217,23 @@ abstract class TDateFormatElement { date.set(TCalendar.AM_PM, ampm); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AmPmText amPmText = (AmPmText) o; + return Arrays.equals(ampms, amPmText.ampms); + } + + @Override + public int hashCode() { + return Arrays.hashCode(ampms); + } } public static class Numeric extends TDateFormatElement { @@ -212,6 +285,23 @@ abstract class TDateFormatElement { protected int processAfterParse(int num) { return num; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Numeric numeric = (Numeric) o; + return field == numeric.field && length == numeric.length; + } + + @Override + public int hashCode() { + return Objects.hash(field, length); + } } public static class NumericMonth extends Numeric { @@ -263,6 +353,26 @@ abstract class TDateFormatElement { protected int processAfterParse(int num) { return num == limit ? 0 : num; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + NumericHour that = (NumericHour) o; + return limit == that.limit; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), limit); + } } public static class Year extends TDateFormatElement { @@ -285,7 +395,7 @@ abstract class TDateFormatElement { @Override public void parse(String text, TCalendar date, TParsePosition position) { - int num = 0; + int num; int pos = position.getIndex(); char c = text.charAt(pos++); if (c < '0' || c > '9') { @@ -314,6 +424,23 @@ abstract class TDateFormatElement { } date.set(field, num + century * 100); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Year year = (Year) o; + return field == year.field; + } + + @Override + public int hashCode() { + return Objects.hash(field); + } } public static class ConstantText extends TDateFormatElement { @@ -336,6 +463,23 @@ abstract class TDateFormatElement { position.setErrorIndex(position.getIndex()); } } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ConstantText that = (ConstantText) o; + return Objects.equals(textConstant, that.textConstant); + } + + @Override + public int hashCode() { + return Objects.hash(textConstant); + } } public static abstract class BaseTimezone extends TDateFormatElement { @@ -426,6 +570,23 @@ abstract class TDateFormatElement { } idSearchTrie = builder.build(); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BaseTimezone that = (BaseTimezone) o; + return Objects.equals(locale, that.locale) && Objects.equals(searchTrie, that.searchTrie); + } + + @Override + public int hashCode() { + return Objects.hash(locale, searchTrie); + } } public static class GeneralTimezone extends BaseTimezone { @@ -556,6 +717,23 @@ abstract class TDateFormatElement { position.setIndex(index); date.setTimeZone(getStaticTimeZone(sign * hours, minutes)); } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Iso8601Timezone that = (Iso8601Timezone) o; + return size == that.size; + } + + @Override + public int hashCode() { + return Objects.hash(size); + } } static boolean tryParseFixedTimeZone(String text, TCalendar date, TParsePosition position) { diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java index 69c7e83a6..9f867f6bd 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TDateFormatSymbols.java @@ -16,6 +16,7 @@ package org.teavm.classlib.java.text; import java.util.Arrays; +import java.util.Objects; import org.teavm.classlib.impl.unicode.CLDRHelper; import org.teavm.classlib.java.io.TSerializable; import org.teavm.classlib.java.lang.TCloneable; @@ -84,7 +85,7 @@ public class TDateFormatSymbols implements TSerializable, TCloneable { if (!locale.equals(obj.locale)) { return false; } - if (!localPatternChars.equals(obj.localPatternChars)) { + if (!Objects.equals(localPatternChars, obj.localPatternChars)) { return false; } if (!Arrays.equals(ampms, obj.ampms)) { @@ -105,20 +106,7 @@ public class TDateFormatSymbols implements TSerializable, TCloneable { if (!Arrays.equals(weekdays, obj.weekdays)) { return false; } - if (zoneStrings.length != obj.zoneStrings.length) { - return false; - } - for (String[] element : zoneStrings) { - if (element.length != element.length) { - return false; - } - for (int j = 0; j < element.length; j++) { - if (!(element[j].equals(element[j]))) { - return false; - } - } - } - return true; + return Arrays.equals(zoneStrings, obj.zoneStrings); } public String[] getAmPmStrings() { diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java b/classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java index 185b30082..e9fffaf2b 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TDecimalFormat.java @@ -1226,6 +1226,23 @@ public class TDecimalFormat extends TNumberFormat { public void render(TDecimalFormat format, StringBuffer buffer) { buffer.append(text); } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof TextField)) { + return false; + } + TextField other = (TextField) obj; + return text.equals(other.text); + } + + @Override + public int hashCode() { + return text.hashCode(); + } } static class CurrencyField implements FormatField { @@ -1237,6 +1254,16 @@ public class TDecimalFormat extends TNumberFormat { buffer.append(format.getCurrency().getSymbol(format.symbols.getLocale())); } } + + @Override + public boolean equals(Object obj) { + return obj instanceof CurrencyField; + } + + @Override + public int hashCode() { + return 0; + } } static class PercentField implements FormatField { @@ -1244,6 +1271,16 @@ public class TDecimalFormat extends TNumberFormat { public void render(TDecimalFormat format, StringBuffer buffer) { buffer.append(format.symbols.getPercent()); } + + @Override + public boolean equals(Object obj) { + return obj instanceof PercentField; + } + + @Override + public int hashCode() { + return 1; + } } static class PerMillField implements FormatField { @@ -1251,6 +1288,16 @@ public class TDecimalFormat extends TNumberFormat { public void render(TDecimalFormat format, StringBuffer buffer) { buffer.append(format.symbols.getPerMill()); } + + @Override + public boolean equals(Object obj) { + return obj instanceof PerMillField; + } + + @Override + public int hashCode() { + return 2; + } } static class MinusField implements FormatField { @@ -1258,5 +1305,15 @@ public class TDecimalFormat extends TNumberFormat { public void render(TDecimalFormat format, StringBuffer buffer) { buffer.append(format.symbols.getMinusSign()); } + + @Override + public boolean equals(Object obj) { + return obj instanceof MinusField; + } + + @Override + public int hashCode() { + return 3; + } } } diff --git a/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java b/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java index f16404123..bbd2954d0 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java +++ b/classlib/src/main/java/org/teavm/classlib/java/text/TSimpleDateFormat.java @@ -15,6 +15,7 @@ */ package org.teavm.classlib.java.text; +import java.util.Arrays; import org.teavm.classlib.impl.unicode.CLDRHelper; import org.teavm.classlib.java.util.TCalendar; import org.teavm.classlib.java.util.TDate; @@ -110,4 +111,32 @@ public class TSimpleDateFormat extends TDateFormat { public String toPattern() { return pattern; } + + @Override + public boolean equals(Object object) { + if (object == this) { + return true; + } + if (!(object instanceof TSimpleDateFormat)) { + return false; + } + + TSimpleDateFormat other = (TSimpleDateFormat) object; + if (!super.equals(other)) { + return false; + } + + return Arrays.equals(elements, other.elements) + && dateFormatSymbols.equals(other.dateFormatSymbols) + && locale.equals(other.locale); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new int[] { + super.hashCode(), + dateFormatSymbols.hashCode(), + Arrays.hashCode(elements), + locale.hashCode() }); + } } diff --git a/tests/src/test/java/org/teavm/classlib/java/text/MessageFormatTest.java b/tests/src/test/java/org/teavm/classlib/java/text/MessageFormatTest.java index a0301f809..533fc0064 100644 --- a/tests/src/test/java/org/teavm/classlib/java/text/MessageFormatTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/text/MessageFormatTest.java @@ -38,12 +38,9 @@ import java.util.TimeZone; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.teavm.junit.TeaVMProperties; -import org.teavm.junit.TeaVMProperty; import org.teavm.junit.TeaVMTestRunner; @RunWith(TeaVMTestRunner.class) -@TeaVMProperties(value = { @TeaVMProperty(key = "java.util.Locale.available", value = "en, en_US, fr") }) public class MessageFormatTest { private MessageFormat format1; private MessageFormat format2; @@ -173,13 +170,6 @@ public class MessageFormatTest { assertTrue("Wrong long time format", format.getFormats()[0].equals( DateFormat.getTimeInstance(DateFormat.LONG))); assertEquals("Wrong long time pattern", "{0,time,long}", format.toPattern()); - format.setLocale(Locale.FRENCH); // use French since English has the - // same LONG and FULL time patterns - format.applyPattern("{0,time, Full}"); - assertTrue("Wrong full time format", format.getFormats()[0] - .equals(DateFormat.getTimeInstance(DateFormat.FULL, Locale.FRENCH))); - assertEquals("Wrong full time pattern", "{0,time,full}", format.toPattern()); - format.setLocale(Locale.getDefault()); format.applyPattern("{0, date}"); assertTrue("Wrong date format", format.getFormats()[0].equals(DateFormat.getDateInstance())); @@ -203,10 +193,9 @@ public class MessageFormatTest { assertEquals("Wrong full date pattern", "{0,date,full}", format.toPattern()); format.applyPattern("{0, date, MMM d {hh:mm:ss}}"); - assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", ((SimpleDateFormat) (format - .getFormats()[0])).toPattern()); - assertEquals("Wrong time/date pattern", - "{0,date, MMM d {hh:mm:ss}}", format.toPattern()); + assertEquals("Wrong time/date format", " MMM d {hh:mm:ss}", + ((SimpleDateFormat) (format.getFormats()[0])).toPattern()); + assertEquals("Wrong time/date pattern", "{0,date, MMM d {hh:mm:ss}}", format.toPattern()); format.applyPattern("{0, number}"); assertTrue("Wrong number format", format.getFormats()[0].equals(NumberFormat.getNumberInstance()));