Ejemplo n.º 1
0
  @SuppressWarnings("unchecked")
  public RuleConditionElement build(
      RuleBuildContext context, BaseDescr descr, Pattern prefixPattern, Query query) {
    PatternDescr patternDescr = (PatternDescr) descr;

    Declaration[] params = query.getParameters();

    List<BaseDescr> args = (List<BaseDescr>) patternDescr.getDescrs();
    List<Integer> declrIndexes = new ArrayList<Integer>();
    List<Integer> varIndexes = new ArrayList<Integer>();
    List<Object> arguments = new ArrayList<Object>(params.length);
    for (int i = 0; i < params.length; i++) {
      // as these could be set in any order, initialise first, to allow setting later.
      arguments.add(null);
    }
    List<Declaration> requiredDeclarations = new ArrayList<Declaration>();

    ObjectType argsObjectType = ClassObjectType.ObjectArray_ObjectType;
    InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class, "this");
    Pattern pattern = new Pattern(context.getNextPatternId(), 0, argsObjectType, null);

    // Deal with the constraints, both positional and bindings
    for (int i = 0, length = args.size(); i < length; i++) {
      BaseDescr base = args.get(i);

      String expression = null;
      boolean isPositional = false;
      boolean isBinding = false;
      BindingDescr bind = null;
      ConstraintConnectiveDescr result = null;
      if (base instanceof BindingDescr) {
        bind = (BindingDescr) base;
        expression =
            bind.getVariable() + (bind.isUnification() ? " := " : " : ") + bind.getExpression();
        isBinding = true;
      } else {
        if (base instanceof ExprConstraintDescr) {
          ExprConstraintDescr ecd = (ExprConstraintDescr) base;
          expression = ecd.getExpression();
          isPositional = ecd.getType() == ExprConstraintDescr.Type.POSITIONAL;

        } else {
          expression = base.getText();
        }

        result = parseExpression(context, patternDescr, expression);
        if (result == null) {
          // error, can't parse expression.
          context.addError(
              new DescrBuildError(
                  context.getParentDescr(),
                  descr,
                  null,
                  "Unable to parse constraint: \n" + expression));
          continue;
        }
        isBinding =
            result.getDescrs().size() == 1 && result.getDescrs().get(0) instanceof BindingDescr;
        if (isBinding) {
          bind = (BindingDescr) result.getDescrs().get(0);
        }
      }

      if ((!isPositional) && (!isBinding)) {
        // error, can't have non binding slots.
        context.addError(
            new DescrBuildError(
                context.getParentDescr(),
                descr,
                null,
                "Query's must use positional or bindings, not field constraints:\n" + expression));
        continue;
      } else if (isPositional && isBinding) {
        // error, can't have positional binding slots.
        context.addError(
            new DescrBuildError(
                context.getParentDescr(),
                descr,
                null,
                "Query's can't use positional bindings:\n" + expression));
        continue;
      } else if (isPositional) {
        processPositional(
            context,
            query,
            params,
            declrIndexes,
            varIndexes,
            arguments,
            requiredDeclarations,
            arrayReader,
            pattern,
            base,
            expression,
            result);
      } else {
        // it is binding
        processBinding(
            context,
            descr,
            params,
            declrIndexes,
            varIndexes,
            arguments,
            requiredDeclarations,
            arrayReader,
            pattern,
            bind,
            result);
      }
    }

    Declaration[] declrsArray =
        requiredDeclarations.toArray(new Declaration[requiredDeclarations.size()]);
    int[] declrIndexArray = new int[declrIndexes.size()];
    for (int i = 0; i < declrsArray.length; i++) {
      declrIndexArray[i] = declrIndexes.get(i);
    }
    int[] varIndexesArray = new int[varIndexes.size()];
    for (int i = 0; i < varIndexesArray.length; i++) {
      varIndexesArray[i] = varIndexes.get(i);
    }

    return new QueryElement(
        pattern,
        query.getName(),
        arguments.toArray(new Object[arguments.size()]),
        declrsArray,
        declrIndexArray,
        varIndexesArray,
        !patternDescr.isQuery());
  }
Ejemplo n.º 2
0
  private void processPositional(
      RuleBuildContext context,
      Query query,
      Declaration[] params,
      List<Integer> declrIndexes,
      List<Integer> varIndexes,
      List<Object> arguments,
      List<Declaration> requiredDeclarations,
      InternalReadAccessor arrayReader,
      Pattern pattern,
      BaseDescr base,
      String expression,
      ConstraintConnectiveDescr result) {
    int position = ((ExprConstraintDescr) base).getPosition();
    if (position >= arguments.size()) {
      context.addError(
          new DescrBuildError(
              context.getParentDescr(),
              base,
              null,
              "Unable to parse query '"
                  + query.getName()
                  + "', as postion "
                  + (position - 1)
                  + " for expression '"
                  + expression
                  + "' does not exist on query size "
                  + arguments.size()));
      return;
    }
    if (isVariable(expression)) {
      // is this already bound?
      Declaration declr = context.getDeclarationResolver().getDeclaration(query, expression);
      if (declr != null) {
        // it exists, so it's an input
        arguments.set(position, declr);
        declrIndexes.add(position);
        requiredDeclarations.add(declr);
      } else {
        // it doesn't exist, so it's an output
        arguments.set(position, Variable.v);

        varIndexes.add(position);

        declr = pattern.addDeclaration(expression);

        // this bit is different, notice its the ArrayElementReader that we wire up to, not the
        // declaration.
        ArrayElementReader reader =
            new ArrayElementReader(
                arrayReader, position, params[position].getExtractor().getExtractToClass());

        declr.setReadAccessor(reader);
      }
    } else {
      // it's an expression and thus an input
      MVELDumper.MVELDumperContext mvelCtx = new MVELDumper.MVELDumperContext();
      String rewrittenExpr =
          context.getCompilerFactory().getExpressionProcessor().dump(result, mvelCtx);
      arguments.set(position, MVEL.eval(rewrittenExpr)); // for now we just work with literals
    }
  }