Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ILI2.4 Evaluation Expressions mit +,-,*,/,=> #117

Merged
merged 4 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions src/main/java/ch/interlis/iox_j/validator/Validator.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ch.interlis.ili2c.generator.Interlis2Generator;
import ch.interlis.ili2c.metamodel.Expression;
import com.vividsolutions.jts.geom.Coordinate;
import ch.ehi.basics.logging.EhiLogger;
import ch.ehi.basics.settings.Settings;
Expand Down Expand Up @@ -1606,6 +1607,61 @@ public Value evaluateExpression(IomObject parentObject, String validationKind, S
}
}
return new Value(false);
} else if(expression instanceof Expression.Implication) {
Expression.Implication implication = (Expression.Implication) expression;
Value leftValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, implication.getLeft(), firstRole);
Value rightValue = Value.createSkipEvaluation();
if (!leftValue.skipEvaluation() && !leftValue.isUndefined() && leftValue.isTrue()) {
rightValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, implication.getRight(), firstRole);
}

if (leftValue.skipEvaluation() || rightValue.skipEvaluation()) {
return rightValue;
}
if (leftValue.isUndefined() || rightValue.isUndefined()) {
return Value.createUndefined();
}
return new Value(!leftValue.isTrue() || (leftValue.isTrue() && rightValue.isTrue()));
} else if (expression instanceof Expression.Addition) {
Expression.Addition addition = (Expression.Addition) expression;
Value leftValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, addition.getLeft(), firstRole);
Value rightValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, addition.getRight(), firstRole);
if (leftValue.skipEvaluation() || rightValue.skipEvaluation())
return Value.createSkipEvaluation();
if (leftValue.isUndefined() || rightValue.isUndefined())
return Value.createUndefined();

return new Value(leftValue.getNumeric() + rightValue.getNumeric());
} else if (expression instanceof Expression.Subtraction) {
Expression.Subtraction subtraction = (Expression.Subtraction) expression;
Value leftValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, subtraction.getLeft(), firstRole);
Value rightValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, subtraction.getRight(), firstRole);
if (leftValue.skipEvaluation() || rightValue.skipEvaluation())
return Value.createSkipEvaluation();
if (leftValue.isUndefined() || rightValue.isUndefined())
return Value.createUndefined();

return new Value(leftValue.getNumeric() - rightValue.getNumeric());
} else if (expression instanceof Expression.Multiplication) {
Expression.Multiplication multiplication = (Expression.Multiplication) expression;
Value leftValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, multiplication.getLeft(), firstRole);
Value rightValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, multiplication.getRight(), firstRole);
if (leftValue.skipEvaluation() || rightValue.skipEvaluation())
return Value.createSkipEvaluation();
if (leftValue.isUndefined() || rightValue.isUndefined())
return Value.createUndefined();

return new Value(leftValue.getNumeric() * rightValue.getNumeric());
} else if (expression instanceof Expression.Division) {
Expression.Division division = (Expression.Division) expression;
Value leftValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, division.getLeft(), firstRole);
Value rightValue = evaluateExpression(parentObject, validationKind, usageScope, iomObj, division.getRight(), firstRole);
if (leftValue.skipEvaluation() || rightValue.skipEvaluation())
return Value.createSkipEvaluation();
if (leftValue.isUndefined() || rightValue.isUndefined())
return Value.createUndefined();

