/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2003-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.data; import java.io.IOException; import java.util.NoSuchElementException; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.Filter; /** * Filtering is performed on this hasNext() method. * * <p> * This implementation writes out content furing the hasNext() method. This * allows the implementation to "peek" ahead. * </p> * * <p> * This FeatureWriter does not support the addition of new content. * </p> * * @author Jody Garnett, Refractions Research * * @source $URL$ */ public class FilteringFeatureWriter implements FeatureWriter<SimpleFeatureType, SimpleFeature> { FeatureWriter<SimpleFeatureType, SimpleFeature> writer; Filter filter; SimpleFeature next = null; // next feature as peeked by hasNext() SimpleFeature current = null; // holds current Feature returned to user public FilteringFeatureWriter(FeatureWriter<SimpleFeatureType, SimpleFeature> writer, Filter filter) { this.writer = writer; this.filter = filter; } public SimpleFeatureType getFeatureType() { return writer.getFeatureType(); } public SimpleFeature next() throws IOException { if (hasNext()) { // use hasNext() to and peek ahead // current = next; next = null; return current; } // FilteringFeatureWriter Does not support the creation // of new content throw new NoSuchElementException( "FeatureWriter does not have additional content"); } public void remove() throws IOException { if (writer == null) { throw new IOException("FeatureWriter has been closed"); } if (current == null) { // We do not have a current Feature // Either: // - we have not started yet // - hasNext() has already skipped current // - write() has already writen current // - remove() has already deleted current throw new IOException("No feature available to remove"); } current = null; writer.remove(); } public void write() throws IOException { if (writer == null) { throw new IOException("FeatureWriter has been closed"); } if (current == null) { // We do not have a current Feature // Either: // - we have not started yet // - hasNext() has already skipped current // - write() has already writen current // - remove() has already deleted current throw new IOException("No feature available to write"); } writer.write(); current = null; } /** * Query if we have more content. * * @return true if writer has additional content * * @throws IOException If writer we are filtering encounters a problem */ public boolean hasNext() throws IOException { if (next != null) { return true; // we found next already } if (writer == null) { return false; // writer is closed } if (current != null) { // we are skipping ahead, the user will lose // any changes to current current = null; } SimpleFeature peek; while (writer.hasNext()) { peek = writer.next(); if (filter.evaluate(peek)) { next = peek; return true; // we have a match! } } return false; } public void close() throws IOException { if (writer != null) { writer.close(); writer = null; } if (filter != null) { filter = null; } current = null; next = null; } }