Skip to content

Commit

Permalink
Merge pull request #58 from GeoWerkstatt/fix-empty-set-constraint
Browse files Browse the repository at this point in the history
Fix Exception when SET CONSTRAINT Where condition excludes all objects
  • Loading branch information
patrickackermann authored Dec 11, 2024
2 parents 3474d91 + 7b39436 commit 7d62bed
Show file tree
Hide file tree
Showing 26 changed files with 246 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import ch.interlis.iox_j.validator.Value;

public abstract class BaseInterlisFunction implements InterlisFunction {
private static Validator lastValidator = null;

protected LogEventFactory logger;
protected TransferDescription td;
Expand All @@ -26,6 +27,11 @@ public final void init(TransferDescription td, Settings settings, IoxValidationC
this.settings = settings;
this.validator = (Validator) settings.getTransientObject(IOX_VALIDATOR);
this.objectPool = objectPool;

if (lastValidator != this.validator) {
resetCaches();
lastValidator = this.validator;
}
}

@Override
Expand All @@ -43,4 +49,9 @@ public final Value evaluate(String validationKind, String usageScope, IomObject
}

protected abstract Value evaluateInternal(String validationKind, String usageScope, IomObject mainObj, Value[] actualArguments);

/**
* A change was detected that requires the caches to be reset.
*/
protected void resetCaches() { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
import ch.interlis.iox_j.validator.Validator;
import ch.interlis.iox_j.validator.Value;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -48,6 +45,8 @@ public static PathEl[] getAttributePathEl(Validator validator, Viewable<Element>
/**
* Get the {@link Viewable} (e.g. the class definition) from the {@link TransferDescription}.
* If the {@code iomObject} is {@code null}, the {@code argObjects} is used to retrieve the {@link Viewable}.
*
* @return the {@link Viewable} instance or {@code null} if no {@link Viewable} could be found.
*/
public static Viewable getContextClass(TransferDescription td, IomObject iomObject, Value argObjects) {
if (iomObject != null) {
Expand Down Expand Up @@ -122,12 +121,17 @@ public static Collection<IomObject> evaluateAttributes(Validator validator, Valu

/**
* Get the collection of {@link IomObject} inside {@code object} by following the provided {@code path} text.
* If the {@code path} is UNDEFINED, the direct collection of {@code object} is returned.
* If the {@code path} is {@link Value#isUndefined()}, the direct collection of {@code object} is returned.
* If {@code object} is empty, an empty collection is returned.
*/
public static Collection<IomObject> evaluateObjectPath(TransferDescription td, Validator validator, Value object, Value path, IomObject contextObject, String usageScope) {
if (path.isUndefined()) {
return object.getComplexObjects();
} else {
if (object.getComplexObjects().isEmpty()) {
return Collections.emptyList();
}

Viewable contextClass = EvaluationHelper.getContextClass(td, contextObject, object);
if (contextClass == null) {
throw new IllegalStateException("unknown class in " + usageScope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public String getQualifiedIliName() {
return "GeoW_FunctionsExt.Filter";
}

@Override
protected void resetCaches() {
EXPRESSION_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] arguments) {
Value argObjects = arguments[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public String getQualifiedIliName() {
return "GeoW_FunctionsExt.FindObjects";
}

@Override
protected void resetCaches() {
OBJECTS_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] arguments) {
Value argObjectClass = arguments[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public String getQualifiedIliName() {
return "GeoW_FunctionsExt.GetInGroups";
}

@Override
protected void resetCaches() {
groups.clear();
}

@Override
public Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] arguments) {
Value argObjects = arguments[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public String getQualifiedIliName() {
return QUALIFIED_ILI_NAME;
}

@Override
protected void resetCaches() {
VALID_AREA_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject mainObj, Value[] arguments) {
Value argDatasetName = arguments[0]; // TEXT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public String getQualifiedIliName() {
return QUALIFIED_ILI_NAME;
}

@Override
protected void resetCaches() {
VALID_AREA_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject mainObj, Value[] arguments) {
Value argTransferFile = arguments[0]; // TEXT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public String getQualifiedIliName() {
return QUALIFIED_ILI_NAME;
}

@Override
protected void resetCaches() {
VALID_AREA_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject mainObj, Value[] arguments) {
Value argReferenceObject = arguments[0]; // ANYSTRUCTURE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public String getQualifiedIliName() {
return "GeoW_FunctionsExt.PolylinesOverlap";
}

@Override
protected void resetCaches() {
HAS_EQUAL_LINE_PART_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] arguments) {
Value argObjects = arguments[0];
Expand All @@ -50,6 +55,7 @@ protected Value evaluateInternal(String validationKind, String usageScope, IomOb
HasEqualLinePartKey key = new HasEqualLinePartKey(objectIds, argPath.isUndefined() ? null : argPath.getValue());

boolean hasOverlap = HAS_EQUAL_LINE_PART_CACHE.computeIfAbsent(key, k -> {
logger.addEvent(logger.logDetailInfoMsg("Calculating {0} for key {1}", getQualifiedIliName(), k.toString()));
List<CompoundCurve> lines = convertToJTSLines(polylineObjects);
return hasEqualLinePart(lines);
});
Expand Down Expand Up @@ -127,5 +133,13 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(objectIds, attributeName);
}

@Override
public String toString() {
return "HasEqualLinePartKey{"
+ "objectIds=[" + String.join(", ", objectIds)
+ "], attributeName='" + attributeName + '\''
+ '}';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ public String getQualifiedIliName() {
return "GeoW_FunctionsExt.Union";
}

@Override
protected void resetCaches() {
UNION_SURFACE_CACHE.clear();
}

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] actualArguments) {
Value argObjects = actualArguments[0];
Expand Down
18 changes: 18 additions & 0 deletions src/test/data/GetInGroups/SetConstraintWhereCondition.ili
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
INTERLIS 2.4;

MODEL TestSuite
AT "mailto:[email protected]" VERSION "2024-01-09" =
IMPORTS GeoW_FunctionsExt;

TOPIC FunctionTestTopic =

CLASS BaseClass =
textAttr: TEXT*16;
type: (t1, t2);
SET CONSTRAINT onlyT1: WHERE type == #t1: INTERLIS.elementCount(GeoW_FunctionsExt.GetInGroups(ALL, "textAttr")) == 2;
SET CONSTRAINT onlyT2: WHERE type == #t2: INTERLIS.elementCount(GeoW_FunctionsExt.GetInGroups(ALL, "textAttr")) == 2;
END BaseClass;

END FunctionTestTopic;

END TestSuite.
23 changes: 23 additions & 0 deletions src/test/data/GetInGroups/TestDataOnlyT2.xtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<ili:transfer xmlns:ili="http://www.interlis.ch/xtf/2.4/INTERLIS" xmlns:geom="http://www.interlis.ch/geometry/1.0"
xmlns:TestSuite="http://www.interlis.ch/xtf/2.4/TestSuite">
<ili:headersection>
<ili:models>
<ili:model>GeoW_FunctionsExt</ili:model>
<ili:model>TestSuite</ili:model>
</ili:models>
<ili:sender>ili2gpkg-4.6.1-63db90def1260a503f0f2d4cb846686cd4851184</ili:sender>
</ili:headersection>
<ili:datasection>
<TestSuite:FunctionTestTopic ili:bid="TestSuite.FunctionTestTopic">
<TestSuite:BaseClass ili:tid="0">
<TestSuite:textAttr>aaa</TestSuite:textAttr>
<TestSuite:type>t2</TestSuite:type>
</TestSuite:BaseClass>
<TestSuite:BaseClass ili:tid="1">
<TestSuite:textAttr>aaa</TestSuite:textAttr>
<TestSuite:type>t2</TestSuite:type>
</TestSuite:BaseClass>
</TestSuite:FunctionTestTopic>
</ili:datasection>
</ili:transfer>
45 changes: 45 additions & 0 deletions src/test/data/PolylinesOverlap/TestDataOnlyT2.xtf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<ili:transfer xmlns:ili="http://www.interlis.ch/xtf/2.4/INTERLIS" xmlns:geom="http://www.interlis.ch/geometry/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:TestSuite="http://www.interlis.ch/xtf/2.4/TestSuite">
<ili:headersection>
<ili:models>
<ili:model>TestSuite</ili:model>
</ili:models>
<ili:sender>ili2gpkg-5.0.0-20f2bb62307ba6329a125fc6f10965ad9a4e6300</ili:sender>
</ili:headersection>
<ili:datasection>
<TestSuite:FunctionTestTopic ili:bid="TestSuite.FunctionTestTopic">
<TestSuite:TestClass ili:tid="1bf1e7c0-4f03-4823-a04b-106a6948cb7c">
<TestSuite:geometry>
<geom:polyline>
<geom:coord>
<geom:c1>2645543.027</geom:c1>
<geom:c2>1249774.761</geom:c2>
</geom:coord>
<geom:coord>
<geom:c1>2645564.119</geom:c1>
<geom:c2>1249788.217</geom:c2>
</geom:coord>
</geom:polyline>
</TestSuite:geometry>
<TestSuite:type>t2</TestSuite:type>
</TestSuite:TestClass>
<TestSuite:TestClass ili:tid="a9ee6314-d0bb-430c-834b-7c7ad60a9608">
<TestSuite:geometry>
<geom:polyline>
<geom:coord>
<geom:c1>2645543.027</geom:c1>
<geom:c2>1249774.761</geom:c2>
</geom:coord>
<geom:coord>
<geom:c1>2645564.119</geom:c1>
<geom:c2>1249788.217</geom:c2>
</geom:coord>
</geom:polyline>
</TestSuite:geometry>
<TestSuite:type>t2</TestSuite:type>
</TestSuite:TestClass>
</TestSuite:FunctionTestTopic>
</ili:datasection>
</ili:transfer>
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package ch.geowerkstatt.ilivalidator.extensions.functions;

import ch.interlis.iox.IoxLogEvent;
import com.vividsolutions.jts.util.Assert;

import java.util.List;
import java.util.regex.Pattern;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;

public final class AssertionHelper {
Expand All @@ -22,7 +22,7 @@ public static void assertConstraintErrors(ValidationTestHelper vh, int expectedC
}
}

Assert.equals(expectedCount, errorsFound,
assertEquals(expectedCount, errorsFound,
String.format("Expected %d but found %d errors with OID <%s> and Source <%s>.", expectedCount, errorsFound, oid, constraintName));
}

Expand All @@ -38,7 +38,7 @@ public static void assertConstraintErrors(ValidationTestHelper vh, int expectedC
}
}

Assert.equals(expectedCount, errorsFound,
assertEquals(expectedCount, errorsFound,
String.format("Expected %s errors with Source <%s> but found %d.", expectedCount, constraintName, errorsFound));
}

Expand All @@ -50,7 +50,7 @@ public static void assertNoConstraintError(ValidationTestHelper vh, String const
}
}

Assert.equals(0, errorsFound,
assertEquals(0, errorsFound,
String.format("Expected No errors with Source <%s> but found %d.", constraintName, errorsFound));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

import ch.interlis.ili2c.Ili2cFailure;
import ch.interlis.iox.IoxException;
import com.vividsolutions.jts.util.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class FilterIoxPluginTest {
protected static final String TEST_DATA = "Filter/TestData.xtf";
private ValidationTestHelper vh;
Expand All @@ -20,7 +21,7 @@ public void setUp() {
@Test
public void mandatoryConstraint() throws Ili2cFailure, IoxException {
vh.runValidation(new String[]{TEST_DATA}, new String[]{"Filter/MandatoryConstraints.ili"});
Assert.equals(2, vh.getErrs().size());
assertEquals(2, vh.getErrs().size());
AssertionHelper.assertNoConstraintError(vh, "trueConstraintEnumAttr");
AssertionHelper.assertNoConstraintError(vh, "trueConstraintNumberAttr");
AssertionHelper.assertConstraintErrors(vh, 1, "base", "falseConstraintEnumAttr");
Expand All @@ -31,7 +32,7 @@ public void mandatoryConstraint() throws Ili2cFailure, IoxException {
@Disabled("Escape sequences in strings (https://github.com/claeis/ili2c/issues/124)")
public void filterTextAttr() throws Ili2cFailure, IoxException {
vh.runValidation(new String[]{TEST_DATA}, new String[]{"Filter/MandatoryConstraintsText.ili"});
Assert.equals(1, vh.getErrs().size());
assertEquals(1, vh.getErrs().size());
AssertionHelper.assertNoConstraintError(vh, "trueConstraintTextAttr");
AssertionHelper.assertConstraintErrors(vh, 1, "base", "falseConstraintTextAttr");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import ch.interlis.ili2c.Ili2cFailure;
import ch.interlis.iox.IoxException;
import com.vividsolutions.jts.util.Assert;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class FindObjectsIoxPluginTest {
protected static final String TEST_DATA = "FindObjects/TestData.xtf";
private ValidationTestHelper vh = null;
Expand All @@ -19,7 +20,7 @@ void setUp() {
@Test
void mandatoryConstraint() throws Ili2cFailure, IoxException {
vh.runValidation(new String[]{TEST_DATA}, new String[]{"FindObjects/MandatoryConstraints.ili"});
Assert.equals(3, vh.getErrs().size());
assertEquals(3, vh.getErrs().size());
AssertionHelper.assertNoConstraintError(vh, "trueConstraintTextAttr");
AssertionHelper.assertNoConstraintError(vh, "trueConstraintEnumAttr");
AssertionHelper.assertNoConstraintError(vh, "trueConstraintNumberAttr");
Expand Down
Loading

0 comments on commit 7d62bed

Please sign in to comment.