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) {
|
if (configDescriptionParameter != null) {
|
||||||
Normalizer normalizer = NormalizerFactory.getNormalizer(configDescriptionParameter);
|
Normalizer normalizer = NormalizerFactory.getNormalizer(configDescriptionParameter);
|
||||||
return normalizer.normalize(value);
|
return normalizer.normalize(value);
|
||||||
} else if (value instanceof Boolean || value instanceof String || value instanceof BigDecimal) {
|
} else if (value instanceof Boolean) {
|
||||||
return value;
|
return NormalizerFactory.getNormalizer(Type.BOOLEAN).normalize(value);
|
||||||
|
} else if (value instanceof String) {
|
||||||
|
return NormalizerFactory.getNormalizer(Type.TEXT).normalize(value);
|
||||||
} else if (value instanceof Number) {
|
} else if (value instanceof Number) {
|
||||||
return new BigDecimal(value.toString());
|
return NormalizerFactory.getNormalizer(Type.DECIMAL).normalize(value);
|
||||||
} else if (value instanceof Collection collection) {
|
} else if (value instanceof Collection collection) {
|
||||||
return normalizeCollection(collection);
|
return normalizeCollection(collection);
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,16 @@ final class DecimalNormalizer extends AbstractNormalizer {
|
|||||||
return stripTrailingZeros(new BigDecimal(stringValue));
|
return stripTrailingZeros(new BigDecimal(stringValue));
|
||||||
}
|
}
|
||||||
if (value instanceof Byte byteValue) {
|
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) {
|
if (value instanceof Integer integerValue) {
|
||||||
return new BigDecimal(integerValue).setScale(1);
|
return new BigDecimal(integerValue);
|
||||||
}
|
}
|
||||||
if (value instanceof Long longValue) {
|
if (value instanceof Long longValue) {
|
||||||
return new BigDecimal(longValue).setScale(1);
|
return new BigDecimal(longValue);
|
||||||
}
|
}
|
||||||
if (value instanceof Float floatValue) {
|
if (value instanceof Float floatValue) {
|
||||||
return new BigDecimal(floatValue.toString());
|
return new BigDecimal(floatValue.toString());
|
||||||
@ -58,9 +61,12 @@ final class DecimalNormalizer extends AbstractNormalizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal stripTrailingZeros(BigDecimal value) {
|
private BigDecimal stripTrailingZeros(BigDecimal value) {
|
||||||
BigDecimal ret = new BigDecimal(value.stripTrailingZeros().toPlainString());
|
BigDecimal ret = value;
|
||||||
if (ret.scale() == 0) {
|
if (ret.scale() > 1) {
|
||||||
ret = ret.setScale(1);
|
ret = ret.stripTrailingZeros();
|
||||||
|
if (ret.scale() == 0) {
|
||||||
|
ret = ret.setScale(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -51,4 +51,14 @@ public final class NormalizerFactory {
|
|||||||
Normalizer ret = NORMALIZERS.get(configDescriptionParameter.getType());
|
Normalizer ret = NORMALIZERS.get(configDescriptionParameter.getType());
|
||||||
return configDescriptionParameter.isMultiple() ? new ListNormalizer(ret) : ret;
|
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
|
@Test
|
||||||
public void assertNormalizationInSetProperties() {
|
public void assertNormalizationInSetProperties() {
|
||||||
Map<String, Object> properties = new HashMap<>();
|
Map<String, Object> properties = new HashMap<>();
|
||||||
|
properties.put("byteField", Byte.valueOf("1"));
|
||||||
|
properties.put("shortField", Short.valueOf("1"));
|
||||||
properties.put("intField", 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 configuration = new Configuration();
|
||||||
configuration.setProperties(properties);
|
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("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
|
@Test
|
||||||
public void assertNormalizationInPut() {
|
public void assertNormalizationInPut() {
|
||||||
Configuration configuration = new Configuration();
|
Configuration configuration = new Configuration();
|
||||||
|
configuration.put("byteField", Byte.valueOf("1"));
|
||||||
|
configuration.put("shortField", Short.valueOf("1"));
|
||||||
configuration.put("intField", 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("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
|
@Test
|
||||||
|
@ -99,18 +99,19 @@ public class NormalizerTest {
|
|||||||
ConfigDescriptionParameterBuilder.create("test", ConfigDescriptionParameter.Type.DECIMAL).build());
|
ConfigDescriptionParameterBuilder.create("test", ConfigDescriptionParameter.Type.DECIMAL).build());
|
||||||
|
|
||||||
assertThat(normalizer.normalize(null), is(nullValue()));
|
assertThat(normalizer.normalize(null), is(nullValue()));
|
||||||
assertThat(normalizer.normalize(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.0"))));
|
assertThat(normalizer.normalize(42L), is(equalTo(new BigDecimal("42"))));
|
||||||
assertThat(normalizer.normalize((byte) 42), is(equalTo(new BigDecimal("42.0"))));
|
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.0), is(equalTo(new BigDecimal("42.0"))));
|
||||||
assertThat(normalizer.normalize(42.0f), 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.0d), is(equalTo(new BigDecimal("42.0"))));
|
||||||
assertThat(normalizer.normalize(42.1), is(equalTo(new BigDecimal("42.1"))));
|
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.88f), is(equalTo(new BigDecimal("42.88"))));
|
||||||
assertThat(normalizer.normalize(42.88d), 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.0"), is(equalTo(new BigDecimal("42.0"))));
|
||||||
assertThat(normalizer.normalize("42.1"), is(equalTo(new BigDecimal("42.1"))));
|
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.11"), is(equalTo(new BigDecimal("42.11"))));
|
||||||
assertThat(normalizer.normalize("42.00"), is(equalTo(new BigDecimal("42.0"))));
|
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) {
|
if (!loadedXmlThingTypes.contains(factory.bundleName) || modelRepository == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val oldThings = thingsMap.get(modelName).clone
|
|
||||||
val newThings = newArrayList()
|
val newThings = newArrayList()
|
||||||
|
val oldThings = thingsMap.put(modelName, newThings)
|
||||||
|
|
||||||
val model = modelRepository.getModel(modelName) as ThingModel
|
val model = modelRepository.getModel(modelName) as ThingModel
|
||||||
if (model !== null) {
|
if (model !== null) {
|
||||||
@ -616,7 +616,6 @@ class GenericThingProvider extends AbstractProviderLazyNullness<Thing> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
newThings.forEach [ newThing |
|
newThings.forEach [ newThing |
|
||||||
thingsMap.get(modelName).add(newThing)
|
|
||||||
val oldThing = oldThings.findFirst[it.UID == newThing.UID]
|
val oldThing = oldThings.findFirst[it.UID == newThing.UID]
|
||||||
if (oldThing !== null) {
|
if (oldThing !== null) {
|
||||||
if (!ThingHelper.equals(oldThing, newThing)) {
|
if (!ThingHelper.equals(oldThing, newThing)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user