Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2003-2016, 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.Closeable;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.data.DataAccessFactory.Param;
import org.geotools.data.collection.CollectionFeatureSource;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.collection.SpatialIndexFeatureCollection;
import org.geotools.data.collection.SpatialIndexFeatureSource;
import org.geotools.data.collection.TreeSetFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureLocking;
import org.geotools.data.simple.SimpleFeatureReader;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
import org.geotools.data.util.NullProgressListener;
import org.geotools.data.view.DefaultView;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.AttributeImpl;
import org.geotools.feature.AttributeTypeBuilder;
import org.geotools.feature.DefaultFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.FeatureTypes;
import org.geotools.feature.GeometryAttributeImpl;
import org.geotools.feature.NameImpl;
import org.geotools.feature.SchemaException;
import org.geotools.feature.collection.BridgeIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.feature.type.AttributeDescriptorImpl;
import org.geotools.feature.type.AttributeTypeImpl;
import org.geotools.feature.type.GeometryDescriptorImpl;
import org.geotools.feature.type.GeometryTypeImpl;
import org.geotools.filter.FilterAttributeExtractor;
import org.geotools.filter.visitor.PropertyNameResolvingVisitor;
import org.geotools.filter.visitor.SimplifyingFilterVisitor;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.geometry.jts.WKTReader2;
import org.geotools.metadata.iso.citation.Citations;
import org.geotools.referencing.CRS;
import org.geotools.styling.UserLayer;
import org.geotools.util.Converters;
import org.geotools.util.Utilities;
import org.geotools.util.factory.Hints;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LineString;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.MultiLineString;
import org.locationtech.jts.geom.MultiPoint;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.geom.Polygon;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureFactory;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.IllegalAttributeException;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.GeometryType;
import org.opengis.feature.type.Name;
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.sort.SortBy;
import org.opengis.filter.sort.SortOrder;
import org.opengis.geometry.BoundingBox;
import org.opengis.metadata.citation.Citation;
import org.opengis.referencing.ReferenceIdentifier;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.util.ProgressListener;
/**
* Utility functions for use with GeoTools with data classes.
*
*
These methods fall into several categories:
*
*
Conversion between common data structures.
*
*
*
{@link #collection} methods: creating/converting a {@link SimpleFeatureCollection} from a
* range of input.
*
{@link #simple} methods: adapting from generic Feature use to SimpleFeature. Used to
* convert to SimpleFeature, SimpleFeatureCollection,SimpleFeatureSource
*
{@link #list} to quickly copy features into a memory based list
*
{@link #reader} methods to convert to FeatureReader
*
{@link #expression} setup a FeatureSource wrapper around the provided data
*
*
*
SimpleFeatureType and SimpleFeature encoding/decoding from String as used by the
* PropertyDataStore tutorials.
*
*
*
{@link #createType} methods: to create a SimpleFeatureType from a one line text string
*
{@link #encodeType}: text string representation of a SimpleFeaturerType
*
{@link #createFeature}: create a SimpleFeature from a one line text String
*
{@link #encodeFeature}: encode a feature as a single line text string
*
*
*
Working with SimpleFeatureType (this class is immutable so we always have to make a modified
* copy):
*
*
*
{@link #createSubType(SimpleFeatureType, String[])} methods return a modified copy of an
* origional feature type. Used to cut down an exsiting feature type to reflect only the
* attributes requested when using {@link SimpleFeatureSource#getFeatures(Filter)}.
*
{@link #compare} and {@link #isMatch(AttributeDescriptor, AttributeDescriptor)} are used to
* check for types compatible with {@link #createSubType} used to verify that feature values
* can be copied across
*
*
*
Manipulating individual features and data values:
*
*
*
{@link #reType} generates a cut down version of an original feature in the same manners as
* {@link #createSubType}
*
{@link #template} and {@link #defaultValue} methods which uses {@link
* AttributeDescriptor#getDefaultValue()} when creating new empty features
*
{@link #duplicate(Object)} used for deep copy of feature data
*
*
*
* And a grab bag of helpful utility methods for those implementing a DataStore:
*
*
*
{@link #includeFilters} and {@link #excludeFilters} work as a compound {@link FileFilter}
* making {@link File#listFiles} easier to use
*
{@link #propertyNames}, {@link #fidSet}, {@link #attributeNames} methods are used to double
* check a provided query and ensure it can be correctly handed. {@link #sortComparator},
* {@link #resolvePropertyNames} and {@link #mixQueries} are used to prep a {@link Query}
* prior to use
*
*
* @author Jody Garnett, Refractions Research
*/
public class DataUtilities {
/** Typemap used by {@link #createType(String, String)} methods */
static Map typeMap = new HashMap();
/** Reverse type map used by {@link #encodeType(FeatureType)} */
static Map typeEncode = new HashMap();
static FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
static {
typeEncode.put(String.class, "String");
typeMap.put("String", String.class);
typeMap.put("string", String.class);
typeMap.put("\"\"", String.class);
typeEncode.put(Integer.class, "Integer");
typeMap.put("Integer", Integer.class);
typeMap.put("int", Integer.class);
typeMap.put("0", Integer.class);
typeEncode.put(Double.class, "Double");
typeMap.put("Double", Double.class);
typeMap.put("double", Double.class);
typeMap.put("0.0", Double.class);
typeEncode.put(Float.class, "Float");
typeMap.put("Float", Float.class);
typeMap.put("float", Float.class);
typeMap.put("0.0f", Float.class);
typeEncode.put(Boolean.class, "Boolean");
typeMap.put("Boolean", Boolean.class);
typeMap.put("true", Boolean.class);
typeMap.put("false", Boolean.class);
typeEncode.put(UUID.class, "UUID");
typeMap.put("UUID", UUID.class);
typeEncode.put(Geometry.class, "Geometry");
typeMap.put("Geometry", Geometry.class);
typeMap.put("com.vividsolutions.jts.geom.Geometry", Geometry.class);
typeMap.put("org.locationtech.jts.geom.Geometry", Geometry.class);
typeEncode.put(Point.class, "Point");
typeMap.put("Point", Point.class);
typeMap.put("com.vividsolutions.jts.geom.Point", Point.class);
typeMap.put("org.locationtech.jts.geom.Point", Point.class);
typeEncode.put(LineString.class, "LineString");
typeMap.put("LineString", LineString.class);
typeMap.put("com.vividsolutions.jts.geom.LineString", LineString.class);
typeMap.put("org.locationtech.jts.geom.LineString", LineString.class);
typeEncode.put(Polygon.class, "Polygon");
typeMap.put("Polygon", Polygon.class);
typeMap.put("com.vividsolutions.jts.geom.Polygon", Polygon.class);
typeMap.put("org.locationtech.jts.geom.Polygon", Polygon.class);
typeEncode.put(MultiPoint.class, "MultiPoint");
typeMap.put("MultiPoint", MultiPoint.class);
typeMap.put("com.vividsolutions.jts.geom.MultiPoint", MultiPoint.class);
typeMap.put("org.locationtech.jts.geom.MultiPoint", MultiPoint.class);
typeEncode.put(MultiLineString.class, "MultiLineString");
typeMap.put("MultiLineString", MultiLineString.class);
typeMap.put("com.vividsolutions.jts.geom.MultiLineString", MultiLineString.class);
typeMap.put("org.locationtech.jts.geom.MultiLineString", MultiLineString.class);
typeEncode.put(MultiPolygon.class, "MultiPolygon");
typeMap.put("MultiPolygon", MultiPolygon.class);
typeMap.put("com.vividsolutions.jts.geom.MultiPolygon", MultiPolygon.class);
typeMap.put("org.locationtech.jts.geom.MultiPolygon", MultiPolygon.class);
typeEncode.put(GeometryCollection.class, "GeometryCollection");
typeMap.put("GeometryCollection", GeometryCollection.class);
typeMap.put("com.vividsolutions.jts.geom.GeometryCollection", GeometryCollection.class);
typeMap.put("org.locationtech.jts.geom.GeometryCollection", GeometryCollection.class);
typeEncode.put(Date.class, "Date");
typeMap.put("Date", Date.class);
}
/**
* Retrieve the attributeNames defined by the featureType
*
* @return array of simple attribute names
*/
public static String[] attributeNames(SimpleFeatureType featureType) {
String[] names = new String[featureType.getAttributeCount()];
final int count = featureType.getAttributeCount();
for (int i = 0; i < count; i++) {
names[i] = featureType.getDescriptor(i).getLocalName();
}
return names;
}
/**
* Traverses the filter and returns any encountered property names.
*
*
The feature type is supplied as contexts used to lookup expressions in cases where the
* attributeName does not match the actual name of the type.
*/
public static String[] attributeNames(Filter filter, final SimpleFeatureType featureType) {
if (filter == null) {
return new String[0];
}
FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(featureType);
filter.accept(attExtractor, null);
String[] attributeNames = attExtractor.getAttributeNames();
return attributeNames;
}
/**
* Traverses the filter and returns any encountered property names.
*
*
The feature type is supplied as contexts used to lookup expressions in cases where the
* attributeName does not match the actual name of the type.
*/
public static Set propertyNames(
Filter filter, final SimpleFeatureType featureType) {
if (filter == null) {
return Collections.emptySet();
}
FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(featureType);
filter.accept(attExtractor, null);
Set propertyNames = attExtractor.getPropertyNameSet();
return propertyNames;
}
/** Traverses the filter and returns any encountered property names. */
public static String[] attributeNames(Filter filter) {
return attributeNames(filter, null);
}
/** Traverses the filter and returns any encountered property names. */
public static Set propertyNames(Filter filter) {
return propertyNames(filter, null);
}
/**
* Traverses the expression and returns any encountered property names.
*
*
The feature type is supplied as contexts used to lookup expressions in cases where the
* attributeName does not match the actual name of the type.
*/
public static String[] attributeNames(
Expression expression, final SimpleFeatureType featureType) {
if (expression == null) {
return new String[0];
}
FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(featureType);
expression.accept(attExtractor, null);
String[] attributeNames = attExtractor.getAttributeNames();
return attributeNames;
}
/**
* Traverses the expression and returns any encountered property names.
*
*
The feature type is supplied as contexts used to lookup expressions in cases where the
* attributeName does not match the actual name of the type.
*/
public static Set propertyNames(
Expression expression, final SimpleFeatureType featureType) {
if (expression == null) {
return Collections.emptySet();
}
FilterAttributeExtractor attExtractor = new FilterAttributeExtractor(featureType);
expression.accept(attExtractor, null);
Set propertyNames = attExtractor.getPropertyNameSet();
return propertyNames;
}
/** Traverses the expression and returns any encountered property names. */
public static String[] attributeNames(Expression expression) {
return attributeNames(expression, null);
}
/** Traverses the expression and returns any encountered property names. */
public static Set propertyNames(Expression expression) {
return propertyNames(expression, null);
}
/**
* Compare attribute coverage between two feature types (allowing the identification of
* subTypes).
*
*
Strict compatibility is assumed meaning that both the local name and java binding are
* compatible (see {@link #compareInternal(SimpleFeatureType, SimpleFeatureType, boolean)} for
* more details.
*
*
Namespace is not considered in this operations. You may still need to reType to get the
* correct namespace, or reorder.
*
*
Please note this method will not result in a stable sort if used in a {@link Comparator}
* as -1 is used to indicate incompatiblity (rather than simply "before").
*
* @param typeA FeatureType being compared
* @param typeB FeatureType being compared against
*/
public static int compare(SimpleFeatureType typeA, SimpleFeatureType typeB) {
return compareInternal(typeA, typeB, true);
}
/**
* Compare attribute coverage between two feature types (allowing the identification of
* subTypes).
*
*
loose compatibility is assumed based on local name (java binding may differ) (see {@link
* #compareInternal(SimpleFeatureType, SimpleFeatureType, boolean)} for more details.
*
*
Namespace is not considered in this operations. You may still need to reType to get the
* correct namespace, or reorder.
*
*
Please note this method will not result in a stable sort if used in a {@link Comparator}
* as -1 is used to indicate incompatiblity (rather than simply "before").
*
* @param typeA FeatureType being compared
* @param typeB FeatureType being compared against
*/
public static int compareNames(SimpleFeatureType typeA, SimpleFeatureType typeB) {
return compareInternal(typeA, typeB, false);
}
/**
* Compare attribute coverage between two feature types (allowing the identification of
* subTypes).
*
*
The comparison results in a number with the following meaning:
*
*
*
1: if typeA is a sub type/reorder/renamespace of typeB
*
0: if typeA and typeB are the same type
*
-1: if typeA is not subtype of typeB
*
*
*
Comparison is based on {@link AttributeDescriptor} - the {@link
* #isMatch(AttributeDescriptor, AttributeDescriptor, boolean)} method is used to quickly
* confirm that the local name and java binding (depending on strict flag value) are compatible.
*
*
Namespace is not considered in this operations. You may still need to reType to get the
* correct namespace, or reorder.
*
*
Please note this method will not result in a stable sort if used in a {@link Comparator}
* as -1 is used to indicate incompatiblity (rather than simply "before").
*
* @param typeA FeatureType being compared
* @param typeB FeatureType being compared against
* @param strict flag controlling the comparison check
*/
protected static int compareInternal(
SimpleFeatureType typeA, SimpleFeatureType typeB, boolean strict) {
if (typeA == typeB) {
return 0;
}
if (typeA == null) {
return -1;
}
if (typeB == null) {
return -1;
}
int countA = typeA.getAttributeCount();
int countB = typeB.getAttributeCount();
if (countA > countB) {
return -1;
}
// may still be the same featureType (Perhaps they differ on namespace?)
AttributeDescriptor a;
int match = 0;
for (int i = 0; i < countA; i++) {
a = typeA.getDescriptor(i);
if (isMatch(a, typeB.getDescriptor(i), strict)) {
match++;
} else if (!isMatch(a, typeB.getDescriptor(a.getLocalName()), strict)) {
// cannot find any match for Attribute in typeA
return -1;
}
}
if ((countA == countB) && (match == countA)) {
// all attributes in typeA agreed with typeB
// (same order and type)
return 0;
}
return 1;
}
/**
* Quickly check if two descriptors are at all compatible.
*
*
This method checks the descriptors name and class binding to see if the values have any
* chance of being compatible. Strict compatibility assumed (see also {@link
* #isMatch(AttributeDescriptor, AttributeDescriptor, boolean)}.
*
* @param a descriptor to compare
* @param b descriptor to compare
* @return true to the descriptors name and binding class match
*/
public static boolean isMatch(AttributeDescriptor a, AttributeDescriptor b) {
return isMatch(a, b, true);
}
/**
* Quickly check descriptors compatibility.
*
*
This method checks the descriptors name and class binding to see if the values have any
* chance of being compatible.
*
* @param a descriptor to compare
* @param b descriptor to compare
* @param strict if true both descriptor name and class binding is checked otherwise a more
* loose form o compatibility is assumed where equality is determined by descriptor name
* only
* @return true if compatibility comparison succeeds
*/
public static boolean isMatch(AttributeDescriptor a, AttributeDescriptor b, boolean strict) {
if (a == b) {
return true;
}
if (b == null) {
return false;
}
if (a == null) {
return false;
}
if (a.equals(b)) {
return true;
}
if (strict) {
if (a.getLocalName().equals(b.getLocalName())
&& a.getType().getBinding().equals(b.getType().getBinding())) {
return true;
}
} else {
if (a.getLocalName().equals(b.getLocalName())) {
return true;
}
}
return false;
}
/**
* Creates duplicate of feature adjusted to the provided featureType.
*
*
Please note this implementation provides "deep copy" using {@link #duplicate(Object)} to
* copy each attribute.
*
* @param featureType FeatureType requested
* @param feature Origional Feature from DataStore
* @return An instance of featureType based on feature
* @throws IllegalAttributeException If opperation could not be performed
*/
public static SimpleFeature reType(SimpleFeatureType featureType, SimpleFeature feature)
throws IllegalAttributeException {
SimpleFeatureType origional = feature.getFeatureType();
if (featureType.equals(origional)) {
return SimpleFeatureBuilder.copy(feature);
}
String id = feature.getID();
int numAtts = featureType.getAttributeCount();
Object[] attributes = new Object[numAtts];
String xpath;
for (int i = 0; i < numAtts; i++) {
AttributeDescriptor curAttType = featureType.getDescriptor(i);
xpath = curAttType.getLocalName();
attributes[i] = duplicate(feature.getAttribute(xpath));
}
return SimpleFeatureBuilder.build(featureType, attributes, id);
}
/**
* Retypes the feature to match the provided featureType.
*
*
The duplicate parameter indicates how the new feature is to be formed:
*
*
*
dupliate is true: A "deep copy" is made of each attribute resulting in a safe
* "copy"Adjusts the attribute order to match the provided featureType.
*
duplicate is false: the attributes are simply reordered and are actually the same
* instances as those in the origional feature
*
*
* In the future this method may simply return a "wrapper" when duplicate is false.
*
*
*
* @param duplicate True to perform {@link #duplicate(Object)} on each attribute
*/
public static SimpleFeature reType(
SimpleFeatureType featureType, SimpleFeature feature, boolean duplicate)
throws IllegalAttributeException {
if (duplicate) {
return reType(featureType, feature);
}
FeatureType origional = feature.getFeatureType();
if (featureType.equals(origional)) {
return feature;
}
String id = feature.getID();
int numAtts = featureType.getAttributeCount();
Object[] attributes = new Object[numAtts];
for (int i = 0; i < numAtts; i++) {
AttributeDescriptor curAttType = featureType.getDescriptor(i);
attributes[i] = feature.getAttribute(curAttType.getLocalName());
}
return SimpleFeatureBuilder.build(featureType, attributes, id);
}
/**
* Performs a deep copy of the provided object.
*
*
A number of tricks are used to make this as fast as possible:
*
*
*
Simple or Immutable types are copied as is (String, Integer, Float, URL, etc..)
*
JTS Geometry objects are cloned
*
Arrays and the Collection classes are duplicated element by element
*
*
* This function is used recusively for (in order to handle complext features) no attempt is
* made to detect cycles at this time so your milage may vary.
*
* @param src Source object
* @return copy of source object
*/
public static Object duplicate(Object src) {
// JD: this method really needs to be replaced with somethign better
if (src == null) {
return null;
}
//
// The following are things I expect
// Features will contain.
//
if (src instanceof String
|| src instanceof Integer
|| src instanceof Double
|| src instanceof Float
|| src instanceof Byte
|| src instanceof Boolean
|| src instanceof Short
|| src instanceof Long
|| src instanceof Character
|| src instanceof Number) {
return src;
}
if (src instanceof Date) {
return new Date(((Date) src).getTime());
}
if (src instanceof URL || src instanceof URI) {
return src; // immutable
}
if (src instanceof Object[]) {
Object[] array = (Object[]) src;
Object[] copy = new Object[array.length];
for (int i = 0; i < array.length; i++) {
copy[i] = duplicate(array[i]);
}
return copy;
}
if (src instanceof Geometry) {
Geometry geometry = (Geometry) src;
return geometry.copy();
}
if (src instanceof SimpleFeature) {
SimpleFeature feature = (SimpleFeature) src;
return SimpleFeatureBuilder.copy(feature);
}
//
// We are now into diminishing returns
// I don't expect Features to contain these often
// (eveything is still nice and recursive)
//
Class extends Object> type = src.getClass();
if (type.isArray() && type.getComponentType().isPrimitive()) {
int length = Array.getLength(src);
Object copy = Array.newInstance(type.getComponentType(), length);
System.arraycopy(src, 0, copy, 0, length);
return copy;
}
if (type.isArray()) {
int length = Array.getLength(src);
Object copy = Array.newInstance(type.getComponentType(), length);
for (int i = 0; i < length; i++) {
Array.set(copy, i, duplicate(Array.get(src, i)));
}
return copy;
}
if (src instanceof List) {
List list = (List) src;
List
*
* @param arrayParameters Array of parameters returned by DataAccessFactory.getParametersInfo()
* @return true if params is in agreement with getParametersInfo, override for additional
* checks.
*/
public static boolean canProcess(Map params, Param[] arrayParameters) {
if (params == null) {
return false;
}
for (int i = 0; i < arrayParameters.length; i++) {
Param param = arrayParameters[i];
Object value;
if (!params.containsKey(param.key)) {
if (param.required) {
return false; // missing required key!
} else {
continue;
}
}
try {
value = param.lookUp(params);
} catch (IOException e) {
// could not upconvert/parse to expected type!
// even if this parameter is not required
// we are going to refuse to process
// these params
return false;
}
if (value == null) {
if (param.required) {
return (false);
}
} else {
if (!param.type.isInstance(value)) {
return false; // value was not of the required type
}
if (param.metadata != null) {
// check metadata
if (param.metadata.containsKey(Param.OPTIONS)) {
List options = (List) param.metadata.get(Param.OPTIONS);
if (options != null && !options.contains(value)) {
return false; // invalid option
}
}
}
}
}
return true;
}
/**
* Returns a {@link IOFileFilter} obtained by excluding from the first input filter argument,
* the additional filter arguments.
*
* @param inputFilter the initial filter from which to exclude other ones.
* @param filters additional filters to be excluded
* @return the updated {@link IOFileFilter}
*/
public static FilenameFilter excludeFilters(
final FilenameFilter inputFilter, final FilenameFilter... filters) {
return new FilenameFilter() {
public boolean accept(File dir, String name) {
if (inputFilter.accept(dir, name)) {
for (FilenameFilter exclude : filters) {
if (exclude.accept(dir, name)) {
return false;
}
}
return true;
}
return false;
}
};
}
/**
* Returns a {@link IOFileFilter} obtained by adding to the first input filter argument, the
* additional filter arguments.
*
* @param inputFilter the initial filter to which to add other ones.
* @param filters additional filters to be included in the main filter.
* @return the updated {@link IOFileFilter}
*/
public static FilenameFilter includeFilters(
final FilenameFilter inputFilter, final FilenameFilter... filters) {
return new FilenameFilter() {
public boolean accept(File dir, String name) {
if (inputFilter.accept(dir, name)) {
return true;
}
for (FilenameFilter include : filters) {
if (include.accept(dir, name)) {
return true;
}
}
return false;
}
};
}
/**
* Create a non-simple template feature from feature type schema
*
* @param schema the feature type
* @return a template feature
*/
public static Feature templateFeature(FeatureType schema) {
FeatureFactory ff = CommonFactoryFinder.getFeatureFactory(null);
Collection value = new ArrayList();
for (PropertyDescriptor pd : schema.getDescriptors()) {
if (pd instanceof AttributeDescriptor) {
if (pd instanceof GeometryDescriptor) {
value.add(
new GeometryAttributeImpl(
((AttributeDescriptor) pd).getDefaultValue(),
(GeometryDescriptor) pd,
null));
} else {
value.add(
new AttributeImpl(
((AttributeDescriptor) pd).getDefaultValue(),
(AttributeDescriptor) pd,
null));
}
}
}
return ff.createFeature(
value, (FeatureType) schema, SimpleFeatureBuilder.createDefaultFeatureId());
}
}