mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 13:21:53 +01:00
Fix change detection for textual things (#4076)
* Don't update unchanged things in .things file There were two problems: - The old things weren't removed, resulting in accumulation of duplicate things and comparing the new one against the old one resulting in erroneous update - Numeric values (usually entered as integer) in a newly loaded Channel Configuration properties are stored as BigDecimal with Scale 0, but subsequent normalization changed it to scale 1. This made equals() return false when it shouldn't. This leads to calling notifyListenersAboutUpdatedElement unnecessarily. Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
parent
21186d6168
commit
eb2339907f
@ -177,10 +177,12 @@ public class ConfigUtil {
|
||||
if (configDescriptionParameter != null) {
|
||||
Normalizer normalizer = NormalizerFactory.getNormalizer(configDescriptionParameter);
|
||||
return normalizer.normalize(value);
|
||||
} else if (value instanceof Boolean || value instanceof String || value instanceof BigDecimal) {
|
||||
return value;
|
||||
} else if (value instanceof Boolean) {
|
||||
return NormalizerFactory.getNormalizer(Type.BOOLEAN).normalize(value);
|
||||
} else if (value instanceof String) {
|
||||
return NormalizerFactory.getNormalizer(Type.TEXT).normalize(value);
|
||||
} else if (value instanceof Number) {
|
||||
return new BigDecimal(value.toString());
|
||||
return NormalizerFactory.getNormalizer(Type.DECIMAL).normalize(value);
|
||||
} else if (value instanceof Collection collection) {
|
||||
return normalizeCollection(collection);
|
||||
}
|
||||
|
@ -35,13 +35,16 @@ final class DecimalNormalizer extends AbstractNormalizer {
|
||||
return stripTrailingZeros(new BigDecimal(stringValue));
|
||||
}
|
||||
if (value instanceof Byte byteValue) {
|
||||
return new BigDecimal(byteValue).setScale(1);
|
||||
return new BigDecimal(byteValue);
|
||||
}
|
||||
if (value instanceof Short shortValue) {
|
||||
return new BigDecimal(shortValue);
|
||||
}
|
||||
if (value instanceof Integer integerValue) {
|
||||
return new BigDecimal(integerValue).setScale(1);
|
||||
return new BigDecimal(integerValue);
|
||||
}
|
||||
if (value instanceof Long longValue) {
|
||||
return new BigDecimal(longValue).setScale(1);
|
||||
return new BigDecimal(longValue);
|
||||
}
|
||||
if (value instanceof Float floatValue) {
|
||||
return new BigDecimal(floatValue.toString());
|
||||
@ -58,9 +61,12 @@ final class DecimalNormalizer extends AbstractNormalizer {
|
||||
}
|
||||
|
||||
private BigDecimal stripTrailingZeros(BigDecimal value) {
|
||||
BigDecimal ret = new BigDecimal(value.stripTrailingZeros().toPlainString());
|
||||
if (ret.scale() == 0) {
|
||||
ret = ret.setScale(1);
|
||||
BigDecimal ret = value;
|
||||
if (ret.scale() > 1) {
|
||||
ret = ret.stripTrailingZeros();
|
||||
if (ret.scale() == 0) {
|
||||
ret = ret.setScale(1);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -51,4 +51,14 @@ public final class NormalizerFactory {
|
||||
Normalizer ret = NORMALIZERS.get(configDescriptionParameter.getType());
|
||||
return configDescriptionParameter.isMultiple() ? new ListNormalizer(ret) : ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Normalizer} for the given ConfigDescriptionParameter type.
|
||||
*
|
||||
* @param type the type
|
||||
* @return the corresponding {@link Normalizer} (not null)
|
||||
*/
|
||||
public static Normalizer getNormalizer(Type type) {
|
||||
return NORMALIZERS.get(type);
|
||||
}
|
||||
}
|
||||
|
@ -160,18 +160,42 @@ public class ConfigurationTest {
|
||||
@Test
|
||||
public void assertNormalizationInSetProperties() {
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
properties.put("byteField", Byte.valueOf("1"));
|
||||
properties.put("shortField", Short.valueOf("1"));
|
||||
properties.put("intField", 1);
|
||||
properties.put("longField", Long.valueOf("1"));
|
||||
properties.put("doubleField", Double.valueOf("1"));
|
||||
properties.put("floatField", Float.valueOf("1"));
|
||||
properties.put("bigDecimalField", BigDecimal.ONE);
|
||||
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.setProperties(properties);
|
||||
assertThat(configuration.get("byteField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("shortField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("intField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("longField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("doubleField"), is(equalTo(new BigDecimal("1.0"))));
|
||||
assertThat(configuration.get("floatField"), is(equalTo(new BigDecimal("1.0"))));
|
||||
assertThat(configuration.get("bigDecimalField"), is(equalTo(BigDecimal.ONE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertNormalizationInPut() {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.put("byteField", Byte.valueOf("1"));
|
||||
configuration.put("shortField", Short.valueOf("1"));
|
||||
configuration.put("intField", 1);
|
||||
configuration.put("longField", Long.valueOf("1"));
|
||||
configuration.put("doubleField", Double.valueOf("1"));
|
||||
configuration.put("floatField", Float.valueOf("1"));
|
||||
configuration.put("bigDecimalField", BigDecimal.ONE);
|
||||
assertThat(configuration.get("byteField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("shortField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("intField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("longField"), is(equalTo(BigDecimal.ONE)));
|
||||
assertThat(configuration.get("doubleField"), is(equalTo(new BigDecimal("1.0"))));
|
||||
assertThat(configuration.get("floatField"), is(equalTo(new BigDecimal("1.0"))));
|
||||
assertThat(configuration.get("bigDecimalField"), is(equalTo(BigDecimal.ONE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -99,18 +99,19 @@ public class NormalizerTest {
|
||||
ConfigDescriptionParameterBuilder.create("test", ConfigDescriptionParameter.Type.DECIMAL).build());
|
||||
|
||||
assertThat(normalizer.normalize(null), is(nullValue()));
|
||||
assertThat(normalizer.normalize(42), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize(42L), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize((byte) 42), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize(42), is(equalTo(new BigDecimal("42"))));
|
||||
assertThat(normalizer.normalize(42L), is(equalTo(new BigDecimal("42"))));
|
||||
assertThat(normalizer.normalize((byte) 42), is(equalTo(new BigDecimal("42"))));
|
||||
assertThat(normalizer.normalize(42.0), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize(42.0f), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize(42.0d), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize(42.1), is(equalTo(new BigDecimal("42.1"))));
|
||||
assertThat(normalizer.normalize(42.88f), is(equalTo(new BigDecimal("42.88"))));
|
||||
assertThat(normalizer.normalize(42.88d), is(equalTo(new BigDecimal("42.88"))));
|
||||
assertThat(normalizer.normalize("42"), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize("42"), is(equalTo(new BigDecimal("42"))));
|
||||
assertThat(normalizer.normalize("42.0"), is(equalTo(new BigDecimal("42.0"))));
|
||||
assertThat(normalizer.normalize("42.1"), is(equalTo(new BigDecimal("42.1"))));
|
||||
assertThat(normalizer.normalize("42.10"), is(equalTo(new BigDecimal("42.1"))));
|
||||
assertThat(normalizer.normalize("42.11"), is(equalTo(new BigDecimal("42.11"))));
|
||||
assertThat(normalizer.normalize("42.00"), is(equalTo(new BigDecimal("42.0"))));
|
||||
|
||||
|
@ -605,8 +605,8 @@ class GenericThingProvider extends AbstractProviderLazyNullness<Thing> implement
|
||||
if (!loadedXmlThingTypes.contains(factory.bundleName) || modelRepository == null) {
|
||||
return
|
||||
}
|
||||
val oldThings = thingsMap.get(modelName).clone
|
||||
val newThings = newArrayList()
|
||||
val oldThings = thingsMap.put(modelName, newThings)
|
||||
|
||||
val model = modelRepository.getModel(modelName) as ThingModel
|
||||
if (model !== null) {
|
||||
@ -616,7 +616,6 @@ class GenericThingProvider extends AbstractProviderLazyNullness<Thing> implement
|
||||
}
|
||||
|
||||
newThings.forEach [ newThing |
|
||||
thingsMap.get(modelName).add(newThing)
|
||||
val oldThing = oldThings.findFirst[it.UID == newThing.UID]
|
||||
if (oldThing !== null) {
|
||||
if (!ThingHelper.equals(oldThing, newThing)) {
|
||||
|
Loading…
Reference in New Issue
Block a user