From 1699f061c0d16e1fae6a456e1cadb017dd4d7594 Mon Sep 17 00:00:00 2001 From: Dominic Burger Date: Thu, 18 Jan 2024 16:11:02 +0100 Subject: [PATCH] Use class type instead of name in FindObjects --- .../functions/FindObjectsIoxPlugin.java | 35 +++++++++---------- src/model/GeoW_FunctionsExt.ili | 4 +-- .../data/FindObjects/MandatoryConstraints.ili | 12 +++---- 3 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/main/java/ch/geowerkstatt/ilivalidator/extensions/functions/FindObjectsIoxPlugin.java b/src/main/java/ch/geowerkstatt/ilivalidator/extensions/functions/FindObjectsIoxPlugin.java index 6a24a93..30bed55 100644 --- a/src/main/java/ch/geowerkstatt/ilivalidator/extensions/functions/FindObjectsIoxPlugin.java +++ b/src/main/java/ch/geowerkstatt/ilivalidator/extensions/functions/FindObjectsIoxPlugin.java @@ -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; @@ -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 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 objects = findObjectsOfClass(key.className); + List objects = findObjectsOfClass(key.objectClass); return objects.stream() .filter(object -> { Value value = validator.getValueFromObjectPath(null, object, attributePath, null); @@ -61,7 +59,8 @@ private List findObjects(FindObjectsKey key) { .collect(Collectors.toList()); } - private List findObjectsOfClass(String className) { + private List findObjectsOfClass(Viewable objectClass) { + String className = objectClass.getScopedName(); List objects = new ArrayList<>(); for (String basketId : objectPool.getBasketIds()) { ObjPoolImpl2 basketObjectPool = objectPool.getObjectsOfBasketId(basketId); @@ -77,12 +76,12 @@ private List 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; } @@ -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()); } } } diff --git a/src/model/GeoW_FunctionsExt.ili b/src/model/GeoW_FunctionsExt.ili index ab6721b..c364083 100644 --- a/src/model/GeoW_FunctionsExt.ili +++ b/src/model/GeoW_FunctionsExt.ili @@ -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. \ No newline at end of file diff --git a/src/test/data/FindObjects/MandatoryConstraints.ili b/src/test/data/FindObjects/MandatoryConstraints.ili index 579bc21..40bc9c8 100644 --- a/src/test/data/FindObjects/MandatoryConstraints.ili +++ b/src/test/data/FindObjects/MandatoryConstraints.ili @@ -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;