diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DecimalType.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DecimalType.java index 137a0f15006..ea704281217 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DecimalType.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DecimalType.java @@ -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); } diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/QuantityType.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/QuantityType.java index 779bdfcd67e..d7059de031b 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/QuantityType.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/QuantityType.java @@ -70,11 +70,11 @@ public class QuantityType> extends Number public static final QuantityType ZERO = new QuantityType<>(0, AbstractUnit.ONE); public static final QuantityType 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 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); } @@ -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 diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DecimalTypeTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DecimalTypeTest.java index 31144649450..1a591ae21c3 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DecimalTypeTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DecimalTypeTest.java @@ -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) { diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/PercentTypeTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/PercentTypeTest.java index e9871ac6238..e29066c0873 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/PercentTypeTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/PercentTypeTest.java @@ -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) { diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/QuantityTypeTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/QuantityTypeTest.java index 248a090dec2..e521be9e8c4 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/QuantityTypeTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/QuantityTypeTest.java @@ -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) {