/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 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 org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.filter.Filter; import org.geotools.feature.SchemaException; /** * Represents a Physical Store for FeatureTypes. * * <p> * The source of data for FeatureTypes. Shapefiles, databases tables, etc. are * referenced through this interface. * </p> * * <p> * Summary of our requirements: * </p> * * <ul> * <li> * Provides lookup of available Feature Types * </li> * <li> * Provides access to low-level Readers/Writers API for a feature type * </li> * <li> * Provides access to high-level FeatureSource/Store/Locking API a feature type * </li> * <li> * Handles the conversion of filters into data source specific queries * </li> * <li> * Handles creation of new Feature Types * </li> * <li> * Provides access of Feature Type Schema information * </li> * </ul> * * Suggestions: * * <ul> * <li>GeoAPI - has reduced this to api to the FeatureStore construct * Jody - since we are no longer using the FeatureReader/ReaderWriter in client * code this would not be a bad idea. * </li> * </ul> * * @author Jody Garnett, Refractions Research * @source $URL$ * @version $Id$ */ public interface DataStore extends DataAccess<SimpleFeatureType, SimpleFeature>{ /** * Used to force namespace and CS info into a persistent change. * <p> * The provided featureType should completely cover the existing schema. * All attributes should be accounted for and the typeName should match. * </p> * <p> * Suggestions: * </p> * <ul> * <li>Sean - don't do this</li> * <li>Jody - Just allow changes to metadata: CS, namespace, and others</li> * <li>James - Allow change/addition of attribtues</li> * </ul> * @param typeName * @throws IOException */ void updateSchema(String typeName, SimpleFeatureType featureType) throws IOException; /** * Retrieves a list of of the available FeatureTypes. * * <p> * This is simply a list of the FeatureType names as aquiring the actual * FeatureType schemas may be expensive. * </p> * * <p> * Warning: this list may not be unique - the types may be * in separate namespaces. * </p> * * <p> * If you need to worry about such things please consider the use of * the Catalog and CatalogEntry interface - many DataStores support this. * getTypeNames is really a convience method for a Catalog.iterator() where * the name of each entry is returned. * </p> * * @return typeNames for available FeatureTypes. */ String[] getTypeNames() throws IOException; /** * Retrieve FeatureType metadata by <code>typeName</code>. * * <p> * Retrieves the Schema information as a FeatureType object. * </p> * * @param typeName typeName of requested FeatureType * * @return FeatureType for the provided typeName * * @throws IOException If typeName cannot be found */ SimpleFeatureType getSchema(String typeName) throws IOException; /** * Access a FeatureSource<SimpleFeatureType, SimpleFeature> for Query providing a high-level API. * <p> * The provided Query does not need to completely cover the existing * schema for Query.getTypeName(). The result will mostly likely only be * a FeatureSource<SimpleFeatureType, SimpleFeature> and probably wont' allow write access by the * FeatureStore method. * </p> * <p> * By using Query we allow support for reprojection, in addition * to overriding the CoordinateSystem used by the native FeatureType. * </p> * <p> * We may wish to limit this method to only support Queries using * Filter.EXCLUDE. * </p> * <p> * Update - GeoServer has an elegatent implementation of this functionality * that we could steal. GeoServerFeatureSource, GeoServerFeatureStore and * GeoServerFeatureLocking serve as a working prototype. * </p> * @param query Query.getTypeName() locates FeatureType being viewed * * @return FeatureSource<SimpleFeatureType, SimpleFeature> providing operations for featureType * @throws IOException If FeatureSource<SimpleFeatureType, SimpleFeature> is not available * @throws SchemaException If fetureType is not covered by existing schema */ FeatureSource<SimpleFeatureType, SimpleFeature> getView(Query query) throws IOException, SchemaException; /** * Access a FeatureSource<SimpleFeatureType, SimpleFeature> for typeName providing a high-level API. * * <p> * The resulting FeatureSource<SimpleFeatureType, SimpleFeature> may implment more functionality: * </p> * <pre><code> * * FeatureSource<SimpleFeatureType, SimpleFeature> fsource = dataStore.getFeatureSource( "roads" ); * FeatureStore fstore = null; * if( fsource instanceof FeatureLocking ){ * fstore = (FeatureStore<SimpleFeatureType, SimpleFeature>) fs; * } * else { * System.out.println("We do not have write access to roads"); * } * </code> * </pre> * * @param typeName * * @return FeatureSource<SimpleFeatureType, SimpleFeature> (or subclass) providing operations for typeName */ FeatureSource<SimpleFeatureType, SimpleFeature> getFeatureSource(String typeName) throws IOException; /** * Access a FeatureReader providing access to Feature information. * * <p> * <b>Filter</b> is used as a low-level indication of constraints. * (Implementations may resort to using a FilteredFeatureReader, or * provide their own optimizations) * </p> * * <p> * <b>FeatureType</b> provides a template for the returned FeatureReader * </p> * * <ul> * <li> * featureType.getTypeName(): used by JDBC as the table reference to query * against. Shapefile reader may need to store a lookup to the required * filename. * </li> * <li> * featureType.getAttributeTypes(): describes the requested content. This * may be a subset of the complete FeatureType defined by the DataStore. * </li> * <li> * getType.getNamespace(): describes the requested namespace for the * results (may be different then the one used internally) * </li> * </ul> * * <p> * <b>Transaction</b> to externalize DataStore state on a per Transaction * basis. The most common example is a JDBC datastore saving a Connection * for use across several FeatureReader requests. Similarly a Shapefile * reader may wish to redirect FeatureReader requests to a alternate * filename over the course of a Transaction. * </p> * * <p> * <b>Notes For Implementing DataStore</b> * </p> * * <p> * Subclasses may need to retrieve additional attributes, beyond those * requested by featureType.getAttributeTypes(), in order to correctly * apply the <code>filter</code>.<br> * These Additional <b>attribtues</b> should be not be returned by * FeatureReader. Subclasses may use ReTypeFeatureReader to aid in * acomplishing this. * </p> * <p> * Helper classes for implementing a FeatureReader (in order): * </p> * <ul> * <li> * DefaultFeatureReader * - basic support for creating a FeatureReader for an AttributeReader * </li> * <li> * FilteringFeatureReader * - filtering support * </li> * <li> * DiffFeatureReader * - In-Process Transaction Support (see TransactionStateDiff) * </li> * <li> * ReTypeFeatureReader * - Feature Type schema manipulation of namesspace and attribute type subsets * </li> * <li> * EmptyFeatureReader * - provides no content for Filter.EXCLUDE optimizations * </li> * </ul> * <p> * Sample use (not optimized): * </p> * <pre><code> * if (filter == Filter.EXCLUDE) { * return new EmptyFeatureReader(featureType); * } * * String typeName = featureType.getTypeName(); * FeatureType schema = getSchema( typeName ); * FeatureReader reader = new DefaultFeatureReader( getAttributeReaders(), schema ); * * if (filter != Filter.INCLUDE) { * reader = new FilteringFeatureReader<SimpleFeatureType, SimpleFeature>(reader, filter); * } * * if (transaction != Transaction.AUTO_COMMIT) { * Map diff = state(transaction).diff(typeName); * reader = new DiffFeatureReader(reader, diff); * } * * if (!featureType.equals(reader.getFeatureType())) { * reader = new ReTypeFeatureReader(reader, featureType); * } * return reader * </code></pre> * <p> * Locking support does not need to be provided for FeatureReaders. * </p> * * @param query Requested form of the returned Features and the filter used * to constraints the results * @param transaction Transaction this query operates against * * @return FeatureReader Allows Sequential Processing of featureType */ FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(Query query, Transaction transaction) throws IOException; /** * Access FeatureWriter for modification of existing DataStore contents. * * <p> * To limit FeatureWriter to the FeatureTypes defined by this DataStore, * typeName is used to indicate FeatureType. The resulting * feature writer will allow modifications against the * same FeatureType provided by getSchema( typeName ) * </p> * * <p> * The FeatureWriter will provide access to the existing contents of the * FeatureType referenced by typeName. The provided filter will be used * to skip over Features as required. * </p> * * <b>Notes For Implementing DataStore</b> * </p> * * <p> * The returned FeatureWriter <b>does not</b> support the addition of new * Features to FeatureType (it would need to police your modifications to * agree with <code>filer</code>). As such it will return * <code>false</code> for getNext() when it reaches the end of the Query * and NoSuchElementException when next() is called. * </p> * * <p> * Helper classes for implementing a FeatureWriter (in order): * </p> * <li> * InProcessLockingManager.checkedWriter( writer ) * - provides a check against locks before allowing modification * * <li> * FilteringFeatureWriter * - filtering support for FeatureWriter (does not allow new content) * </li> * <li> * DiffFeatureWriter * - In-Process Transaction Support (see TransactionStateDiff) * </li> * <li> * EmptyFeatureWriter * - provides no content for Filter.EXCLUDE optimizations * </li> * </ul> * * @param typeName Indicates featureType to be modified * @param filter constraints used to limit the modification * @param transaction Transaction this query operates against * * @return FeatureWriter Allows Sequential Modification of featureType */ FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName, Filter filter, Transaction transaction) throws IOException; /** * Access FeatureWriter for modification of the DataStore typeName. * * <p> * FeatureWriters will need to be limited to the FeatureTypes defined by * the DataStore, the easiest way to express this limitation is to the * FeatureType by a provided typeName. * </p> * * <p> * The returned FeatureWriter will return <code>false</code> for getNext() * when it reaches the end of the Query. * </p> * * @param typeName Indicates featureType to be modified * @param transaction Transaction to operates against * * @return FeatureReader Allows Sequential Processing of featureType */ FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriter(String typeName, Transaction transaction) throws IOException; /** * Aquire a FeatureWriter for adding new content to a FeatureType. * * <p> * This FeatureWriter will return <code>false</code> for hasNext(), however * next() may be used to aquire new Features that may be writen out to add * new content. * </p> * * @param typeName Indicates featureType to be modified * @param transaction Transaction to operates against * * @return FeatureWriter that may only be used to append new content * * @throws IOException */ FeatureWriter<SimpleFeatureType, SimpleFeature> getFeatureWriterAppend(String typeName, Transaction transaction) throws IOException; /** * Retrieve a per featureID based locking service from this DataStore. * * <p> * It is common to return an instanceof InProcessLockingManager for * DataStores that do not provide native locking. * </p> * * <p> * AbstractFeatureLocking makes use of this service to provide locking * support. You are not limitied by this implementation and may simply * return <code>null</code> for this value. * </p> * * @return DataStores may return <code>null</code>, if the handling locking * in another fashion. */ LockingManager getLockingManager(); }