示例#1
0
  /** Evaluate isUnique expression. */
  protected final Value evalIsUnique(EvalContext ctx) {
    // evaluate range
    Value v = fRangeExp.eval(ctx);
    if (v.isUndefined()) return UndefinedValue.instance;
    CollectionValue rangeVal = (CollectionValue) v;

    // collect values for finding duplicates
    Set<Value> values = new HashSet<Value>();

    // loop over range elements
    for (Value elemVal : rangeVal) {

      // bind element variable to range element, if variable was
      // declared
      if (!fElemVarDecls.isEmpty()) ctx.pushVarBinding(fElemVarDecls.varDecl(0).name(), elemVal);

      // evaluate collect expression
      Value val = fQueryExp.eval(ctx);

      if (!fElemVarDecls.isEmpty()) ctx.popVarBinding();

      // stop if duplicate element is found
      if (values.contains(val)) return BooleanValue.FALSE;
      else values.add(val);
    }

    // result is true if no duplicates where found
    return BooleanValue.TRUE;
  }
示例#2
0
  /** Evaluate collect expressions. */
  protected final Value evalCollectNested(EvalContext ctx) {
    // evaluate range
    Value v = fRangeExp.eval(ctx);
    if (v.isUndefined()) return UndefinedValue.instance;
    CollectionValue rangeVal = (CollectionValue) v;

    // prepare result value
    ArrayList<Value> resValues = new ArrayList<Value>();

    // loop over range elements
    for (Value elemVal : rangeVal) {

      // bind element variable to range element, if variable was
      // declared
      if (!fElemVarDecls.isEmpty()) ctx.pushVarBinding(fElemVarDecls.varDecl(0).name(), elemVal);

      // evaluate collect expression
      Value val = fQueryExp.eval(ctx);

      // add element to result
      resValues.add(val);

      if (!fElemVarDecls.isEmpty()) ctx.popVarBinding();
    }

    // result is collection with mapped values
    if (fRangeExp.type().isSequence() || fRangeExp.type().isOrderedSet())
      return new SequenceValue(fQueryExp.type(), resValues);
    else return new BagValue(fQueryExp.type(), resValues);
  }
示例#3
0
  /**
   * Evaluate exists and forAll expressions. The array <code>moreElemVars</code> may be null if
   * there is at most one element variable declared.
   */
  protected final Value evalExistsOrForAll(EvalContext ctx, boolean doExists) {
    // evaluate range
    Value v = fRangeExp.eval(ctx);
    if (v.isUndefined()) return UndefinedValue.instance;
    CollectionValue rangeVal = (CollectionValue) v;

    // we need recursion for the permutation of assignments of
    // range values to all element variables.
    boolean res = evalExistsOrForAll0(0, rangeVal, ctx, doExists);
    return BooleanValue.get(res);
  }
示例#4
0
  @Override
  public Value eval(EvalContext ctx, Value[] args, Type resultType) {
    ScriptEngineManager m = new ScriptEngineManager();
    ScriptEngine rubyEngine = m.getEngineByName("jruby");

    if (rubyEngine == null)
      throw new RuntimeException("Did not find the ruby engine. Please verify your classpath");

    ScriptContext context = rubyEngine.getContext();
    context.setErrorWriter(new NullWriter());

    context.setAttribute(
        "self", RubyHelper.useValueToRubyValue(args[0]), ScriptContext.ENGINE_SCOPE);

    for (int i = 0; i < parameter.size(); i++) {
      context.setAttribute(
          parameter.get(i).getName(),
          RubyHelper.useValueToRubyValue(args[i + 1]),
          ScriptContext.ENGINE_SCOPE);
    }

    try {
      Object result = rubyEngine.eval(operationBody, context);
      Value resultValue = RubyHelper.rubyValueToUseValue(result, resultType);

      // Wrong result type!
      if (!resultValue.type().isSubtypeOf(this.resultType)) {
        Log.warn(
            "Extension method `"
                + name
                + "' returned wrong type! Expected `"
                + this.resultType.toString()
                + "' got `"
                + resultValue.type().toString()
                + "'");
        return UndefinedValue.instance;
      } else {
        return resultValue;
      }

    } catch (ScriptException e) {
      Log.error(e.getMessage());
    } catch (EvalFailedException e) {
      Log.error(e.getMessage());
    }

    return UndefinedValue.instance;
  }
