Skip to content

Commit

Permalink
Fix change detection for textual things (#4076)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
jimtng authored May 2, 2024
1 parent 21186d6 commit eb23399
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,12 @@ public static Object normalizeType(Object value, @Nullable ConfigDescriptionPara
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@ public Object doNormalize(Object value) {
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());
Expand All @@ -58,9 +61,12 @@ public Object doNormalize(Object value) {
}

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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,14 @@ public static Normalizer getNormalizer(ConfigDescriptionParameter configDescript
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,42 @@ public void assertToStringHandlesNullValuesGracefully() {
@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,19 @@ public void testDecimalNormalizer() {
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"))));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)) {
Expand Down

0 comments on commit eb23399

Please sign in to comment.