< prev index next >

src/java.base/share/classes/java/text/DecimalFormatSymbols.java

Print this page
rev 54198 : [mq]: 8220224

*** 1,7 **** /* ! * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 36,51 **** --- 36,53 ---- * */ package java.text; + import java.io.InvalidObjectException; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.text.spi.DecimalFormatSymbolsProvider; import java.util.Currency; import java.util.Locale; + import java.util.Objects; import sun.util.locale.provider.CalendarDataUtility; import sun.util.locale.provider.LocaleProviderAdapter; import sun.util.locale.provider.LocaleServiceProviderPool; import sun.util.locale.provider.ResourceBundleBasedAdapter;
*** 253,262 **** --- 255,299 ---- * * @param perMill the character used for per mille sign */ public void setPerMill(char perMill) { this.perMill = perMill; + this.perMillText = Character.toString(perMill); + } + + /** + * Gets the string used for per mille sign. Different for Arabic, etc. + * + * @return the string used for per mille sign + * @since 13 + */ + String getPerMillText() { + return perMillText; + } + + /** + * Sets the string used for per mille sign. Different for Arabic, etc. + * + * Setting the {@code perMillText} affects the return value of + * {@link #getPerMill()}, in which the first non-format character of + * {@code perMillText} is returned. + * + * @param perMillText the string used for per mille sign + * @throws NullPointerException if {@code perMillText} is null + * @throws IllegalArgumentException if {@code perMillText} is an empty string + * @see #getPerMill() + * @see #getPerMillText() + * @since 13 + */ + void setPerMillText(String perMillText) { + Objects.requireNonNull(perMillText); + if (perMillText.isEmpty()) { + throw new IllegalArgumentException("Empty argument string"); + } + + this.perMillText = perMillText; + this.perMill = findNonFormatChar(perMillText, '\u2030'); } /** * Gets the character used for percent sign. Different for Arabic, etc. *
*** 271,280 **** --- 308,352 ---- * * @param percent the character used for percent sign */ public void setPercent(char percent) { this.percent = percent; + this.percentText = Character.toString(percent); + } + + /** + * Gets the string used for percent sign. Different for Arabic, etc. + * + * @return the string used for percent sign + * @since 13 + */ + String getPercentText() { + return percentText; + } + + /** + * Sets the string used for percent sign. Different for Arabic, etc. + * + * Setting the {@code percentText} affects the return value of + * {@link #getPercent()}, in which the first non-format character of + * {@code percentText} is returned. + * + * @param percentText the string used for percent sign + * @throws NullPointerException if {@code percentText} is null + * @throws IllegalArgumentException if {@code percentText} is an empty string + * @see #getPercent() + * @see #getPercentText() + * @since 13 + */ + void setPercentText(String percentText) { + Objects.requireNonNull(percentText); + if (percentText.isEmpty()) { + throw new IllegalArgumentException("Empty argument string"); + } + + this.percentText = percentText; + this.percent = findNonFormatChar(percentText, '%'); } /** * Gets the character used for a digit in a pattern. *
*** 371,380 **** --- 443,492 ---- * * @param minusSign the character representing minus sign */ public void setMinusSign(char minusSign) { this.minusSign = minusSign; + this.minusSignText = Character.toString(minusSign); + } + + /** + * Gets the string used to represent minus sign. If no explicit + * negative format is specified, one is formed by prefixing + * minusSignText to the positive format. + * + * @return the string representing minus sign + * @since 13 + */ + String getMinusSignText() { + return minusSignText; + } + + /** + * Sets the string used to represent minus sign. If no explicit + * negative format is specified, one is formed by prefixing + * minusSignText to the positive format. + * + * Setting the {@code minusSignText} affects the return value of + * {@link #getMinusSign()}, in which the first non-format character of + * {@code minusSignText} is returned. + * + * @param minusSignText the character representing minus sign + * @throws NullPointerException if {@code minusSignText} is null + * @throws IllegalArgumentException if {@code minusSignText} is an + * empty string + * @see #getMinusSign() + * @see #getMinusSignText() + * @since 13 + */ + void setMinusSignText(String minusSignText) { + Objects.requireNonNull(minusSignText); + if (minusSignText.isEmpty()) { + throw new IllegalArgumentException("Empty argument string"); + } + + this.minusSignText = minusSignText; + this.minusSign = findNonFormatChar(minusSignText, '-'); } /** * Returns the currency symbol for the currency of these * DecimalFormatSymbols in their locale.
*** 581,593 **** --- 693,708 ---- DecimalFormatSymbols other = (DecimalFormatSymbols) obj; return (zeroDigit == other.zeroDigit && groupingSeparator == other.groupingSeparator && decimalSeparator == other.decimalSeparator && percent == other.percent && + percentText.equals(other.percentText) && perMill == other.perMill && + perMillText.equals(other.perMillText) && digit == other.digit && minusSign == other.minusSign && + minusSignText.equals(other.minusSignText) && patternSeparator == other.patternSeparator && infinity.equals(other.infinity) && NaN.equals(other.NaN) && getCurrencySymbol().equals(other.getCurrencySymbol()) && // possible currency init occurs here intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
*** 629,645 **** String[] numberElements = (String[]) data[0]; decimalSeparator = numberElements[0].charAt(0); groupingSeparator = numberElements[1].charAt(0); patternSeparator = numberElements[2].charAt(0); ! percent = numberElements[3].charAt(0); zeroDigit = numberElements[4].charAt(0); //different for Arabic,etc. digit = numberElements[5].charAt(0); ! minusSign = numberElements[6].charAt(0); exponential = numberElements[7].charAt(0); exponentialSeparator = numberElements[7]; //string representation new since 1.6 ! perMill = numberElements[8].charAt(0); infinity = numberElements[9]; NaN = numberElements[10]; // maybe filled with previously cached values, or null. intlCurrencySymbol = (String) data[1]; --- 744,763 ---- String[] numberElements = (String[]) data[0]; decimalSeparator = numberElements[0].charAt(0); groupingSeparator = numberElements[1].charAt(0); patternSeparator = numberElements[2].charAt(0); ! percentText = numberElements[3]; ! percent = findNonFormatChar(percentText, '%'); zeroDigit = numberElements[4].charAt(0); //different for Arabic,etc. digit = numberElements[5].charAt(0); ! minusSignText = numberElements[6]; ! minusSign = findNonFormatChar(minusSignText, '-'); exponential = numberElements[7].charAt(0); exponentialSeparator = numberElements[7]; //string representation new since 1.6 ! perMillText = numberElements[8]; ! perMill = findNonFormatChar(perMillText, '\u2030'); infinity = numberElements[9]; NaN = numberElements[10]; // maybe filled with previously cached values, or null. intlCurrencySymbol = (String) data[1];
*** 650,659 **** --- 768,787 ---- // If that changes, add a new entry to NumberElements. monetarySeparator = decimalSeparator; } /** + * Obtains non-format single character from String + */ + private char findNonFormatChar(String src, char defChar) { + return (char)src.chars() + .filter(c -> Character.getType(c) != Character.FORMAT) + .findFirst() + .orElse(defChar); + } + + /** * Lazy initialization for currency related fields */ private void initializeCurrency(Locale locale) { if (currencyInitialized) { return;
*** 710,723 **** --- 838,857 ---- * to be 'E'. * If <code>serialVersionOnStream</code> is less than 2, * initializes <code>locale</code>to the root locale, and initializes * If <code>serialVersionOnStream</code> is less than 3, it initializes * <code>exponentialSeparator</code> using <code>exponential</code>. + * If <code>serialVersionOnStream</code> is less than 4, it initializes + * <code>perMillText</code>, <code>percentText</code>, and + * <code>minusSignText</code> using <code>perMill</code>, <code>percent</code>, and + * <code>minusSign</code> respectively. * Sets <code>serialVersionOnStream</code> back to the maximum allowed value so that * default serialization will work properly if this object is streamed out again. * Initializes the currency from the intlCurrencySymbol field. * + * @throws InvalidObjectException if <code>char</code> and <code>String</code> + * representations of either percent, per mille, and/or minus sign disagree. * @since 1.1.6 */ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject();
*** 733,742 **** --- 867,893 ---- } if (serialVersionOnStream < 3) { // didn't have exponentialSeparator. Create one using exponential exponentialSeparator = Character.toString(exponential); } + if (serialVersionOnStream < 4) { + // didn't have perMillText, percentText, and minusSignText. + // Create one using corresponding char variations. + perMillText = Character.toString(perMill); + percentText = Character.toString(percent); + minusSignText = Character.toString(minusSign); + } else { + // Check whether char and text fields agree + if (findNonFormatChar(perMillText, '\uFFFF') != perMill || + findNonFormatChar(percentText, '\uFFFF') != percent || + findNonFormatChar(minusSignText, '\uFFFF') != minusSign) { + throw new InvalidObjectException( + "'char' and 'String' representations of either percent, " + + "per mille, and/or minus sign disagree."); + } + } + serialVersionOnStream = currentSerialVersion; if (intlCurrencySymbol != null) { try { currency = Currency.getInstance(intlCurrencySymbol);
*** 876,885 **** --- 1027,1069 ---- * @serial * @since 1.4 */ private Locale locale; + /** + * String representation of per mille sign, which may include + * formatting characters, such as BiDi control characters. + * The first non-format character of this string is the same as + * <code>perMill</code>. + * + * @serial + * @since 13 + */ + private String perMillText; + + /** + * String representation of percent sign, which may include + * formatting characters, such as BiDi control characters. + * The first non-format character of this string is the same as + * <code>percent</code>. + * + * @serial + * @since 13 + */ + private String percentText; + + /** + * String representation of minus sign, which may include + * formatting characters, such as BiDi control characters. + * The first non-format character of this string is the same as + * <code>minusSign</code>. + * + * @serial + * @since 13 + */ + private String minusSignText; + // currency; only the ISO code is serialized. private transient Currency currency; private transient volatile boolean currencyInitialized; // Proclaim JDK 1.1 FCS compatibility
*** 889,899 **** // - 0 (default) for version up to JDK 1.1.5 // - 1 for version from JDK 1.1.6, which includes two new fields: // monetarySeparator and exponential. // - 2 for version from J2SE 1.4, which includes locale field. // - 3 for version from J2SE 1.6, which includes exponentialSeparator field. ! private static final int currentSerialVersion = 3; /** * Describes the version of <code>DecimalFormatSymbols</code> present on the stream. * Possible values are: * <ul> --- 1073,1085 ---- // - 0 (default) for version up to JDK 1.1.5 // - 1 for version from JDK 1.1.6, which includes two new fields: // monetarySeparator and exponential. // - 2 for version from J2SE 1.4, which includes locale field. // - 3 for version from J2SE 1.6, which includes exponentialSeparator field. ! // - 4 for version from Java SE 13, which includes perMillText, percentText, ! // and minusSignText field. ! private static final int currentSerialVersion = 4; /** * Describes the version of <code>DecimalFormatSymbols</code> present on the stream. * Possible values are: * <ul>
*** 903,912 **** --- 1089,1101 ---- * two new fields: <code>monetarySeparator</code> and <code>exponential</code>. * <li><b>2</b>: Versions written by J2SE 1.4 or later, which include a * new <code>locale</code> field. * <li><b>3</b>: Versions written by J2SE 1.6 or later, which include a * new <code>exponentialSeparator</code> field. + * <li><b>4</b>: Versions written by Java SE 13 or later, which include + * new <code>perMillText</code>, <code>percentText</code>, and + * <code>minusSignText</code> field. * </ul> * When streaming out a <code>DecimalFormatSymbols</code>, the most recent format * (corresponding to the highest allowable <code>serialVersionOnStream</code>) * is always written. *
< prev index next >