Skip to content

Commit

Permalink
Improve error log (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickackermann authored Jun 14, 2024
2 parents 39a03e2 + 93a05b0 commit fc6d28a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import ch.interlis.iom.IomObject;
import ch.interlis.iox_j.jts.Iox2jtsext;
import ch.interlis.iox_j.validator.Value;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;

Expand Down Expand Up @@ -70,7 +71,7 @@ private Value isInsideArea(String usageScope, Collection<IomObject> objects, Pat
Geometry::union
));

List<Geometry> sortedGeometries;
List<Map.Entry<ValueKey, Geometry>> sortedGeometries;
ValueKey firstKey = geometriesByCodeValue.keySet().iterator().next();
Type keyType = firstKey.getType();

Expand All @@ -88,33 +89,48 @@ private Value isInsideArea(String usageScope, Collection<IomObject> objects, Pat
return Value.createSkipEvaluation();
}

boolean result = true;
for (int i = 0; i < sortedGeometries.size() - 1; i++) {
Geometry current = sortedGeometries.get(i);
Geometry next = sortedGeometries.get(i + 1);

if (!next.contains(current)) {
return new Value(false);
Map.Entry<ValueKey, Geometry> current = sortedGeometries.get(i);
Map.Entry<ValueKey, Geometry> next = sortedGeometries.get(i + 1);

if (!next.getValue().contains(current.getValue())) {
Geometry offendingGeometry = current.getValue().difference(next.getValue());
Coordinate position = offendingGeometry.getCoordinate();
String offendingEnvelopeWkt = offendingGeometry.getEnvelope().toText();

String currentCode = current.getKey().getStringValue();
String nextCode = next.getKey().getStringValue();

logger.addEvent(logger.logErrorMsg(
"IsInsideAreaByCode found an invalid overlap between code '{0}' and '{1}'. The offending geometry is inside this envelope: {2}",
position.x,
position.y,
position.z,
currentCode,
nextCode,
offendingEnvelopeWkt));

result = false;
}
}

return new Value(true);
return new Value(result);
}

private List<Geometry> sortByEnumValues(Map<ValueKey, Geometry> map, EnumerationType enumType) {
private List<Map.Entry<ValueKey, Geometry>> sortByEnumValues(Map<ValueKey, Geometry> map, EnumerationType enumType) {
List<String> enumValues = enumType.getValues();

return map.entrySet()
.stream()
.sorted(Comparator.comparingInt(entry -> enumValues.indexOf(entry.getKey().getStringValue())))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}

private List<Geometry> sortByNumericValues(Map<ValueKey, Geometry> map) {
private List<Map.Entry<ValueKey, Geometry>> sortByNumericValues(Map<ValueKey, Geometry> map) {
return map.entrySet()
.stream()
.sorted(Comparator.comparingDouble(entry -> entry.getKey().getNumericValue()))
.map(Map.Entry::getValue)
.collect(Collectors.toList());
}

Expand Down
1 change: 1 addition & 0 deletions src/test/data/IsInsideAreaByCode/SetConstraints.ili
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ MODEL TestSuite
codeNumeric : CodeNumeric;
surface : SURFACE WITH (STRAIGHTS) VERTEX CHKoord WITHOUT OVERLAPS > 0.001;

!!@ ilivalid.msg = "Custom message."
SET CONSTRAINT insideAreaConstraintEnum: NGK_SO_FunctionsExt.IsInsideAreaByCode(ALL, "surface", "codeEnum");
SET CONSTRAINT insideAreaConstraintNumeric: NGK_SO_FunctionsExt.IsInsideAreaByCode(ALL, "surface", "codeNumeric");
END BaseClass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,19 @@ public static void assertLogEventsContainMessage(List<IoxLogEvent> logs, String
fail(String.format("The logs are missing the message <%s>.", expectedMessageRegex));
}
}

/**
* Asserts that the logs contain the expected message regex a specific number of times.
*
* @param logs The logs to check.
* @param expectedMessageRegex The regex to match.
* @param expectedMatchCount The expected number of matches.
*/
public static void assertLogEventsMessages(List<IoxLogEvent> logs, String expectedMessageRegex, long expectedMatchCount) {
Pattern pattern = Pattern.compile(expectedMessageRegex);
long actualMatchCount = logs.stream().filter(log -> pattern.matcher(log.getEventMsg()).find()).count();
if (actualMatchCount != expectedMatchCount) {
fail(String.format("Expected %d messages to match the regex <%s> but found %d.", expectedMatchCount, expectedMessageRegex, actualMatchCount));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,13 @@ public void setConstraintOk() throws Ili2cFailure, IoxException {
@Test
public void setConstraintFail() throws Ili2cFailure, IoxException {
vh.runValidation(new String[]{TEST_DATA_FAIL}, new String[]{ILI_FILE});
Assert.equals(2, vh.getErrs().size());
AssertionHelper.assertConstraintErrors(vh, 1, "insideAreaConstraintEnum");
Assert.equals(9, vh.getErrs().size());

AssertionHelper.assertLogEventsMessages(vh.getErrs(), "^IsInsideAreaByCode found an invalid overlap between code 'code_2' and 'code_3'", 1);
AssertionHelper.assertLogEventsMessages(vh.getErrs(), "^IsInsideAreaByCode found an invalid overlap between code 'code_3' and 'code_4'", 1);
AssertionHelper.assertLogEventsMessages(vh.getErrs(), "^IsInsideAreaByCode found an invalid overlap between code '22' and '33'", 1);
AssertionHelper.assertLogEventsMessages(vh.getErrs(), "^IsInsideAreaByCode found an invalid overlap between code '33' and '44'", 1);
AssertionHelper.assertLogEventsMessages(vh.getErrs(), "^Custom message\\.$", 4);
AssertionHelper.assertConstraintErrors(vh, 1, "insideAreaConstraintNumeric");
}
}

0 comments on commit fc6d28a

Please sign in to comment.