Merge "Revert "reflection: Add new AnnotatedElement 1.8 methods.""
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index e9a73de..fdf6056 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -245,12 +245,12 @@
}
/*
- * TODO (dimitry): Revert after GMS core stops relying on the existence of this
- * method (see b/21957414 for details)
+ * TODO (dimitry): Revert after apps stops relying on the existence of this
+ * method (see http://b/21957414 and http://b/26317852 for details)
*/
private static Element[] makePathElements(List<File> files, File optimizedDirectory,
List<IOException> suppressedExceptions) {
- return makeElements(files, null, suppressedExceptions, true, null);
+ return makeElements(files, optimizedDirectory, suppressedExceptions, false, null);
}
private static Element[] makeElements(List<File> files, File optimizedDirectory,
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index db08a10..cf6c852 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -29,11 +29,6 @@
bug: 2541757
},
{
- description: "NaN character not found when deserializing DecimalFormatSymbols",
- name: "libcore.java.text.OldDecimalFormatSymbolsTest#test_RIHarmony_compatible",
- bug: 3056792
-},
-{
description: "DecimalFormat is limited to 127 digits",
name: "libcore.java.text.DecimalFormatTest#test_setMaximumIntegerDigits",
bug: 2400429
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index 13f693a..df0b6df 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -2171,8 +2171,8 @@
testUrlToRequestMapping(")", ")", ")");
testUrlToUriMapping("*", "*", "*", "*", "*");
testUrlToRequestMapping("*", "*", "*");
- testUrlToUriMapping("+", "+", "+", "%20", "+");
- testUrlToRequestMapping("+", "+", "%20");
+ testUrlToUriMapping("+", "+", "+", "+", "+");
+ testUrlToRequestMapping("+", "+", "+");
testUrlToUriMapping(",", ",", ",", ",", ",");
testUrlToRequestMapping(",", ",", ",");
testUrlToUriMapping("-", "-", "-", "-", "-");
diff --git a/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java b/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
index c078684..fa98bf9 100644
--- a/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
+++ b/luni/src/test/java/libcore/java/text/OldDecimalFormatSymbolsTest.java
@@ -38,7 +38,7 @@
getClass()
.getClassLoader()
.getResourceAsStream(
- "serialization/java/text/DecimalFormatSymbols.ser"));
+ "serialization/org/apache/harmony/tests/java/text/DecimalFormatSymbols.ser"));
DecimalFormatSymbols riSymbols = (DecimalFormatSymbols) i.readObject();
// RI's default NaN is U+FFFD, Harmony's is based on ICU
// This suggests an RI bug, assuming that non-UTF8 bytes are UTF8 and
diff --git a/ojluni/src/main/java/java/text/DecimalFormat.java b/ojluni/src/main/java/java/text/DecimalFormat.java
index 49299a8..b8eade3 100755
--- a/ojluni/src/main/java/java/text/DecimalFormat.java
+++ b/ojluni/src/main/java/java/text/DecimalFormat.java
@@ -39,16 +39,15 @@
package java.text;
-import java.io.InvalidObjectException;
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
-import java.util.ArrayList;
import java.util.Currency;
import java.util.Locale;
-import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -380,6 +379,8 @@
*/
public class DecimalFormat extends NumberFormat {
+ private transient android.icu.text.DecimalFormat icuDecimalFormat;
+
/**
* Creates a DecimalFormat using the default pattern and symbols
* for the default locale. This is a convenient way to obtain a
@@ -395,9 +396,6 @@
* @see java.text.NumberFormat#getCurrencyInstance
* @see java.text.NumberFormat#getPercentInstance
*/
-
- private android.icu.text.DecimalFormat icuDecimalFormat;
-
public DecimalFormat() {
Locale def = Locale.getDefault(Locale.Category.FORMAT);
// try to get the pattern from the cache
@@ -409,12 +407,7 @@
cachedLocaleData.putIfAbsent(def, pattern);
}
this.symbols = new DecimalFormatSymbols(def);
- this.icuDecimalFormat = new android.icu.text.DecimalFormat(pattern,
- symbols.getIcuDecimalFormatSymbols());
- maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits();
- minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits();
- maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits();
- minimumFractionDigits = icuDecimalFormat.getMinimumFractionDigits();
+ init(pattern);
}
@@ -438,12 +431,7 @@
*/
public DecimalFormat(String pattern) {
this.symbols = new DecimalFormatSymbols(Locale.getDefault(Locale.Category.FORMAT));
- this.icuDecimalFormat = new android.icu.text.DecimalFormat(pattern,
- symbols.getIcuDecimalFormatSymbols());
- maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits();
- minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits();
- maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits();
- minimumFractionDigits = icuDecimalFormat.getMinimumFractionDigits();
+ init(pattern);
}
@@ -471,8 +459,12 @@
public DecimalFormat (String pattern, DecimalFormatSymbols symbols) {
// Always applyPattern after the symbols are set
this.symbols = (DecimalFormatSymbols)symbols.clone();
+ init(pattern);
+ }
+
+ private void init(String pattern) {
this.icuDecimalFormat = new android.icu.text.DecimalFormat(pattern,
- symbols.getIcuDecimalFormatSymbols());
+ symbols.getIcuDecimalFormatSymbols());
maximumIntegerDigits = icuDecimalFormat.getMaximumIntegerDigits();
minimumIntegerDigits = icuDecimalFormat.getMinimumIntegerDigits();
maximumFractionDigits = icuDecimalFormat.getMaximumFractionDigits();
@@ -1428,6 +1420,61 @@
}
}
+ private static final int currentSerialVersion = 4;
+
+ // the fields list to be serialized
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("positivePrefix", String.class),
+ new ObjectStreamField("positiveSuffix", String.class),
+ new ObjectStreamField("negativePrefix", String.class),
+ new ObjectStreamField("negativeSuffix", String.class),
+ new ObjectStreamField("posPrefixPattern", String.class),
+ new ObjectStreamField("posSuffixPattern", String.class),
+ new ObjectStreamField("negPrefixPattern", String.class),
+ new ObjectStreamField("negSuffixPattern", String.class),
+ new ObjectStreamField("multiplier", int.class),
+ new ObjectStreamField("groupingSize", byte.class),
+ new ObjectStreamField("groupingUsed", boolean.class),
+ new ObjectStreamField("decimalSeparatorAlwaysShown", boolean.class),
+ new ObjectStreamField("parseBigDecimal", boolean.class),
+ new ObjectStreamField("roundingMode", RoundingMode.class),
+ new ObjectStreamField("symbols", DecimalFormatSymbols.class),
+ new ObjectStreamField("useExponentialNotation", boolean.class),
+ new ObjectStreamField("minExponentDigits", byte.class),
+ new ObjectStreamField("maximumIntegerDigits", int.class),
+ new ObjectStreamField("minimumIntegerDigits", int.class),
+ new ObjectStreamField("maximumFractionDigits", int.class),
+ new ObjectStreamField("minimumFractionDigits", int.class),
+ new ObjectStreamField("serialVersionOnStream", int.class),
+ };
+
+ private void writeObject(ObjectOutputStream stream) throws IOException, ClassNotFoundException {
+ ObjectOutputStream.PutField fields = stream.putFields();
+ fields.put("positivePrefix", icuDecimalFormat.getPositivePrefix());
+ fields.put("positiveSuffix", icuDecimalFormat.getPositiveSuffix());
+ fields.put("negativePrefix", icuDecimalFormat.getNegativePrefix());
+ fields.put("negativeSuffix", icuDecimalFormat.getNegativeSuffix());
+ fields.put("posPrefixPattern", (String) null);
+ fields.put("posSuffixPattern", (String) null);
+ fields.put("negPrefixPattern", (String) null);
+ fields.put("negSuffixPattern", (String) null);
+ fields.put("multiplier", icuDecimalFormat.getMultiplier());
+ fields.put("groupingSize", (byte) icuDecimalFormat.getGroupingSize());
+ fields.put("groupingUsed", icuDecimalFormat.isGroupingUsed());
+ fields.put("decimalSeparatorAlwaysShown", icuDecimalFormat.isDecimalSeparatorAlwaysShown());
+ fields.put("parseBigDecimal", icuDecimalFormat.isParseBigDecimal());
+ fields.put("roundingMode", roundingMode);
+ fields.put("symbols", symbols);
+ fields.put("useExponentialNotation", false);
+ fields.put("minExponentDigits", (byte) 0);
+ fields.put("maximumIntegerDigits", icuDecimalFormat.getMaximumIntegerDigits());
+ fields.put("minimumIntegerDigits", icuDecimalFormat.getMinimumIntegerDigits());
+ fields.put("maximumFractionDigits", icuDecimalFormat.getMaximumFractionDigits());
+ fields.put("minimumFractionDigits", icuDecimalFormat.getMinimumFractionDigits());
+ fields.put("serialVersionOnStream", currentSerialVersion);
+ stream.writeFields();
+ }
+
/**
* Reads the default serializable fields from the stream and performs
* validations and adjustments for older serialized versions. The
@@ -1472,49 +1519,47 @@
* the pre-version-2 behavior.
*/
private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException
- {
- stream.defaultReadObject();
+ throws IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = stream.readFields();
+ this.symbols = (DecimalFormatSymbols) fields.get("symbols", null);
- if (serialVersionOnStream < 4) {
- setRoundingMode(RoundingMode.HALF_EVEN);
- }
- // We only need to check the maximum counts because NumberFormat
- // .readObject has already ensured that the maximum is greater than the
- // minimum count.
- if (super.getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
- super.getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
- throw new InvalidObjectException("Digit count out of range");
- }
+ init("");
- // ICU has its own logic about what these values can be set to. We set the desired value
- // on icuDecimalFormat and then update NumberFormat's idea of the limits to what ICU has
- // allowed to be set. This isn't RI-compatible, but then very little of our
+ icuDecimalFormat.setPositivePrefix((String) fields.get("positivePrefix", ""));
+ icuDecimalFormat.setPositiveSuffix((String) fields.get("positiveSuffix", ""));
+ icuDecimalFormat.setNegativePrefix((String) fields.get("negativePrefix", "-"));
+ icuDecimalFormat.setNegativeSuffix((String) fields.get("negativeSuffix", ""));
+ icuDecimalFormat.setMultiplier(fields.get("multiplier", 1));
+ icuDecimalFormat.setGroupingSize(fields.get("groupingSize", (byte) 3));
+ icuDecimalFormat.setGroupingUsed(fields.get("groupingUsed", true));
+ icuDecimalFormat.setDecimalSeparatorAlwaysShown(fields.get("decimalSeparatorAlwaysShown",
+ false));
+
+ setRoundingMode((RoundingMode) fields.get("roundingMode", RoundingMode.HALF_EVEN));
+
+ final int maximumIntegerDigits = fields.get("maximumIntegerDigits", 309);
+ final int minimumIntegerDigits = fields.get("minimumIntegerDigits", 309);
+ final int maximumFractionDigits = fields.get("maximumFractionDigits", 340);
+ final int minimumFractionDigits = fields.get("minimumFractionDigits", 340);
+ // Tell ICU what we want, then ask it what we can have, and then
+ // set that in our Java object. This isn't RI-compatible, but then very little of our
// behavior in this area is, and it's not obvious how we can second-guess ICU (or tell
- // it to just do exactly what we ask).
+ // it to just do exactly what we ask). We only need to do this with maximumIntegerDigits
+ // because ICU doesn't seem to have its own ideas about the other options.
icuDecimalFormat.setMaximumIntegerDigits(maximumIntegerDigits);
- setMaximumIntegerDigits(icuDecimalFormat.getMaximumIntegerDigits());
+ super.setMaximumIntegerDigits(icuDecimalFormat.getMaximumIntegerDigits());
- icuDecimalFormat.setMinimumIntegerDigits(minimumIntegerDigits);
- setMinimumIntegerDigits(icuDecimalFormat.getMinimumIntegerDigits());
-
- icuDecimalFormat.setMaximumFractionDigits(maximumFractionDigits);
- setMaximumFractionDigits(icuDecimalFormat.getMaximumFractionDigits());
-
- icuDecimalFormat.setMinimumFractionDigits(minimumFractionDigits);
+ setMinimumIntegerDigits(minimumIntegerDigits);
setMinimumFractionDigits(minimumFractionDigits);
+ setMaximumFractionDigits(maximumFractionDigits);
+ setParseBigDecimal(fields.get("parseBigDecimal", false));
- if (serialVersionOnStream < 3) {
+ if (fields.get("serialVersionOnStream", 0) < 3) {
setMaximumIntegerDigits(super.getMaximumIntegerDigits());
setMinimumIntegerDigits(super.getMinimumIntegerDigits());
setMaximumFractionDigits(super.getMaximumFractionDigits());
setMinimumFractionDigits(super.getMinimumFractionDigits());
}
- if (serialVersionOnStream < 1) {
- // Didn't have exponential fields
- useExponentialNotation = false;
- }
- serialVersionOnStream = currentSerialVersion;
}
//----------------------------------------------------------------------
@@ -1530,16 +1575,7 @@
* @see #setDecimalFormatSymbols
* @see java.text.DecimalFormatSymbols
*/
- private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
-
- /**
- * True to force the use of exponential (i.e. scientific) notation when formatting
- * numbers.
- *
- * @serial
- * @since 1.2
- */
- private boolean useExponentialNotation; // Newly persistent in the Java 2 platform v.1.2
+ private DecimalFormatSymbols symbols;
/**
* The maximum number of digits allowed in the integer portion of a
@@ -1597,34 +1633,7 @@
*/
private RoundingMode roundingMode = RoundingMode.HALF_EVEN;
- //----------------------------------------------------------------------
- static final int currentSerialVersion = 4;
-
- /**
- * The internal serial version which says which version was written.
- * Possible values are:
- * <ul>
- * <li><b>0</b> (default): versions before the Java 2 platform v1.2
- * <li><b>1</b>: version for 1.2, which includes the two new fields
- * <code>useExponentialNotation</code> and
- * <code>minExponentDigits</code>.
- * <li><b>2</b>: version for 1.3 and later, which adds four new fields:
- * <code>posPrefixPattern</code>, <code>posSuffixPattern</code>,
- * <code>negPrefixPattern</code>, and <code>negSuffixPattern</code>.
- * <li><b>3</b>: version for 1.5 and later, which adds five new fields:
- * <code>maximumIntegerDigits</code>,
- * <code>minimumIntegerDigits</code>,
- * <code>maximumFractionDigits</code>,
- * <code>minimumFractionDigits</code>, and
- * <code>parseBigDecimal</code>.
- * <li><b>4</b>: version for 1.6 and later, which adds one new field:
- * <code>roundingMode</code>.
- * </ul>
- * @since 1.2
- * @serial
- */
- private int serialVersionOnStream = currentSerialVersion;
//----------------------------------------------------------------------
// CONSTANTS
diff --git a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
index 4263f68..4ae3097 100755
--- a/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DecimalFormatSymbols.java
@@ -41,6 +41,8 @@
import java.io.IOException;
import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.io.Serializable;
import java.text.spi.DecimalFormatSymbolsProvider;
import java.util.Currency;
@@ -741,6 +743,56 @@
}
+ private static final ObjectStreamField[] serialPersistentFields = {
+ new ObjectStreamField("currencySymbol", String.class),
+ new ObjectStreamField("decimalSeparator", char.class),
+ new ObjectStreamField("digit", char.class),
+ new ObjectStreamField("exponential", char.class),
+ new ObjectStreamField("exponentialSeparator", String.class),
+ new ObjectStreamField("groupingSeparator", char.class),
+ new ObjectStreamField("infinity", String.class),
+ new ObjectStreamField("intlCurrencySymbol", String.class),
+ new ObjectStreamField("minusSign", char.class),
+ new ObjectStreamField("monetarySeparator", char.class),
+ new ObjectStreamField("NaN", String.class),
+ new ObjectStreamField("patternSeparator", char.class),
+ new ObjectStreamField("percent", char.class),
+ new ObjectStreamField("perMill", char.class),
+ new ObjectStreamField("serialVersionOnStream", int.class),
+ new ObjectStreamField("zeroDigit", char.class),
+ new ObjectStreamField("locale", Locale.class),
+ new ObjectStreamField("minusSignStr", String.class),
+ new ObjectStreamField("percentStr", String.class),
+ };
+
+ private void writeObject(ObjectOutputStream stream) throws IOException {
+ ObjectOutputStream.PutField fields = stream.putFields();
+ fields.put("currencySymbol", currencySymbol);
+ fields.put("decimalSeparator", getDecimalSeparator());
+ fields.put("digit", getDigit());
+ fields.put("exponential", exponentialSeparator.charAt(0));
+ fields.put("exponentialSeparator", exponentialSeparator);
+ fields.put("groupingSeparator", getGroupingSeparator());
+ fields.put("infinity", infinity);
+ fields.put("intlCurrencySymbol", intlCurrencySymbol);
+ fields.put("monetarySeparator", getMonetaryDecimalSeparator());
+ fields.put("NaN", NaN);
+ fields.put("patternSeparator", getPatternSeparator());
+ fields.put("perMill", getPerMill());
+ fields.put("serialVersionOnStream", 3);
+ fields.put("zeroDigit", getZeroDigit());
+ fields.put("locale", locale);
+
+ // Hardcode values here for backwards compatibility. These values will only be used
+ // if we're de-serializing this object on an earlier version of android.
+ fields.put("minusSign", minusSign);
+ fields.put("percent", percent);
+
+ fields.put("minusSignStr", getMinusSignString());
+ fields.put("percentStr", getPercentString());
+ stream.writeFields();
+ }
+
/**
* Reads the default serializable fields, provides default values for objects
* in older serial versions, and initializes non-serializable fields.
@@ -758,30 +810,59 @@
*
* @since JDK 1.1.6
*/
- private void readObject(ObjectInputStream stream)
- throws IOException, ClassNotFoundException {
- stream.defaultReadObject();
- if (serialVersionOnStream < 1) {
- // Didn't have monetarySeparator or exponential field;
- // use defaults.
- monetarySeparator = decimalSeparator;
- exponential = 'E';
- }
- if (serialVersionOnStream < 2) {
- // didn't have locale; use root locale
- locale = Locale.ROOT;
- }
- if (serialVersionOnStream < 3) {
- // didn't have exponentialSeparator. Create one using exponential
- exponentialSeparator = Character.toString(exponential);
- }
- serialVersionOnStream = currentSerialVersion;
+ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
+ ObjectInputStream.GetField fields = stream.readFields();
+ final int serialVersionOnStream = fields.get("serialVersionOnStream", 0);
+ currencySymbol = (String) fields.get("currencySymbol", "");
+ setDecimalSeparator(fields.get("decimalSeparator", '.'));
+ setDigit(fields.get("digit", '#'));
+ setGroupingSeparator(fields.get("groupingSeparator", ','));
+ infinity = (String) fields.get("infinity", "");
+ intlCurrencySymbol = (String) fields.get("intlCurrencySymbol", "");
+ NaN = (String) fields.get("NaN", "");
+ setPatternSeparator(fields.get("patternSeparator", ';'));
- if (intlCurrencySymbol != null) {
- try {
- currency = Currency.getInstance(intlCurrencySymbol);
- } catch (IllegalArgumentException e) {
- }
+ // Special handling for minusSign and percent. If we've serialized the string versions of
+ // these fields, use them. If not, fall back to the single character versions. This can
+ // only happen if we're de-serializing an object that was written by an older version of
+ // android (something that's strongly discouraged anyway).
+ final String minusSignStr = (String) fields.get("minusSignStr", null);
+ if (minusSignStr != null) {
+ minusSign = minusSignStr.charAt(0);
+ } else {
+ setMinusSign(fields.get("minusSign", '-'));
+ }
+ final String percentStr = (String) fields.get("percentStr", null);
+ if (percentStr != null) {
+ percent = percentStr.charAt(0);
+ } else {
+ setPercent(fields.get("percent", '%'));
+ }
+
+ setPerMill(fields.get("perMill", '\u2030'));
+ setZeroDigit(fields.get("zeroDigit", '0'));
+ locale = (Locale) fields.get("locale", null);
+ if (serialVersionOnStream == 0) {
+ setMonetaryDecimalSeparator(getDecimalSeparator());
+ } else {
+ setMonetaryDecimalSeparator(fields.get("monetarySeparator", '.'));
+ }
+
+ if (serialVersionOnStream == 0) {
+ // Prior to Java 1.1.6, the exponent separator wasn't configurable.
+ exponentialSeparator = "E";
+ } else if (serialVersionOnStream < 3) {
+ // In Javas 1.1.6 and 1.4, there was a character field "exponential".
+ setExponentSeparator(String.valueOf(fields.get("exponential", 'E')));
+ } else {
+ // In Java 6, there's a new "exponentialSeparator" field.
+ setExponentSeparator((String) fields.get("exponentialSeparator", "E"));
+ }
+
+ try {
+ currency = Currency.getInstance(intlCurrencySymbol);
+ } catch (IllegalArgumentException e) {
+ currency = null;
}
}