]> granicus.if.org Git - icu/commitdiff
ICU-13177 Fixing serialization test failures in ICU4J.
authorShane Carr <shane@unicode.org>
Wed, 27 Sep 2017 10:11:00 +0000 (10:11 +0000)
committerShane Carr <shane@unicode.org>
Wed, 27 Sep 2017 10:11:00 +0000 (10:11 +0000)
X-SVN-Rev: 40478

icu4j/main/classes/core/src/com/ibm/icu/impl/number/DecimalFormatProperties.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/Properties.java [new file with mode: 0644]
icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/PropertiesTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/serializable/SerializableTestUtility.java

index 52535762e695c745b4e3855088a73e365213605d..3e8c8e594dcd86fa0a1ad40ca5acd784601b3128 100644 (file)
@@ -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 (file)
index 0000000..bb635cd
--- /dev/null
@@ -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);
+    }
+}
index 30aab435270956016d8b3d7e397a3bb9b657421c..04c8d8905afef486850fb296ed6853ea0847da17 100644 (file)
@@ -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) {
index 75f76002089daff6dab28836bfa246103e17858f..5772a08c56f6a2af7db423b2f45f40acc2818807 100644 (file)
@@ -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
index e3a1a9b848b5dc9ebd04da26d3ad777865ee47c6..a93b7673dda6ce9ac1a4001b3967c2558dcf82d4 100644 (file)
@@ -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;
+    }
+  }
 }
index fb1cd7b7641c0cbf94636011153243f2c5d7b695..e0ef2f668c437658220106adaba6a5fd65cb937c 100644 (file)
@@ -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());