예제 #1
0
  public Query descend(final String a_field) {
    synchronized (streamLock()) {
      final QQuery query = new QQuery(_trans, _this, a_field);
      IntByRef run = new IntByRef(1);
      if (!descend1(query, a_field, run)) {

        // try to add unparented nodes on the second run,
        // if not added in the first run and a descendant
        // was not found

        if (run.value == 1) {
          run.value = 2;
          if (!descend1(query, a_field, run)) {
            new QConUnconditional(_trans, false).attach(query, a_field);
          }
        }
      }
      return query;
    }
  }
예제 #2
0
  private boolean descend1(final QQuery query, final String fieldName, IntByRef run) {
    if (run.value == 2 || i_constraints.size() == 0) {

      // On the second run we are really creating a second independant
      // query network that is not joined to other higher level
      // constraints.
      // Let's see how this works out. We may need to join networks.

      run.value = 0; // prevent a double run of this code

      stream()
          .classCollection()
          .attachQueryNode(
              fieldName,
              new Visitor4() {

                boolean untypedFieldConstraintCollected = false;

                public void visit(Object obj) {

                  Object[] pair = ((Object[]) obj);
                  ClassMetadata containingClass = (ClassMetadata) pair[0];
                  FieldMetadata field = (FieldMetadata) pair[1];

                  if (isTyped(field)) {
                    addFieldConstraint(containingClass, field);
                    return;
                  }

                  if (untypedFieldConstraintCollected) return;

                  addFieldConstraint(containingClass, field);
                  untypedFieldConstraintCollected = true;
                }

                private boolean isTyped(FieldMetadata field) {
                  return !Handlers4.isUntyped(field.getHandler());
                }

                private void addFieldConstraint(
                    ClassMetadata containingClass, FieldMetadata field) {
                  QConClass qcc =
                      new QConClass(
                          _trans, null, field.qField(_trans), containingClass.classReflector());
                  addConstraint(qcc);
                  toConstraint(i_constraints).or(qcc);
                }
              });
    }

    checkConstraintsEvaluationMode();

    final BooleanByRef foundClass = new BooleanByRef(false);
    Iterator4 i = iterateConstraints();
    while (i.moveNext()) {
      if (((QCon) i.current()).attach(query, fieldName)) {
        foundClass.value = true;
      }
    }
    return foundClass.value;
  }