Class Visitor<R,A>

java.lang.Object
org.apache.sis.internal.filter.Visitor<R,A>
Type Parameters:
R - the type of resources (e.g. Feature) used as inputs.
A - type of the accumulator object where actions will write their results.
Direct Known Subclasses:
SelectionClauseWriter

public abstract class Visitor<R,A> extends Object
An executor of different actions depending on filter or expression type. Action are defined by BiConsumer where the first parameter is the filter or expression, and the second parameter is an arbitrary object used as accumulator. For example, the accumulator may be a StringBuilder where the filter is written as a SQL or CQL statement.
Relationship with the visitor pattern
This class provides similar functionalities than the "visitor pattern". The actions are defined by lambda functions in a HashMap instead of by overriding methods, but the results are similar.

Thread-safety

Visitor instances are thread-safe if protected methods are invoked at construction time only.
Since:
1.1
Version:
1.1
  • Field Details

  • Constructor Details

    • Visitor

      protected Visitor()
      Creates a new visitor.
    • Visitor

      protected Visitor(boolean hasFilters, boolean hasExpressions)
      Creates a new visitor which will accept only the specified type of objects.
      Parameters:
      hasFilters - whether this filter will accepts filters.
      hasExpressions - whether this filter will accepts expressions.
    • Visitor

      protected Visitor(Visitor<R,A> source, boolean copyFilters, boolean copyExpressions)
      Creates a new visitor initialized to the same handlers than the specified visitor. This constructor can be used for creating a copy from a template before to add or remove handlers. If any of the copy argument is false, it is caller's responsibility to not modify the corresponding map of handlers because it will be an instance shared with the source.
      Parameters:
      source - the visitor from which to copy the handlers.
      copyFilters - whether to copy the map of filter handlers.
      copyExpressions - whether to copy the map of expression handlers.
      See Also:
  • Method Details

    • getFilterHandler

      protected final BiConsumer<Filter<R>,A> getFilterHandler(Enum<?> type)
      Returns the action to execute for the given type of filter. The null type is legal and identifies the action to execute when the Filter instance is null or has a null type.
      Parameters:
      type - identification of the filter type (can be null).
      Returns:
      the action to execute when the identified filter is found, or null if none.
    • getExpressionHandler

      protected final BiConsumer<Expression<R,?>,A> getExpressionHandler(String type)
      Returns the action to execute for the given type of expression. The null type is legal and identifies the action to execute when the Expression instance is null.
      Parameters:
      type - identification of the expression type (can be null).
      Returns:
      the action to execute when the identified expression is found, or null if none.
    • setFilterHandler

      protected final void setFilterHandler(Enum<?> type, BiConsumer<Filter<R>,A> action)
      Sets the action to execute for the given type of filter. The null type is legal and identifies the action to execute when the Filter instance is null or has a null type.
      Parameters:
      type - identification of the filter type (can be null).
      action - the action to execute when the identified filter is found.
    • setFamilyHandlers

      private void setFamilyHandlers(Enum<?> lastType, BiConsumer<Filter<R>,A> action)
      Sets the same action for all member of the same family of filters. The action is set in enumeration declaration order up to the last type inclusive.
      Parameters:
      lastType - identification of the last filter type (inclusive).
      action - the action to execute when an identified filter is found.
    • setExpressionHandler

      protected final void setExpressionHandler(String type, BiConsumer<Expression<R,?>,A> action)
      Sets the action to execute for the given type of expression. The null type is legal and identifies the action to execute when the Expression instance is null.
      Parameters:
      type - identification of the expression type (can be null).
      action - the action to execute when the identified expression is found.
    • setExpressionHandlers

      private void setExpressionHandlers(BiConsumer<Expression<R,?>,A> action, String... types)
      Sets the same action to execute for the given types of expression.
      Parameters:
      action - the action to execute when the identified expression is found.
      types - identification of the expression types.
    • setLogicalHandlers

      protected final void setLogicalHandlers(BiConsumer<Filter<R>,A> action)
      Sets the same action to execute for the AND, OR and NOT types filter.
      Parameters:
      action - the action to execute when one of the enumerated filters is found.
    • setNullAndNilHandlers

      protected final void setNullAndNilHandlers(BiConsumer<Filter<R>,A> action)
      Sets the same action for both the IsNull and IsNil types of filter.
      Parameters:
      action - the action to execute when one of the enumerated filters is found.
    • setBinaryComparisonHandlers

      protected final void setBinaryComparisonHandlers(BiConsumer<Filter<R>,A> action)
      Sets the same action to execute for the <, >, ≤, ≥, = and ≠ types of filter.
      Parameters:
      action - the action to execute when one of the enumerated filters is found.
    • setBinaryTemporalHandlers

      protected final void setBinaryTemporalHandlers(BiConsumer<Filter<R>,A> action)
      Sets the same action to execute for the temporal comparison operators. The operators are AFTER, BEFORE, BEGINS, BEGUN_BY, CONTAINS, DURING, EQUALS, OVERLAPS, MEETS, ENDS, OVERLAPPED_BY, MET_BY, ENDED_BY and ANY_INTERACTS types filter.
      Parameters:
      action - the action to execute when one of the enumerated filters is found.
    • setSpatialHandlers

      protected final void setSpatialHandlers(BiConsumer<Filter<R>,A> action)
      Sets the same action to execute for the spatial comparison operators, including the ones with a distance parameter. The operators are BBOX, EQUALS, DISJOINT, INTERSECTS, TOUCHES, CROSSES, WITHIN, CONTAINS, OVERLAPS, DWITHIN and BEYOND types filter.
      Parameters:
      action - the action to execute when one of the enumerated filters is found.
    • setMathHandlers

      protected final void setMathHandlers(BiConsumer<Expression<R,?>,A> action)
      Sets the same action to execute for the +, −, × and ÷ expressions.
      Parameters:
      action - the action to execute when one of the enumerated expressions is found.
    • removeFilterHandlers

      protected final void removeFilterHandlers(Collection<? extends Enum<?>> types)
      Removes all filters of the given types. Types that have no registered handlers are ignored.
      Parameters:
      types - types of filters to remove.
    • visit

      public void visit(Filter<R> filter, A accumulator)
      Executes the registered action for the given filter. Actions are registered by calls to setFooHandler(…) before the call to this visit(…) method.

      Note on parameterized type

      This method often needs to be invoked with instances of Filter<? super R>, because this is the type of filters returned by GeoAPI methods such as LogicalOperator.getOperands(). But the parameterized type expected by this method matches the parameterized type of handlers registered by setFilterHandler(Enum, BiConsumer) and similar methods, which use the exact <R> type. This restriction exists because when doing otherwise, parameterized types become hard to express in Java (we get a cascade of super keywords, something like <? super ? super R>). However, doing the (Filter<R>) filter cast is actually safe if the handlers do not invoke any filter method having a return value (directly or indirectly as list elements) restricted to the exact <R> type. Such methods do not exist in the GeoAPI interfaces, so the cast is safe if the BiConsumer handlers do not invoke implementation-specific methods. Since only subclasses known the details of registered handlers, the decision to cast or not is left to those subclasses.
      Parameters:
      filter - the filter for which to execute an action based on its type.
      accumulator - where to write the result of all actions.
      Throws:
      UnsupportedOperationException - if there is no action registered for the given filter.
    • visit

      public void visit(Expression<R,?> expression, A accumulator)
      Executes the registered action for the given expression. Actions are registered by calls to setFooHandler(…) before the call to this visit(…) method.

      Note on parameterized type

      This method often needs to be invoked with instances of Expression<? super R, ?>, because this is the type of filters returned by GeoAPI methods such as Expression.getParameters(). But the parameterized type expected by this method matches the parameterized type of handlers registered by setExpressionHandler(String, BiConsumer) and similar methods, which use the exact <R> type. This restriction exists because when doing otherwise, parameterized types become hard to express in Java (we get a cascade of super keywords, something like <? super ? super R>). However, doing the (Expression<R>,?) expression cast is actually safe if the handlers do not invoke any expression method having a return value (directly or indirectly as list elements) restricted to the exact <R> type. Such methods do not exist in the GeoAPI interfaces, so the cast is safe if the BiConsumer handlers do not invoke implementation-specific methods. Since only subclasses known the details of registered handlers, the decision to cast or not is left to those subclasses.
      Parameters:
      expression - the expression for which to execute an action based on its type.
      accumulator - where to write the result of all actions.
      Throws:
      UnsupportedOperationException - if there is no action registered for the given expression.
    • typeNotFound

      protected void typeNotFound(Enum<?> type, Filter<R> filter, A accumulator)
      Adds the value to use or throws an exception when there is no action registered for a given filter type. The default implementation throws UnsupportedOperationException.
      Parameters:
      type - the filter type which has not been found, or null if is null.
      filter - the filter (may be null).
      accumulator - where to write the result of all actions.
      Throws:
      UnsupportedOperationException - if there is no default action.
    • typeNotFound

      protected void typeNotFound(String type, Expression<R,?> expression, A accumulator)
      Adds the value to use or throws an exception when there is no action registered for a given expression type. The default implementation throws UnsupportedOperationException.
      Parameters:
      type - the expression type which has not been found, or null if is null.
      expression - the expression (may be null).
      accumulator - where to write the result of all actions.
      Throws:
      UnsupportedOperationException - if there is no default value.