Class ValidationRSQLVisitor

java.lang.Object
in.co.akshitbansal.springwebquery.ast.ValidationRSQLVisitor
All Implemented Interfaces:
cz.jirutka.rsql.parser.ast.RSQLVisitor<Void,NodeMetadata>

public class ValidationRSQLVisitor extends Object implements cz.jirutka.rsql.parser.ast.RSQLVisitor<Void,NodeMetadata>
Validates a parsed RSQL abstract syntax tree against the active query rules and collects DTO-to-entity selector mappings for later predicate construction.

This visitor is the bridge between syntactic parsing and executable query generation. It walks the parsed RSQL tree once and performs the validation that depends on application-specific metadata rather than on parser syntax alone. In particular, it is responsible for:

  • rejecting logical operators that are disabled for the current query
  • enforcing a maximum AST depth
  • mapping DTO-facing selector paths to entity paths
  • validating that the terminal DTO field permits the requested comparison operator
  • recording the successful selector mappings for downstream predicate conversion

The visitor is stateful and intended for validating a single parsed tree. During traversal it accumulates selector mappings in fieldMappings. Those mappings are later consumed by the predicate converter so that a query written against the DTO contract can be executed against entity attributes.

Depth handling is zero-based. The root node is typically visited with depth 0, and each child node is visited with its parent's depth plus one. A node is rejected only when its depth is strictly greater than the configured maximum depth.

  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the DTO-to-entity selector mappings discovered so far during traversal.
    @Nullable Void
    visit(@NonNull cz.jirutka.rsql.parser.ast.AndNode node, @NonNull NodeMetadata metadata)
    Validates a logical AND node and then recursively visits its children.
    @Nullable Void
    visit(@NonNull cz.jirutka.rsql.parser.ast.ComparisonNode node, @NonNull NodeMetadata metadata)
    Validates a comparison node, resolves its selector path, and records the resulting entity mapping for downstream predicate creation.
    @Nullable Void
    visit(@NonNull cz.jirutka.rsql.parser.ast.OrNode node, @NonNull NodeMetadata metadata)
    Validates a logical OR node and then recursively visits its children.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • getFieldMappings

      public Map<String,String> getFieldMappings()
      Returns the DTO-to-entity selector mappings discovered so far during traversal.

      Only successfully validated comparison selectors are added to this map. Logical nodes do not contribute entries. The returned value is an unmodifiable view keyed by the original DTO selector string, with each value containing the entity path that should be used for predicate construction.

      If the same DTO selector appears multiple times in the query, later visits replace earlier entries for the same key. In practice the mapping is deterministic for a given DTO/entity pair, so repeated selectors still resolve to the same entity path.

      Returns:
      unmodifiable view of the collected selector mappings
    • visit

      public @Nullable Void visit(@NonNull @NonNull cz.jirutka.rsql.parser.ast.AndNode node, @NonNull @NonNull NodeMetadata metadata)
      Validates a logical AND node and then recursively visits its children.

      This method first validates the current node's logical operator and depth. If validation succeeds, each child is visited with a NodeMetadata instance whose depth is one greater than the current node's depth.

      Specified by:
      visit in interface cz.jirutka.rsql.parser.ast.RSQLVisitor<Void,NodeMetadata>
      Parameters:
      node - logical AND node to validate
      metadata - traversal metadata for the current node
      Returns:
      always null
      Throws:
      QueryForbiddenLogicalOperatorException - if AND is disabled for the current query
      QueryMaxASTDepthExceededException - if this node exceeds the configured maximum depth
    • visit

      public @Nullable Void visit(@NonNull @NonNull cz.jirutka.rsql.parser.ast.OrNode node, @NonNull @NonNull NodeMetadata metadata)
      Validates a logical OR node and then recursively visits its children.

      This method follows the same traversal pattern as visit(AndNode, NodeMetadata): it validates the current node first and then visits each child at the next depth level.

      Specified by:
      visit in interface cz.jirutka.rsql.parser.ast.RSQLVisitor<Void,NodeMetadata>
      Parameters:
      node - logical OR node to validate
      metadata - traversal metadata for the current node
      Returns:
      always null
      Throws:
      QueryForbiddenLogicalOperatorException - if OR is disabled for the current query
      QueryMaxASTDepthExceededException - if this node exceeds the configured maximum depth
    • visit

      public @Nullable Void visit(@NonNull @NonNull cz.jirutka.rsql.parser.ast.ComparisonNode node, @NonNull @NonNull NodeMetadata metadata)
      Validates a comparison node, resolves its selector path, and records the resulting entity mapping for downstream predicate creation.

      The validation flow for a comparison node is:

      1. validate the current node's depth
      2. extract the DTO selector and requested comparison operator
      3. map the DTO selector to an entity path
      4. validate that the terminal DTO field allows the requested operator
      5. store the successful selector-to-entity mapping

      No predicate is created here. This visitor only validates the request and gathers the metadata needed by later query construction steps.

      Specified by:
      visit in interface cz.jirutka.rsql.parser.ast.RSQLVisitor<Void,NodeMetadata>
      Parameters:
      node - comparison node to validate
      metadata - traversal metadata for the current node
      Returns:
      always null
      Throws:
      QueryMaxASTDepthExceededException - if this node exceeds the configured maximum depth
      QueryFieldValidationException - if the selector is invalid or filtering is not permitted on the terminal DTO field
      QueryForbiddenOperatorException - if the terminal DTO field does not allow the requested operator
      QueryConfigurationException - if the DTO selector resolves but maps to an invalid entity path