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