/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014-2015, 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.store; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; import org.geotools.data.FeatureReader; import org.geotools.data.FeatureWriter; import org.geotools.data.Query; import org.geotools.data.simple.SimpleFeatureReader; import org.geotools.data.simple.SimpleFeatureWriter; import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.LineString; public abstract class AbstractContentTest { /** * Mock feature type name. */ protected static final Name TYPENAME = new NameImpl("http://www.geotools.org", "Mock"); /** * Mock feature type. */ protected static final SimpleFeatureType TYPE = buildType(); /** * The list of features on which paging is tested. */ @SuppressWarnings("serial") List<SimpleFeature> FEATURES = new ArrayList<SimpleFeature>() { { add(buildFeature("mock.3")); add(buildFeature("mock.1")); add(buildFeature("mock.2")); } }; /** * Build the test type. */ protected static SimpleFeatureType buildType() { SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.setName(TYPENAME); builder.add("geom", LineString.class); return builder.buildFeatureType(); } /** * Build a test feature with the specified id. */ protected static SimpleFeature buildFeature(String id) { SimpleFeatureBuilder builder = new SimpleFeatureBuilder(TYPE); builder.add(new Envelope(0, 1, 0, 1)); return builder.buildFeature(id); } /** * {@link ContentDataStore} for the test features. * */ protected class MockContentDataStore extends ContentDataStore { { namespaceURI = TYPE.getName().getNamespaceURI(); } /** * @see org.geotools.data.store.ContentDataStore#createTypeNames() */ @SuppressWarnings("serial") @Override protected List<Name> createTypeNames() throws IOException { return new ArrayList<Name>() { { add(TYPENAME); } }; } /** * @see org.geotools.data.store.ContentDataStore#createFeatureSource(org.geotools.data.store.ContentEntry) */ @Override protected ContentFeatureSource createFeatureSource(ContentEntry entry) throws IOException { return new MockContentFeatureStore(entry, null); } } /** * {@link ContentFeatureSource} that returns the test features. */ @SuppressWarnings("unchecked") protected class MockContentFeatureStore extends ContentFeatureStore { public MockContentFeatureStore(ContentEntry entry, Query query) { super(entry, query); } /** * Not implemented. */ @Override protected ReferencedEnvelope getBoundsInternal(Query query) throws IOException { throw new UnsupportedOperationException(); } /** * Not implemented. */ @Override protected int getCountInternal(Query query) throws IOException { if (query.getFilter() == Filter.INCLUDE) { int count = 0; FeatureReader<SimpleFeatureType, SimpleFeature> featureReader = getReaderInternal(query); try { while (featureReader.hasNext()) { featureReader.next(); count++; } } finally { featureReader.close(); } return count; } return -1; } /** * @see org.geotools.data.store.ContentFeatureSource#getReaderInternal(org.geotools.data.Query) */ @Override protected FeatureReader<SimpleFeatureType, SimpleFeature> getReaderInternal(Query query) throws IOException { return new MockSimpleFeatureReader(); } /** * @see org.geotools.data.store.ContentFeatureSource#buildFeatureType() */ @Override protected SimpleFeatureType buildFeatureType() throws IOException { return TYPE; } @Override protected FeatureWriter<SimpleFeatureType, SimpleFeature> getWriterInternal(Query query, int flags) throws IOException { return new MockSimpleFeatureWriter(); } } /** * Decorate the list of test features as a {@link SimpleFeatureReader}. */ protected class MockSimpleFeatureReader implements SimpleFeatureReader { /** * Index of the next test feature to be returned. */ private int index = 0; /** * @see org.geotools.data.FeatureReader#getFeatureType() */ @Override public SimpleFeatureType getFeatureType() { return TYPE; } /** * @see org.geotools.data.FeatureReader#next() */ @Override public SimpleFeature next() throws IOException, IllegalArgumentException, NoSuchElementException { return FEATURES.get(index++); } /** * @see org.geotools.data.FeatureReader#hasNext() */ @Override public boolean hasNext() throws IOException { return index < FEATURES.size(); } /** * @see org.geotools.data.FeatureReader#close() */ @Override public void close() throws IOException { // ignored } } /** * Decorate the list of test features as a {@link SimpleFeatureReader}. */ protected class MockSimpleFeatureWriter implements SimpleFeatureWriter { /** * Index of the next test feature to be returned. */ private int index = 0; SimpleFeature newFeature; @Override public SimpleFeatureType getFeatureType() { return TYPE; } @Override public SimpleFeature next() throws IOException { if (index >= FEATURES.size()) { newFeature = buildFeature("mock." + (++index)); return newFeature; } return FEATURES.get(index++); } @Override public void remove() throws IOException { if (index > 0 && index <= FEATURES.size()) { SimpleFeature feature = FEATURES.remove(index - 1); } } @Override public void write() throws IOException { if (index > FEATURES.size()) { FEATURES.add(newFeature); } } @Override public boolean hasNext() throws IOException { return index < FEATURES.size(); } @Override public void close() throws IOException { // ignored } } }