Example #1
0
 public void visitExprConstraintDescr(final ExprConstraintDescr descr) {
   this.template =
       "<expr>"
           + XmlDumper.eol
           + StringUtils.escapeXmlString(descr.getExpression())
           + XmlDumper.eol
           + "</expr>";
   //        if ( !descr.getRestrictions().isEmpty() ) {
   //            this.template = "<field-constraint field-name=\"" + descr.getFieldName() + "\"> "
   // + XmlDumper.eol + processFieldConstraint( descr.getRestrictions() ) + XmlDumper.eol +
   // "</field-constraint>";
   //        }
 }
  @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());
  }