[Geoserver-devel] (GEOS-328) Parsing More Than 2 Levels of Logic Filters

I fixed this - your comment in the email was correct. Please test!

I also went through and documented the class. I turned the 3 lines of
comments in the orinal file to the comments included below.

I must say the state of documentation in open source projects (and
probably most close-source) is almost always awful. I find it very
annoying and time-wasting.

dave

*
* DJB: okay, there's no where near enough comments in here to
understand whats going on. Hopefully I'm correct.
* I've looked at this for a bit, and this is what I can figure
out.
*
* This is called by the FilterFilter class (nice name...NOT)
which is also a sax parser-like class.
* Basically, the FilterFilter does most of the Filter parsing -
but it hands most of the work off to the
* appropriate classes. For NOT, AND, OR clauses, this class is
used.
*
* As a simple example, <filter> <OR> [STATE_NAME = 'NY']
[STATE_NAME = 'WA'] </OR></FILTER>
* Or, in long form:
* <Filter>
* <Or>
* <PropertyIsEqualTo>
* <PropertyName>STATE_NAME</PropertyName>
* <Literal>NY</Literal>
* </PropertyIsEqualTo>
* <PropertyIsEqualTo>
* <PropertyName>STATE_NAME</PropertyName>
* <Literal>WA</Literal>
* </PropertyIsEqualTo>
* </Or>
* </Filter>
*
* The "PropertyIsEqualTo" is handled by another parser, so we dont
have to worry about it here for the moment.
*
* So, the order of events are like this:
*
*
* start( "OR" )
* add([STATE_NAME = 'NY']) // these are handled by another class
* add([STATE_NAME = 'WA']) // these are handled by another class
* end ("OR")
* create() // this creates an actual Filter [[
STATE_NAME = NY ] OR [ STATE_NAME = WA ]]
*
* This is pretty simple, but it gets more complex when you have
nested structures.
*
*
* <Filter>
* <And>
* <Or>
* <PropertyIsEqualTo>
* <PropertyName>STATE_NAME</PropertyName>
* <Literal>NY</Literal>
* </PropertyIsEqualTo>
* <PropertyIsEqualTo>
* <PropertyName>STATE_NAME</PropertyName>
* <Literal>WA</Literal>
* </PropertyIsEqualTo>
* </Or>
* <PropertyIsEqualTo>
* <PropertyName>STATE_NAME</PropertyName>
* <Literal>BC</Literal>
* </PropertyIsEqualTo>
* </And>
* </Filter>
*
* Again, we're going to ignore the "PropertyIsEqualTo" stuff since
its handled elsewhere.
*
* The main idea is that there will be a LogicSAXParser for the
top-level "AND" and another one
* for the nested "OR". It gets a bit harder to describe because
the classes start passing events
* to each other.
*
* start("AND") -- the parent LogicSAXParser starts to construct
an "AND" filter
* start("OR") -- the "AND" parser sees that its sub-element is
another logic operator.
* It makes another LogicSAXParser that will
handle the "OR" SAX events.
* add([STATE_NAME = 'NY']) -- this is sent to the "AND" parser.
It then sends it to the "OR" parser.
* + "OR" parser remembers this
component
* add([STATE_NAME = 'WA']) -- this is sent to the "AND" parser.
It then sends it to the "OR" parser.
* + "OR" parser remembers this
component
* end("OR") -- this is sent to the "AND" parser. It then sends
it to the "OR" parser.
* + The "OR" parser marks itself as
complete
* + The "AND" parser notices that its
child is completed parsing
* + The "AND" parser calls create() on the
"OR" parser to make a filter (see next step)
* + Since "OR" is finished, "AND" stop
passing events to it.
* "OR".create() -- makes a "[[ STATE_NAME = NY ] OR [ STATE_NAME
= WA ]]" and "AND" remembers it as a component
* add ([ STATE_NAME = BC ]) --This is added as a component to
the "AND" filter.
* end ("AND") -- the "AND" parser marks itself as complete
* create() -- the "AND" parser creates a FILTER [[[
STATE_NAME = NY ] OR [ STATE_NAME = WA ]] AND [ STATE_NAME = BC ]]
*
*
* Higher levels of nesting work the same way - each level will
send the event down to the next level.
*
* If logicFilter == null then this object is the one doing the
processing. If its non-null, then
* the sub-object is doing the processing - event are sent to it.
*

----------------------------------------------------------
This mail sent through IMP: https://webmail.limegroup.com/