Пример #1
0
 @Override
 public ValueList evaluate(RuleEvaluation evaluation, BinaryOperator statement) {
   switch (statement.getOperator()) {
     case plus:
     case minus:
     case multiply:
     case divide:
     case modulo:
     case exponent:
       return evaluateArithmeticOperator(evaluation, statement);
     case gt:
     case ge:
     case lt:
     case le:
     case eq:
     case ne:
       return evaluateRelOpOperator(evaluation, statement);
     case and:
     case or:
     case xor:
       return evaluateBooleanOperator(evaluation, statement);
     case matches:
       return evaluateBooleanConstraint(evaluation, statement);
     case implies:
       return evaluateImplies(evaluation, statement);
       // for all is not listed here; it has more information that just two operands, so it has its
       // own evaluator
       // not and exists are unary operators and not handled here
   }
   throw new RuntimeException("operation " + statement.getOperator() + " not yet supported");
 }
Пример #2
0
  private ValueList evaluateArithmeticOperator(
      RuleEvaluation evaluation, BinaryOperator statement) {
    ValueList leftValues = evaluation.evaluate(statement.getLeftOperand());
    ValueList rightValues = evaluation.evaluate(statement.getRightOperand());

    ValueList possibleNullResult = checkAndHandleNull(leftValues, rightValues);
    if (possibleNullResult != null) {
      possibleNullResult.setType(PrimitiveType.Real);
      return possibleNullResult;
    } else {
      ValueList result = new ValueList();
      result.setType(PrimitiveType.Real);

      checkIsNumber(leftValues, rightValues);
      if (leftValues.size() == rightValues.size()) {
        for (int i = 0; i < leftValues.size(); i++) {
          Value leftValue = leftValues.get(i);
          Value rightValue = rightValues.get(i);
          evaluateArithmetic(
              statement,
              result,
              rightValue.getValue(),
              leftValue.getValue(),
              getPaths(leftValue, rightValue));
        }
      } else if (leftValues.size() == 1) {
        Value leftValue = leftValues.get(0);
        for (Value rightValue : rightValues.getValues()) {
          evaluateArithmetic(
              statement,
              result,
              rightValue.getValue(),
              leftValue.getValue(),
              getPaths(leftValue, rightValue));
        }
      } else if (rightValues.size() == 1) {
        Value rightValue = rightValues.get(0);
        for (Value leftValue : leftValues.getValues()) {
          evaluateArithmetic(
              statement,
              result,
              rightValue.getValue(),
              leftValue.getValue(),
              getPaths(leftValue, rightValue));
        }
      } else {
        // TODO: this also happens when one of the modelreferences has a value that does not exist
        // in the model, but others have - while the rules are correct. Those are very valid cases
        // how to fix?
        throw new IllegalArgumentException("sizes of operator arguments not compatible");
      }
      return result;
    }
  }
Пример #3
0
 private ValueList evaluateImplies(RuleEvaluation evaluation, BinaryOperator statement) {
   ValueList leftValue = evaluation.evaluate(statement.getLeftOperand());
   if (leftValue.getSingleBooleanResult()) {
     ValueList rightValue = evaluation.evaluate(statement.getRightOperand());
     return rightValue;
   } else {
     // if the left operand evaluates to false, the entire result is true, to not violate the
     // assertion
     // not sure if this should be the case
     return new ValueList(true, leftValue.getAllPaths());
   }
 }
Пример #4
0
 private Boolean evaluateBoolean(
     BinaryOperator statement, Boolean leftBoolean, Boolean rightBoolean) {
   switch (statement.getOperator()) {
     case and:
       return leftBoolean & rightBoolean;
     case or:
       return leftBoolean | rightBoolean;
     case xor:
       return leftBoolean ^ rightBoolean;
     default:
       throw new IllegalArgumentException("Not a boolean operator: " + statement.getOperator());
   }
 }
Пример #5
0
 private ValueList evaluateBooleanConstraint(RuleEvaluation evaluation, BinaryOperator statement) {
   ValueList leftValues = evaluation.evaluate(statement.getLeftOperand());
   if (!(statement.getRightOperand() instanceof Constraint)) {
     throw new IllegalArgumentException(
         "cannot evaluate matches statement, right operand not a constraint");
   }
   Constraint constraint = (Constraint) statement.getRightOperand();
   ValueList result = new ValueList();
   result.setType(PrimitiveType.Boolean);
   for (Value value : leftValues.getValues()) {
     result.addValue(constraint.getItem().isValidValue(value.getValue()), value.getPaths());
   }
   return result;
 }
