Make DecimalType, QuantityType, PercentType accept lowercased exponent notation (#3834)
Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>pull/3815/head^2
parent
09b3160a55
commit
304453ec58
|
@ -82,7 +82,7 @@ public class DecimalType extends Number implements PrimitiveType, State, Command
|
|||
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(locale);
|
||||
df.setParseBigDecimal(true);
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
BigDecimal parsedValue = (BigDecimal) df.parseObject(value, position);
|
||||
BigDecimal parsedValue = (BigDecimal) df.parseObject(value.toUpperCase(locale), position);
|
||||
if (parsedValue == null || position.getErrorIndex() != -1 || position.getIndex() < value.length()) {
|
||||
throw new NumberFormatException("Invalid BigDecimal value: " + value);
|
||||
}
|
||||
|
|
|
@ -70,11 +70,11 @@ public class QuantityType<T extends Quantity<T>> extends Number
|
|||
public static final QuantityType<Dimensionless> ZERO = new QuantityType<>(0, AbstractUnit.ONE);
|
||||
public static final QuantityType<Dimensionless> ONE = new QuantityType<>(1, AbstractUnit.ONE);
|
||||
|
||||
// Regular expression to split unit from value
|
||||
// split on any blank character, even none (\\s*) which occurs after a digit (?<=\\d) and before
|
||||
// a "unit" character ?=[a-zA-Z°µ%'] which itself must not be preceded by plus/minus digit (?![\\+\\-]?\\d).
|
||||
// The later would be an exponent from the scalar value.
|
||||
private static final String UNIT_PATTERN = "(?<=\\d)\\s*(?=[a-zA-Z°µ%'](?![\\+\\-]?\\d))";
|
||||
// Regular expression to split unit from value. Split on any blank character, even none (\\s*)
|
||||
// which occurs after a digit (?<=\\d) and before a "unit" character ?=[a-zA-Z°µ\u03BC%']
|
||||
// which itself must not be preceded by plus/minus digit (?![\\+\\-]?\\d).
|
||||
// The latter would be an exponent from the scalar value.
|
||||
private static final String UNIT_PATTERN = "(?<=\\d)\\s*(?=[a-zA-Z°µ\u03BC%'](?![\\+\\-]?\\d))";
|
||||
|
||||
static {
|
||||
UnitInitializer.init();
|
||||
|
@ -119,13 +119,16 @@ public class QuantityType<T extends Quantity<T>> extends Number
|
|||
public QuantityType(String value, Locale locale) {
|
||||
String[] constituents = value.split(UNIT_PATTERN);
|
||||
|
||||
if (constituents.length > 0) {
|
||||
constituents[0] = constituents[0].toUpperCase(locale);
|
||||
}
|
||||
// getQuantity needs a space between numeric value and unit
|
||||
String formatted = String.join(" ", constituents);
|
||||
if (!formatted.contains(" ")) {
|
||||
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(locale);
|
||||
df.setParseBigDecimal(true);
|
||||
ParsePosition position = new ParsePosition(0);
|
||||
BigDecimal parsedValue = (BigDecimal) df.parseObject(value, position);
|
||||
BigDecimal parsedValue = (BigDecimal) df.parseObject(formatted, position);
|
||||
if (parsedValue == null || position.getErrorIndex() != -1 || position.getIndex() < value.length()) {
|
||||
throw new NumberFormatException("Invalid BigDecimal value: " + value);
|
||||
}
|
||||
|
@ -294,7 +297,7 @@ public class QuantityType<T extends Quantity<T>> extends Number
|
|||
* change the dimension.
|
||||
*
|
||||
* @param targetUnit the unit to which this {@link QuantityType} will be converted to.
|
||||
* @return the new {@link QuantityType} in the given {@link Unit} or {@code null} in case of an erro.
|
||||
* @return the new {@link QuantityType} in the given {@link Unit} or {@code null} in case of an error.
|
||||
*/
|
||||
public @Nullable QuantityType<?> toInvertibleUnit(Unit<?> targetUnit) {
|
||||
// only invert if unit is not equal and inverse is compatible and targetUnit is not ONE
|
||||
|
|
|
@ -90,6 +90,12 @@ public class DecimalTypeTest {
|
|||
DecimalType.valueOf(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerCaseExponents() {
|
||||
assertEquals(DecimalType.valueOf("1e3"), DecimalType.valueOf("1E3"));
|
||||
assertEquals(DecimalType.valueOf("2.5e-3"), DecimalType.valueOf("2.5E-3"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("locales")
|
||||
public void testLocalizedStringConstruction(Locale defaultLocale) {
|
||||
|
|
|
@ -77,6 +77,12 @@ public class PercentTypeTest {
|
|||
PercentType.valueOf(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerCaseExponents() {
|
||||
assertEquals(PercentType.valueOf("1e2"), PercentType.valueOf("1E2"));
|
||||
assertEquals(PercentType.valueOf("1.1e1"), PercentType.valueOf("1.1E1"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("locales")
|
||||
public void testLocalizedStringConstruction(Locale defaultLocale) {
|
||||
|
|
|
@ -146,6 +146,20 @@ public class QuantityTypeTest {
|
|||
QuantityType.valueOf("2m");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLowerCaseExponents() {
|
||||
assertEquals(QuantityType.valueOf("10e3"), QuantityType.valueOf("10E3"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3 W"), QuantityType.valueOf("1.1E3 W"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3 m"), QuantityType.valueOf("1.1E3 m"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3m"), QuantityType.valueOf("1.1E3 m"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3m³"), QuantityType.valueOf("1.1E3 m³"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3m·cm"), QuantityType.valueOf("1.1E3 m·cm"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3 \u03BCm"), QuantityType.valueOf("1.1E3 µm"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3\u03BCm"), QuantityType.valueOf("1.1E3 µm"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3 \u00B5m"), QuantityType.valueOf("1.1E3 µm"));
|
||||
assertEquals(QuantityType.valueOf("1.1e3\u00B5m"), QuantityType.valueOf("1.1E3 µm"));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("locales")
|
||||
public void testLocalizedStringConstruction(Locale defaultLocale) {
|
||||
|
|
Loading…
Reference in New Issue