001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.wfs.kvp;
006:
007: import org.geoserver.ows.KvpParser;
008: import org.geoserver.ows.util.KvpUtils;
009: import org.geotools.filter.FilterFilter;
010: import org.geotools.filter.v1_0.OGCConfiguration;
011: import org.geotools.gml.GMLFilterDocument;
012: import org.geotools.gml.GMLFilterGeometry;
013: import org.geotools.xml.Configuration;
014: import org.geotools.xml.Parser;
015: import org.opengis.filter.Filter;
016: import org.vfny.geoserver.ServiceException;
017: import org.vfny.geoserver.util.requests.FilterHandlerImpl;
018: import org.vfny.geoserver.util.requests.readers.XmlRequestReader;
019: import org.xml.sax.InputSource;
020: import org.xml.sax.SAXException;
021: import org.xml.sax.helpers.ParserAdapter;
022: import java.io.ByteArrayInputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.io.Reader;
026: import java.io.StringReader;
027: import java.util.ArrayList;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.logging.Level;
031: import javax.xml.parsers.ParserConfigurationException;
032: import javax.xml.parsers.SAXParser;
033: import javax.xml.parsers.SAXParserFactory;
034:
035: public class FilterKvpParser extends KvpParser {
036: public FilterKvpParser() {
037: super ("filter", List.class);
038: }
039:
040: public Object parse(String value) throws Exception {
041: //create the parser
042: Configuration configuration = new OGCConfiguration();
043: Parser parser = new Parser(configuration);
044:
045: //seperate the individual filter strings
046: List unparsed = KvpUtils.readFlat(value,
047: KvpUtils.OUTER_DELIMETER);
048: List filters = new ArrayList();
049:
050: Iterator i = unparsed.listIterator();
051:
052: while (i.hasNext()) {
053: String string = (String) i.next();
054: if ("".equals(string.trim())) {
055: filters.add(Filter.INCLUDE);
056: } else {
057: InputStream input = new ByteArrayInputStream(string
058: .getBytes());
059:
060: try {
061: Filter filter = (Filter) parser.parse(input);
062:
063: if (filter == null) {
064: throw new NullPointerException();
065: }
066:
067: filters.add(filter);
068: } catch (Exception e) {
069: //parsing failed, fall back to old parser
070: String msg = "Unable to parse filter: " + string;
071: LOGGER.log(Level.WARNING, msg, e);
072:
073: Filter filter = parseXMLFilterWithOldParser(new StringReader(
074: string));
075:
076: if (filter != null) {
077: filters.add(filter);
078: }
079: }
080: }
081: }
082:
083: return filters;
084: }
085:
086: /**
087: * Reads the Filter XML request into a geotools Feature object.
088: * <p>
089: * This uses the "old" filter parser and is around to maintain some
090: * backwards compatability with cases in which the new parser chokes on a
091: * filter that hte old one could handle.
092: * </p>
093: *
094: * @param rawRequest The plain POST text from the client.
095: *
096: * @return The geotools filter constructed from rawRequest.
097: *
098: * @throws WfsException For any problems reading the request.
099: */
100: protected Filter parseXMLFilterWithOldParser(Reader rawRequest)
101: throws ServiceException {
102: // translate string into a proper SAX input source
103: InputSource requestSource = new InputSource(rawRequest);
104:
105: // instantiante parsers and content handlers
106: FilterHandlerImpl contentHandler = new FilterHandlerImpl();
107: FilterFilter filterParser = new FilterFilter(contentHandler,
108: null);
109: GMLFilterGeometry geometryFilter = new GMLFilterGeometry(
110: filterParser);
111: GMLFilterDocument documentFilter = new GMLFilterDocument(
112: geometryFilter);
113:
114: // read in XML file and parse to content handler
115: try {
116: SAXParserFactory factory = SAXParserFactory.newInstance();
117: SAXParser parser = factory.newSAXParser();
118: ParserAdapter adapter = new ParserAdapter(parser
119: .getParser());
120:
121: adapter.setContentHandler(documentFilter);
122: adapter.parse(requestSource);
123: LOGGER.fine("just parsed: " + requestSource);
124: } catch (SAXException e) {
125: throw new ServiceException(e,
126: "XML getFeature request SAX parsing error",
127: XmlRequestReader.class.getName());
128: } catch (IOException e) {
129: throw new ServiceException(e,
130: "XML get feature request input error",
131: XmlRequestReader.class.getName());
132: } catch (ParserConfigurationException e) {
133: throw new ServiceException(e,
134: "Some sort of issue creating parser",
135: XmlRequestReader.class.getName());
136: }
137:
138: LOGGER.fine("passing filter: " + contentHandler.getFilter());
139:
140: return contentHandler.getFilter();
141: }
142: }
|