/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.feature.retype;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.geoserver.feature.RetypingFeatureCollection;
import org.geotools.data.DataStore;
import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureListener;
import org.geotools.data.FeatureSource;
import org.geotools.data.Query;
import org.geotools.data.QueryCapabilities;
import org.geotools.data.ResourceInfo;
import org.geotools.feature.FeatureCollection;
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;
/**
* Renaming wrapper for a {@link FeatureSource} instance, to be used along with
* {@link RetypingDataStore}
*/
public class RetypingFeatureSource implements FeatureSource<SimpleFeatureType, SimpleFeature>{
FeatureSource<SimpleFeatureType, SimpleFeature> wrapped;
FeatureTypeMap typeMap;
RetypingDataStore store;
Map listeners = new HashMap();
RetypingFeatureSource(RetypingDataStore ds,
FeatureSource<SimpleFeatureType, SimpleFeature> wrapped, FeatureTypeMap typeMap) {
this.store = ds;
this.wrapped = wrapped;
this.typeMap = typeMap;
}
/**
* Returns the same name than the feature type (ie,
* {@code getSchema().getName()} to honor the simple feature land common
* practice of calling the same both the Features produces and their types
*
* @since 1.7
* @see FeatureSource#getName()
*/
public Name getName() {
return getSchema().getName();
}
public void addFeatureListener(FeatureListener listener) {
FeatureListener wrapper = new WrappingFeatureListener(this, listener);
listeners.put(listener, wrapper);
wrapped.addFeatureListener(wrapper);
}
public void removeFeatureListener(FeatureListener listener) {
FeatureListener wrapper = (FeatureListener) listeners.get(listener);
if (wrapper != null) {
wrapped.removeFeatureListener(wrapper);
listeners.remove(listener);
}
}
public ReferencedEnvelope getBounds() throws IOException {
// not fully correct if we use this to shave attributes too, but this is
// not in the scope now
return wrapped.getBounds();
}
public ReferencedEnvelope getBounds(Query query) throws IOException {
// not fully correct if we use this to shave attributes too, but this is
// not in the scope now
return wrapped.getBounds(store.retypeQuery(query, typeMap));
}
public int getCount(Query query) throws IOException {
return wrapped.getCount(store.retypeQuery(query, typeMap));
}
public DataStore getDataStore() {
return store;
}
public FeatureCollection<SimpleFeatureType, SimpleFeature> getFeatures() throws IOException {
return getFeatures(Query.ALL);
}
public FeatureCollection<SimpleFeatureType, SimpleFeature> getFeatures(Query query) throws IOException {
if (query.getTypeName() == null) {
query = new DefaultQuery(query);
((DefaultQuery) query).setTypeName(typeMap.getName());
} else if (!typeMap.getName().equals(query.getTypeName())) {
throw new IOException("Cannot query this feature source with " + query.getTypeName()
+ " since it serves only " + typeMap.getName());
}
//GEOS-3210, if the query specifies a subset of property names we need to take that into
// account
SimpleFeatureType target = typeMap.getFeatureType();
if ( query.getPropertyNames() != Query.ALL_NAMES ) {
target = SimpleFeatureTypeBuilder.retype(target, query.getPropertyNames());
}
return new RetypingFeatureCollection(wrapped.getFeatures(store.retypeQuery(query, typeMap)),
target);
}
public FeatureCollection<SimpleFeatureType, SimpleFeature> getFeatures(Filter filter) throws IOException {
return getFeatures(new DefaultQuery(typeMap.getName(), filter));
}
public SimpleFeatureType getSchema() {
return typeMap.getFeatureType();
}
public Set getSupportedHints() {
return wrapped.getSupportedHints();
}
public ResourceInfo getInfo() {
return wrapped.getInfo();
}
public QueryCapabilities getQueryCapabilities() {
return wrapped.getQueryCapabilities();
}
}