From e8663e832241f72de186f843aa8f40f92d67bf15 Mon Sep 17 00:00:00 2001 From: Torben Barsballe Date: Mon, 20 Feb 2017 09:43:19 -0800 Subject: [PATCH] Migrate MultiDimDataStore to ContentDataStore Migrated from AbstractDataStore implementation. --- .../geoserver/wcs2_0/MultiDimDataStore.java | 664 ++++++++---------- .../wcs2_0/MultiDimDataStoreFactory.java | 33 +- 2 files changed, 321 insertions(+), 376 deletions(-) diff --git a/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStore.java b/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStore.java index 1f19b5c2f2f..5a540dba868 100644 --- a/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStore.java +++ b/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStore.java @@ -5,33 +5,17 @@ */ package org.geoserver.wcs2_0; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.TimeZone; -import java.util.logging.Level; -import java.util.logging.Logger; - -import org.geotools.data.AbstractDataStore; -import org.geotools.data.AbstractFeatureSource; +import com.vividsolutions.jts.geom.Envelope; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; import org.geotools.data.CollectionFeatureReader; -import org.geotools.data.DataSourceException; -import org.geotools.data.DataStore; -import org.geotools.data.DataUtilities; -import org.geotools.data.EmptyFeatureReader; -import org.geotools.data.FeatureListener; import org.geotools.data.FeatureReader; -import org.geotools.data.MaxFeatureReader; import org.geotools.data.Query; import org.geotools.data.QueryCapabilities; -import org.geotools.data.ReTypeFeatureReader; -import org.geotools.data.Transaction; -import org.geotools.data.simple.SimpleFeatureSource; -import org.geotools.feature.SchemaException; +import org.geotools.data.store.ContentDataStore; +import org.geotools.data.store.ContentEntry; +import org.geotools.data.store.ContentFeatureSource; +import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.filter.visitor.DefaultFilterVisitor; @@ -42,6 +26,7 @@ import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import org.opengis.filter.PropertyIsBetween; import org.opengis.filter.PropertyIsEqualTo; @@ -55,9 +40,16 @@ import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; -import com.vividsolutions.jts.geom.Envelope; -import com.vividsolutions.jts.geom.Geometry; -import com.vividsolutions.jts.geom.GeometryFactory; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.TimeZone; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -66,26 +58,23 @@ * @author Jeroen Dries jeroen.dries@vito.be * */ -public class MultiDimDataStore extends AbstractDataStore { +public class MultiDimDataStore extends ContentDataStore { - - - protected static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.wcs2_0"); + private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geoserver.wcs2_0"); private static final CoordinateReferenceSystem EPSG_4326; static { - CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84; - try { - crs = CRS.decode("EPSG:4326"); - } catch (FactoryException e) { - LOGGER.log(Level.WARNING, e.getMessage(), e); - } - EPSG_4326 = crs; + CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84; + try { + crs = CRS.decode("EPSG:4326"); + } catch (FactoryException e) { + LOGGER.log(Level.WARNING, e.getMessage(), e); + } + EPSG_4326 = crs; } - private static final List BAND_LIST = Arrays.asList("NDVI", "BLUE/TOC", "SWIR/VAA", "NIR/TOC", "RED/TOC", - "SWIR/TOC", "VNIR/VAA"); + "SWIR/TOC", "VNIR/VAA"); /** * The 'dim_' prefix is mandatory as per the WMS spec, and also required by @@ -94,17 +83,18 @@ public class MultiDimDataStore extends AbstractDataStore { private static final String BAND_DIMENSION = "BANDS"; private static final SimpleDateFormat PROBA_DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy"); - static{ - PROBA_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); + static { + PROBA_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); } - + + private static final Date THE_DATE = new Date(); private static final ReferencedEnvelope TOTAL_BOUNDS = new ReferencedEnvelope(10.000, 55, 40, 70, - EPSG_4326); - public static final String FILE_LOCATION_ATTRIBUTE = "fileLocation"; + EPSG_4326); + private static final String FILE_LOCATION_ATTRIBUTE = "fileLocation"; private static final String LABEL_ATTRIBUTE = "label"; - public static final String GEOMETRY_ATTRIBUTE = "geometry"; - static final String TIME_ATTRIBUTE = "timestamp"; - public static final String TYPENAME = "FlexysCoverage"; + private static final String GEOMETRY_ATTRIBUTE = "geometry"; + private static final String TIME_ATTRIBUTE = "timestamp"; + private static final String TYPENAME = "FlexysCoverage"; private static final SimpleFeatureType FEATURE_TYPE = createSchema(); private SimpleFeature feature1; @@ -112,359 +102,285 @@ public class MultiDimDataStore extends AbstractDataStore { private SimpleFeature feature2; - public MultiDimDataStore(String parentLocation) { - super(false); - GeometryFactory geometryBuilder = new GeometryFactory(); - SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); - featureBuilder.add(geometryBuilder.toGeometry(new Envelope(10, 30, 40, 70))); - - featureBuilder.add(parentLocation + "/2DLatLonCoverage.nc"); - Date theDate = new Date(); - featureBuilder.add(theDate); - featureBuilder.set(BAND_DIMENSION, "MyBand"); - featureBuilder.set(LABEL_ATTRIBUTE, "X" + 0 + "Y" + 0); - feature1 = featureBuilder.buildFeature("feature1"); - - featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); - - featureBuilder.add(geometryBuilder.toGeometry(new Envelope(35, 55, 40, 70))); - - featureBuilder.add(parentLocation + "/2DLatLonCoverage2.nc"); - featureBuilder.add(theDate); - featureBuilder.set(BAND_DIMENSION, "MyBand"); - featureBuilder.set(LABEL_ATTRIBUTE, "X" + 0 + "Y" + 0); - - feature2 = featureBuilder.buildFeature("feature2"); + MultiDimDataStore(String parentLocation) { + super(); + GeometryFactory geometryBuilder = new GeometryFactory(); + SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); + featureBuilder.add(geometryBuilder.toGeometry(new Envelope(10, 30, 40, 70))); + + featureBuilder.add(parentLocation + "/2DLatLonCoverage.nc"); + featureBuilder.add(THE_DATE); + featureBuilder.set(BAND_DIMENSION, "MyBand"); + featureBuilder.set(LABEL_ATTRIBUTE, "X" + 0 + "Y" + 0); + feature1 = featureBuilder.buildFeature("feature1"); + + featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); + + featureBuilder.add(geometryBuilder.toGeometry(new Envelope(35, 55, 40, 70))); + + featureBuilder.add(parentLocation + "/2DLatLonCoverage2.nc"); + featureBuilder.add(THE_DATE); + featureBuilder.set(BAND_DIMENSION, "MyBand"); + featureBuilder.set(LABEL_ATTRIBUTE, "X" + 0 + "Y" + 0); + + feature2 = featureBuilder.buildFeature("feature2"); } @Override - public String[] getTypeNames() throws IOException { - return new String[] { TYPENAME }; + public List createTypeNames() throws IOException { + return Collections.singletonList(new NameImpl(TYPENAME)); } @Override - public SimpleFeatureType getSchema(String typeName) throws IOException { - return FEATURE_TYPE; + public SimpleFeatureType getSchema(Name typeName) throws IOException { + return FEATURE_TYPE; } private static SimpleFeatureType createSchema() { - SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); - builder.setName(TYPENAME); + SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); + builder.setName(TYPENAME); - builder.setCRS(EPSG_4326); + builder.setCRS(EPSG_4326); - builder.setDefaultGeometry(GEOMETRY_ATTRIBUTE); - builder.setNamespaceURI("VITOEOData"); + builder.setDefaultGeometry(GEOMETRY_ATTRIBUTE); + builder.setNamespaceURI("VITOEOData"); - builder.add(GEOMETRY_ATTRIBUTE, Geometry.class); - builder.add(FILE_LOCATION_ATTRIBUTE, String.class); - builder.add(TIME_ATTRIBUTE, Date.class); - builder.add(BAND_DIMENSION, String.class); - builder.add(LABEL_ATTRIBUTE,String.class); - return builder.buildFeatureType(); + builder.add(GEOMETRY_ATTRIBUTE, Geometry.class); + builder.add(FILE_LOCATION_ATTRIBUTE, String.class); + builder.add(TIME_ATTRIBUTE, Date.class); + builder.add(BAND_DIMENSION, String.class); + builder.add(LABEL_ATTRIBUTE,String.class); + return builder.buildFeatureType(); } @Override - protected FeatureReader getFeatureReader(String typeName, Query query) - throws IOException { - - - if (query.getPropertyNames() != null && query.getPropertyNames().length == 1) { - if (query.getPropertyNames()[0].equals(TIME_ATTRIBUTE)) { - // geoserver is determining the time domain - List availableTimes = Arrays.asList(new Date()); - List features = new ArrayList(availableTimes.size()); - - int idCounter = 0; - for (Date date : availableTimes) { - SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); - featureBuilder.set(TIME_ATTRIBUTE, date); - features.add(featureBuilder.buildFeature("dummyID" + idCounter++)); - } - return wrapAndCache(features); - } - if (query.getPropertyNames()[0].equals(BAND_DIMENSION)) { - List features = new ArrayList(BAND_LIST.size()); - - int idCounter = 0; - for (String band : BAND_LIST) { - SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); - featureBuilder.set(BAND_DIMENSION, band); - features.add(featureBuilder.buildFeature("dummyID" + idCounter++)); - } - return wrapAndCache(features); - } - } - try { - final Date date = new Date(); - date.setTime(0); - - final Date beginDate = new Date(); - beginDate.setTime(0); - final Date endDate = new Date(); - endDate.setTime(0); - final List band = new ArrayList(); - - DefaultFilterVisitor filterVisitor = new DefaultFilterVisitor() { - - @Override - public Object visit(BBOX filter, Object data) { - Envelope2D envelope = (Envelope2D) data; - filter.getBounds(); - envelope.setBounds(filter.getBounds()); - return super.visit(filter, data); - } - - - - @Override - public Object visit(Intersects filter, Object data) { - Envelope2D envelope = (Envelope2D) data; - - Geometry polygon= ((Geometry)((Literal)filter.getExpression2()).getValue()); - org.opengis.geometry.Geometry polygon2 = JTSUtils.jtsToGo1(polygon, envelope.getCoordinateReferenceSystem()); - envelope.setBounds(new Envelope2D(polygon2.getEnvelope())); - return super.visit(filter, data); - } - - - - /** - * Used by WCS 2.0 to select a time range - */ - @Override - public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object data) { - PropertyName prop; - Literal lit; - if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else if (filter.getExpression2() instanceof PropertyName - && filter.getExpression1() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else { - return super.visit(filter, data); - } - if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { - if(lit.getValue()!=null){ - beginDate.setTime(((Date) lit.getValue()).getTime()); - } - } - return super.visit(filter, data); - } - - /** - * Used by WCS 2.0 to select a time range - */ - @Override - public Object visit(PropertyIsLessThanOrEqualTo filter, Object data) { - PropertyName prop; - Literal lit; - if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else if (filter.getExpression2() instanceof PropertyName - && filter.getExpression1() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else { - return super.visit(filter, data); - } - if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { - if(lit.getValue()!=null){ - endDate.setTime(((Date) lit.getValue()).getTime()); - } - } - return super.visit(filter, data); - } - - @Override - public Object visit(PropertyIsEqualTo filter, Object data) { - PropertyName prop; - Literal lit; - if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else if (filter.getExpression2() instanceof PropertyName - && filter.getExpression1() instanceof Literal) { - prop = (PropertyName) filter.getExpression1(); - lit = (Literal) filter.getExpression2(); - } else { - return super.visit(filter, data); - } - if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { - date.setTime(((Date) lit.getValue()).getTime()); - } - if (prop.getPropertyName().equals(BAND_DIMENSION)) { - band.add((String) lit.getValue()); - - } - return super.visit(filter, data); - } - - @Override - public Object visit(PropertyIsBetween filter, Object data) { - PropertyName prop = (PropertyName) filter.getExpression(); - - if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { - beginDate.setTime(((Date) ((Literal)filter.getLowerBoundary()).getValue()).getTime()); - endDate.setTime(((Date) ((Literal)filter.getUpperBoundary()).getValue()).getTime()); - } if (prop.getPropertyName().equals(BAND_DIMENSION)) { - String bands = (String) ((Literal)filter.getLowerBoundary()).getValue(); - String[] singleBands = bands.split(","); - band.addAll(Arrays.asList(singleBands)); - - } - return super.visit(filter, data); - } - - }; - Envelope2D bbox = new Envelope2D(DefaultGeographicCRS.WGS84,-180,-90,360,180); - - - query.getFilter().accept(filterVisitor, bbox); - LOGGER.fine("Mosaic query on bbox: " + bbox); - - //very rudimentary filtering, for unit test only! - if(bbox.getMaxX()<=35.){ - return wrapAndCache(Arrays.asList(feature1)); - }else{ - return wrapAndCache(Arrays.asList(feature1,feature2)); - } - - - - } catch (Exception e) { - - e.printStackTrace(); - throw new RuntimeException(e); - } - } + public ContentFeatureSource createFeatureSource(ContentEntry entry) throws IOException { + return new ContentFeatureSource(entry, Query.ALL) { + + { + queryCapabilities = new QueryCapabilities() { + @Override + public boolean supportsSorting(SortBy[] sortAttributes) { + if (sortAttributes != null && sortAttributes.length == 1) { + if (sortAttributes[0].getPropertyName().getPropertyName().equals("timestamp")) { + // sort by timestamp happens to be what we do by + // default + // TODO does the PDF support a sort order? + return true; + } + } + return super.supportsSorting(sortAttributes); + } + }; + } - + // the image mosaic reader does not want this bounds to be null + @Override + public ReferencedEnvelope getBoundsInternal(Query query) throws IOException { + return TOTAL_BOUNDS; + } - @Override - protected FeatureReader getFeatureReader(String typeName) throws IOException { - return new CollectionFeatureReader(Collections.EMPTY_LIST, FEATURE_TYPE); - } - - public FeatureReader getFeatureReader(Query query,Transaction transaction) throws IOException { - Filter filter = query.getFilter(); - String typeName = query.getTypeName(); - String propertyNames[] = query.getPropertyNames(); - - if (filter == null) { - throw new NullPointerException("getFeatureReader requires Filter: " - + "did you mean Filter.INCLUDE?"); - } - if( typeName == null ){ - throw new NullPointerException( - "getFeatureReader requires typeName: " - + "use getTypeNames() for a list of available types"); - } - if (transaction == null) { - throw new NullPointerException( - "getFeatureReader requires Transaction: " - + "did you mean to use Transaction.AUTO_COMMIT?"); - } - SimpleFeatureType featureType = getSchema( query.getTypeName() ); + @Override + protected int getCountInternal(Query query) throws IOException { + if (query.getFilter() == Filter.INCLUDE) { //filtering not implemented + int count = 0; + try (FeatureReader featureReader = getReaderInternal(query)) { + while (featureReader.hasNext()) { + featureReader.next(); + count++; + } + } + return count; + } + return -1; // feature by feature scan required to count records + } - if( propertyNames != null || query.getCoordinateSystem()!=null ){ - try { - featureType = DataUtilities.createSubType( featureType, propertyNames, query.getCoordinateSystem() ); - } catch (SchemaException e) { - LOGGER.log( Level.FINEST, e.getMessage(), e); - throw new DataSourceException( "Could not create Feature Type for query", e ); + @Override + protected FeatureReader getReaderInternal(Query query) + throws IOException { + + + if (query.getPropertyNames() != null && query.getPropertyNames().length == 1) { + if (query.getPropertyNames()[0].equals(TIME_ATTRIBUTE)) { + // geoserver is determining the time domain + List availableTimes = Collections.singletonList(THE_DATE); + List features = new ArrayList<>(availableTimes.size()); + + int idCounter = 0; + for (Date date : availableTimes) { + SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); + featureBuilder.set(TIME_ATTRIBUTE, date); + features.add(featureBuilder.buildFeature("dummyID" + idCounter++)); + } + return wrapAndCache(features); + } + if (query.getPropertyNames()[0].equals(BAND_DIMENSION)) { + List features = new ArrayList<>(BAND_LIST.size()); + + int idCounter = 0; + for (String band : BAND_LIST) { + SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(FEATURE_TYPE); + featureBuilder.set(BAND_DIMENSION, band); + features.add(featureBuilder.buildFeature("dummyID" + idCounter++)); + } + return wrapAndCache(features); + } + } + try { + final Date date = THE_DATE; + date.setTime(0); + + final Date beginDate = THE_DATE; + beginDate.setTime(0); + final Date endDate = THE_DATE; + endDate.setTime(0); + final List band = new ArrayList<>(); + + DefaultFilterVisitor filterVisitor = new DefaultFilterVisitor() { + + @Override + public Object visit(BBOX filter, Object data) { + Envelope2D envelope = (Envelope2D) data; + filter.getBounds(); + envelope.setBounds(filter.getBounds()); + return super.visit(filter, data); + } + + @Override + public Object visit(Intersects filter, Object data) { + Envelope2D envelope = (Envelope2D) data; + + Geometry polygon= ((Geometry)((Literal)filter.getExpression2()).getValue()); + org.opengis.geometry.Geometry polygon2 = JTSUtils.jtsToGo1(polygon, envelope.getCoordinateReferenceSystem()); + envelope.setBounds(new Envelope2D(polygon2.getEnvelope())); + return super.visit(filter, data); + } + + /** + * Used by WCS 2.0 to select a time range + */ + @Override + public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object data) { + PropertyName prop; + Literal lit; + if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else if (filter.getExpression2() instanceof PropertyName && filter.getExpression1() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else { + return super.visit(filter, data); + } + if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { + if(lit.getValue()!=null){ + beginDate.setTime(((Date) lit.getValue()).getTime()); + } + } + return super.visit(filter, data); + } + + /** + * Used by WCS 2.0 to select a time range + */ + @Override + public Object visit(PropertyIsLessThanOrEqualTo filter, Object data) { + PropertyName prop; + Literal lit; + if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else if (filter.getExpression2() instanceof PropertyName && filter.getExpression1() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else { + return super.visit(filter, data); + } + if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { + if(lit.getValue()!=null){ + endDate.setTime(((Date) lit.getValue()).getTime()); + } + } + return super.visit(filter, data); + } + + @Override + public Object visit(PropertyIsEqualTo filter, Object data) { + PropertyName prop; + Literal lit; + if (filter.getExpression1() instanceof PropertyName && filter.getExpression2() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else if (filter.getExpression2() instanceof PropertyName && filter.getExpression1() instanceof Literal) { + prop = (PropertyName) filter.getExpression1(); + lit = (Literal) filter.getExpression2(); + } else { + return super.visit(filter, data); + } + if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { + date.setTime(((Date) lit.getValue()).getTime()); + } + if (prop.getPropertyName().equals(BAND_DIMENSION)) { + band.add((String) lit.getValue()); + } + return super.visit(filter, data); + } + + @Override + public Object visit(PropertyIsBetween filter, Object data) { + PropertyName prop = (PropertyName) filter.getExpression(); + + if (prop.getPropertyName().equals(TIME_ATTRIBUTE)) { + beginDate.setTime(((Date) ((Literal)filter.getLowerBoundary()).getValue()).getTime()); + endDate.setTime(((Date) ((Literal)filter.getUpperBoundary()).getValue()).getTime()); + } + if (prop.getPropertyName().equals(BAND_DIMENSION)) { + String bands = (String) ((Literal)filter.getLowerBoundary()).getValue(); + String[] singleBands = bands.split(","); + band.addAll(Arrays.asList(singleBands)); + } + return super.visit(filter, data); + } + + }; + Envelope2D bbox = new Envelope2D(DefaultGeographicCRS.WGS84,-180,-90,360,180); + + query.getFilter().accept(filterVisitor, bbox); + LOGGER.fine("Mosaic query on bbox: " + bbox); + + //very rudimentary filtering, for unit test only! + if(bbox.getMaxX()<=35.){ + return wrapAndCache(Collections.singletonList(feature1)); + }else{ + return wrapAndCache(Arrays.asList(feature1,feature2)); + } + + } catch (Exception e) { + + e.printStackTrace(); + throw new RuntimeException(e); + } + } + @Override + protected SimpleFeatureType buildFeatureType() throws IOException { + return FEATURE_TYPE; } - } - if ( filter == Filter.EXCLUDE || filter.equals( Filter.EXCLUDE )) { - return new EmptyFeatureReader(featureType); - } - //GR: allow subclases to implement as much filtering as they can, - //by returning just it's unsupperted filter - filter = getUnsupportedFilter(typeName, filter); - if(filter == null){ - throw new NullPointerException("getUnsupportedFilter shouldn't return null. Do you mean Filter.INCLUDE?"); - } - - - // This calls our subclass "simple" implementation - // All other functionality will be built as a reader around - // this class - // - FeatureReader reader = getFeatureReader(typeName, query); - - if (!featureType.equals(reader.getFeatureType())) { - LOGGER.fine("Recasting feature type to subtype by using a ReTypeFeatureReader"); - reader = new ReTypeFeatureReader(reader, featureType, false); - } + public ContentDataStore getDataStore() { + return MultiDimDataStore.this; + } - if (query.getMaxFeatures() != Query.DEFAULT_MAX) { - reader = new MaxFeatureReader(reader, query.getMaxFeatures()); - } + public String toString() { + return "AbstractDataStore.AbstractFeatureSource(" + TYPENAME + ")"; + } - return reader; + }; } - @Override - public SimpleFeatureSource getFeatureSource(final String typeName) throws IOException { - return new AbstractFeatureSource(getSupportedHints()) { - - { - queryCapabilities = new QueryCapabilities() { - @Override - public boolean supportsSorting(SortBy[] sortAttributes) { - if (sortAttributes != null && sortAttributes.length == 1) { - if (sortAttributes[0].getPropertyName().getPropertyName().equals("timestamp")) { - // sort by timestamp happens to be what we do by - // default - // TODO does the PDF support a sort order? - return true; - } - } - return super.supportsSorting(sortAttributes); - } - - }; - } - - // the image mosaic reader does not want this bounds to be null - @Override - public ReferencedEnvelope getBounds() throws IOException { - return TOTAL_BOUNDS; - } - - public DataStore getDataStore() { - return MultiDimDataStore.this; - } - - public String toString() { - return "AbstractDataStore.AbstractFeatureSource(" + TYPENAME + ")"; - } - - public void addFeatureListener(FeatureListener listener) { - listenerManager.addFeatureListener(this, listener); - } - - public void removeFeatureListener(FeatureListener listener) { - listenerManager.removeFeatureListener(this, listener); - } - - public SimpleFeatureType getSchema() { - return FEATURE_TYPE; - } - }; - } - private FeatureReader wrapAndCache(List features) { - CollectionFeatureReader result = new CollectionFeatureReader(features, FEATURE_TYPE); - - return result; - } - + return new CollectionFeatureReader(features, FEATURE_TYPE); + } } diff --git a/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStoreFactory.java b/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStoreFactory.java index 5a100eb54a2..469f308fc07 100644 --- a/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStoreFactory.java +++ b/src/extension/netcdf-out/src/test/java/org/geoserver/wcs2_0/MultiDimDataStoreFactory.java @@ -5,24 +5,38 @@ */ package org.geoserver.wcs2_0; +import java.awt.*; +import java.io.File; import java.io.IOException; import java.io.Serializable; +import java.util.Collections; import java.util.Map; import org.geotools.data.AbstractDataStoreFactory; import org.geotools.data.DataStore; import org.geotools.data.DataStoreFactorySpi; -public class MultiDimDataStoreFactory extends AbstractDataStoreFactory { +public class MultiDimDataStoreFactory implements DataStoreFactorySpi { @Override public DataStore createDataStore(Map params) throws IOException { return new MultiDimDataStore((String) params.get("ParentLocation")); } + @Override + public String getDisplayName() { + return "MultiDim"; + } + @Override public DataStore createNewDataStore(Map params) throws IOException { - throw new UnsupportedOperationException("Can not create a new dummy data store"); + File dir = new File((String) params.get("ParentLocation")); + + if (dir.exists()) { + throw new IOException(dir + " already exists"); + } + + return new MultiDimDataStore((String) params.get("ParentLocation")); } @Override @@ -35,4 +49,19 @@ public Param[] getParametersInfo() { return new DataStoreFactorySpi.Param[] { new Param("ParentLocation") }; } + @Override + public boolean canProcess(Map map) { + File dir = new File((String) map.get("ParentLocation")); + return dir.exists(); + } + + @Override + public boolean isAvailable() { + return true; + } + + @Override + public Map getImplementationHints() { + return Collections.emptyMap(); + } }