From: Shane Carr Date: Wed, 27 Sep 2017 10:11:00 +0000 (+0000) Subject: ICU-13177 Fixing serialization test failures in ICU4J. X-Git-Tag: release-60-rc~98^2~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b7bedcbab005574e31bbc5b6f8fe9b09032f1f74;p=icu ICU-13177 Fixing serialization test failures in ICU4J. X-SVN-Rev: 40478 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalFormatProperties.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalFormatProperties.java index 52535762e69..3e8c8e594dc 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalFormatProperties.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalFormatProperties.java @@ -537,6 +537,10 @@ public class DecimalFormatProperties implements Cloneable, Serializable { /** Custom serialization: re-create object from serialized properties. */ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + readObjectImpl(ois); + } + + /* package-private */ void readObjectImpl(ObjectInputStream ois) throws IOException, ClassNotFoundException { ois.defaultReadObject(); // Initialize to empty @@ -1301,6 +1305,10 @@ public class DecimalFormatProperties implements Cloneable, Serializable { * the future in any order. Only save fields that differ from their default value. */ private void writeObject(ObjectOutputStream oos) throws IOException { + writeObjectImpl(oos); + } + + /* package-private */ void writeObjectImpl(ObjectOutputStream oos) throws IOException { oos.defaultWriteObject(); // Extra int for possible future use diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Properties.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Properties.java new file mode 100644 index 00000000000..bb635cdc70a --- /dev/null +++ b/icu4j/main/classes/core/src/com/ibm/icu/impl/number/Properties.java @@ -0,0 +1,38 @@ +// © 2017 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html#License +package com.ibm.icu.impl.number; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * ICU 59 called the class DecimalFormatProperties as just Properties. We need to keep a thin implementation for the + * purposes of serialization. + */ +public class Properties implements Serializable { + + /** Same as DecimalFormatProperties. */ + private static final long serialVersionUID = 4095518955889349243L; + + private transient DecimalFormatProperties instance; + + public DecimalFormatProperties getInstance() { + return instance; + } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + if (instance == null) { + instance = new DecimalFormatProperties(); + } + instance.readObjectImpl(ois); + } + + private void writeObject(ObjectOutputStream oos) throws IOException { + if (instance == null) { + instance = new DecimalFormatProperties(); + } + instance.writeObjectImpl(oos); + } +} diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java index 30aab435270..04c8d8905af 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java @@ -217,15 +217,13 @@ final class NumberPropertyMapper { // This whole section feels like a hack, but it is needed for regression tests. // The mapping from property bag to scientific notation is nontrivial due to LDML rules. // The maximum of 8 digits has unknown origins and is not in the spec. - if (maxInt > 8) { + if (minInt > 8) { + minInt = 8; maxInt = 8; - if (minInt > maxInt) { - minInt = maxInt; - } macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt); } - int engineering = (maxInt != -1) ? maxInt : properties.getMaximumIntegerDigits(); - engineering = (engineering < 0) ? 0 : (engineering > 8) ? minInt : engineering; + int engineering = maxInt > 8 ? minInt : maxInt < minInt ? -1 : maxInt; + engineering = (engineering < 0) ? 0 : engineering; // Bug #13289: if maxInt > minInt > 1, then minInt should be 1. // Clear out IntegerWidth to prevent padding extra zeros. if (maxInt > minInt && minInt > 1) { diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java index 75f76002089..5772a08c56f 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java @@ -527,7 +527,14 @@ public class DecimalFormat extends NumberFormat { // Extra int for possible future use: ois.readInt(); // 1) Property Bag - properties = (DecimalFormatProperties) ois.readObject(); + Object serializedProperties = ois.readObject(); + if (serializedProperties instanceof DecimalFormatProperties) { + // ICU 60+ + properties = (DecimalFormatProperties) serializedProperties; + } else { + // ICU 59 + properties = ((com.ibm.icu.impl.number.Properties) serializedProperties).getInstance(); + } // 2) DecimalFormatSymbols symbols = (DecimalFormatSymbols) ois.readObject(); // Re-build transient fields diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java index e3a1a9b848b..a93b7673dda 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java @@ -30,10 +30,10 @@ import org.junit.Test; import com.ibm.icu.dev.test.serializable.SerializableTestUtility; import com.ibm.icu.impl.number.DecimalFormatProperties; +import com.ibm.icu.impl.number.Padder.PadPosition; import com.ibm.icu.impl.number.Parse.GroupingMode; import com.ibm.icu.impl.number.Parse.ParseMode; import com.ibm.icu.impl.number.PatternStringParser; -import com.ibm.icu.impl.number.Padder.PadPosition; import com.ibm.icu.text.CompactDecimalFormat.CompactStyle; import com.ibm.icu.text.CurrencyPluralInfo; import com.ibm.icu.text.MeasureFormat.FormatWidth; @@ -347,4 +347,20 @@ public class PropertiesTest { return a.equals(b); } } + + /** Handler for the ICU 59 class named "Properties" before it was renamed to "DecimalFormatProperties". */ + public static class ICU59PropertiesHandler implements SerializableTestUtility.Handler { + + @Override + public Object[] getTestObjects() { + return new Object[] { + new com.ibm.icu.impl.number.Properties() + }; + } + + @Override + public boolean hasSameBehavior(Object a, Object b) { + return true; + } + } } diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java index fb1cd7b7641..e0ef2f668c4 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java @@ -829,7 +829,9 @@ public class SerializableTestUtility { map.put("com.ibm.icu.util.TimeUnit", new MeasureUnitTest.MeasureUnitHandler()); map.put("com.ibm.icu.util.NoUnit", new MeasureUnitTest.MeasureUnitHandler()); map.put("com.ibm.icu.text.MeasureFormat", new MeasureUnitTest.MeasureFormatHandler()); - map.put("com.ibm.icu.impl.number.Properties", new PropertiesTest.PropertiesHandler()); + map.put("com.ibm.icu.impl.number.Properties", new PropertiesTest.ICU59PropertiesHandler()); + map.put("com.ibm.icu.impl.number.DecimalFormatProperties", new PropertiesTest.PropertiesHandler()); + map.put("com.ibm.icu.impl.number.CustomSymbolCurrency", new CurrencyHandler()); map.put("com.ibm.icu.util.ICUException", new ICUExceptionHandler()); map.put("com.ibm.icu.util.ICUUncheckedIOException", new ICUUncheckedIOExceptionHandler());