For bonus points did you read the page :-) The final answer is one line: - Set set = (Set) myFilter.accept( new FilterAttributeExtractor(), null );
There are several implementations of this idea around (one in DataUtilities as well). Jody Farber, Saul (EEA) wrote: > 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
