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
FilterAdapter
visits theOR Filter
first.OR
Filter visits its children in a loop.- The first child in the loop that is encountered is the LHS
PropertyIsLike.
The
FilterAdapter
will call theFilterDelegate
PropertyIsLike
method with the LHS property and literal.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 thatft:query
in this instance is a custom XQuery module for this specific XML database that does full text searches.- The
FilterAdapter
then moves back to theOR
Filter
which visits its second child. - The
FilterAdapter
will call theFilterDelegate
PropertyIsLike
method with the RHS property and literal. - 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/@subject.
Note thatft:query
in this instance is a custom XQuery module for this specific XML database that does full text searches. The
FilterAdapter
then moves back to itsOR Filter
which is now done with its children.- It then collects the output of each child and and sends the list of results to the
FilterDelegate OR
method. The final result object will be returned from the
FilterAdapter
adapt method.
FilterVisitor Process for Figure Parsing-Filters2
- FilterVisitor visits the
OR Filter
first. OR
Filter visits its children in a loop.- The first child in the loop that is encountered is the LHS
PropertyIsLike.
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 thatft:query
in this instance is a custom XQuery module for this specific XML database that does full text searches.- The FilterVisitor then moves back to the
OR
Filter
which visits its second child. - 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 thatft:query
in this instance is a custom XQuery module for this specific XML database that does full text searches. 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; ... }