com.ibm.icu.impl.number.PropertiesAffixPatternProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
package com.ibm.icu.impl.number;
public class PropertiesAffixPatternProvider implements AffixPatternProvider {
private final String posPrefix;
private final String posSuffix;
private final String negPrefix;
private final String negSuffix;
private final boolean isCurrencyPattern;
public PropertiesAffixPatternProvider(DecimalFormatProperties properties) {
// There are two ways to set affixes in DecimalFormat: via the pattern string (applyPattern), and via the
// explicit setters (setPositivePrefix and friends). The way to resolve the settings is as follows:
//
// 1) If the explicit setting is present for the field, use it.
// 2) Otherwise, follows UTS 35 rules based on the pattern string.
//
// Importantly, the explicit setters affect only the one field they override. If you set the positive
// prefix, that should not affect the negative prefix.
// Convenience: Extract the properties into local variables.
// Variables are named with three chars: [p/n][p/s][o/p]
// [p/n] => p for positive, n for negative
// [p/s] => p for prefix, s for suffix
// [o/p] => o for escaped custom override string, p for pattern string
String ppo = AffixUtils.escape(properties.getPositivePrefix());
String pso = AffixUtils.escape(properties.getPositiveSuffix());
String npo = AffixUtils.escape(properties.getNegativePrefix());
String nso = AffixUtils.escape(properties.getNegativeSuffix());
String ppp = properties.getPositivePrefixPattern();
String psp = properties.getPositiveSuffixPattern();
String npp = properties.getNegativePrefixPattern();
String nsp = properties.getNegativeSuffixPattern();
if (ppo != null) {
posPrefix = ppo;
} else if (ppp != null) {
posPrefix = ppp;
} else {
// UTS 35: Default positive prefix is empty string.
posPrefix = "";
}
if (pso != null) {
posSuffix = pso;
} else if (psp != null) {
posSuffix = psp;
} else {
// UTS 35: Default positive suffix is empty string.
posSuffix = "";
}
if (npo != null) {
negPrefix = npo;
} else if (npp != null) {
negPrefix = npp;
} else {
// UTS 35: Default negative prefix is "-" with positive prefix.
// Important: We prepend the "-" to the pattern, not the override!
negPrefix = ppp == null ? "-" : "-" + ppp;
}
if (nso != null) {
negSuffix = nso;
} else if (nsp != null) {
negSuffix = nsp;
} else {
// UTS 35: Default negative prefix is the positive prefix.
negSuffix = psp == null ? "" : psp;
}
// For declaring if this is a currency pattern, we need to look at the
// original pattern, not at any user-specified overrides.
isCurrencyPattern = (
AffixUtils.hasCurrencySymbols(ppp) ||
AffixUtils.hasCurrencySymbols(psp) ||
AffixUtils.hasCurrencySymbols(npp) ||
AffixUtils.hasCurrencySymbols(nsp));
}
@Override
public char charAt(int flags, int i) {
return getString(flags).charAt(i);
}
@Override
public int length(int flags) {
return getString(flags).length();
}
@Override
public String getString(int flags) {
boolean prefix = (flags & Flags.PREFIX) != 0;
boolean negative = (flags & Flags.NEGATIVE_SUBPATTERN) != 0;
if (prefix && negative) {
return negPrefix;
} else if (prefix) {
return posPrefix;
} else if (negative) {
return negSuffix;
} else {
return posSuffix;
}
}
@Override
public boolean positiveHasPlusSign() {
return AffixUtils.containsType(posPrefix, AffixUtils.TYPE_PLUS_SIGN)
|| AffixUtils.containsType(posSuffix, AffixUtils.TYPE_PLUS_SIGN);
}
@Override
public boolean hasNegativeSubpattern() {
return (
negSuffix != posSuffix ||
negPrefix.length() != posPrefix.length() + 1 ||
!negPrefix.regionMatches(1, posPrefix, 0, posPrefix.length()) ||
negPrefix.charAt(0) != '-'
);
}
@Override
public boolean negativeHasMinusSign() {
return AffixUtils.containsType(negPrefix, AffixUtils.TYPE_MINUS_SIGN)
|| AffixUtils.containsType(negSuffix, AffixUtils.TYPE_MINUS_SIGN);
}
@Override
public boolean hasCurrencySign() {
return isCurrencyPattern;
}
@Override
public boolean containsSymbolType(int type) {
return AffixUtils.containsType(posPrefix, type) || AffixUtils.containsType(posSuffix, type)
|| AffixUtils.containsType(negPrefix, type) || AffixUtils.containsType(negSuffix, type);
}
@Override
public boolean hasBody() {
return true;
}
@Override
public String toString() {
return super.toString()
+ " {"
+ posPrefix
+ "#"
+ posSuffix
+ ";"
+ negPrefix
+ "#"
+ negSuffix
+ "}";
}
}