Skip to content

Commit

Permalink
Use class type instead of name in FindObjects
Browse files Browse the repository at this point in the history
  • Loading branch information
domi-b committed Jan 18, 2024
1 parent ae060a8 commit 1699f06
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.geowerkstatt.ilivalidator.extensions.functions;

import ch.ehi.iox.objpool.impl.ObjPoolImpl2;
import ch.interlis.ili2c.metamodel.Element;
import ch.interlis.ili2c.metamodel.PathEl;
import ch.interlis.ili2c.metamodel.TextType;
import ch.interlis.ili2c.metamodel.Viewable;
Expand All @@ -27,32 +26,31 @@ public String getQualifiedIliName() {

@Override
protected Value evaluateInternal(String validationKind, String usageScope, IomObject contextObject, Value[] arguments) {
Value argClassName = arguments[0];
Value argObjectClass = arguments[0];
Value argPath = arguments[1];
Value argValue = arguments[2];

if (argClassName.isUndefined() || argPath.isUndefined()) {
if (argObjectClass.isUndefined() || argPath.isUndefined()) {
return Value.createSkipEvaluation();
}

String className = argClassName.getValue();
Viewable<?> objectClass = argObjectClass.getViewable();
String attributePath = argPath.getValue();
if (className == null || attributePath == null) {
if (attributePath == null) {
return Value.createUndefined();
}
if (objectClass == null) {
throw new IllegalStateException("Failed to find objects: Invalid class reference in " + usageScope);
}

FindObjectsKey key = new FindObjectsKey(className, attributePath, argValue);
FindObjectsKey key = new FindObjectsKey(objectClass, attributePath, argValue);
return new Value(OBJECTS_CACHE.computeIfAbsent(key, this::findObjects));
}

private List<IomObject> findObjects(FindObjectsKey key) {
Element classElement = td.getElement(key.className);
if (!(classElement instanceof Viewable)) {
throw new IllegalStateException("Could not find class \"" + key.className + "\"");
}
PathEl[] attributePath = EvaluationHelper.getAttributePathEl(validator, (Viewable) classElement, new Value(new TextType(), key.attributePath));
PathEl[] attributePath = EvaluationHelper.getAttributePathEl(validator, (Viewable) key.objectClass, new Value(new TextType(), key.attributePath));

List<IomObject> objects = findObjectsOfClass(key.className);
List<IomObject> objects = findObjectsOfClass(key.objectClass);
return objects.stream()
.filter(object -> {
Value value = validator.getValueFromObjectPath(null, object, attributePath, null);
Expand All @@ -61,7 +59,8 @@ private List<IomObject> findObjects(FindObjectsKey key) {
.collect(Collectors.toList());
}

private List<IomObject> findObjectsOfClass(String className) {
private List<IomObject> findObjectsOfClass(Viewable<?> objectClass) {
String className = objectClass.getScopedName();
List<IomObject> objects = new ArrayList<>();
for (String basketId : objectPool.getBasketIds()) {
ObjPoolImpl2<ObjectPoolKey, IomObject> basketObjectPool = objectPool.getObjectsOfBasketId(basketId);
Expand All @@ -77,12 +76,12 @@ private List<IomObject> findObjectsOfClass(String className) {
}

private static final class FindObjectsKey {
private final String className;
private final Viewable<?> objectClass;
private final String attributePath;
private final Value value;

FindObjectsKey(String className, String attributePath, Value value) {
this.className = className;
FindObjectsKey(Viewable<?> objectClass, String attributePath, Value value) {
this.objectClass = objectClass;
this.attributePath = attributePath;
this.value = value;
}
Expand All @@ -96,14 +95,14 @@ public boolean equals(Object o) {
return false;
}
FindObjectsKey that = (FindObjectsKey) o;
return className.equals(that.className)
return objectClass.getScopedName().equals(that.objectClass.getScopedName())
&& attributePath.equals(that.attributePath)
&& value.compareTo(that.value) == 0;
}

@Override
public int hashCode() {
return Objects.hash(className, attributePath, value.getValue());
return Objects.hash(objectClass.getScopedName(), attributePath, value.getValue());
}
}
}
4 changes: 2 additions & 2 deletions src/model/GeoW_FunctionsExt.ili
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ MODEL GeoW_FunctionsExt
FUNCTION PolylinesOverlap (Objects: OBJECTS OF ANYCLASS; LineAttr: TEXT): BOOLEAN;

!!@ fn.description = "Sucht im aktuellen Transfer nach Objekten der angegebenen Klasse, welche das Filterkriterium erfüllen. Für 'FilterAttr' soll der Pfad zum Attribut in INTERLIS 2 Syntax angegeben werden. Für 'FilterValue' kann ein beliebiger Wert angegeben werden.";
!!@ fn.param = "ClassName: Qualifizierter Klassenname (inklusive Modell und Topic) der Objekte, die gesucht werden. FilterAttr: Pfad zum Attribut, welches für den Filter verwendet werden soll. FilterValue: Wert für das Filterkriterium";
!!@ fn.param = "ObjectClass: Klasse der Objekte, die gesucht werden. FilterAttr: Pfad zum Attribut, welches für den Filter verwendet werden soll. FilterValue: Wert für das Filterkriterium";
!!@ fn.return = "Alle Objekte der angegebenen Klasse aus dem aktuellen Transfer, welche das Filterkriterium erfüllen";
!!@ fn.since = "2024-01-10";
FUNCTION FindObjects(ClassName: TEXT; FilterAttr: TEXT; FilterValue: ANYSTRUCTURE): BAG OF ANYSTRUCTURE;
FUNCTION FindObjects(ObjectClass: CLASS; FilterAttr: TEXT; FilterValue: ANYSTRUCTURE): BAG OF ANYSTRUCTURE;
END GeoW_FunctionsExt.
12 changes: 6 additions & 6 deletions src/test/data/FindObjects/MandatoryConstraints.ili
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ MODEL TestSuite
END ReferencedClass;

CLASS BaseClass =
MANDATORY CONSTRAINT trueConstraintTextAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "textAttr", "Some Value")) == 2;
MANDATORY CONSTRAINT trueConstraintEnumAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "enumAttr", #val2)) == 3;
MANDATORY CONSTRAINT trueConstraintNumberAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "numberAttr", 3)) == 1;
MANDATORY CONSTRAINT falseConstraintTextAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "textAttr", "Some Value")) == 0;
MANDATORY CONSTRAINT falseConstraintEnumAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "enumAttr", #val2)) == 0;
MANDATORY CONSTRAINT falseConstraintNumberAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects("TestSuite.FunctionTestTopic.ReferencedClass", "numberAttr", 3)) == 0;
MANDATORY CONSTRAINT trueConstraintTextAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>ReferencedClass, "textAttr", "Some Value")) == 2;
MANDATORY CONSTRAINT trueConstraintEnumAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>TestSuite.FunctionTestTopic.ReferencedClass, "enumAttr", #val2)) == 3;
MANDATORY CONSTRAINT trueConstraintNumberAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>TestSuite.FunctionTestTopic.ReferencedClass, "numberAttr", 3)) == 1;
MANDATORY CONSTRAINT falseConstraintTextAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>TestSuite.FunctionTestTopic.ReferencedClass, "textAttr", "Some Value")) == 0;
MANDATORY CONSTRAINT falseConstraintEnumAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>ReferencedClass, "enumAttr", #val2)) == 0;
MANDATORY CONSTRAINT falseConstraintNumberAttr: INTERLIS.elementCount(GeoW_FunctionsExt.FindObjects(>ReferencedClass, "numberAttr", 3)) == 0;
END BaseClass;

END FunctionTestTopic;
Expand Down

0 comments on commit 1699f06

Please sign in to comment.