/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.csw.feature;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.geoserver.csw.feature.sort.ComplexComparatorFactory;
import org.geotools.feature.FeatureCollection;
import org.opengis.feature.Feature;
import org.opengis.feature.type.FeatureType;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
/**
* A fully in memory feature collection
*
* @author Andrea Aime - GeoSolutions
*/
public class MemoryFeatureCollection extends AbstractFeatureCollection<FeatureType, Feature> {
protected ArrayList<Feature> features;
public MemoryFeatureCollection(FeatureType memberType) {
this(memberType, null);
}
public MemoryFeatureCollection(FeatureType memberType, List<Feature> features) {
super(memberType);
this.features = new ArrayList<Feature>();
if (features != null) {
for (Feature f : features) {
if (!f.getType().equals(memberType)) {
// TODO: handle inheritance
throw new IllegalArgumentException(
"Found a feature whose feature type is not equal to the declared one: "
+ f);
}
this.features.add(f);
}
}
}
@Override
public FeatureCollection<FeatureType, Feature> subCollection(Filter filter) {
List<Feature> results = new ArrayList<Feature>();
for (Feature f : features) {
if (filter.evaluate(f)) {
results.add(f);
}
}
return new MemoryFeatureCollection(getSchema(), results);
}
@Override
public FeatureCollection<FeatureType, Feature> sort(SortBy order) {
List<Feature> results = new ArrayList<Feature>(features);
Comparator<Feature> comparator = ComplexComparatorFactory.buildComparator(order);
Collections.sort(results, comparator);
return new MemoryFeatureCollection(getSchema(), results);
}
@Override
protected Iterator<Feature> openIterator() {
return features.iterator();
}
@Override
protected void closeIterator(Iterator<Feature> close) {
// nothing to do
}
@Override
public int size() {
return features.size();
}
/**
* Removes a single instance of the specified element from this collection, if it is present
* (optional operation).
*
* @param o element to be removed from this collection, if present.
* @return <tt>true</tt> if the collection contained the specified element.
* @throws UnsupportedOperationException if the <tt>remove</tt> method is not supported by this
* collection.
*/
public boolean remove(Object o) {
return features.remove(o);
}
/**
* Removes from this collection all of its elements that are contained in the specified
* collection (optional operation).
* <p>
*
* @param c elements to be removed from this collection.
* @return <tt>true</tt> if this collection changed as a result of the call.
* @throws UnsupportedOperationException if the <tt>removeAll</tt> method is not supported by
* this collection.
* @throws NullPointerException if the specified collection is null.
*
* @see #remove(Object)
* @see #contains(Object)
*/
final public boolean removeAll(Collection<?> c) {
return features.removeAll(c);
}
/**
* Retains only the elements in this collection that are contained in the specified collection
* (optional operation).
*
* @param c elements to be retained in this collection.
* @return <tt>true</tt> if this collection changed as a result of the call.
* @throws UnsupportedOperationException if the <tt>retainAll</tt> method is not supported by
* this Collection.
* @throws NullPointerException if the specified collection is null.
*
* @see #remove(Object)
* @see #contains(Object)
*/
final public boolean retainAll(Collection<?> c) {
return features.removeAll(c);
}
/**
* Implement to support modification.
*
* @param o element whose presence in this collection is to be ensured.
* @return <tt>true</tt> if the collection changed as a result of the call.
*
* @throws UnsupportedOperationException if the <tt>add</tt> method is not supported by this
* collection.
*
* @throws NullPointerException if this collection does not permit <tt>null</tt> elements, and
* the specified element is <tt>null</tt>.
*
* @throws ClassCastException if the class of the specified element prevents it from being added
* to this collection.
*
* @throws IllegalArgumentException if some aspect of this element prevents it from being added
* to this collection.
*/
public boolean add(Feature o) {
return features.add(o);
}
/**
* Adds all of the elements in the specified collection to this collection (optional operation).
*
* @param c collection whose elements are to be added to this collection.
* @return <tt>true</tt> if this collection changed as a result of the call.
* @throws UnsupportedOperationException if this collection does not support the <tt>addAll</tt>
* method.
* @throws NullPointerException if the specified collection is null.
*
* @see #add(Feature)
*/
public boolean addAll(Collection<Feature> c) {
return features.addAll(c);
}
public boolean addAll(FeatureCollection<FeatureType, Feature> c) {
Feature[] array = (Feature[]) c.toArray(new Feature[c.size()]);
return features.addAll(Arrays.asList(array));
}
}