OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.payments; | 5 package org.chromium.chrome.browser.payments; |
6 | 6 |
7 import java.text.DecimalFormatSymbols; | 7 import java.text.DecimalFormatSymbols; |
8 import java.util.Currency; | 8 import java.util.Currency; |
9 import java.util.Locale; | 9 import java.util.Locale; |
10 import java.util.regex.Matcher; | 10 import java.util.regex.Matcher; |
11 import java.util.regex.Pattern; | 11 import java.util.regex.Pattern; |
12 | 12 |
13 /** | 13 /** |
14 * Formatter for currency strings that can be too large to parse into numbers. | 14 * Formatter for currency strings that can be too large to parse into numbers. |
15 * https://w3c.github.io/browser-payment-api/specs/paymentrequest.html#currencya
mount | 15 * https://w3c.github.io/browser-payment-api/specs/paymentrequest.html#currencya
mount |
16 */ | 16 */ |
17 public class CurrencyStringFormatter { | 17 public class CurrencyStringFormatter { |
18 // Amount value pattern and capture group numbers. | 18 // Amount value pattern and capture group numbers. |
19 private static final String AMOUNT_VALUE_PATTERN = "^(-?)([0-9]+)(\\.([0-9]+
))?$"; | 19 private static final String AMOUNT_VALUE_PATTERN = "^(-?)([0-9]+)(\\.([0-9]+
))?$"; |
20 private static final int OPTIONAL_NEGATIVE_GROUP = 1; | 20 private static final int OPTIONAL_NEGATIVE_GROUP = 1; |
21 private static final int DIGITS_BETWEEN_NEGATIVE_AND_PERIOD_GROUP = 2; | 21 private static final int DIGITS_BETWEEN_NEGATIVE_AND_PERIOD_GROUP = 2; |
22 private static final int DIGITS_AFTER_PERIOD_GROUP = 4; | 22 private static final int DIGITS_AFTER_PERIOD_GROUP = 4; |
23 | 23 |
24 // Amount currency code pattern. | 24 // Max currency code length. Maximum length of currency code can be at most
2048. |
25 private static final String AMOUNT_CURRENCY_CODE_PATTERN = "^[A-Z]{3}$"; | 25 private static final int MAX_CURRENCY_CODE_LEN = 2048; |
26 | 26 |
27 // Formatting constants. | 27 // Formatting constants. |
28 private static final int DIGIT_GROUPING_SIZE = 3; | 28 private static final int DIGIT_GROUPING_SIZE = 3; |
29 | 29 |
30 private final Pattern mAmountValuePattern; | 30 private final Pattern mAmountValuePattern; |
31 private final Pattern mAmountCurrencyCodePattern; | |
32 | 31 |
33 /** | 32 /** |
34 * The symbol for the currency specified on the bill. For example, the symbo
l for "USD" is "$". | 33 * The symbol for the currency specified on the bill. For example, the symbo
l for "USD" is "$". |
35 */ | 34 */ |
36 private final String mCurrencySymbol; | 35 private final String mCurrencySymbol; |
37 | 36 |
38 /** | 37 /** |
39 * The number of digits after the decimal separator for the currency specifi
ed on the bill. For | 38 * The number of digits after the decimal separator for the currency specifi
ed on the bill. For |
40 * example, 2 for "USD" and 0 for "JPY". | 39 * example, 2 for "USD" and 0 for "JPY". |
41 */ | 40 */ |
(...skipping 17 matching lines...) Expand all Loading... |
59 * @param currencyCode The currency code. Most commonly, this follows ISO 42
17 format: 3 upper | 58 * @param currencyCode The currency code. Most commonly, this follows ISO 42
17 format: 3 upper |
60 * case ASCII letters. For example, "USD". Format is not
restricted. Should | 59 * case ASCII letters. For example, "USD". Format is not
restricted. Should |
61 * not be null. | 60 * not be null. |
62 * @param userLocale User's current locale. Should not be null. | 61 * @param userLocale User's current locale. Should not be null. |
63 */ | 62 */ |
64 public CurrencyStringFormatter(String currencyCode, Locale userLocale) { | 63 public CurrencyStringFormatter(String currencyCode, Locale userLocale) { |
65 assert currencyCode != null : "currencyCode should not be null"; | 64 assert currencyCode != null : "currencyCode should not be null"; |
66 assert userLocale != null : "userLocale should not be null"; | 65 assert userLocale != null : "userLocale should not be null"; |
67 | 66 |
68 mAmountValuePattern = Pattern.compile(AMOUNT_VALUE_PATTERN); | 67 mAmountValuePattern = Pattern.compile(AMOUNT_VALUE_PATTERN); |
69 mAmountCurrencyCodePattern = Pattern.compile(AMOUNT_CURRENCY_CODE_PATTER
N); | |
70 | 68 |
71 String currencySymbol; | 69 String currencySymbol; |
72 int defaultFractionDigits; | 70 int defaultFractionDigits; |
73 try { | 71 try { |
74 Currency currency = Currency.getInstance(currencyCode); | 72 Currency currency = Currency.getInstance(currencyCode); |
75 currencySymbol = currency.getSymbol(); | 73 currencySymbol = currency.getSymbol(); |
76 defaultFractionDigits = currency.getDefaultFractionDigits(); | 74 defaultFractionDigits = currency.getDefaultFractionDigits(); |
77 } catch (IllegalArgumentException e) { | 75 } catch (IllegalArgumentException e) { |
78 // The spec does not limit the currencies to official ISO 4217 curre
ncy code list, which | 76 // The spec does not limit the currencies to official ISO 4217 curre
ncy code list, which |
79 // is used by java.util.Currency. For example, "BTX" (bitcoin) is no
t an official ISO | 77 // is used by java.util.Currency. For example, "BTX" (bitcoin) is no
t an official ISO |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 return amountValue != null && mAmountValuePattern.matcher(amountValue).m
atches(); | 111 return amountValue != null && mAmountValuePattern.matcher(amountValue).m
atches(); |
114 } | 112 } |
115 | 113 |
116 /** | 114 /** |
117 * Returns true if the currency code string is in valid format. | 115 * Returns true if the currency code string is in valid format. |
118 * | 116 * |
119 * @param amountCurrencyCode The currency code to check for validity. | 117 * @param amountCurrencyCode The currency code to check for validity. |
120 * @return Whether the currency code is in valid format. | 118 * @return Whether the currency code is in valid format. |
121 */ | 119 */ |
122 public boolean isValidAmountCurrencyCode(String amountCurrencyCode) { | 120 public boolean isValidAmountCurrencyCode(String amountCurrencyCode) { |
123 return amountCurrencyCode != null | 121 return amountCurrencyCode != null && amountCurrencyCode.length() <= MAX_
CURRENCY_CODE_LEN; |
124 && mAmountCurrencyCodePattern.matcher(amountCurrencyCode).matche
s(); | |
125 } | 122 } |
126 | 123 |
127 /** | 124 /** |
128 * Formats the currency string for display. Does not parse the string into a
number, because it | 125 * Formats the currency string for display. Does not parse the string into a
number, because it |
129 * might be too large. The number is formatted for the current locale and fo
llows the symbol of | 126 * might be too large. The number is formatted for the current locale and fo
llows the symbol of |
130 * the currency code. | 127 * the currency code. |
131 * | 128 * |
132 * @param amountValue The number to format. Should be in "^-?[0-9]+(\.[0-9]+
)?$" format. Should | 129 * @param amountValue The number to format. Should be in "^-?[0-9]+(\.[0-9]+
)?$" format. Should |
133 * not be null. | 130 * not be null. |
134 * @return The currency symbol followed by a space and the formatted number. | 131 * @return The currency symbol followed by a space and the formatted number. |
(...skipping 25 matching lines...) Expand all Loading... |
160 if (null != decimals) result.append(decimals); | 157 if (null != decimals) result.append(decimals); |
161 | 158 |
162 for (int i = numberOfDecimals; i < mDefaultFractionDigits; i++) { | 159 for (int i = numberOfDecimals; i < mDefaultFractionDigits; i++) { |
163 result.append("0"); | 160 result.append("0"); |
164 } | 161 } |
165 } | 162 } |
166 | 163 |
167 return result.toString(); | 164 return result.toString(); |
168 } | 165 } |
169 } | 166 } |
OLD | NEW |