Пример #6
0
 private Value evaluateRelOp(
     BinaryOperator statement, Object leftValue, Object rightValue, List<String> paths) {
   if (leftValue == null || rightValue == null) {
     return new Value(evaluateNullRelOp(statement.getOperator(), leftValue, rightValue), paths);
   } else if (leftValue instanceof Long && rightValue instanceof Long) {
     return new Value(
         evaluateIntegerRelOp(statement.getOperator(), (Long) leftValue, (Long) rightValue),
         paths);
   } else {
     return new Value(
         evaluateRealRelOp(
             statement.getOperator(), convertToDouble(leftValue), convertToDouble(rightValue)),
         paths);
   }
 }
Пример #7
0
  private ValueList evaluateBooleanOperator(RuleEvaluation evaluation, BinaryOperator statement) {

    ValueList leftValues = evaluation.evaluate(statement.getLeftOperand());
    ValueList rightValues = evaluation.evaluate(statement.getRightOperand());

    ValueList possibleNullResult = checkAndHandleNull(leftValues, rightValues);
    if (possibleNullResult != null) {
      possibleNullResult.setType(PrimitiveType.Boolean);
      return possibleNullResult;
    }

    checkisBoolean(leftValues, rightValues);

    ValueList result = new ValueList();
    result.setType(PrimitiveType.Boolean);
    if (leftValues.size() == rightValues.size()) {
      for (int i = 0; i < leftValues.size(); i++) {
        Value<Boolean> leftValue = leftValues.get(i);
        Value<Boolean> rightValue = rightValues.get(i);
        List<String> paths = getPaths(leftValue, rightValue);
        result.addValue(
            evaluateBoolean(statement, leftValue.getValue(), rightValue.getValue()), paths);
      }
    } else if (leftValues.size() == 1) {
      Value<Boolean> leftValue = leftValues.get(0);
      for (Value<Boolean> rightValue : rightValues.getValues()) {
        List<String> paths = getPaths(leftValue, rightValue);
        result.addValue(
            evaluateBoolean(statement, leftValue.getValue(), rightValue.getValue()), paths);
      }
    } else if (rightValues.size() == 1) {
      Value<Boolean> rightValue = rightValues.get(0);
      for (Value<Boolean> leftValue : leftValues.getValues()) {
        List<String> paths = getPaths(leftValue, rightValue);
        result.addValue(
            evaluateBoolean(statement, leftValue.getValue(), rightValue.getValue()), paths);
      }
    } else {
      throw new IllegalArgumentException("sizes of operator arguments not compatible");
    }

    return result;
  }
Пример #8
0
 private void evaluateArithmetic(
     BinaryOperator statement,
     ValueList result,
     Object rightValue,
     Object leftValue,
     List<String> paths) {
   if (leftValue instanceof Long && rightValue instanceof Long) {
     result.addValue(
         evaluateIntegerArithmetic(statement.getOperator(), (Long) leftValue, (Long) rightValue),
         paths);
     result.setType(PrimitiveType.Integer);
   } else {
     result.addValue(
         evaluateRealArithmetic(
             statement.getOperator(), convertToDouble(leftValue), convertToDouble(rightValue)),
         paths);
     result.setType(PrimitiveType.Real);
   }
 }
Пример #9
0
  @NotNull
  private ValueList evaluateRelOpOperator(RuleEvaluation evaluation, BinaryOperator statement) {
    ValueList leftValues = evaluation.evaluate(statement.getLeftOperand());
    ValueList rightValues = evaluation.evaluate(statement.getRightOperand());

    ValueList possibleNullResult =
        handlePossibleNullRelOpResult(statement, leftValues, rightValues);
    if (possibleNullResult != null) {
      possibleNullResult.setType(PrimitiveType.Boolean);
      return possibleNullResult;
    } else {
      checkIsNumberOrNull(leftValues, rightValues);

      ValueList result = new ValueList();
      result.setType(PrimitiveType.Boolean);

      // according to the xpath spec, at least one pair from both collections must exist that
      // matches the condition.
      // want otherwise? Use for_all/every
      result.addValue(evaluateMultipleValuesRelOp(statement, leftValues, rightValues));

      return result;
    }
  }
Пример #10
0
 private ValueList handlePossibleNullRelOpResult(
     BinaryOperator statement, ValueList leftValues, ValueList rightValues) {
   switch (statement.getOperator()) {
     case eq:
     case ne:
       // if null, can be true or false depending on checks
       return null;
     case gt:
     case ge:
     case lt:
     case le:
       // if null, result undefined, return null
       return checkAndHandleNull(leftValues, rightValues);
     default:
       throw new IllegalStateException("unknown relop operator");
   }
 }