/
Parsing Filters

Parsing Filters

Overview

According to the OGC Filter Specification (04-095), a "(filter expression) representation can be...parsed and then transformed into whatever target language is required to retrieve or modify object instances stored in some persistent object store." Filters can be thought of as the WHERE clause for a SQL SELECT statement to "fetch data stored in a SQL-based relational database" (04-095). 

Sources can parse OGC Filters using the FilterAdapter and FilterDelegate.  See Developing a Filter Delegate for more details on implementing a new FilterDelegate.  This is the preferred way to handle OGC Filters in a consistent manner.

Alternately, org.opengis.filter.Filter implementations can be parsed using implementations of the interface org.opengis.filter.FilterVisitor. The FilterVisitor uses the Visitor pattern. Essentially FilterVisitor instances "visit" each part of the Filter tree allowing developers to implement logic to handle the Filter's operations. Geotools 8 includes implementations of the FilterVisitor interface. The DefaultFilterVisitor, as an example, provides only business logic to visit every node in the Filter tree.  The DefaultFilterVisitor methods are meant to be overwritten with the correct business logic.  The simplest approach when using FilterVisitor instances is to build the appropriate query syntax for a target language as each part of the Filter is visited. For instance, when given an incoming Filter object to be evaluated against a RDBMS, a CatalogProvider instance could use a FilterVisitor to interpret each filter operation on the Filter object and translate those operations into SQL.  The FilterVisitor might be needed to support Filter functionality not currently handled by the FilterAdapter and FilterDelegate reference implementation.

Examples

Interpreting a filter to create SQL

If the FilterAdapter encountered or "visited" a PropertyIsLike filter with its property assigned as title and its literal expression assigned as mission, the FilterDelegate could create the proper SQL syntax similar to 

title LIKE mission
Figure Parsing-Filters1

 

Interpreting a filter to create XQuery

If the FilterAdapter encountered an OR filter such as in Figure Parsing-Filters2 and the target language was XQuery, then the FilterDelegate could yield an expression such as 

ft:query(//inventory:book/@subject,'math') union ft:query(//inventory:book/@subject,'science')

Figure Parsing-Filters2
FilterAdapter/Delegate Process for Figure Parsing-Filters2
  1. FilterAdapter visits the OR Filter first.
  2. OR Filter visits its children in a loop. 
  3. The first child in the loop that is encountered is the LHS PropertyIsLike.
  4. The FilterAdapter will call the FilterDelegate PropertyIsLike method with the LHS property and literal.

  5. The LHS PropertyIsLike delegate method builds the XQuery syntax that makes sense for this particular underlying object store. In this case, the subject property is specific to this XML database, and the business logic maps the subject property to its index at //inventory:book/@subject. Note that ft:query in this instance is a custom XQuery module for this specific XML database that does full text searches.

  6. The FilterAdapter then moves back to the OR Filter which visits its second child.
  7. The FilterAdapter will call the FilterDelegate PropertyIsLike method with the RHS property and literal.
  8. The RHS PropertyIsLike delegate method builds the XQuery syntax that makes sense for this particular underlying object store. In this case, the subject property is specific to this XML database, and the business logic maps the subject property to its index at //inventory:book/@subjectNote that ft:query in this instance is a custom XQuery module for this specific XML database that does full text searches.
  9. The FilterAdapter then moves back to its OR Filter which is now done with its children.

  10. It then collects the output of each child and and sends the list of results to the FilterDelegate OR method.
  11. The final result object will be returned from the FilterAdapter adapt method.

FilterVisitor Process for Figure Parsing-Filters2
  1. FilterVisitor visits the OR Filter first.
  2. OR Filter visits its children in a loop. 
  3. The first child in the loop that is encountered is the LHS PropertyIsLike.
  4. The LHS PropertyIsLike builds the XQuery syntax that makes sense for this particular underlying object store. In this case, the subject property is specific to this XML database, and the business logic maps the subject property to its index at //inventory:book/@subject. Note that ft:query in this instance is a custom XQuery module for this specific XML database that does full text searches.

  5. The FilterVisitor then moves back to the OR Filter which visits its second child.
  6. The RHS PropertyIsLike builds the XQuery syntax that makes sense for this particular underlying object store. In this case, the subject property is specific to this XML database, and the business logic maps the subject property to its index at //inventory:book/@subject. Note that ft:query in this instance is a custom XQuery module for this specific XML database that does full text searches.
  7. The FilterVisitor then moves back to its OR Filter which is now done with its children. It then collects the output of each child and could potentially execute the following code to produce the above expression

    public visit( Or filter, Object data) {
    ... 
       /* the equivalent statement for the OR filter in this domain (XQuery) */
       xQuery = childFilter1Output + " union " + childFilter2Output;
    ... 
    }