示例#5
0
  /** Evaluate sortedBy expressions. */
  protected final Value evalSortedBy(EvalContext ctx) {
    // evaluate range
    Value v = fRangeExp.eval(ctx);
    if (v.isUndefined()) return UndefinedValue.instance;
    CollectionValue rangeVal = (CollectionValue) v;

    ArrayList<KeyValPair> keyValList = new ArrayList<KeyValPair>();

    // loop over range elements
    for (Value elemVal : rangeVal) {

      // bind element variable to range element, if variable was
      // declared
      if (!fElemVarDecls.isEmpty()) ctx.pushVarBinding(fElemVarDecls.varDecl(0).name(), elemVal);

      // evaluate sortedBy expression and store the result as a
      // key together with elemVal
      Value key = fQueryExp.eval(ctx);
      keyValList.add(new KeyValPair(key, elemVal));

      if (!fElemVarDecls.isEmpty()) ctx.popVarBinding();
    }

    // sort elements by key
    Collections.sort(
        keyValList,
        new Comparator<KeyValPair>() {
          public int compare(KeyValPair o1, KeyValPair o2) {
            return o1.fKey.compareTo(o2.fKey);
          }
        });

    // drop the keys from the list
    ListIterator<KeyValPair> listIter = keyValList.listIterator();
    Collection<Value> result = new ArrayList<Value>(keyValList.size());

    while (listIter.hasNext()) {
      KeyValPair kvp = listIter.next();
      result.add(kvp.fElem);
    }

    Type rangeElemType = ((CollectionType) fRangeExp.type()).elemType();
    return new SequenceValue(rangeElemType, result);
  }
示例#6
0
  /** Evaluate select and reject expressions. */
  protected final Value evalSelectOrReject(EvalContext ctx, boolean doSelect) {
    // evaluate range
    Value v = fRangeExp.eval(ctx);
    if (v.isUndefined()) return UndefinedValue.instance;
    CollectionValue rangeVal = (CollectionValue) v;

    // prepare result value
    ArrayList<Value> resValues = new ArrayList<Value>();
    Type elemType = rangeVal.elemType();
    if (!rangeVal.type().isInstantiableCollection())
      throw new RuntimeException("rangeVal is not of collection type: " + rangeVal.type());

    // loop over range elements
    for (Value elemVal : rangeVal) {

      // bind element variable to range element, if variable was
      // declared
      if (!fElemVarDecls.isEmpty()) ctx.pushVarBinding(fElemVarDecls.varDecl(0).name(), elemVal);

      // evaluate select expression
      Value queryVal = fQueryExp.eval(ctx);

      // undefined query values default to false
      if (queryVal.isUndefined()) queryVal = BooleanValue.FALSE;

      if (((BooleanValue) queryVal).value() == doSelect) resValues.add(elemVal);

      if (!fElemVarDecls.isEmpty()) ctx.popVarBinding();
    }

    CollectionValue res;
    if (rangeVal.type().isSet()) res = new SetValue(elemType, resValues);
    else if (rangeVal.type().isSequence()) res = new SequenceValue(elemType, resValues);
    else if (rangeVal.type().isBag()) res = new BagValue(elemType, resValues);
    else if (rangeVal.type().isOrderedSet()) res = new OrderedSetValue(elemType, resValues);
    else {
      // should not happen
      throw new RuntimeException("rangeVal is not of collection type: " + rangeVal.type());
    }
    // result is collection with selected/rejected values
    return res;
  }
示例#7
0
  private final boolean evalExistsOrForAll0(
      int nesting, CollectionValue rangeVal, EvalContext ctx, boolean doExists) {
    // loop over range elements
    boolean res = !doExists;

    for (Value elemVal : rangeVal) {

      // bind element variable to range element, if variable was
      // declared
      if (!fElemVarDecls.isEmpty())
        ctx.pushVarBinding(fElemVarDecls.varDecl(nesting).name(), elemVal);

      if (!fElemVarDecls.isEmpty() && nesting < fElemVarDecls.size() - 1) {
        // call recursively to iterate over range while
        // assigning each value to each element variable
        // eventually
        if (res != doExists) res = evalExistsOrForAll0(nesting + 1, rangeVal, ctx, doExists);
        else
          // don't change the result value when expression is true
          // (exists) or
          // false (forAll) and continue iteration
          evalExistsOrForAll0(nesting + 1, rangeVal, ctx, doExists);
      } else {
        // evaluate predicate expression
        Value queryVal = fQueryExp.eval(ctx);

        // undefined query values default to false
        if (queryVal.isUndefined()) queryVal = BooleanValue.FALSE;

        // don't change the result value when expression is true
        // (exists) or
        // false (forAll) and continue iteration
        if (res != doExists && ((BooleanValue) queryVal).value() == doExists) res = doExists;
      }

      if (!fElemVarDecls.isEmpty()) ctx.popVarBinding();
    }

    return res;
  }