return new Value(leftValue.getNumeric() / rightValue.getNumeric());
} else if(expression instanceof Constant){
// constant
Constant constantObj = (Constant) expression;
Expand Down Expand Up @@ -1959,6 +2015,9 @@ public Value getValueFromObjectPath(IomObject parentObject,IomObject iomObjStart
}
}
if (currentObjects.size() == 1) {
if (type instanceof NumericType){
return new Value(Double.valueOf(attrValue));
}
return new Value(type, attrValue);
} else {
String[] attrValues = new String[currentObjects.size()];
Expand Down
15 changes: 15 additions & 0 deletions src/test/data/validator/Expressions.ili
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
INTERLIS 2.4;

MODEL ModelA AT "http://www.interlis.ch/ili2c/tests/" VERSION "1" =
TOPIC TopicA =
CLASS ClassA =
attr1 : 10 .. 20 ;
attr2 : 10 .. 20 ;
MANDATORY CONSTRAINT CheckImplication: (attr1 > 15) => (attr2 > 15);
MANDATORY CONSTRAINT CheckAddition: (attr1 + attr2) > 30;
MANDATORY CONSTRAINT CheckSubtraction: (attr1 - attr2) < 10;
MANDATORY CONSTRAINT CheckMultiplication: (attr1 * attr2) > 200;
MANDATORY CONSTRAINT CheckDivision: (attr1 / attr2) >= 1;
END ClassA;
END TopicA;
END ModelA.
139 changes: 139 additions & 0 deletions src/test/java/ch/interlis/iox_j/validator/ExpressionsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package ch.interlis.iox_j.validator;

import ch.ehi.basics.settings.Settings;
import ch.interlis.ili2c.config.Configuration;
import ch.interlis.ili2c.config.FileEntry;
import ch.interlis.ili2c.config.FileEntryKind;
import ch.interlis.ili2c.metamodel.TransferDescription;
import ch.interlis.iom_j.Iom_jObject;
import ch.interlis.iox_j.EndBasketEvent;
import ch.interlis.iox_j.EndTransferEvent;
import ch.interlis.iox_j.ObjectEvent;
import ch.interlis.iox_j.StartBasketEvent;
import ch.interlis.iox_j.StartTransferEvent;
import ch.interlis.iox_j.logging.LogEventFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;

public class ExpressionsTest {

private TransferDescription td;
private LogCollector logger;
private Validator validator;
@Before
public void setUp() throws Exception {
Configuration ili2cConfig = new Configuration();
FileEntry fileEntry = new FileEntry("src/test/data/validator/Expressions.ili", FileEntryKind.ILIMODELFILE);
ili2cConfig.addFileEntry(fileEntry);
td=ch.interlis.ili2c.Ili2c.runCompiler(ili2cConfig);
assertNotNull(td);

ValidationConfig validationConfig = new ValidationConfig();
logger=new LogCollector();
LogEventFactory errFactory = new LogEventFactory();
Settings settings = new Settings();
validator = new Validator(td, validationConfig,logger,errFactory,settings);

validator.validate(new StartTransferEvent());
validator.validate(new StartBasketEvent("ModelA.TopicA", "b1"));
}

private void CloseBasketAndValidate(){
validator.validate(new EndBasketEvent());
validator.validate(new EndTransferEvent());
}

private void AddClassAObject(Integer attr1, Integer attr2){
Iom_jObject object = new Iom_jObject("ModelA.TopicA.ClassA", java.util.UUID.randomUUID().toString());
if(attr1 != null)
object.addattrvalue("attr1", attr1.toString());

if (attr2 != null)
object.addattrvalue("attr2", attr2.toString());

validator.validate(new ObjectEvent(object));
}

private void AssertLogErrorContains(int count, String text){
int counter = 0;
for (int i = 0; i < logger.getErrs().size(); i++) {
if (logger.getErrs().get(i).getEventMsg().contains(text)){
counter++;
}
}
Assert.assertEquals(String.format("Unexpected number of errors containing <%s>", text), count, counter);
}

@Test
public void Implication_OK(){
AddClassAObject(10, 10);
AddClassAObject(20, 20);
CloseBasketAndValidate();
AssertLogErrorContains(0, "CheckImplication");
}

@Test
public void Implication_Fail(){
AddClassAObject(20, 10);
CloseBasketAndValidate();
AssertLogErrorContains(1, "CheckImplication");
}

@Test
public void Addition_OK(){
AddClassAObject(20, 20);
CloseBasketAndValidate();
AssertLogErrorContains(0, "CheckAddition");
}

@Test
public void Addition_Fail(){
AddClassAObject(10, 10);
CloseBasketAndValidate();
AssertLogErrorContains(1, "CheckAddition");
}

@Test
public void Subtraction_OK(){
AddClassAObject(20, 15);
CloseBasketAndValidate();
AssertLogErrorContains(0, "CheckSubtraction");
}

@Test
public void Subtraction_Fail(){
AddClassAObject(20, 10);
CloseBasketAndValidate();
AssertLogErrorContains(1, "CheckSubtraction");
}

@Test
public void Multiplication_OK(){
AddClassAObject(20, 20);
CloseBasketAndValidate();
AssertLogErrorContains(0, "CheckMultiplication");
}

@Test
public void Multiplication_Fail(){
AddClassAObject(10, 10);
CloseBasketAndValidate();
AssertLogErrorContains(1, "CheckMultiplication");
}

@Test
public void Division_OK(){
AddClassAObject(20, 10);
CloseBasketAndValidate();
AssertLogErrorContains(0, "CheckDivision");
}

@Test
public void Division_Fail(){
AddClassAObject(10, 15);
CloseBasketAndValidate();
AssertLogErrorContains(1, "CheckDivision");
}
}