Uploaded image for project: 'Hippo Site Toolkit 2'
  1. Hippo Site Toolkit 2
  2. HSTTWO-3835

Better compile time guidance of the fluent query api

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 4.1.0
    • Component/s: None
    • Labels:
      None
    • Similar issues:
    • Processed by team:
      Platform
    • Sprint:
      Platform Sprint 140, Platform Sprint 141

      Description

      The fluent query api can compile time better support the user.

      For example in the testsuite, I had the following code:

                  ConstraintBuilder constraint;
      
                  if (drqc == null) {
                      constraint = constraint(".").contains(parsedQuery);
                  } else {
                      constraint =
                              and(
                                      constraint(".").contains(parsedQuery),
                                      // below on purpose not between because drqc.getFromDate() or drqc.getToDate() can be
                                      // null. #between expects both values not to be null
                                      constraint(drqc.getProperty()).greaterOrEqualThan(drqc.getFromDate(), drqc.getResolution()),
                                      constraint(drqc.getProperty()).lessOrEqualThan(drqc.getToDate(), drqc.getResolution())
                              );
                  }
      
                  HstQuery hstQuery = HstQueryBuilder.create(scope)
                          .ofTypes(nodeType)
                          .where(
                                  constraint
                          )
                          .limit(pageSize)
                          .offset(offset)
                          .orderByDescending(sortBy)
                          .build();
      

      The problem is in the argument of the #where method. Imho, it shouldn't take a ConstraintBuilder as argument, but a Constraint. It doesn't make sense that after I have for example created a constraint via

          constraint = constraint(".").contains(parsedQuery);
      

      that I can still invoke other methods (like #equalTo).

      Hence, I thought the ConstraintBuilder should look as follows:

          public static FieldConstraintBuilder constraint(String fieldName) {
              FieldConstraintBuilder fieldConstraintBuilder = new FieldConstraintBuilder(fieldName);
              return fieldConstraintBuilder;
          }
      
          public static Constraint and(Constraint ... constraints) {
              AndConstraint andConstraint = new AndConstraint(constraints);
              return andConstraint;
          }
      
          public static Constraint or(Constraint ... constraints) {
              OrConstraint orConstraint = new OrConstraint(constraints);
              return orConstraint;
          }
      

      FieldConstraintBuilder in turn has all the methods like #equalTo, #contains, etc. Those methods return as well the object Constraint. On Constraint, end users can only invoke #negate().

      Then, the earlier code from the Testsuite becomes this:

                  Constraint constraint;
      
                  if (drqc == null) {
                      constraint = constraint(".").contains(parsedQuery);
                  } else {
                      constraint =
                              and(
                                      constraint(".").contains(parsedQuery),
                                      // below on purpose not between because drqc.getFromDate() or drqc.getToDate() can be
                                      // null. #between expects both values not to be null
                                      constraint(drqc.getProperty()).greaterOrEqualThan(drqc.getFromDate(), drqc.getResolution()),
                                      constraint(drqc.getProperty()).lessOrEqualThan(drqc.getToDate(), drqc.getResolution())
                              );
                  }
      
                  HstQuery hstQuery = HstQueryBuilder.create(scope)
                          .ofTypes(nodeType)
                          .where(constraint)
                          .limit(pageSize)
                          .offset(offset)
                          .orderByDescending(sortBy)
                          .build();
      

      It looks very similar, but the big difference is that the #where methods get a Constraint object, and that

      and (
            ............
       )
      

      also returns a Constraint Object instead of a ConstraintBuilder

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                aschrijvers Ard Schrijvers
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: