/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.filter; import java.io.StringReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.AssertionFailedError; import junit.framework.TestCase; import org.geotools.gml.GMLFilterDocument; import org.geotools.gml.GMLFilterGeometry; import org.geotools.util.logging.Logging; import org.xml.sax.InputSource; import org.xml.sax.helpers.ParserAdapter; import org.xml.sax.helpers.XMLFilterImpl; public class FilterFilterTest extends TestCase { public static void testWithoutFunction() throws Exception { String filter = "<wfs:GetFeature service=\"WFS\" version=\"1.0.0\" " + "outputFormat=\"GML2\" " + "xmlns:topp=\"http://www.openplans.org/topp\" " + "xmlns:wfs=\"http://www.opengis.net/wfs\" " + "xmlns:ogc=\"http://www.opengis.net/ogc\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd\">" + "<wfs:Query typeName=\"topp:states\">" + "<Filter xmlns=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\">" + "<And>" + "<Intersects>" + "<PropertyName>the_geom</PropertyName>" + "<gml:Polygon>" + "<gml:outerBoundaryIs>" + "<gml:LinearRing><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-99.79800943339099,30.41833858217994 -99.79800943339099,30.71813913408305 -99.49820888148788,30.71813913408305 -99.49820888148788,30.41833858217994 -99.79800943339099,30.41833858217994</gml:coordinates>" + "</gml:LinearRing>" + "</gml:outerBoundaryIs>" + "</gml:Polygon>" + "</Intersects>" + "<BBOX><PropertyName>the_geom</PropertyName>" + "<gml:Box><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-124.731422,24.955967 -66.969849,49.371735</gml:coordinates></gml:Box>" + "</BBOX>" + "</And>" + "</Filter>" + "</wfs:Query>" + "</wfs:GetFeature>"; StringReader reader = new StringReader( filter ); InputSource requestSource = new InputSource(reader); // instantiante parsers and content handlers MyHandler contentHandler = new MyHandler(); FilterFilter filterParser = new FilterFilter(contentHandler, null); GMLFilterGeometry geometryFilter = new GMLFilterGeometry(filterParser); GMLFilterDocument documentFilter = new GMLFilterDocument(geometryFilter); // read in XML file and parse to content handler SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ParserAdapter adapter = new ParserAdapter(parser.getParser()); adapter.setContentHandler(documentFilter); adapter.parse(requestSource); assertEquals(contentHandler.filters.size(),1); LogicFilterImpl f = (LogicFilterImpl) contentHandler.filters.get(0); List sub = f.getSubFilters(); assertEquals(2,sub.size()); Filter f1 = (Filter) sub.get(0); Filter f2 = (Filter) sub.get(1); assertEquals(FilterType.GEOMETRY_INTERSECTS,f1.getFilterType()); assertEquals(FilterType.GEOMETRY_BBOX, f2.getFilterType()); } public void testWithFunction() throws Exception { String filter = "<wfs:GetFeature service=\"WFS\" version=\"1.0.0\" " + "outputFormat=\"GML2\" " + "xmlns:topp=\"http://www.openplans.org/topp\" " + "xmlns:wfs=\"http://www.opengis.net/wfs\" " + "xmlns:ogc=\"http://www.opengis.net/ogc\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd\">" + "<wfs:Query typeName=\"topp:states\">" + "<Filter xmlns=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\">" + "<Or>" + "<And>" + "<Intersects>" + "<PropertyName>the_geom</PropertyName>" + "<gml:Polygon>" + "<gml:outerBoundaryIs>" + "<gml:LinearRing><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-99.79800943339099,30.41833858217994 -99.79800943339099,30.71813913408305 -99.49820888148788,30.71813913408305 -99.49820888148788,30.41833858217994 -99.79800943339099,30.41833858217994</gml:coordinates>" + "</gml:LinearRing>" + "</gml:outerBoundaryIs>" + "</gml:Polygon>" + "</Intersects>" + "<BBOX><PropertyName>the_geom</PropertyName>" + "<gml:Box><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-124.731422,24.955967 -66.969849,49.371735</gml:coordinates></gml:Box>" + "</BBOX>" + "</And>" + "<PropertyIsEqualTo>" + "<Function name=\"geometryType\"><PropertyName>the_geom</PropertyName></Function>" + "<Literal>Point</Literal>" + "</PropertyIsEqualTo>" + "</Or>" + "</Filter>" + "</wfs:Query>" + "</wfs:GetFeature>"; StringReader reader = new StringReader( filter ); InputSource requestSource = new InputSource(reader); // instantiante parsers and content handlers MyHandler contentHandler = new MyHandler(); FilterFilter filterParser = new FilterFilter(contentHandler, null); GMLFilterGeometry geometryFilter = new GMLFilterGeometry(filterParser); GMLFilterDocument documentFilter = new GMLFilterDocument(geometryFilter); // read in XML file and parse to content handler SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ParserAdapter adapter = new ParserAdapter(parser.getParser()); adapter.setContentHandler(documentFilter); adapter.parse(requestSource); assertEquals(contentHandler.filters.size(),1); } public void testWithFunction2() throws Exception { String filter = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+ "<sld:StyledLayerDescriptor xmlns:sld=\"http://www.opengis.net/sld\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\" version=\"1.0.0\">"+ "<sld:UserLayer>"+ "<sld:LayerFeatureConstraints>"+ "<sld:FeatureTypeConstraint/>"+ "</sld:LayerFeatureConstraints>"+ "<sld:UserStyle>"+ "<sld:FeatureTypeStyle>"+ "<sld:FeatureTypeName>Feature</sld:FeatureTypeName>"+ "<sld:Rule>"+ "<ogc:Filter>"+ "<ogc:PropertyIsEqualTo>"+ "<ogc:Function name=\"geometryType\">"+ "<ogc:PropertyName>the_geom</ogc:PropertyName>"+ "</ogc:Function>"+ "<ogc:Literal>Point</ogc:Literal>"+ "</ogc:PropertyIsEqualTo>"+ "</ogc:Filter>"+ "<sld:PointSymbolizer>"+ "</sld:PointSymbolizer>"+ "</sld:Rule>"+ "<sld:Rule>"+ "<ogc:Filter>"+ "<ogc:PropertyIsEqualTo>"+ "<ogc:Function name=\"geometryType\">"+ "<ogc:PropertyName>the_geom</ogc:PropertyName>"+ "</ogc:Function>"+ "<ogc:Literal>MultiPoint</ogc:Literal>"+ "</ogc:PropertyIsEqualTo>"+ "</ogc:Filter>"+ "<sld:PointSymbolizer>"+ "</sld:PointSymbolizer>"+ "</sld:Rule>"+ "</sld:FeatureTypeStyle>"+ "</sld:UserStyle>"+ "</sld:UserLayer>"+ "</sld:StyledLayerDescriptor>"; StringReader reader = new StringReader( filter ); InputSource requestSource = new InputSource(reader); // instantiante parsers and content handlers MyHandler contentHandler = new MyHandler(); FilterFilter filterParser = new FilterFilter(contentHandler, null); GMLFilterGeometry geometryFilter = new GMLFilterGeometry(filterParser); GMLFilterDocument documentFilter = new GMLFilterDocument(geometryFilter); // Logger logger = Logging.getLogger("org.geotools.filter"); // logger.setLevel(Level.ALL); // ConsoleHandler consoleHandler = new ConsoleHandler(); // consoleHandler.setLevel(Level.ALL); // logger.addHandler(consoleHandler); // read in XML file and parse to content handler SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ParserAdapter adapter = new ParserAdapter(parser.getParser()); adapter.setContentHandler(documentFilter); adapter.parse(requestSource); // assertEquals(contentHandler.filters.size(),1); } /** * As for GEOT-821, this test ensures that the filter parser makes proper use * of the characters(...) method in ContentHandler to not truncate the content * of attribute names * * @throws Exception */ public void testLargeFilter() throws Exception{ final int filterCount = 100; String filter = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<GetFeature xmlns=\"http://www.opengis.net/wfs\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" version=\"1.0.0\" service=\"WFS\" outputFormat=\"GML2\"><Query typeName=\"topp:roadevent_pnt\"><ogc:PropertyName>roadeventid</ogc:PropertyName>" + "<ogc:Filter>" + "<ogc:Or>"; for(int i = 0; i < filterCount; i++){ StringBuffer attName = new StringBuffer(); for(int repCount = 0; repCount <= i; repCount++){ attName.append("eventtype-" + repCount + "_"); } filter += "<ogc:PropertyIsEqualTo><ogc:PropertyName>" + attName + "</ogc:PropertyName>" + "<ogc:Literal>literal-" + i + "</ogc:Literal>" + "</ogc:PropertyIsEqualTo>"; } filter += "</ogc:Or>" + "</ogc:Filter>" + "</Query>" + "</GetFeature>"; StringReader reader = new StringReader( filter ); InputSource requestSource = new InputSource(reader); // instantiante parsers and content handlers MyHandler contentHandler = new MyHandler(); FilterFilter filterParser = new FilterFilter(contentHandler, null); GMLFilterGeometry geometryFilter = new GMLFilterGeometry(filterParser); GMLFilterDocument documentFilter = new GMLFilterDocument(geometryFilter); Logger logger = Logging.getLogger("org.geotools.filter"); logger.setLevel(Level.INFO); ConsoleHandler consoleHandler = new ConsoleHandler(); consoleHandler.setLevel(Level.INFO); logger.addHandler(consoleHandler); // read in XML file and parse to content handler SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ParserAdapter adapter = new ParserAdapter(parser.getParser()); adapter.setContentHandler(documentFilter); adapter.parse(requestSource); assertEquals(1, contentHandler.filters.size()); Filter f = (Filter)contentHandler.filters.get(0); assertTrue(f instanceof LogicFilter); assertEquals(FilterType.LOGIC_OR, f.getFilterType()); int i = 0; for(Iterator filters = ((LogicFilter)f).getFilterIterator(); filters.hasNext(); i++){ CompareFilter subFitler = (CompareFilter)filters.next(); StringBuffer attName = new StringBuffer(); for(int repCount = 0; repCount <= i; repCount++){ attName.append("eventtype-" + repCount + "_"); } String parsedName = ((AttributeExpression)subFitler.getLeftValue()).getAttributePath(); try{ assertEquals("at index " + i, attName.toString(), parsedName); }catch(AssertionFailedError e){ Logging.getLogger("org.geotools.filter").warning("expected " + attName + ",\n but was " + parsedName); throw e; } assertEquals("literal-" + i, ((LiteralExpression)subFitler.getRightValue()).getLiteral()); } assertEquals(filterCount, i); } static class MyHandler extends XMLFilterImpl implements FilterHandler { public List filters = new ArrayList(); public void filter(org.opengis.filter.Filter filter) { filters.add(filter); } } }