Skip to content

Commit

Permalink
Make DecimalType, QuantityType, PercentType accept lowercased exponen…
Browse files Browse the repository at this point in the history
…t notation (openhab#3834)

Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng authored Oct 9, 2023
1 parent 09b3160 commit 304453e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public DecimalType(String value, Locale locale) {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -119,13 +119,16 @@ public QuantityType(String value) {
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);
}
Expand Down Expand Up @@ -294,7 +297,7 @@ public Dimension getDimension() {
* 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ public void testValidConstructors(String value) throws Exception {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ public void testValidConstructors(String value) {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,20 @@ public void testValidConstructors(Locale locale) {
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) {
Expand Down

0 comments on commit 304453e

Please sign in to comment.