Good to hear from you too Jody!
 
I actually was knee-deep in DefaultFilterVisitor when I wrote that email, and 
yet still managed to miss the fact that I could have written that visitor 
exactly as you wrote.
 
I can only blame a lack of coffee.  Thank you much for that pointer!
 
--saul
 
 

________________________________

From: Jody Garnett [mailto:[EMAIL PROTECTED]
Sent: Thu 8/2/2007 5:55 PM
To: Farber, Saul (EEA)
Cc: [email protected]
Subject: Re: [Geotools-devel] DefaultFilterVisitor improvements



Hi Saul - good to hear from you.

For your specific case you will want to implement both a FilterVisitor
and an ExpressionVisitor, by using the a default implementation that has
all the methods stubbed you should be able to reduce your code example
to a single method.

The example you provided has been done a lot in the GeoTools code base
by different developers;
- http://docs.codehaus.org/display/GEOTDOC/FilterVisitor+Examples

Here is the example from that page:
> class FindNames extends DefaultFilterVisitor {
>     public Object visit( PropertyName expression, Object data ) {
>         Set set = (Set) data;
>         set.add( expression.getPropertyName() );
>        
>         return set;
>     }
> }
> Set set = (Set) myFilter.accept( new FindNames(), new HashSet() );
Cheers,
Jody


Farber, Saul (EEA) wrote:
> Hey all,
> 
> I've been writing a little filtervisitor today, just to run through a filter 
> and collect some pertinent information.
> 
> Problem is, that 'little' filtervisitor is actually enormous, because there's 
> not type-generalization built into DefaultFilterVisitor.
> 
> Suppose I want to collect all the PropertyNames from a filter (so I can 
> figure out if someone has provided a filter but not asked for the 
> propertyname in their query).  I write a little filtervisitor to check every 
> node of the filter and if it's a PropertyName expression, grab the property 
> name.
> 
> My class gets really big really quick:
> 
> Filter f = ...
> FilterVisitor pnCollector = new DefaultFilterVisitor() {
>   public Object visit(And a, Object o) {
>     Iterator ichildren = a.getChildren().iterator();
>     while (ichildren.hasNext()) {
>       ((Filter)ichildren.next()).accept(this, o);
>     }
>     return null;
>   }
> 
>   public Object visit (Or o, Object o) {
>      //duplicate method body of And, or else call to a shared function
>   }
> 
>   public Object visit (PropertyIsEqualTo p, Object o) {
>     p.getExpression1().accept(this, o);
>     p.getExpression2().accept(this, o);
>   }
> 
>   public Object visit(<every other BinaryComparisonOperator> p, Object o) {
>     //call to shared function that looks a lot like the above visit 
> PropIsEqualTo...
>   }
> 
>   public Object visit(<every BinarySpatialOperator> so, Object o) {
>     //call to shared function from EVERY binaryspatialoperator...
>   }
> 
>   ... etc ...
> 
> };
> f.accept(pnCollector);
> 
> 
> That's a long implementation that could be considerably shoretened by 
> including a few convenience methods in DefaultFilterVisitor.
> 
> I propose the addition of methods like this:
> 
> public Object visit (BinarySpatialOperator o, Object o) {
> ...
> }
> 
> and
> 
> public Object visit (BinaryComparisonOperator o, Object o) {
> ...
> }
> 
> and
> 
> public Object visit (Filter f, Object o) {
> ...
> }
> 
> and so on (for all the various intermediate interfaces in between 
> org.opengis.filter.Filter and org.opengis.filter.<leaf-filter-types>, up-to 
> and including Filter itself)
> 
> 
> 
> Further, I propose that DefaultFilterVisitor change its implementation of  
> 'public visit(<Leaf-filter-type> f, Object o)' to call the 'next up the 
> chain' interface.  So, for example, the DefaultFilterVisitor impl of 
> 'visit(Touches f, Object o)' would look like:
> 
> public Object visit(Touches t, Object o) {
>   return visit((BinarySpatialOperator)t, o);
> }
> 
> also, visit(bso) would look like:
> public Object visit(BinarySpatialOperator f, Object o) {
>   return visit((SpatialOperator)f, o);
> }
> 
> etc.
> 
> All the way up to Filter, for each type.
> 
> 
> This would make those writing FilterVisitors have to write MUCH MUCH less 
> code, and would allow for good type-based dispatching by allowing someone to 
> interact with EXACTLY the bits of the filter that they're interested in with 
> much less code.
> 
> 
> If this is a bit confusing for DefaultFilterVisitor, perhaps this could go 
> into a DefaultFilterVisitor subclass?  Perhaps 'HierarchicalFilterVisitor' or 
> something?
> 
> 
> I chatted with aaime about this, and his only concern was that those using 
> IDEs might be lead astray by having to only implement ONE filter callback 
> method (visit(Filter f, Object o)) and just use a big switch statement.  I 
> agree this is a risk, but perhaps could be alleviated with good documentation.
> 
> 
> Thoughts anyone?
> 
> --saul
> 
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems?  Stop.
> Now Search log events and configuration files using AJAX and a browser.
> Download your FREE copy of Splunk now >>  http://get.splunk.com/
> _______________________________________________
> Geotools-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/geotools-devel
>  





-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
Geotools-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to