[Schmitzm-commits] r1285 - in trunk: src/schmitzm/xml src_junit/org/geotools/data
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Nov 18 14:11:37 CET 2010
Author: mojays
Date: 2010-11-18 14:11:35 +0100 (Thu, 18 Nov 2010)
New Revision: 1285
Modified:
trunk/src/schmitzm/xml/XMLUtil.java
trunk/src_junit/org/geotools/data/DataUtilities.java
Log:
XMLUtil: new utilities for JDOM_TO_JAX
DataUtilities: completely outlined
Modified: trunk/src/schmitzm/xml/XMLUtil.java
===================================================================
--- trunk/src/schmitzm/xml/XMLUtil.java 2010-11-17 11:23:45 UTC (rev 1284)
+++ trunk/src/schmitzm/xml/XMLUtil.java 2010-11-18 13:11:35 UTC (rev 1285)
@@ -39,6 +39,7 @@
import org.apache.log4j.Logger;
import org.jdom.Element;
import org.jdom.adapters.JAXPDOMAdapter;
+import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
@@ -62,7 +63,56 @@
public static final XMLOutputter XML_OUTPUTTER = new XMLOutputter( Format.getPrettyFormat() );
/** Delimiter to encode lists in an XML attribute. */
public static final String LIST_DELIMITER = ";";
+
+ /** A builder to read an XML file. */
+ public static final SAXBuilder SAX_BUILDER = new SAXBuilder();
+
+
/**
+ * Returns the i-th sub-child of an element or {@code null} if the
+ * path can not be tracked because a child does not exist.
+ * @param element an element
+ * @param childName the child names to track
+ */
+ public static Element getSubChild(Element element, String...childName) {
+ for (int i=0; i<childName.length; i++) {
+ if ( element == null )
+ return null;
+ element = element.getChild(childName[i]);
+ }
+ return element;
+ }
+
+ /**
+ * Checks whether an element has one of the specified children (OR).
+ * @param element an element
+ * @param childName the child names to track
+ */
+ public static boolean hasChild(Element element, String...childName) {
+ if ( element == null )
+ return false;
+ for (int i=0; i<childName.length; i++)
+ if ( element.getChild(childName[i]) != null )
+ return true;
+
+ return false;
+ }
+
+ /**
+ * Checks whether an element has all of the specified children (AND).
+ * @param element an element
+ * @param childName the child names to track
+ */
+ public static boolean hasChildren(Element element, String...childName) {
+ if ( element == null )
+ return false;
+ for (int i=0; i<childName.length; i++)
+ if ( element.getChild(childName[i]) == null )
+ return false;
+
+ return true;
+ }
+ /**
* Gets the attribute value from element.
* @param element element where the attribute is determined from
* @param attrName name of the attribute
Modified: trunk/src_junit/org/geotools/data/DataUtilities.java
===================================================================
--- trunk/src_junit/org/geotools/data/DataUtilities.java 2010-11-17 11:23:45 UTC (rev 1284)
+++ trunk/src_junit/org/geotools/data/DataUtilities.java 2010-11-18 13:11:35 UTC (rev 1285)
@@ -1,2005 +1,2005 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2003-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.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Array;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-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.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.commons.io.filefilter.IOFileFilter;
-import org.geotools.data.collection.CollectionDataStore;
-import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.feature.AttributeTypeBuilder;
-import org.geotools.feature.DefaultFeatureCollection;
-import org.geotools.feature.FeatureCollection;
-import org.geotools.feature.FeatureCollections;
-import org.geotools.feature.FeatureIterator;
-import org.geotools.feature.FeatureTypes;
-import org.geotools.feature.IllegalAttributeException;
-import org.geotools.feature.NameImpl;
-import org.geotools.feature.SchemaException;
-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.geometry.jts.ReferencedEnvelope;
-import org.geotools.metadata.iso.citation.Citations;
-import org.geotools.referencing.CRS;
-import org.geotools.resources.Utilities;
-import org.geotools.resources.i18n.ErrorKeys;
-import org.geotools.resources.i18n.Errors;
-import org.geotools.util.Converters;
-import org.opengis.coverage.grid.GridCoverage;
-import org.opengis.feature.Feature;
-import org.opengis.feature.FeatureVisitor;
-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.PropertyDescriptor;
-import org.opengis.filter.Filter;
-import org.opengis.filter.FilterFactory;
-import org.opengis.filter.expression.Expression;
-import org.opengis.referencing.ReferenceIdentifier;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryCollection;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.LineString;
-import com.vividsolutions.jts.geom.LinearRing;
-import com.vividsolutions.jts.geom.MultiLineString;
-import com.vividsolutions.jts.geom.MultiPoint;
-import com.vividsolutions.jts.geom.MultiPolygon;
-import com.vividsolutions.jts.geom.Point;
-import com.vividsolutions.jts.geom.Polygon;
-
-/**
- * Utility functions for use when implementing working with data classes.
- * <p>
- * TODO: Move FeatureType manipulation to feature package
- * </p>
- * @author Jody Garnett, Refractions Research
- * @source $URL$
- */
-public class DataUtilities {
-
- static Map<String,Class> typeMap = new HashMap<String,Class>();
- static Map<Class,String> typeEncode = new HashMap<Class,String>();
-
- static FilterFactory ff = CommonFactoryFinder.getFilterFactory( null );
-
- 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( Geometry.class, "Geometry");
- typeMap.put("Geometry", Geometry.class);
-
- typeEncode.put( Point.class, "Point");
- typeMap.put("Point", Point.class);
-
- typeEncode.put( LineString.class, "LineString");
- typeMap.put("LineString", LineString.class);
-
- typeEncode.put( Polygon.class, "Polygon");
- typeMap.put("Polygon", Polygon.class);
-
- typeEncode.put( MultiPoint.class, "MultiPoint");
- typeMap.put("MultiPoint", MultiPoint.class);
-
- typeEncode.put( MultiLineString.class, "MultiLineString");
- typeMap.put("MultiLineString", MultiLineString.class);
-
- typeEncode.put( MultiPolygon.class, "MultiPolygon");
- typeMap.put("MultiPolygon", MultiPolygon.class);
-
- typeEncode.put( GeometryCollection.class, "GeometryCollection");
- typeMap.put("GeometryCollection", GeometryCollection.class);
-
- typeEncode.put( Date.class, "Date");
- typeMap.put("Date",Date.class);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- 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;
- }
-
- /**
- * A replacement for File.toURI().toURL().
- * <p>
- * The handling of file.toURL() is broken; the handling of file.toURI().toURL() is known
- * to be broken on a few platforms like mac. We have the urlToFile( URL ) method that
- * is able to untangle both these problems and we use it in the geotools library.
- * <p>
- * However occasionally we need to pick up a file and hand it to a third party library
- * like EMF; this method performs a couple of sanity checks which we can use to prepare
- * a good URL reference to a file in these situtations.
- *
- * @param file
- * @return URL
- */
- public static URL fileToURL(File file) {
- try {
- URL url = file.toURI().toURL();
- String string = url.toExternalForm();
- if( string.contains("+")){
- // this represents an invalid URL created using either
- // file.toURL(); or
- // file.toURI().toURL() on a specific version of Java 5 on Mac
- string = string.replace("+","%2B");
- }
- if( string.contains(" ")){
- // this represents an invalid URL created using either
- // file.toURL(); or
- // file.toURI().toURL() on a specific version of Java 5 on Mac
- string = string.replace(" ","%20");
- }
- return new URL( string );
- } catch (MalformedURLException e) {
- return null;
- }
- }
-
- /**
- * Takes a URL and converts it to a File. The attempts to deal with
- * Windows UNC format specific problems, specifically files located
- * on network shares and different drives.
- *
- * If the URL.getAuthority() returns null or is empty, then only the
- * url's path property is used to construct the file. Otherwise, the
- * authority is prefixed before the path.
- *
- * It is assumed that url.getProtocol returns "file".
- *
- * Authority is the drive or network share the file is located on.
- * Such as "C:", "E:", "\\fooServer"
- *
- * @param url a URL object that uses protocol "file"
- * @return a File that corresponds to the URL's location
- */
- public static File urlToFile(URL url) {
- if( !"file".equals(url.getProtocol())){
- return null; // not a File URL
- }
- String string = url.toExternalForm();
- if( string.contains("+")){
- // this represents an invalid URL created using either
- // file.toURL(); or
- // file.toURI().toURL() on a specific version of Java 5 on Mac
- string = string.replace("+","%2B");
- }
- try {
- string = URLDecoder.decode(string, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Could not decode the URL to UTF-8 format", e);
- }
-
- String path3;
-
- String simplePrefix = "file:/";
- String standardPrefix = "file://";
- String os = System.getProperty("os.name");
-
- if (os.toUpperCase().contains("WINDOWS") && string.startsWith(standardPrefix)) {
- // win32: host/share reference
- path3 = string.substring(standardPrefix.length()-2);
- }
- else if( string.startsWith(standardPrefix) ){
- path3 = string.substring( standardPrefix.length() );
- } else if( string.startsWith(simplePrefix)){
- path3 = string.substring( simplePrefix.length()-1 );
- } else {
- String auth = url.getAuthority();
- String path2 = url.getPath().replace("%20", " ");
- if (auth != null && !auth.equals("")) {
- path3 = "//" + auth + path2;
- } else {
- path3 = path2;
- }
- }
-
- return new File(path3);
- }
-
-
- /**
- * Traverses the filter and returns any encoutered property names.
- * <p>
- * The feautre type is supplied as contexts used to lookup expressions in cases where the
- * attributeName does not match the actual name of the type.
- * </p>
- */
- 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 encoutered property names.
- * @deprecated use {@link #attributeNames(Filter, FeatureType)}/
- */
- public static String[] attributeNames(Filter filter) {
- return attributeNames( filter, null );
- }
-
- /**
- * Traverses the expression and returns any encoutered property names.
- * <p>
- * The feautre type is supplied as contexts used to lookup expressions in cases where the
- * attributeName does not match the actual name of the type.
- * </p>
- */
- 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 encoutered property names.
- * @deprecated use {@link #attributeNames(Expression, FeatureType)}/
- */
- public static String[] attributeNames(Expression expression) {
- return attributeNames( expression, null );
- }
-
- /**
- * Compare operation for FeatureType.
- *
- * <p>
- * Results in:
- * </p>
- *
- * <ul>
- * <li>
- * 1: if typeA is a sub type/reorder/renamespace of typeB
- * </li>
- * <li>
- * 0: if typeA and typeB are the same type
- * </li>
- * <li>
- * -1: if typeA is not subtype of typeB
- * </li>
- * </ul>
- *
- * <p>
- * Comparison is based on AttributeTypes, an IOException is thrown if the
- * AttributeTypes are not compatiable.
- * </p>
- *
- * <p>
- * Namespace is not considered in this opperations. You may still need to
- * reType to get the correct namesapce, or reorder.
- * </p>
- *
- * @param typeA FeatureType beind compared
- * @param typeB FeatureType being compared against
- *
- */
- public static int compare(SimpleFeatureType typeA, SimpleFeatureType typeB) {
- 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;
-
- // may still be the same featureType
- // (Perhaps they differ on namespace?)
- int match = 0;
-
- for (int i = 0; i < countA; i++) {
- a = typeA.getDescriptor(i);
-
- if (isMatch(a, typeB.getDescriptor(i))) {
- match++;
- } else if (isMatch(a, typeB.getDescriptor(a.getLocalName()))) {
- // match was found in a different position
- } else {
- // 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)
- // if (typeA.getNamespace() == null) {
- // if(typeB.getNamespace() == null) {
- // return 0;
- // } else {
- // return 1;
- // }
- // } else if(typeA.getNamespace().equals(typeB.getNamespace())) {
- // return 0;
- // } else {
- // return 1;
- // }
- return 0;
- }
-
- return 1;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param a DOCUMENT ME!
- * @param b DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public static boolean isMatch(AttributeDescriptor a, AttributeDescriptor b) {
- if (a == b) {
- return true;
- }
-
- if (b == null) {
- return false;
- }
-
- if (a == null) {
- return false;
- }
-
- if (a.equals(b)) {
- return true;
- }
-
- if (a.getLocalName().equals(b.getLocalName())
- && a.getClass().equals(b.getClass())) {
- return true;
- }
-
- return false;
- }
-
- /**
- * Creates duplicate of feature adjusted to the provided featureType.
- *
- * @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);
- }
-
- 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.clone();
- }
-
- 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<Object> copy = new ArrayList<Object>(list.size());
-
- for (Iterator i = list.iterator(); i.hasNext();) {
- copy.add(duplicate(i.next()));
- }
-
- return Collections.unmodifiableList(copy);
- }
-
- if (src instanceof Map) {
- Map map = (Map) src;
- Map copy = new HashMap(map.size());
-
- for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
- Map.Entry entry = (Map.Entry) i.next();
- copy.put(entry.getKey(), duplicate(entry.getValue()));
- }
-
- return Collections.unmodifiableMap(copy);
- }
-
- if( src instanceof GridCoverage ){
- return src; // inmutable
- }
-
-
- //
- // I have lost hope and am returning the orgional reference
- // Please extend this to support additional classes.
- //
- // And good luck getting Cloneable to work
- throw new IllegalAttributeException("Do not know how to deep copy "
- + type.getName());
- }
-
- /**
- * Constructs an empty feature to use as a Template for new content.
- *
- * <p>
- * We may move this functionality to FeatureType.create( null )?
- * </p>
- *
- * @param featureType Type of feature we wish to create
- *
- * @return A new Feature of type featureType
- *
- * @throws IllegalAttributeException if we could not create featureType
- * instance with acceptable default values
- */
- public static SimpleFeature template(SimpleFeatureType featureType)
- throws IllegalAttributeException {
- return SimpleFeatureBuilder.build(featureType, defaultValues(featureType), null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- * @param featureID DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- */
- public static SimpleFeature template(SimpleFeatureType featureType, String featureID)
- throws IllegalAttributeException {
- return SimpleFeatureBuilder.build(featureType, defaultValues(featureType), featureID);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- */
- public static Object[] defaultValues(SimpleFeatureType featureType)
- throws IllegalAttributeException {
- return defaultValues(featureType, null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- * @param atts DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- */
- public static SimpleFeature template(SimpleFeatureType featureType, Object[] atts)
- throws IllegalAttributeException {
- return SimpleFeatureBuilder.build(featureType,defaultValues(featureType, atts),null);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- * @param featureID DOCUMENT ME!
- * @param atts DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- */
- public static SimpleFeature template(SimpleFeatureType featureType, String featureID,
- Object[] atts) throws IllegalAttributeException {
- return SimpleFeatureBuilder.build(featureType, defaultValues(featureType, atts), featureID);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- * @param values DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- * @throws ArrayIndexOutOfBoundsException DOCUMENT ME!
- */
- public static Object[] defaultValues(SimpleFeatureType featureType,
- Object[] values) throws IllegalAttributeException {
- if (values == null) {
- values = new Object[featureType.getAttributeCount()];
- } else if (values.length != featureType.getAttributeCount()) {
- throw new ArrayIndexOutOfBoundsException("values");
- }
-
- for (int i = 0; i < featureType.getAttributeCount(); i++) {
- values[i] = defaultValue(featureType.getDescriptor(i));
- }
-
- return values;
- }
-
- /**
- * Provides a defautlValue for attributeType.
- *
- * <p>
- * Will return null if attributeType isNillable(), or attempt to use
- * Reflection, or attributeType.parse( null )
- * </p>
- *
- * @param attributeType
- *
- * @return null for nillable attributeType, attempt at reflection
- *
- * @throws IllegalAttributeException If value cannot be constructed for
- * attribtueType
- */
- public static Object defaultValue(AttributeDescriptor attributeType)
- throws IllegalAttributeException {
- Object value = attributeType.getDefaultValue();
-
- if (value == null && !attributeType.isNillable()) {
- return null; // sometimes there is no valid default value :-(
- // throw new IllegalAttributeException("Got null default value for non-null type.");
- }
- return value;
- }
-
- /**
- * Returns a non-null default value for the class that is passed in. This is a helper class an can't create a
- * default class for any type but it does support:
- * <ul>
- * <li>String</li>
- * <li>Object - will return empty string</li>
- * <li>Number</li>
- * <li>Character</li>
- * <li>JTS Geometries</li>
- * </ul>
- *
- *
- * @param type
- * @return
- */
- public static Object defaultValue(Class type){
- if( type==String.class || type==Object.class){
- return "";
- }
- if( type==Integer.class ){
- return new Integer(0);
- }
- if( type==Double.class ){
- return new Double(0);
- }
- if( type==Long.class ){
- return new Long(0);
- }
- if( type==Short.class ){
- return new Short((short)0);
- }
- if( type==Float.class ){
- return new Float(0.0f);
- }
- if( type==BigDecimal.class){
- return BigDecimal.valueOf(0);
- }
- if( type==BigInteger.class){
- return BigInteger.valueOf(0);
- }
- if( type==Character.class ){
- return new Character(' ');
- }
- if( type==Boolean.class){
- return Boolean.FALSE;
- }
- if( type==Timestamp.class)
- return new Timestamp(System.currentTimeMillis());
- if( type==java.sql.Date.class)
- return new java.sql.Date(System.currentTimeMillis());
- if( type==java.sql.Time.class)
- return new java.sql.Time(System.currentTimeMillis());
- if( type==java.util.Date.class)
- return new java.util.Date();
-
-
- GeometryFactory fac=new GeometryFactory();
- Coordinate coordinate = new Coordinate(0, 0);
- Point point = fac.createPoint(coordinate);
-
- if( type==Point.class ){
- return point;
- }
- if( type==MultiPoint.class ){
- return fac.createMultiPoint(new Point[]{point});
- }
- if( type==LineString.class ){
- return fac.createLineString(new Coordinate[]{coordinate,coordinate,coordinate,coordinate});
- }
- LinearRing linearRing = fac.createLinearRing(new Coordinate[]{coordinate,coordinate,coordinate,coordinate});
- if( type==LinearRing.class ){
- return linearRing;
- }
- if( type==MultiLineString.class ){
- return fac.createMultiLineString(new LineString[]{linearRing});
- }
- Polygon polygon = fac.createPolygon(linearRing, new LinearRing[0]);
- if( type==Polygon.class ){
- return polygon;
- }
- if( type==MultiPolygon.class ){
- return fac.createMultiPolygon(new Polygon[]{polygon});
- }
- if( type==Geometry.class ){
- ArrayList<Geometry> gl = new ArrayList<Geometry>();
- gl.add(polygon);
- gl.add(linearRing);
- gl.add(point);
- return fac.buildGeometry(gl);
- }
-
- throw new IllegalArgumentException(type+" is not supported by this method");
- }
- /**
- * Creates a FeatureReader<SimpleFeatureType, SimpleFeature> for testing.
- *
- * @param features Array of features
- *
- * @return FeatureReader<SimpleFeatureType, SimpleFeature> spaning provided feature array
- *
- * @throws IOException If provided features Are null or empty
- * @throws NoSuchElementException DOCUMENT ME!
- */
- public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(final SimpleFeature[] features)
- throws IOException {
- if ((features == null) || (features.length == 0)) {
- throw new IOException("Provided features where empty");
- }
-
- return new FeatureReader<SimpleFeatureType, SimpleFeature>() {
- SimpleFeature[] array = features;
- int offset = -1;
-
- public SimpleFeatureType getFeatureType() {
- return features[0].getFeatureType();
- }
-
- public SimpleFeature next(){
- if (!hasNext()) {
- throw new NoSuchElementException("No more features");
- }
-
- return array[++offset];
- }
-
- public boolean hasNext(){
- return (array != null) && (offset < (array.length - 1));
- }
-
- public void close(){
- array = null;
- offset = -1;
- }
- };
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureArray DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IOException DOCUMENT ME!
- * @throws RuntimeException DOCUMENT ME!
- */
- public static FeatureSource<SimpleFeatureType, SimpleFeature> source(final SimpleFeature[] featureArray) {
- final SimpleFeatureType featureType;
-
- if ((featureArray == null) || (featureArray.length == 0)) {
- featureType = FeatureTypes.EMPTY;
- } else {
- featureType = featureArray[0].getFeatureType();
- }
-
- DataStore arrayStore = new AbstractDataStore() {
- public String[] getTypeNames() {
- return new String[] { featureType.getTypeName() };
- }
-
- public SimpleFeatureType getSchema(String typeName)
- throws IOException {
- if ((typeName != null)
- && typeName.equals(featureType.getTypeName())) {
- return featureType;
- }
-
- throw new IOException(typeName + " not available");
- }
-
- protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName)
- throws IOException {
- return reader(featureArray);
- }
- };
-
- try {
- return arrayStore.getFeatureSource(arrayStore.getTypeNames()[0]);
- } catch (IOException e) {
- throw new RuntimeException(
- "Something is wrong with the geotools code, "
- + "this exception should not happen", e);
- }
- }
-
- /**
- * Wrap up the provided FeatureCollection as a feature soruce; allowing queries to be performed etc...
- *
- * @param collection FeatureCollection
- *
- * @return FeatureSource
- *
- * @throws NullPointerException If the collection is null
- * @throws RuntimeException
- */
- public static FeatureSource<SimpleFeatureType, SimpleFeature> source(final FeatureCollection<SimpleFeatureType, SimpleFeature> collection) {
- if (collection == null) {
- throw new NullPointerException();
- }
-
- DataStore store = new CollectionDataStore(collection);
-
- try {
- return store.getFeatureSource(store.getTypeNames()[0]);
- } catch (IOException e) {
- throw new RuntimeException(
- "FeatureCollection is not consistent, unable to access contents", e);
- }
- }
-
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> results(SimpleFeature[] featureArray){
- return results(collection(featureArray));
- }
-
- /**
- * Returns collection if non empty.
- *
- * @param collection
- *
- * @return provided collection
- *
- * @throws IOException Raised if collection was empty
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> results(final FeatureCollection<SimpleFeatureType, SimpleFeature> collection){
- if (collection.size() == 0) {
- //throw new IOException("Provided collection was empty");
- }
- return collection;
- }
-
- /**
- * Adapt a collection to a reader for use with FeatureStore.setFeatures( reader ).
- *
- * @param collection Collection of SimpleFeature
- *
- * @return FeatureRedaer over the provided contents
- * @throws IOException IOException if there is any problem reading the content.
- */
- public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(Collection<SimpleFeature> collection)
- throws IOException {
- return reader(collection.toArray(
- new SimpleFeature[collection.size()]));
- }
- /**
- * Adapt a collection to a reader for use with FeatureStore.setFeatures( reader ).
- *
- * @param collection Collection of SimpleFeature
- *
- * @return FeatureRedaer over the provided contents
- * @throws IOException IOException if there is any problem reading the content.
- */
- public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(
- FeatureCollection<SimpleFeatureType,SimpleFeature> collection) throws IOException {
- return reader(collection
- .toArray(new SimpleFeature[collection.size()]));
- }
-
- /**
- * Copies the provided features into a FeatureCollection.
- * <p>
- * Often used when gathering features for FeatureStore:<pre><code>
- * featureStore.addFeatures( DataUtilities.collection(array));
- * </code></pre>
- *
- * @param features Array of features
- * @return FeatureCollection
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(SimpleFeature[] features) {
- FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
- final int length = features.length;
- for (int i = 0; i < length; i++) {
- collection.add(features[i]);
- }
- return collection;
- }
- /**
- * Copies the provided features into a FeatureCollection.
- * <p>
- * Often used when gathering a FeatureCollection<SimpleFeatureType, SimpleFeature> into memory.
- *
- * @param FeatureCollection<SimpleFeatureType, SimpleFeature> the features to add to a new feature collection.
- * @return FeatureCollection
- */
- public static DefaultFeatureCollection collection( FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection ){
- return new DefaultFeatureCollection( featureCollection );
- }
- /**
- * Copies the provided fetaures into a List.
- *
- * @param featureCollection
- * @return List of features copied into memory
- */
- public static List<SimpleFeature> list( FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection ){
- final ArrayList<SimpleFeature> list = new ArrayList<SimpleFeature>();
- try {
- featureCollection.accepts( new FeatureVisitor(){
- public void visit(Feature feature) {
- list.add( (SimpleFeature) feature );
- }
- }, null );
- }
- catch( IOException ignore ){
- }
- return list;
- }
- /**
- * Copies the feature ids from each and every feature into a set.
- * <p>
- * This method can be slurp an in memory record of the contents of a
- * @param featureCollection
- * @return
- */
- public static Set<String> fidSet( FeatureCollection<?,?> featureCollection ){
- final HashSet<String> fids = new HashSet<String>();
- try {
- featureCollection.accepts( new FeatureVisitor(){
- public void visit(Feature feature) {
- fids.add( feature.getIdentifier().getID() );
- }
- }, null );
- }
- catch( IOException ignore ){
- }
- return fids;
- }
- /**
- * Copies the provided features into a FeatureCollection.
- * <p>
- * Often used when gathering a FeatureCollection<SimpleFeatureType, SimpleFeature> into memory.
- *
- * @param list features to add to a new FeatureCollection
- * @return FeatureCollection
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection( List<SimpleFeature> list ) {
- FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
- for ( SimpleFeature feature : list ){
- collection.add( feature );
- }
- return collection;
- }
-
-
- /**
- * Copies the provided features into a FeatureCollection.
- * <p>
- * Often used when gathering features for FeatureStore:<pre><code>
- * featureStore.addFeatures( DataUtilities.collection(feature));
- * </code></pre>
- *
- * @param feature a feature to add to a new collection
- * @return FeatureCollection
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection( SimpleFeature feature ){
- FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
- collection.add(feature);
- return collection;
- }
-
- /**
- * Copies the provided reader into a FeatureCollection, reader will be closed.
- * <p>
- * Often used when gathering features for FeatureStore:<pre><code>
- * featureStore.addFeatures( DataUtilities.collection(reader));
- * </code></pre>
- *
- * @return FeatureCollection
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(FeatureReader <SimpleFeatureType, SimpleFeature> reader) throws IOException {
- FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
- try {
- while( reader.hasNext() ) {
- try {
- collection.add( reader.next() );
- } catch (NoSuchElementException e) {
- throw (IOException) new IOException("EOF").initCause( e );
- } catch (IllegalAttributeException e) {
- throw (IOException) new IOException().initCause( e );
- }
- }
- }
- finally {
- reader.close();
- }
- return collection;
- }
- /**
- * Copies the provided reader into a FeatureCollection, reader will be closed.
- * <p>
- * Often used when gathering features for FeatureStore:<pre><code>
- * featureStore.addFeatures( DataUtilities.collection(reader));
- * </code></pre>
- *
- * @return FeatureCollection
- */
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(FeatureIterator<SimpleFeature> reader) throws IOException {
- FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
- try {
- while( reader.hasNext() ) {
- try {
- collection.add( reader.next() );
- } catch (NoSuchElementException e) {
- throw (IOException) new IOException("EOF").initCause( e );
- }
- }
- }
- finally {
- reader.close();
- }
- return collection;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param att DOCUMENT ME!
- * @param otherAtt DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public static boolean attributesEqual(Object att, Object otherAtt) {
- if (att == null) {
- if (otherAtt != null) {
- return false;
- }
- } else {
- if (!att.equals(otherAtt)) {
- if (att instanceof Geometry && otherAtt instanceof Geometry) {
- // we need to special case Geometry
- // as JTS is broken
- // Geometry.equals( Object ) and Geometry.equals( Geometry )
- // are different
- // (We should fold this knowledge into AttributeType...)
- //
- if (!((Geometry) att).equals((Geometry) otherAtt)) {
- return false;
- }
- } else {
- return false;
- }
- }
- }
-
- return true;
- }
-
- /**
- * Create a derived FeatureType
- *
- * <p></p>
- *
- * @param featureType
- * @param properties - if null, every property of the feature type in input will be used
- * @param override
- *
- *
- * @throws SchemaException
- */
- public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
- String[] properties, CoordinateReferenceSystem override)
- throws SchemaException {
- URI namespaceURI = null;
- if ( featureType.getName().getNamespaceURI() != null ) {
- try {
- namespaceURI = new URI( featureType.getName().getNamespaceURI() );
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
- }
-
- return createSubType( featureType, properties, override, featureType.getTypeName(), namespaceURI );
-
- }
-
- public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
- String[] properties, CoordinateReferenceSystem override, String typeName, URI namespace )
- throws SchemaException {
-
- if ((properties == null) && (override == null)) {
- return featureType;
- }
-
- if(properties == null) {
- properties = new String[featureType.getAttributeCount()];
- for (int i = 0; i < properties.length; i++) {
- properties[i] = featureType.getDescriptor(i).getLocalName();
- }
- }
-
- String namespaceURI = namespace != null ? namespace.toString() : null;
- boolean same = featureType.getAttributeCount() == properties.length &&
- featureType.getTypeName().equals( typeName ) &&
- Utilities.equals(featureType.getName().getNamespaceURI(), namespaceURI );
-
-
- for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
- AttributeDescriptor type = featureType.getDescriptor(i);
- same = type.getLocalName().equals(properties[i])
- && (((override != null)
- && type instanceof GeometryDescriptor)
- ? assertEquals(override, ((GeometryDescriptor) type).getCoordinateReferenceSystem())
- : true);
- }
-
- if (same) {
- return featureType;
- }
-
- AttributeDescriptor[] types = new AttributeDescriptor[properties.length];
-
- for (int i = 0; i < properties.length; i++) {
- types[i] = featureType.getDescriptor(properties[i]);
-
- if ((override != null) && types[i] instanceof GeometryDescriptor) {
- AttributeTypeBuilder ab = new AttributeTypeBuilder();
- ab.init( types[i] );
- ab.setCRS(override);
- types[i] = ab.buildDescriptor(types[i].getLocalName(), ab.buildGeometryType());
- }
- }
-
- if( typeName == null ) typeName = featureType.getTypeName();
- if( namespace == null && featureType.getName().getNamespaceURI() != null )
- try {
- namespace = new URI(featureType.getName().getNamespaceURI());
- } catch (URISyntaxException e) {
- throw new RuntimeException(e);
- }
-
-
-
- SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
- tb.setName( typeName );
- tb.setNamespaceURI( namespace );
- tb.addAll(types);
-
- return tb.buildFeatureType();
- }
-
- private static boolean assertEquals(Object o1, Object o2){
- return o1 == null && o2 == null? true :
- (o1 != null? o1.equals(o2) : false);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param featureType DOCUMENT ME!
- * @param properties DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws SchemaException DOCUMENT ME!
- */
- public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
- String[] properties) throws SchemaException {
- if (properties == null) {
- return featureType;
- }
-
- boolean same = featureType.getAttributeCount() == properties.length;
-
- for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
- same = featureType.getDescriptor(i).getLocalName().equals(properties[i]);
- }
-
- if (same) {
- return featureType;
- }
-
- SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
- tb.setName( featureType.getName() );
-
- for (int i = 0; i < properties.length; i++) {
- tb.add( featureType.getDescriptor(properties[i]) );
- }
- return tb.buildFeatureType();
- }
-
- /**
- * Utility method for FeatureType construction.
- * <p>
- * Will parse a String of the form: <i>"name:Type,name2:Type2,..."</i>
- * </p>
- *
- * <p>
- * Where <i>Type</i> is defined by createAttribute.
- * </p>
- *
- * <p>
- * You may indicate the default Geometry with an astrix: "*geom:Geometry". You
- * may also indicate the srid (used to look up a EPSG code).
- * </p>
- *
- * <p>
- * Examples:
- * <ul>
- * <li><code>name:"",age:0,geom:Geometry,centroid:Point,url:java.io.URL"</code>
- * <li><code>id:String,polygonProperty:Polygon:srid=32615</code>
- * </ul>
- * </p>
- *
- * @param identification identification of FeatureType:
- * (<i>namesapce</i>).<i>typeName</i>
- * @param typeSpec Specification for FeatureType
- *
- *
- * @throws SchemaException
- */
- public static SimpleFeatureType createType(String identification, String typeSpec)
- throws SchemaException {
- int split = identification.lastIndexOf('.');
- String namespace = (split == -1) ? null
- : identification.substring(0, split);
- String typeName = (split == -1) ? identification
- : identification.substring(split + 1);
-
- return createType(namespace, typeName, typeSpec);
- }
-
- /**
- * Utility method for FeatureType construction.
- * <p>
- * Will parse a String of the form: <i>"name:Type,name2:Type2,..."</i>
- * </p>
- *
- * <p>
- * Where <i>Type</i> is defined by createAttribute.
- * </p>
- *
- * <p>
- * You may indicate the default Geometry with an astrix: "*geom:Geometry". You
- * may also indicate the srid (used to look up a EPSG code).
- * </p>
- *
- * <p>
- * Examples:
- * <ul>
- * <li><code>name:"",age:0,geom:Geometry,centroid:Point,url:java.io.URL"</code>
- * <li><code>id:String,polygonProperty:Polygon:srid=32615</code>
- * </ul>
- * </p>
- *
- * @param identification identification of FeatureType:
- * (<i>namesapce</i>).<i>typeName</i>
- * @param typeSpec Specification for FeatureType
- *
- *
- * @throws SchemaException
- */
- public static SimpleFeatureType createType(String namespace, String typeName, String typeSpec)
- throws SchemaException {
- SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
- tb.setName( typeName );
- tb.setNamespaceURI(namespace);
-
- String[] types = typeSpec.split(",");
-
- AttributeDescriptor attributeType;
-
- for (int i = 0; i < types.length; i++) {
- boolean defaultGeometry = types[i].startsWith("*");
- if (types[i].startsWith("*")) {
- types[i] = types[i].substring(1);
- }
-
- attributeType = createAttribute(types[i]);
- tb.add(attributeType);
-
- if ( defaultGeometry ) {
- tb.setDefaultGeometry(attributeType.getLocalName());
- }
- }
-
- return tb.buildFeatureType();
- }
-
-
-
-
- /**
- * DOCUMENT ME!
- *
- * @param type DOCUMENT ME!
- * @param fid DOCUMENT ME!
- * @param text DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- *
- * @throws IllegalAttributeException DOCUMENT ME!
- */
- public static SimpleFeature parse(SimpleFeatureType type, String fid, String[] text)
- throws IllegalAttributeException {
- Object[] attributes = new Object[text.length];
-
- for (int i = 0; i < text.length; i++) {
- AttributeType attType = type.getDescriptor(i).getType();
- attributes[i] = Converters.convert(text[i], attType.getBinding());
- }
-
- return SimpleFeatureBuilder.build(type, attributes, fid);
- }
-
- /**
- * A "quick" String representation of a FeatureType.
- * <p>
- * This string representation may be used with createType( name, spec ).
- * </p>
- * @param featureType FeatureType to represent
- *
- * @return The string "specification" for the featureType
- */
- public static String spec(FeatureType featureType) {
- Collection<PropertyDescriptor> types = featureType.getDescriptors();
- StringBuffer buf = new StringBuffer();
-
- for( PropertyDescriptor type : types ){
- buf.append(type.getName().getLocalPart());
- buf.append(":");
- buf.append(typeMap(type.getType().getBinding()));
- if(type instanceof GeometryDescriptor) {
- GeometryDescriptor gd = (GeometryDescriptor) type;
- if(gd.getCoordinateReferenceSystem() != null && gd.getCoordinateReferenceSystem().getIdentifiers() != null) {
- for (Iterator<ReferenceIdentifier> it = gd.getCoordinateReferenceSystem().getIdentifiers().iterator(); it.hasNext();) {
- ReferenceIdentifier id = it.next();
-
- if ((id.getAuthority() != null)
- && id.getAuthority().getTitle().equals(Citations.EPSG.getTitle())) {
- buf.append(":srid=" + id.getCode());
- break;
- }
-
- }
- }
- }
- buf.append(",");
- }
- buf.delete(buf.length()-1,buf.length()); // remove last ","
-
- return buf.toString();
- }
-
- static Class type(String typeName) throws ClassNotFoundException {
- if (typeMap.containsKey(typeName)) {
- return typeMap.get(typeName);
- }
-
- return Class.forName(typeName);
- }
-
- static String typeMap(Class type) {
- if( typeEncode.containsKey(type)){
- return typeEncode.get( type );
- }
- /*
- SortedSet<String> choose = new TreeSet<String>();
- for (Iterator i = typeMap.entrySet().iterator(); i.hasNext();) {
- Map.Entry entry = (Entry) i.next();
-
- if (entry.getValue().equals(type)) {
- choose.add( (String) entry.getKey() );
- }
- }
- if( !choose.isEmpty() ){
- return choose.last();
- }
- */
- return type.getName();
- }
-
- /**
- * Takes two {@link Query}objects and produce a new one by mixing the
- * restrictions of both of them.
- *
- * <p>
- * The policy to mix the queries components is the following:
- *
- * <ul>
- * <li>
- * typeName: type names MUST match (not checked if some or both queries
- * equals to <code>Query.ALL</code>)
- * </li>
- * <li>
- * handle: you must provide one since no sensible choice can be done
- * between the handles of both queries
- * </li>
- * <li>
- * maxFeatures: the lower of the two maxFeatures values will be used (most
- * restrictive)
- * </li>
- * <li>
- * attributeNames: the attributes of both queries will be joined in a
- * single set of attributes. IMPORTANT: only <b><i>explicitly</i></b>
- * requested attributes will be joint, so, if the method
- * <code>retrieveAllProperties()</code> of some of the queries returns
- * <code>true</code> it does not means that all the properties will be
- * joined. You must create the query with the names of the properties you
- * want to load.
- * </li>
- * <li>
- * filter: the filtets of both queries are or'ed
- * </li>
- * <li>
- * <b>any other query property is ignored</b> and no guarantees are made of
- * their return values, so client code shall explicitly care of hints, startIndex, etc.,
- * if needed.
- * </li>
- * </ul>
- * </p>
- *
- * @param firstQuery Query against this DataStore
- * @param secondQuery DOCUMENT ME!
- * @param handle DOCUMENT ME!
- *
- * @return Query restricted to the limits of definitionQuery
- *
- * @throws NullPointerException if some of the queries is null
- * @throws IllegalArgumentException if the type names of both queries do
- * not match
- */
- public static Query mixQueries(Query firstQuery, Query secondQuery,
- String handle) {
- if ((firstQuery == null) || (secondQuery == null)) {
- throw new NullPointerException("got a null query argument");
- }
-
- if (firstQuery.equals(Query.ALL)) {
- return secondQuery;
- } else if (secondQuery.equals(Query.ALL)) {
- return firstQuery;
- }
-
- if ((firstQuery.getTypeName() != null)
- && (secondQuery.getTypeName() != null)) {
- if (!firstQuery.getTypeName().equals(secondQuery.getTypeName())) {
- String msg = "Type names do not match: "
- + firstQuery.getTypeName() + " != "
- + secondQuery.getTypeName();
- throw new IllegalArgumentException(msg);
- }
- }
-
- // mix versions, if possible
- String version;
- if(firstQuery.getVersion() != null) {
- if(secondQuery.getVersion() != null && !secondQuery.getVersion().equals(firstQuery.getVersion()))
- throw new IllegalArgumentException("First and second query refer different versions");
- version = firstQuery.getVersion();
- } else {
- version = secondQuery.getVersion();
- }
-
-
- //none of the queries equals Query.ALL, mix them
- //use the more restrictive max features field
- int maxFeatures = Math.min(firstQuery.getMaxFeatures(),
- secondQuery.getMaxFeatures());
-
- //join attributes names
- String[] propNames = joinAttributes(firstQuery.getPropertyNames(),
- secondQuery.getPropertyNames());
-
- //join filters
- Filter filter = firstQuery.getFilter();
- Filter filter2 = secondQuery.getFilter();
-
- if ((filter == null) || filter.equals(Filter.INCLUDE)) {
- filter = filter2;
- } else if ((filter2 != null) && !filter2.equals(Filter.INCLUDE)) {
- filter = ff.and( filter, filter2);
- }
- Integer start=0;
- if( firstQuery.getStartIndex() != null ){
- start = firstQuery.getStartIndex();
- }
- if( secondQuery.getStartIndex() != null ){
- start += secondQuery.getStartIndex();
- }
- //build the mixed query
- String typeName = firstQuery.getTypeName() != null?
- firstQuery.getTypeName() : secondQuery.getTypeName();
-
- DefaultQuery mixed = new DefaultQuery(typeName, filter, maxFeatures, propNames, handle);
- mixed.setVersion(version);
- if(start != 0){
- mixed.setStartIndex(start);
- }
- return mixed;
- }
-
- /**
- * Creates a set of attribute names from the two input lists of names,
- * maintaining the order of the first list and appending the non repeated
- * names of the second.
- * <p>
- * In the case where both lists are <code>null</code>, <code>null</code>
- * is returned.
- * </p>
- *
- * @param atts1 the first list of attribute names, who's order will be
- * maintained
- * @param atts2 the second list of attribute names, from wich the non
- * repeated names will be appended to the resulting list
- *
- * @return Set of attribute names from <code>atts1</code> and
- * <code>atts2</code>
- */
- private static String[] joinAttributes(String[] atts1, String[] atts2) {
- String[] propNames = null;
-
- if ( atts1 == null && atts2 == null ) {
- return null;
- }
-
- List<String> atts = new LinkedList<String>();
-
- if (atts1 != null) {
- atts.addAll(Arrays.asList(atts1));
- }
-
- if (atts2 != null) {
- for (int i = 0; i < atts2.length; i++) {
- if (!atts.contains(atts2[i])) {
- atts.add(atts2[i]);
- }
- }
- }
-
- propNames = new String[atts.size()];
- atts.toArray(propNames);
-
- return propNames;
- }
-
- /**
- * Returns AttributeType based on String specification (based on UML).
- *
- * <p>
- * Will parse a String of the form: <i>"name:Type:hint"</i>
- * </p>
- *
- * <p>
- * Where <i>Type</i> is:
- * </p>
- *
- * <ul>
- * <li>
- * 0,Interger,int: represents Interger
- * </li>
- * <li>
- * 0.0, Double, double: represents Double
- * </li>
- * <li>
- * "",String,string: represents String
- * </li>
- * <li>
- * Geometry: represents Geometry
- * </li>
- * <li>
- * <i>full.class.path</i>: represents java type
- * </li>
- * </ul>
- *
- * <p>
- * Where <i>hint</i> is "hint1;hint2;...;hintN", in which "hintN" is one
- * of:
- * <ul>
- * <li><code>nillable</code></li>
- * <li><code>srid=<#></code></li>
- * </ul>
- * </p>
- *
- * @param typeSpec
- *
- *
- * @throws SchemaException If typeSpect could not be interpreted
- */
- static AttributeDescriptor createAttribute(String typeSpec)
- throws SchemaException {
- int split = typeSpec.indexOf(":");
-
- String name;
- String type;
- String hint = null;
-
- if (split == -1) {
- name = typeSpec;
- type = "String";
- } else {
- name = typeSpec.substring(0, split);
-
- int split2 = typeSpec.indexOf(":", split + 1);
-
- if (split2 == -1) {
- type = typeSpec.substring(split + 1);
- } else {
- type = typeSpec.substring(split + 1, split2);
- hint = typeSpec.substring(split2 + 1);
- }
- }
-
- try {
- boolean nillable = true;
- CoordinateReferenceSystem crs = null;
-
- if ( hint != null ) {
- StringTokenizer st = new StringTokenizer( hint, ";" );
- while ( st.hasMoreTokens() ) {
- String h = st.nextToken();
- h = h.trim();
-
- //nillable?
- //JD: i am pretty sure this hint is useless since the
- // default is to make attributes nillable
- if ( h.equals( "nillable" )) {
- nillable = true;
- }
- //spatial reference identieger?
- if ( h.startsWith("srid=" )) {
- String srid = h.split("=")[1];
- Integer.parseInt( srid );
- try {
- crs = CRS.decode( "EPSG:" + srid );
- }
- catch( Exception e ) {
- String msg = "Error decoding srs: " + srid;
- throw new SchemaException( msg, e );
- }
- }
- }
- }
-
- Class clazz = type(type);
- if(Geometry.class.isAssignableFrom(clazz)) {
- GeometryType at = new GeometryTypeImpl(new NameImpl( name ), clazz , crs, false, false, Collections.EMPTY_LIST, null, null );
- return new GeometryDescriptorImpl( at, new NameImpl(name), 0,1, nillable, null );
- } else {
- AttributeType at = new AttributeTypeImpl( new NameImpl( name ), clazz , false, false, Collections.EMPTY_LIST, null, null );
- return new AttributeDescriptorImpl( at, new NameImpl(name), 0,1, nillable, null );
- }
- } catch (ClassNotFoundException e) {
- throw new SchemaException("Could not type " + name + " as:" + type, e);
- }
- }
-
- /**
- * Manually calculates the bounds of a feature collection.
- *
- * @param collection
- * @return
- */
- public static Envelope bounds(
- FeatureCollection<? extends FeatureType, ? extends Feature> collection) {
- FeatureIterator<? extends Feature> i = collection.features();
- try {
- ReferencedEnvelope bounds = new ReferencedEnvelope(collection.getSchema()
- .getCoordinateReferenceSystem());
- if (!i.hasNext()) {
- bounds.setToNull();
- return bounds;
- }
-
- bounds.init(((SimpleFeature) i.next()).getBounds());
- return bounds;
- } finally {
- i.close();
- }
- }
-
-
- /**
- * Changes the ending (e.g. ".sld") of a {@link URL}
- *
- * @param url
- * {@link URL} like <code>file:/sds/a.bmp</code> or
- * <code>http://www.some.org/foo/bar.shp</code>
- * @param postfix
- * New file extension for the {@link URL} without <code>.</code>
- *
- * @return A new {@link URL} with new extension.
- *
- * @throws {@link MalformedURLException} if the new {@link URL} can not be
- * created.
- */
- public static URL changeUrlExt(final URL url, final String postfix)
- throws IllegalArgumentException {
- String a = url.toExternalForm();
- final int lastDotPos = a.lastIndexOf('.');
- if (lastDotPos >= 0)
- a = a.substring(0, lastDotPos);
- a = a + "." + postfix;
- try {
- return new URL(a);
- } catch (final MalformedURLException e) {
- throw new IllegalArgumentException("can't create a new URL for "+ url + " with new extension " + postfix, e);
- }
- }
-
- /**
- * The function is supposed to be equivalent to {@link File}.getParent().
- * The {@link URL} is converted to a String, truncated to the last / and
- * then recreated as a new URL.
- *
- * @throws {@link MalformedURLException} if the parent {@link URL} can not
- * be created.
- */
- public static URL getParentUrl(final URL url) throws MalformedURLException {
- String a = url.toExternalForm();
- final int lastDotPos = a.lastIndexOf('/');
- if (lastDotPos >= 0)
- a = a.substring(0, lastDotPos);
-
- /**
- * The parent of jar:file:some!/bar.file is jar:file:some!/, not jar:file:some!
- */
- if (a.endsWith("!")) a+="/";
-
- return new URL(a);
- }
-
- /**
- * Extends an {@link URL}.
- *
- * @param base
- * Has to be a {@link URL} pointing to a directory. If it doesn't
- * end with a <code>/</code> it will be added automatically.
- * @param extension
- * The part that will be added to the {@link URL}
- *
- * @throws MalformedURLException
- * if the new {@link URL} can not be created.
- */
- public static URL extendURL(URL base, String extension)
- throws MalformedURLException {
- if(base==null)
- throw new NullPointerException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1,"base"));
- if(extension==null)
- throw new NullPointerException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1,"extension"));
- String a = base.toExternalForm();
- if (!a.endsWith("/"))
- a += "/";
- a += extension;
- return new URL(a);
- }
-
- /**
- * Checks that a {@link File} is a real file, exists and is readable.
- *
- * @param file the {@link File} instance to check. Must not be null.
- * @param logger an optional {@link Logger} (can be null) where to log detailed
- * info about the file properties (path/readable/hidden/writable)
- *
- * @return {@code true} in case the file is a real file, exists and is readable;
- * {@code false} otherwise.
- */
- public static boolean checkFileReadable(final File file, final Logger logger) {
- if (logger != null && logger.isLoggable(Level.FINE)) {
- final StringBuilder builder = new StringBuilder("Checking file:")
- .append(file.getAbsolutePath()).append("\n")
- .append("canRead:").append(file.canRead()).append("\n")
- .append("isHidden:").append(file.isHidden()).append("\n")
- .append("isFile").append(file.isFile()).append("\n")
- .append("canWrite").append(file.canWrite()).append("\n");
- logger.fine(builder.toString());
- }
- if (!file.exists() || !file.canRead() || !file.isFile())
- return false;
- return true;
- }
-
- /**
- * Checks that the provided directory path refers to an existing/readable directory.
- * Finally, return it as a normalized directory path (removing double and single dot path steps
- * if any) followed by the separator char if missing ({@code '/'} On UNIX systems; {@code '\\}
- * on Microsoft Windows systems.
- *
- * @param directoryPath the input directory path. Must not be null.
- * @return the re-formatted directory path.
- * @throws IllegalArgumentException in case the specified path doesn't rely on a
- * existing/readable directory.
- */
- public static File checkDirectory(File file)
- throws IllegalArgumentException {
- String directoryPath = file.getPath();
- File inDir = file;
- if(!inDir.isDirectory()){
- throw new IllegalArgumentException("Not a directory: "+directoryPath );
- }
- if (!inDir.canRead()) {
- throw new IllegalArgumentException("Not a writable directory: "+ directoryPath );
- }
- try {
- directoryPath = inDir.getCanonicalPath();
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
- /*
- directoryPath = FilenameUtils.normalize(directoryPath);
- if (!directoryPath.endsWith(File.separator)){
- directoryPath = directoryPath + File.separator;
- }
- */
- // test to see if things are still good
- inDir = new File(directoryPath);
- if(!inDir.isDirectory()){
- throw new IllegalArgumentException("Not a directory: "+directoryPath );
- }
- if (!inDir.canRead()) {
- throw new IllegalArgumentException("Not a writable directory: "+ directoryPath );
- }
- return new File(directoryPath);
- }
-
- /**
- * 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;
- }
- };
- }
-
-}
+///*
+// * GeoTools - The Open Source Java GIS Toolkit
+// * http://geotools.org
+// *
+// * (C) 2003-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.File;
+//import java.io.FilenameFilter;
+//import java.io.IOException;
+//import java.io.UnsupportedEncodingException;
+//import java.lang.reflect.Array;
+//import java.math.BigDecimal;
+//import java.math.BigInteger;
+//import java.net.MalformedURLException;
+//import java.net.URI;
+//import java.net.URISyntaxException;
+//import java.net.URL;
+//import java.net.URLDecoder;
+//import java.sql.Timestamp;
+//import java.util.ArrayList;
+//import java.util.Arrays;
+//import java.util.Collection;
+//import java.util.Collections;
+//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.logging.Level;
+//import java.util.logging.Logger;
+//
+//import org.apache.commons.io.filefilter.IOFileFilter;
+//import org.geotools.data.collection.CollectionDataStore;
+//import org.geotools.factory.CommonFactoryFinder;
+//import org.geotools.feature.AttributeTypeBuilder;
+//import org.geotools.feature.DefaultFeatureCollection;
+//import org.geotools.feature.FeatureCollection;
+//import org.geotools.feature.FeatureCollections;
+//import org.geotools.feature.FeatureIterator;
+//import org.geotools.feature.FeatureTypes;
+//import org.geotools.feature.IllegalAttributeException;
+//import org.geotools.feature.NameImpl;
+//import org.geotools.feature.SchemaException;
+//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.geometry.jts.ReferencedEnvelope;
+//import org.geotools.metadata.iso.citation.Citations;
+//import org.geotools.referencing.CRS;
+//import org.geotools.resources.Utilities;
+//import org.geotools.resources.i18n.ErrorKeys;
+//import org.geotools.resources.i18n.Errors;
+//import org.geotools.util.Converters;
+//import org.opengis.coverage.grid.GridCoverage;
+//import org.opengis.feature.Feature;
+//import org.opengis.feature.FeatureVisitor;
+//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.PropertyDescriptor;
+//import org.opengis.filter.Filter;
+//import org.opengis.filter.FilterFactory;
+//import org.opengis.filter.expression.Expression;
+//import org.opengis.referencing.ReferenceIdentifier;
+//import org.opengis.referencing.crs.CoordinateReferenceSystem;
+//
+//import com.vividsolutions.jts.geom.Coordinate;
+//import com.vividsolutions.jts.geom.Envelope;
+//import com.vividsolutions.jts.geom.Geometry;
+//import com.vividsolutions.jts.geom.GeometryCollection;
+//import com.vividsolutions.jts.geom.GeometryFactory;
+//import com.vividsolutions.jts.geom.LineString;
+//import com.vividsolutions.jts.geom.LinearRing;
+//import com.vividsolutions.jts.geom.MultiLineString;
+//import com.vividsolutions.jts.geom.MultiPoint;
+//import com.vividsolutions.jts.geom.MultiPolygon;
+//import com.vividsolutions.jts.geom.Point;
+//import com.vividsolutions.jts.geom.Polygon;
+//
+///**
+// * Utility functions for use when implementing working with data classes.
+// * <p>
+// * TODO: Move FeatureType manipulation to feature package
+// * </p>
+// * @author Jody Garnett, Refractions Research
+// * @source $URL$
+// */
+//public class DataUtilities {
+//
+// static Map<String,Class> typeMap = new HashMap<String,Class>();
+// static Map<Class,String> typeEncode = new HashMap<Class,String>();
+//
+// static FilterFactory ff = CommonFactoryFinder.getFilterFactory( null );
+//
+// 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( Geometry.class, "Geometry");
+// typeMap.put("Geometry", Geometry.class);
+//
+// typeEncode.put( Point.class, "Point");
+// typeMap.put("Point", Point.class);
+//
+// typeEncode.put( LineString.class, "LineString");
+// typeMap.put("LineString", LineString.class);
+//
+// typeEncode.put( Polygon.class, "Polygon");
+// typeMap.put("Polygon", Polygon.class);
+//
+// typeEncode.put( MultiPoint.class, "MultiPoint");
+// typeMap.put("MultiPoint", MultiPoint.class);
+//
+// typeEncode.put( MultiLineString.class, "MultiLineString");
+// typeMap.put("MultiLineString", MultiLineString.class);
+//
+// typeEncode.put( MultiPolygon.class, "MultiPolygon");
+// typeMap.put("MultiPolygon", MultiPolygon.class);
+//
+// typeEncode.put( GeometryCollection.class, "GeometryCollection");
+// typeMap.put("GeometryCollection", GeometryCollection.class);
+//
+// typeEncode.put( Date.class, "Date");
+// typeMap.put("Date",Date.class);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// */
+// 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;
+// }
+//
+// /**
+// * A replacement for File.toURI().toURL().
+// * <p>
+// * The handling of file.toURL() is broken; the handling of file.toURI().toURL() is known
+// * to be broken on a few platforms like mac. We have the urlToFile( URL ) method that
+// * is able to untangle both these problems and we use it in the geotools library.
+// * <p>
+// * However occasionally we need to pick up a file and hand it to a third party library
+// * like EMF; this method performs a couple of sanity checks which we can use to prepare
+// * a good URL reference to a file in these situtations.
+// *
+// * @param file
+// * @return URL
+// */
+// public static URL fileToURL(File file) {
+// try {
+// URL url = file.toURI().toURL();
+// String string = url.toExternalForm();
+// if( string.contains("+")){
+// // this represents an invalid URL created using either
+// // file.toURL(); or
+// // file.toURI().toURL() on a specific version of Java 5 on Mac
+// string = string.replace("+","%2B");
+// }
+// if( string.contains(" ")){
+// // this represents an invalid URL created using either
+// // file.toURL(); or
+// // file.toURI().toURL() on a specific version of Java 5 on Mac
+// string = string.replace(" ","%20");
+// }
+// return new URL( string );
+// } catch (MalformedURLException e) {
+// return null;
+// }
+// }
+//
+// /**
+// * Takes a URL and converts it to a File. The attempts to deal with
+// * Windows UNC format specific problems, specifically files located
+// * on network shares and different drives.
+// *
+// * If the URL.getAuthority() returns null or is empty, then only the
+// * url's path property is used to construct the file. Otherwise, the
+// * authority is prefixed before the path.
+// *
+// * It is assumed that url.getProtocol returns "file".
+// *
+// * Authority is the drive or network share the file is located on.
+// * Such as "C:", "E:", "\\fooServer"
+// *
+// * @param url a URL object that uses protocol "file"
+// * @return a File that corresponds to the URL's location
+// */
+// public static File urlToFile(URL url) {
+// if( !"file".equals(url.getProtocol())){
+// return null; // not a File URL
+// }
+// String string = url.toExternalForm();
+// if( string.contains("+")){
+// // this represents an invalid URL created using either
+// // file.toURL(); or
+// // file.toURI().toURL() on a specific version of Java 5 on Mac
+// string = string.replace("+","%2B");
+// }
+// try {
+// string = URLDecoder.decode(string, "UTF-8");
+// } catch (UnsupportedEncodingException e) {
+// throw new RuntimeException("Could not decode the URL to UTF-8 format", e);
+// }
+//
+// String path3;
+//
+// String simplePrefix = "file:/";
+// String standardPrefix = "file://";
+// String os = System.getProperty("os.name");
+//
+// if (os.toUpperCase().contains("WINDOWS") && string.startsWith(standardPrefix)) {
+// // win32: host/share reference
+// path3 = string.substring(standardPrefix.length()-2);
+// }
+// else if( string.startsWith(standardPrefix) ){
+// path3 = string.substring( standardPrefix.length() );
+// } else if( string.startsWith(simplePrefix)){
+// path3 = string.substring( simplePrefix.length()-1 );
+// } else {
+// String auth = url.getAuthority();
+// String path2 = url.getPath().replace("%20", " ");
+// if (auth != null && !auth.equals("")) {
+// path3 = "//" + auth + path2;
+// } else {
+// path3 = path2;
+// }
+// }
+//
+// return new File(path3);
+// }
+//
+//
+// /**
+// * Traverses the filter and returns any encoutered property names.
+// * <p>
+// * The feautre type is supplied as contexts used to lookup expressions in cases where the
+// * attributeName does not match the actual name of the type.
+// * </p>
+// */
+// 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 encoutered property names.
+// * @deprecated use {@link #attributeNames(Filter, FeatureType)}/
+// */
+// public static String[] attributeNames(Filter filter) {
+// return attributeNames( filter, null );
+// }
+//
+// /**
+// * Traverses the expression and returns any encoutered property names.
+// * <p>
+// * The feautre type is supplied as contexts used to lookup expressions in cases where the
+// * attributeName does not match the actual name of the type.
+// * </p>
+// */
+// 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 encoutered property names.
+// * @deprecated use {@link #attributeNames(Expression, FeatureType)}/
+// */
+// public static String[] attributeNames(Expression expression) {
+// return attributeNames( expression, null );
+// }
+//
+// /**
+// * Compare operation for FeatureType.
+// *
+// * <p>
+// * Results in:
+// * </p>
+// *
+// * <ul>
+// * <li>
+// * 1: if typeA is a sub type/reorder/renamespace of typeB
+// * </li>
+// * <li>
+// * 0: if typeA and typeB are the same type
+// * </li>
+// * <li>
+// * -1: if typeA is not subtype of typeB
+// * </li>
+// * </ul>
+// *
+// * <p>
+// * Comparison is based on AttributeTypes, an IOException is thrown if the
+// * AttributeTypes are not compatiable.
+// * </p>
+// *
+// * <p>
+// * Namespace is not considered in this opperations. You may still need to
+// * reType to get the correct namesapce, or reorder.
+// * </p>
+// *
+// * @param typeA FeatureType beind compared
+// * @param typeB FeatureType being compared against
+// *
+// */
+// public static int compare(SimpleFeatureType typeA, SimpleFeatureType typeB) {
+// 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;
+//
+// // may still be the same featureType
+// // (Perhaps they differ on namespace?)
+// int match = 0;
+//
+// for (int i = 0; i < countA; i++) {
+// a = typeA.getDescriptor(i);
+//
+// if (isMatch(a, typeB.getDescriptor(i))) {
+// match++;
+// } else if (isMatch(a, typeB.getDescriptor(a.getLocalName()))) {
+// // match was found in a different position
+// } else {
+// // 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)
+// // if (typeA.getNamespace() == null) {
+// // if(typeB.getNamespace() == null) {
+// // return 0;
+// // } else {
+// // return 1;
+// // }
+// // } else if(typeA.getNamespace().equals(typeB.getNamespace())) {
+// // return 0;
+// // } else {
+// // return 1;
+// // }
+// return 0;
+// }
+//
+// return 1;
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param a DOCUMENT ME!
+// * @param b DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// */
+// public static boolean isMatch(AttributeDescriptor a, AttributeDescriptor b) {
+// if (a == b) {
+// return true;
+// }
+//
+// if (b == null) {
+// return false;
+// }
+//
+// if (a == null) {
+// return false;
+// }
+//
+// if (a.equals(b)) {
+// return true;
+// }
+//
+// if (a.getLocalName().equals(b.getLocalName())
+// && a.getClass().equals(b.getClass())) {
+// return true;
+// }
+//
+// return false;
+// }
+//
+// /**
+// * Creates duplicate of feature adjusted to the provided featureType.
+// *
+// * @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);
+// }
+//
+// 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.clone();
+// }
+//
+// 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<Object> copy = new ArrayList<Object>(list.size());
+//
+// for (Iterator i = list.iterator(); i.hasNext();) {
+// copy.add(duplicate(i.next()));
+// }
+//
+// return Collections.unmodifiableList(copy);
+// }
+//
+// if (src instanceof Map) {
+// Map map = (Map) src;
+// Map copy = new HashMap(map.size());
+//
+// for (Iterator i = map.entrySet().iterator(); i.hasNext();) {
+// Map.Entry entry = (Map.Entry) i.next();
+// copy.put(entry.getKey(), duplicate(entry.getValue()));
+// }
+//
+// return Collections.unmodifiableMap(copy);
+// }
+//
+// if( src instanceof GridCoverage ){
+// return src; // inmutable
+// }
+//
+//
+// //
+// // I have lost hope and am returning the orgional reference
+// // Please extend this to support additional classes.
+// //
+// // And good luck getting Cloneable to work
+// throw new IllegalAttributeException("Do not know how to deep copy "
+// + type.getName());
+// }
+//
+// /**
+// * Constructs an empty feature to use as a Template for new content.
+// *
+// * <p>
+// * We may move this functionality to FeatureType.create( null )?
+// * </p>
+// *
+// * @param featureType Type of feature we wish to create
+// *
+// * @return A new Feature of type featureType
+// *
+// * @throws IllegalAttributeException if we could not create featureType
+// * instance with acceptable default values
+// */
+// public static SimpleFeature template(SimpleFeatureType featureType)
+// throws IllegalAttributeException {
+// return SimpleFeatureBuilder.build(featureType, defaultValues(featureType), null);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// * @param featureID DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// */
+// public static SimpleFeature template(SimpleFeatureType featureType, String featureID)
+// throws IllegalAttributeException {
+// return SimpleFeatureBuilder.build(featureType, defaultValues(featureType), featureID);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// */
+// public static Object[] defaultValues(SimpleFeatureType featureType)
+// throws IllegalAttributeException {
+// return defaultValues(featureType, null);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// * @param atts DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// */
+// public static SimpleFeature template(SimpleFeatureType featureType, Object[] atts)
+// throws IllegalAttributeException {
+// return SimpleFeatureBuilder.build(featureType,defaultValues(featureType, atts),null);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// * @param featureID DOCUMENT ME!
+// * @param atts DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// */
+// public static SimpleFeature template(SimpleFeatureType featureType, String featureID,
+// Object[] atts) throws IllegalAttributeException {
+// return SimpleFeatureBuilder.build(featureType, defaultValues(featureType, atts), featureID);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// * @param values DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// * @throws ArrayIndexOutOfBoundsException DOCUMENT ME!
+// */
+// public static Object[] defaultValues(SimpleFeatureType featureType,
+// Object[] values) throws IllegalAttributeException {
+// if (values == null) {
+// values = new Object[featureType.getAttributeCount()];
+// } else if (values.length != featureType.getAttributeCount()) {
+// throw new ArrayIndexOutOfBoundsException("values");
+// }
+//
+// for (int i = 0; i < featureType.getAttributeCount(); i++) {
+// values[i] = defaultValue(featureType.getDescriptor(i));
+// }
+//
+// return values;
+// }
+//
+// /**
+// * Provides a defautlValue for attributeType.
+// *
+// * <p>
+// * Will return null if attributeType isNillable(), or attempt to use
+// * Reflection, or attributeType.parse( null )
+// * </p>
+// *
+// * @param attributeType
+// *
+// * @return null for nillable attributeType, attempt at reflection
+// *
+// * @throws IllegalAttributeException If value cannot be constructed for
+// * attribtueType
+// */
+// public static Object defaultValue(AttributeDescriptor attributeType)
+// throws IllegalAttributeException {
+// Object value = attributeType.getDefaultValue();
+//
+// if (value == null && !attributeType.isNillable()) {
+// return null; // sometimes there is no valid default value :-(
+// // throw new IllegalAttributeException("Got null default value for non-null type.");
+// }
+// return value;
+// }
+//
+// /**
+// * Returns a non-null default value for the class that is passed in. This is a helper class an can't create a
+// * default class for any type but it does support:
+// * <ul>
+// * <li>String</li>
+// * <li>Object - will return empty string</li>
+// * <li>Number</li>
+// * <li>Character</li>
+// * <li>JTS Geometries</li>
+// * </ul>
+// *
+// *
+// * @param type
+// * @return
+// */
+// public static Object defaultValue(Class type){
+// if( type==String.class || type==Object.class){
+// return "";
+// }
+// if( type==Integer.class ){
+// return new Integer(0);
+// }
+// if( type==Double.class ){
+// return new Double(0);
+// }
+// if( type==Long.class ){
+// return new Long(0);
+// }
+// if( type==Short.class ){
+// return new Short((short)0);
+// }
+// if( type==Float.class ){
+// return new Float(0.0f);
+// }
+// if( type==BigDecimal.class){
+// return BigDecimal.valueOf(0);
+// }
+// if( type==BigInteger.class){
+// return BigInteger.valueOf(0);
+// }
+// if( type==Character.class ){
+// return new Character(' ');
+// }
+// if( type==Boolean.class){
+// return Boolean.FALSE;
+// }
+// if( type==Timestamp.class)
+// return new Timestamp(System.currentTimeMillis());
+// if( type==java.sql.Date.class)
+// return new java.sql.Date(System.currentTimeMillis());
+// if( type==java.sql.Time.class)
+// return new java.sql.Time(System.currentTimeMillis());
+// if( type==java.util.Date.class)
+// return new java.util.Date();
+//
+//
+// GeometryFactory fac=new GeometryFactory();
+// Coordinate coordinate = new Coordinate(0, 0);
+// Point point = fac.createPoint(coordinate);
+//
+// if( type==Point.class ){
+// return point;
+// }
+// if( type==MultiPoint.class ){
+// return fac.createMultiPoint(new Point[]{point});
+// }
+// if( type==LineString.class ){
+// return fac.createLineString(new Coordinate[]{coordinate,coordinate,coordinate,coordinate});
+// }
+// LinearRing linearRing = fac.createLinearRing(new Coordinate[]{coordinate,coordinate,coordinate,coordinate});
+// if( type==LinearRing.class ){
+// return linearRing;
+// }
+// if( type==MultiLineString.class ){
+// return fac.createMultiLineString(new LineString[]{linearRing});
+// }
+// Polygon polygon = fac.createPolygon(linearRing, new LinearRing[0]);
+// if( type==Polygon.class ){
+// return polygon;
+// }
+// if( type==MultiPolygon.class ){
+// return fac.createMultiPolygon(new Polygon[]{polygon});
+// }
+// if( type==Geometry.class ){
+// ArrayList<Geometry> gl = new ArrayList<Geometry>();
+// gl.add(polygon);
+// gl.add(linearRing);
+// gl.add(point);
+// return fac.buildGeometry(gl);
+// }
+//
+// throw new IllegalArgumentException(type+" is not supported by this method");
+// }
+// /**
+// * Creates a FeatureReader<SimpleFeatureType, SimpleFeature> for testing.
+// *
+// * @param features Array of features
+// *
+// * @return FeatureReader<SimpleFeatureType, SimpleFeature> spaning provided feature array
+// *
+// * @throws IOException If provided features Are null or empty
+// * @throws NoSuchElementException DOCUMENT ME!
+// */
+// public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(final SimpleFeature[] features)
+// throws IOException {
+// if ((features == null) || (features.length == 0)) {
+// throw new IOException("Provided features where empty");
+// }
+//
+// return new FeatureReader<SimpleFeatureType, SimpleFeature>() {
+// SimpleFeature[] array = features;
+// int offset = -1;
+//
+// public SimpleFeatureType getFeatureType() {
+// return features[0].getFeatureType();
+// }
+//
+// public SimpleFeature next(){
+// if (!hasNext()) {
+// throw new NoSuchElementException("No more features");
+// }
+//
+// return array[++offset];
+// }
+//
+// public boolean hasNext(){
+// return (array != null) && (offset < (array.length - 1));
+// }
+//
+// public void close(){
+// array = null;
+// offset = -1;
+// }
+// };
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureArray DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IOException DOCUMENT ME!
+// * @throws RuntimeException DOCUMENT ME!
+// */
+// public static FeatureSource<SimpleFeatureType, SimpleFeature> source(final SimpleFeature[] featureArray) {
+// final SimpleFeatureType featureType;
+//
+// if ((featureArray == null) || (featureArray.length == 0)) {
+// featureType = FeatureTypes.EMPTY;
+// } else {
+// featureType = featureArray[0].getFeatureType();
+// }
+//
+// DataStore arrayStore = new AbstractDataStore() {
+// public String[] getTypeNames() {
+// return new String[] { featureType.getTypeName() };
+// }
+//
+// public SimpleFeatureType getSchema(String typeName)
+// throws IOException {
+// if ((typeName != null)
+// && typeName.equals(featureType.getTypeName())) {
+// return featureType;
+// }
+//
+// throw new IOException(typeName + " not available");
+// }
+//
+// protected FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(String typeName)
+// throws IOException {
+// return reader(featureArray);
+// }
+// };
+//
+// try {
+// return arrayStore.getFeatureSource(arrayStore.getTypeNames()[0]);
+// } catch (IOException e) {
+// throw new RuntimeException(
+// "Something is wrong with the geotools code, "
+// + "this exception should not happen", e);
+// }
+// }
+//
+// /**
+// * Wrap up the provided FeatureCollection as a feature soruce; allowing queries to be performed etc...
+// *
+// * @param collection FeatureCollection
+// *
+// * @return FeatureSource
+// *
+// * @throws NullPointerException If the collection is null
+// * @throws RuntimeException
+// */
+// public static FeatureSource<SimpleFeatureType, SimpleFeature> source(final FeatureCollection<SimpleFeatureType, SimpleFeature> collection) {
+// if (collection == null) {
+// throw new NullPointerException();
+// }
+//
+// DataStore store = new CollectionDataStore(collection);
+//
+// try {
+// return store.getFeatureSource(store.getTypeNames()[0]);
+// } catch (IOException e) {
+// throw new RuntimeException(
+// "FeatureCollection is not consistent, unable to access contents", e);
+// }
+// }
+//
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> results(SimpleFeature[] featureArray){
+// return results(collection(featureArray));
+// }
+//
+// /**
+// * Returns collection if non empty.
+// *
+// * @param collection
+// *
+// * @return provided collection
+// *
+// * @throws IOException Raised if collection was empty
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> results(final FeatureCollection<SimpleFeatureType, SimpleFeature> collection){
+// if (collection.size() == 0) {
+// //throw new IOException("Provided collection was empty");
+// }
+// return collection;
+// }
+//
+// /**
+// * Adapt a collection to a reader for use with FeatureStore.setFeatures( reader ).
+// *
+// * @param collection Collection of SimpleFeature
+// *
+// * @return FeatureRedaer over the provided contents
+// * @throws IOException IOException if there is any problem reading the content.
+// */
+// public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(Collection<SimpleFeature> collection)
+// throws IOException {
+// return reader(collection.toArray(
+// new SimpleFeature[collection.size()]));
+// }
+// /**
+// * Adapt a collection to a reader for use with FeatureStore.setFeatures( reader ).
+// *
+// * @param collection Collection of SimpleFeature
+// *
+// * @return FeatureRedaer over the provided contents
+// * @throws IOException IOException if there is any problem reading the content.
+// */
+// public static FeatureReader<SimpleFeatureType, SimpleFeature> reader(
+// FeatureCollection<SimpleFeatureType,SimpleFeature> collection) throws IOException {
+// return reader(collection
+// .toArray(new SimpleFeature[collection.size()]));
+// }
+//
+// /**
+// * Copies the provided features into a FeatureCollection.
+// * <p>
+// * Often used when gathering features for FeatureStore:<pre><code>
+// * featureStore.addFeatures( DataUtilities.collection(array));
+// * </code></pre>
+// *
+// * @param features Array of features
+// * @return FeatureCollection
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(SimpleFeature[] features) {
+// FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
+// final int length = features.length;
+// for (int i = 0; i < length; i++) {
+// collection.add(features[i]);
+// }
+// return collection;
+// }
+// /**
+// * Copies the provided features into a FeatureCollection.
+// * <p>
+// * Often used when gathering a FeatureCollection<SimpleFeatureType, SimpleFeature> into memory.
+// *
+// * @param FeatureCollection<SimpleFeatureType, SimpleFeature> the features to add to a new feature collection.
+// * @return FeatureCollection
+// */
+// public static DefaultFeatureCollection collection( FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection ){
+// return new DefaultFeatureCollection( featureCollection );
+// }
+// /**
+// * Copies the provided fetaures into a List.
+// *
+// * @param featureCollection
+// * @return List of features copied into memory
+// */
+// public static List<SimpleFeature> list( FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection ){
+// final ArrayList<SimpleFeature> list = new ArrayList<SimpleFeature>();
+// try {
+// featureCollection.accepts( new FeatureVisitor(){
+// public void visit(Feature feature) {
+// list.add( (SimpleFeature) feature );
+// }
+// }, null );
+// }
+// catch( IOException ignore ){
+// }
+// return list;
+// }
+// /**
+// * Copies the feature ids from each and every feature into a set.
+// * <p>
+// * This method can be slurp an in memory record of the contents of a
+// * @param featureCollection
+// * @return
+// */
+// public static Set<String> fidSet( FeatureCollection<?,?> featureCollection ){
+// final HashSet<String> fids = new HashSet<String>();
+// try {
+// featureCollection.accepts( new FeatureVisitor(){
+// public void visit(Feature feature) {
+// fids.add( feature.getIdentifier().getID() );
+// }
+// }, null );
+// }
+// catch( IOException ignore ){
+// }
+// return fids;
+// }
+// /**
+// * Copies the provided features into a FeatureCollection.
+// * <p>
+// * Often used when gathering a FeatureCollection<SimpleFeatureType, SimpleFeature> into memory.
+// *
+// * @param list features to add to a new FeatureCollection
+// * @return FeatureCollection
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection( List<SimpleFeature> list ) {
+// FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
+// for ( SimpleFeature feature : list ){
+// collection.add( feature );
+// }
+// return collection;
+// }
+//
+//
+// /**
+// * Copies the provided features into a FeatureCollection.
+// * <p>
+// * Often used when gathering features for FeatureStore:<pre><code>
+// * featureStore.addFeatures( DataUtilities.collection(feature));
+// * </code></pre>
+// *
+// * @param feature a feature to add to a new collection
+// * @return FeatureCollection
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection( SimpleFeature feature ){
+// FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
+// collection.add(feature);
+// return collection;
+// }
+//
+// /**
+// * Copies the provided reader into a FeatureCollection, reader will be closed.
+// * <p>
+// * Often used when gathering features for FeatureStore:<pre><code>
+// * featureStore.addFeatures( DataUtilities.collection(reader));
+// * </code></pre>
+// *
+// * @return FeatureCollection
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(FeatureReader <SimpleFeatureType, SimpleFeature> reader) throws IOException {
+// FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
+// try {
+// while( reader.hasNext() ) {
+// try {
+// collection.add( reader.next() );
+// } catch (NoSuchElementException e) {
+// throw (IOException) new IOException("EOF").initCause( e );
+// } catch (IllegalAttributeException e) {
+// throw (IOException) new IOException().initCause( e );
+// }
+// }
+// }
+// finally {
+// reader.close();
+// }
+// return collection;
+// }
+// /**
+// * Copies the provided reader into a FeatureCollection, reader will be closed.
+// * <p>
+// * Often used when gathering features for FeatureStore:<pre><code>
+// * featureStore.addFeatures( DataUtilities.collection(reader));
+// * </code></pre>
+// *
+// * @return FeatureCollection
+// */
+// public static FeatureCollection<SimpleFeatureType, SimpleFeature> collection(FeatureIterator<SimpleFeature> reader) throws IOException {
+// FeatureCollection<SimpleFeatureType, SimpleFeature> collection = FeatureCollections.newCollection();
+// try {
+// while( reader.hasNext() ) {
+// try {
+// collection.add( reader.next() );
+// } catch (NoSuchElementException e) {
+// throw (IOException) new IOException("EOF").initCause( e );
+// }
+// }
+// }
+// finally {
+// reader.close();
+// }
+// return collection;
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param att DOCUMENT ME!
+// * @param otherAtt DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// */
+// public static boolean attributesEqual(Object att, Object otherAtt) {
+// if (att == null) {
+// if (otherAtt != null) {
+// return false;
+// }
+// } else {
+// if (!att.equals(otherAtt)) {
+// if (att instanceof Geometry && otherAtt instanceof Geometry) {
+// // we need to special case Geometry
+// // as JTS is broken
+// // Geometry.equals( Object ) and Geometry.equals( Geometry )
+// // are different
+// // (We should fold this knowledge into AttributeType...)
+// //
+// if (!((Geometry) att).equals((Geometry) otherAtt)) {
+// return false;
+// }
+// } else {
+// return false;
+// }
+// }
+// }
+//
+// return true;
+// }
+//
+// /**
+// * Create a derived FeatureType
+// *
+// * <p></p>
+// *
+// * @param featureType
+// * @param properties - if null, every property of the feature type in input will be used
+// * @param override
+// *
+// *
+// * @throws SchemaException
+// */
+// public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
+// String[] properties, CoordinateReferenceSystem override)
+// throws SchemaException {
+// URI namespaceURI = null;
+// if ( featureType.getName().getNamespaceURI() != null ) {
+// try {
+// namespaceURI = new URI( featureType.getName().getNamespaceURI() );
+// } catch (URISyntaxException e) {
+// throw new RuntimeException(e);
+// }
+// }
+//
+// return createSubType( featureType, properties, override, featureType.getTypeName(), namespaceURI );
+//
+// }
+//
+// public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
+// String[] properties, CoordinateReferenceSystem override, String typeName, URI namespace )
+// throws SchemaException {
+//
+// if ((properties == null) && (override == null)) {
+// return featureType;
+// }
+//
+// if(properties == null) {
+// properties = new String[featureType.getAttributeCount()];
+// for (int i = 0; i < properties.length; i++) {
+// properties[i] = featureType.getDescriptor(i).getLocalName();
+// }
+// }
+//
+// String namespaceURI = namespace != null ? namespace.toString() : null;
+// boolean same = featureType.getAttributeCount() == properties.length &&
+// featureType.getTypeName().equals( typeName ) &&
+// Utilities.equals(featureType.getName().getNamespaceURI(), namespaceURI );
+//
+//
+// for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
+// AttributeDescriptor type = featureType.getDescriptor(i);
+// same = type.getLocalName().equals(properties[i])
+// && (((override != null)
+// && type instanceof GeometryDescriptor)
+// ? assertEquals(override, ((GeometryDescriptor) type).getCoordinateReferenceSystem())
+// : true);
+// }
+//
+// if (same) {
+// return featureType;
+// }
+//
+// AttributeDescriptor[] types = new AttributeDescriptor[properties.length];
+//
+// for (int i = 0; i < properties.length; i++) {
+// types[i] = featureType.getDescriptor(properties[i]);
+//
+// if ((override != null) && types[i] instanceof GeometryDescriptor) {
+// AttributeTypeBuilder ab = new AttributeTypeBuilder();
+// ab.init( types[i] );
+// ab.setCRS(override);
+// types[i] = ab.buildDescriptor(types[i].getLocalName(), ab.buildGeometryType());
+// }
+// }
+//
+// if( typeName == null ) typeName = featureType.getTypeName();
+// if( namespace == null && featureType.getName().getNamespaceURI() != null )
+// try {
+// namespace = new URI(featureType.getName().getNamespaceURI());
+// } catch (URISyntaxException e) {
+// throw new RuntimeException(e);
+// }
+//
+//
+//
+// SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+// tb.setName( typeName );
+// tb.setNamespaceURI( namespace );
+// tb.addAll(types);
+//
+// return tb.buildFeatureType();
+// }
+//
+// private static boolean assertEquals(Object o1, Object o2){
+// return o1 == null && o2 == null? true :
+// (o1 != null? o1.equals(o2) : false);
+// }
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param featureType DOCUMENT ME!
+// * @param properties DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws SchemaException DOCUMENT ME!
+// */
+// public static SimpleFeatureType createSubType(SimpleFeatureType featureType,
+// String[] properties) throws SchemaException {
+// if (properties == null) {
+// return featureType;
+// }
+//
+// boolean same = featureType.getAttributeCount() == properties.length;
+//
+// for (int i = 0; (i < featureType.getAttributeCount()) && same; i++) {
+// same = featureType.getDescriptor(i).getLocalName().equals(properties[i]);
+// }
+//
+// if (same) {
+// return featureType;
+// }
+//
+// SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+// tb.setName( featureType.getName() );
+//
+// for (int i = 0; i < properties.length; i++) {
+// tb.add( featureType.getDescriptor(properties[i]) );
+// }
+// return tb.buildFeatureType();
+// }
+//
+// /**
+// * Utility method for FeatureType construction.
+// * <p>
+// * Will parse a String of the form: <i>"name:Type,name2:Type2,..."</i>
+// * </p>
+// *
+// * <p>
+// * Where <i>Type</i> is defined by createAttribute.
+// * </p>
+// *
+// * <p>
+// * You may indicate the default Geometry with an astrix: "*geom:Geometry". You
+// * may also indicate the srid (used to look up a EPSG code).
+// * </p>
+// *
+// * <p>
+// * Examples:
+// * <ul>
+// * <li><code>name:"",age:0,geom:Geometry,centroid:Point,url:java.io.URL"</code>
+// * <li><code>id:String,polygonProperty:Polygon:srid=32615</code>
+// * </ul>
+// * </p>
+// *
+// * @param identification identification of FeatureType:
+// * (<i>namesapce</i>).<i>typeName</i>
+// * @param typeSpec Specification for FeatureType
+// *
+// *
+// * @throws SchemaException
+// */
+// public static SimpleFeatureType createType(String identification, String typeSpec)
+// throws SchemaException {
+// int split = identification.lastIndexOf('.');
+// String namespace = (split == -1) ? null
+// : identification.substring(0, split);
+// String typeName = (split == -1) ? identification
+// : identification.substring(split + 1);
+//
+// return createType(namespace, typeName, typeSpec);
+// }
+//
+// /**
+// * Utility method for FeatureType construction.
+// * <p>
+// * Will parse a String of the form: <i>"name:Type,name2:Type2,..."</i>
+// * </p>
+// *
+// * <p>
+// * Where <i>Type</i> is defined by createAttribute.
+// * </p>
+// *
+// * <p>
+// * You may indicate the default Geometry with an astrix: "*geom:Geometry". You
+// * may also indicate the srid (used to look up a EPSG code).
+// * </p>
+// *
+// * <p>
+// * Examples:
+// * <ul>
+// * <li><code>name:"",age:0,geom:Geometry,centroid:Point,url:java.io.URL"</code>
+// * <li><code>id:String,polygonProperty:Polygon:srid=32615</code>
+// * </ul>
+// * </p>
+// *
+// * @param identification identification of FeatureType:
+// * (<i>namesapce</i>).<i>typeName</i>
+// * @param typeSpec Specification for FeatureType
+// *
+// *
+// * @throws SchemaException
+// */
+// public static SimpleFeatureType createType(String namespace, String typeName, String typeSpec)
+// throws SchemaException {
+// SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+// tb.setName( typeName );
+// tb.setNamespaceURI(namespace);
+//
+// String[] types = typeSpec.split(",");
+//
+// AttributeDescriptor attributeType;
+//
+// for (int i = 0; i < types.length; i++) {
+// boolean defaultGeometry = types[i].startsWith("*");
+// if (types[i].startsWith("*")) {
+// types[i] = types[i].substring(1);
+// }
+//
+// attributeType = createAttribute(types[i]);
+// tb.add(attributeType);
+//
+// if ( defaultGeometry ) {
+// tb.setDefaultGeometry(attributeType.getLocalName());
+// }
+// }
+//
+// return tb.buildFeatureType();
+// }
+//
+//
+//
+//
+// /**
+// * DOCUMENT ME!
+// *
+// * @param type DOCUMENT ME!
+// * @param fid DOCUMENT ME!
+// * @param text DOCUMENT ME!
+// *
+// * @return DOCUMENT ME!
+// *
+// * @throws IllegalAttributeException DOCUMENT ME!
+// */
+// public static SimpleFeature parse(SimpleFeatureType type, String fid, String[] text)
+// throws IllegalAttributeException {
+// Object[] attributes = new Object[text.length];
+//
+// for (int i = 0; i < text.length; i++) {
+// AttributeType attType = type.getDescriptor(i).getType();
+// attributes[i] = Converters.convert(text[i], attType.getBinding());
+// }
+//
+// return SimpleFeatureBuilder.build(type, attributes, fid);
+// }
+//
+// /**
+// * A "quick" String representation of a FeatureType.
+// * <p>
+// * This string representation may be used with createType( name, spec ).
+// * </p>
+// * @param featureType FeatureType to represent
+// *
+// * @return The string "specification" for the featureType
+// */
+// public static String spec(FeatureType featureType) {
+// Collection<PropertyDescriptor> types = featureType.getDescriptors();
+// StringBuffer buf = new StringBuffer();
+//
+// for( PropertyDescriptor type : types ){
+// buf.append(type.getName().getLocalPart());
+// buf.append(":");
+// buf.append(typeMap(type.getType().getBinding()));
+// if(type instanceof GeometryDescriptor) {
+// GeometryDescriptor gd = (GeometryDescriptor) type;
+// if(gd.getCoordinateReferenceSystem() != null && gd.getCoordinateReferenceSystem().getIdentifiers() != null) {
+// for (Iterator<ReferenceIdentifier> it = gd.getCoordinateReferenceSystem().getIdentifiers().iterator(); it.hasNext();) {
+// ReferenceIdentifier id = it.next();
+//
+// if ((id.getAuthority() != null)
+// && id.getAuthority().getTitle().equals(Citations.EPSG.getTitle())) {
+// buf.append(":srid=" + id.getCode());
+// break;
+// }
+//
+// }
+// }
+// }
+// buf.append(",");
+// }
+// buf.delete(buf.length()-1,buf.length()); // remove last ","
+//
+// return buf.toString();
+// }
+//
+// static Class type(String typeName) throws ClassNotFoundException {
+// if (typeMap.containsKey(typeName)) {
+// return typeMap.get(typeName);
+// }
+//
+// return Class.forName(typeName);
+// }
+//
+// static String typeMap(Class type) {
+// if( typeEncode.containsKey(type)){
+// return typeEncode.get( type );
+// }
+// /*
+// SortedSet<String> choose = new TreeSet<String>();
+// for (Iterator i = typeMap.entrySet().iterator(); i.hasNext();) {
+// Map.Entry entry = (Entry) i.next();
+//
+// if (entry.getValue().equals(type)) {
+// choose.add( (String) entry.getKey() );
+// }
+// }
+// if( !choose.isEmpty() ){
+// return choose.last();
+// }
+// */
+// return type.getName();
+// }
+//
+// /**
+// * Takes two {@link Query}objects and produce a new one by mixing the
+// * restrictions of both of them.
+// *
+// * <p>
+// * The policy to mix the queries components is the following:
+// *
+// * <ul>
+// * <li>
+// * typeName: type names MUST match (not checked if some or both queries
+// * equals to <code>Query.ALL</code>)
+// * </li>
+// * <li>
+// * handle: you must provide one since no sensible choice can be done
+// * between the handles of both queries
+// * </li>
+// * <li>
+// * maxFeatures: the lower of the two maxFeatures values will be used (most
+// * restrictive)
+// * </li>
+// * <li>
+// * attributeNames: the attributes of both queries will be joined in a
+// * single set of attributes. IMPORTANT: only <b><i>explicitly</i></b>
+// * requested attributes will be joint, so, if the method
+// * <code>retrieveAllProperties()</code> of some of the queries returns
+// * <code>true</code> it does not means that all the properties will be
+// * joined. You must create the query with the names of the properties you
+// * want to load.
+// * </li>
+// * <li>
+// * filter: the filtets of both queries are or'ed
+// * </li>
+// * <li>
+// * <b>any other query property is ignored</b> and no guarantees are made of
+// * their return values, so client code shall explicitly care of hints, startIndex, etc.,
+// * if needed.
+// * </li>
+// * </ul>
+// * </p>
+// *
+// * @param firstQuery Query against this DataStore
+// * @param secondQuery DOCUMENT ME!
+// * @param handle DOCUMENT ME!
+// *
+// * @return Query restricted to the limits of definitionQuery
+// *
+// * @throws NullPointerException if some of the queries is null
+// * @throws IllegalArgumentException if the type names of both queries do
+// * not match
+// */
+// public static Query mixQueries(Query firstQuery, Query secondQuery,
+// String handle) {
+// if ((firstQuery == null) || (secondQuery == null)) {
+// throw new NullPointerException("got a null query argument");
+// }
+//
+// if (firstQuery.equals(Query.ALL)) {
+// return secondQuery;
+// } else if (secondQuery.equals(Query.ALL)) {
+// return firstQuery;
+// }
+//
+// if ((firstQuery.getTypeName() != null)
+// && (secondQuery.getTypeName() != null)) {
+// if (!firstQuery.getTypeName().equals(secondQuery.getTypeName())) {
+// String msg = "Type names do not match: "
+// + firstQuery.getTypeName() + " != "
+// + secondQuery.getTypeName();
+// throw new IllegalArgumentException(msg);
+// }
+// }
+//
+// // mix versions, if possible
+// String version;
+// if(firstQuery.getVersion() != null) {
+// if(secondQuery.getVersion() != null && !secondQuery.getVersion().equals(firstQuery.getVersion()))
+// throw new IllegalArgumentException("First and second query refer different versions");
+// version = firstQuery.getVersion();
+// } else {
+// version = secondQuery.getVersion();
+// }
+//
+//
+// //none of the queries equals Query.ALL, mix them
+// //use the more restrictive max features field
+// int maxFeatures = Math.min(firstQuery.getMaxFeatures(),
+// secondQuery.getMaxFeatures());
+//
+// //join attributes names
+// String[] propNames = joinAttributes(firstQuery.getPropertyNames(),
+// secondQuery.getPropertyNames());
+//
+// //join filters
+// Filter filter = firstQuery.getFilter();
+// Filter filter2 = secondQuery.getFilter();
+//
+// if ((filter == null) || filter.equals(Filter.INCLUDE)) {
+// filter = filter2;
+// } else if ((filter2 != null) && !filter2.equals(Filter.INCLUDE)) {
+// filter = ff.and( filter, filter2);
+// }
+// Integer start=0;
+// if( firstQuery.getStartIndex() != null ){
+// start = firstQuery.getStartIndex();
+// }
+// if( secondQuery.getStartIndex() != null ){
+// start += secondQuery.getStartIndex();
+// }
+// //build the mixed query
+// String typeName = firstQuery.getTypeName() != null?
+// firstQuery.getTypeName() : secondQuery.getTypeName();
+//
+// DefaultQuery mixed = new DefaultQuery(typeName, filter, maxFeatures, propNames, handle);
+// mixed.setVersion(version);
+// if(start != 0){
+// mixed.setStartIndex(start);
+// }
+// return mixed;
+// }
+//
+// /**
+// * Creates a set of attribute names from the two input lists of names,
+// * maintaining the order of the first list and appending the non repeated
+// * names of the second.
+// * <p>
+// * In the case where both lists are <code>null</code>, <code>null</code>
+// * is returned.
+// * </p>
+// *
+// * @param atts1 the first list of attribute names, who's order will be
+// * maintained
+// * @param atts2 the second list of attribute names, from wich the non
+// * repeated names will be appended to the resulting list
+// *
+// * @return Set of attribute names from <code>atts1</code> and
+// * <code>atts2</code>
+// */
+// private static String[] joinAttributes(String[] atts1, String[] atts2) {
+// String[] propNames = null;
+//
+// if ( atts1 == null && atts2 == null ) {
+// return null;
+// }
+//
+// List<String> atts = new LinkedList<String>();
+//
+// if (atts1 != null) {
+// atts.addAll(Arrays.asList(atts1));
+// }
+//
+// if (atts2 != null) {
+// for (int i = 0; i < atts2.length; i++) {
+// if (!atts.contains(atts2[i])) {
+// atts.add(atts2[i]);
+// }
+// }
+// }
+//
+// propNames = new String[atts.size()];
+// atts.toArray(propNames);
+//
+// return propNames;
+// }
+//
+// /**
+// * Returns AttributeType based on String specification (based on UML).
+// *
+// * <p>
+// * Will parse a String of the form: <i>"name:Type:hint"</i>
+// * </p>
+// *
+// * <p>
+// * Where <i>Type</i> is:
+// * </p>
+// *
+// * <ul>
+// * <li>
+// * 0,Interger,int: represents Interger
+// * </li>
+// * <li>
+// * 0.0, Double, double: represents Double
+// * </li>
+// * <li>
+// * "",String,string: represents String
+// * </li>
+// * <li>
+// * Geometry: represents Geometry
+// * </li>
+// * <li>
+// * <i>full.class.path</i>: represents java type
+// * </li>
+// * </ul>
+// *
+// * <p>
+// * Where <i>hint</i> is "hint1;hint2;...;hintN", in which "hintN" is one
+// * of:
+// * <ul>
+// * <li><code>nillable</code></li>
+// * <li><code>srid=<#></code></li>
+// * </ul>
+// * </p>
+// *
+// * @param typeSpec
+// *
+// *
+// * @throws SchemaException If typeSpect could not be interpreted
+// */
+// static AttributeDescriptor createAttribute(String typeSpec)
+// throws SchemaException {
+// int split = typeSpec.indexOf(":");
+//
+// String name;
+// String type;
+// String hint = null;
+//
+// if (split == -1) {
+// name = typeSpec;
+// type = "String";
+// } else {
+// name = typeSpec.substring(0, split);
+//
+// int split2 = typeSpec.indexOf(":", split + 1);
+//
+// if (split2 == -1) {
+// type = typeSpec.substring(split + 1);
+// } else {
+// type = typeSpec.substring(split + 1, split2);
+// hint = typeSpec.substring(split2 + 1);
+// }
+// }
+//
+// try {
+// boolean nillable = true;
+// CoordinateReferenceSystem crs = null;
+//
+// if ( hint != null ) {
+// StringTokenizer st = new StringTokenizer( hint, ";" );
+// while ( st.hasMoreTokens() ) {
+// String h = st.nextToken();
+// h = h.trim();
+//
+// //nillable?
+// //JD: i am pretty sure this hint is useless since the
+// // default is to make attributes nillable
+// if ( h.equals( "nillable" )) {
+// nillable = true;
+// }
+// //spatial reference identieger?
+// if ( h.startsWith("srid=" )) {
+// String srid = h.split("=")[1];
+// Integer.parseInt( srid );
+// try {
+// crs = CRS.decode( "EPSG:" + srid );
+// }
+// catch( Exception e ) {
+// String msg = "Error decoding srs: " + srid;
+// throw new SchemaException( msg, e );
+// }
+// }
+// }
+// }
+//
+// Class clazz = type(type);
+// if(Geometry.class.isAssignableFrom(clazz)) {
+// GeometryType at = new GeometryTypeImpl(new NameImpl( name ), clazz , crs, false, false, Collections.EMPTY_LIST, null, null );
+// return new GeometryDescriptorImpl( at, new NameImpl(name), 0,1, nillable, null );
+// } else {
+// AttributeType at = new AttributeTypeImpl( new NameImpl( name ), clazz , false, false, Collections.EMPTY_LIST, null, null );
+// return new AttributeDescriptorImpl( at, new NameImpl(name), 0,1, nillable, null );
+// }
+// } catch (ClassNotFoundException e) {
+// throw new SchemaException("Could not type " + name + " as:" + type, e);
+// }
+// }
+//
+// /**
+// * Manually calculates the bounds of a feature collection.
+// *
+// * @param collection
+// * @return
+// */
+// public static Envelope bounds(
+// FeatureCollection<? extends FeatureType, ? extends Feature> collection) {
+// FeatureIterator<? extends Feature> i = collection.features();
+// try {
+// ReferencedEnvelope bounds = new ReferencedEnvelope(collection.getSchema()
+// .getCoordinateReferenceSystem());
+// if (!i.hasNext()) {
+// bounds.setToNull();
+// return bounds;
+// }
+//
+// bounds.init(((SimpleFeature) i.next()).getBounds());
+// return bounds;
+// } finally {
+// i.close();
+// }
+// }
+//
+//
+// /**
+// * Changes the ending (e.g. ".sld") of a {@link URL}
+// *
+// * @param url
+// * {@link URL} like <code>file:/sds/a.bmp</code> or
+// * <code>http://www.some.org/foo/bar.shp</code>
+// * @param postfix
+// * New file extension for the {@link URL} without <code>.</code>
+// *
+// * @return A new {@link URL} with new extension.
+// *
+// * @throws {@link MalformedURLException} if the new {@link URL} can not be
+// * created.
+// */
+// public static URL changeUrlExt(final URL url, final String postfix)
+// throws IllegalArgumentException {
+// String a = url.toExternalForm();
+// final int lastDotPos = a.lastIndexOf('.');
+// if (lastDotPos >= 0)
+// a = a.substring(0, lastDotPos);
+// a = a + "." + postfix;
+// try {
+// return new URL(a);
+// } catch (final MalformedURLException e) {
+// throw new IllegalArgumentException("can't create a new URL for "+ url + " with new extension " + postfix, e);
+// }
+// }
+//
+// /**
+// * The function is supposed to be equivalent to {@link File}.getParent().
+// * The {@link URL} is converted to a String, truncated to the last / and
+// * then recreated as a new URL.
+// *
+// * @throws {@link MalformedURLException} if the parent {@link URL} can not
+// * be created.
+// */
+// public static URL getParentUrl(final URL url) throws MalformedURLException {
+// String a = url.toExternalForm();
+// final int lastDotPos = a.lastIndexOf('/');
+// if (lastDotPos >= 0)
+// a = a.substring(0, lastDotPos);
+//
+// /**
+// * The parent of jar:file:some!/bar.file is jar:file:some!/, not jar:file:some!
+// */
+// if (a.endsWith("!")) a+="/";
+//
+// return new URL(a);
+// }
+//
+// /**
+// * Extends an {@link URL}.
+// *
+// * @param base
+// * Has to be a {@link URL} pointing to a directory. If it doesn't
+// * end with a <code>/</code> it will be added automatically.
+// * @param extension
+// * The part that will be added to the {@link URL}
+// *
+// * @throws MalformedURLException
+// * if the new {@link URL} can not be created.
+// */
+// public static URL extendURL(URL base, String extension)
+// throws MalformedURLException {
+// if(base==null)
+// throw new NullPointerException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1,"base"));
+// if(extension==null)
+// throw new NullPointerException(Errors.format(ErrorKeys.NULL_ARGUMENT_$1,"extension"));
+// String a = base.toExternalForm();
+// if (!a.endsWith("/"))
+// a += "/";
+// a += extension;
+// return new URL(a);
+// }
+//
+// /**
+// * Checks that a {@link File} is a real file, exists and is readable.
+// *
+// * @param file the {@link File} instance to check. Must not be null.
+// * @param logger an optional {@link Logger} (can be null) where to log detailed
+// * info about the file properties (path/readable/hidden/writable)
+// *
+// * @return {@code true} in case the file is a real file, exists and is readable;
+// * {@code false} otherwise.
+// */
+// public static boolean checkFileReadable(final File file, final Logger logger) {
+// if (logger != null && logger.isLoggable(Level.FINE)) {
+// final StringBuilder builder = new StringBuilder("Checking file:")
+// .append(file.getAbsolutePath()).append("\n")
+// .append("canRead:").append(file.canRead()).append("\n")
+// .append("isHidden:").append(file.isHidden()).append("\n")
+// .append("isFile").append(file.isFile()).append("\n")
+// .append("canWrite").append(file.canWrite()).append("\n");
+// logger.fine(builder.toString());
+// }
+// if (!file.exists() || !file.canRead() || !file.isFile())
+// return false;
+// return true;
+// }
+//
+// /**
+// * Checks that the provided directory path refers to an existing/readable directory.
+// * Finally, return it as a normalized directory path (removing double and single dot path steps
+// * if any) followed by the separator char if missing ({@code '/'} On UNIX systems; {@code '\\}
+// * on Microsoft Windows systems.
+// *
+// * @param directoryPath the input directory path. Must not be null.
+// * @return the re-formatted directory path.
+// * @throws IllegalArgumentException in case the specified path doesn't rely on a
+// * existing/readable directory.
+// */
+// public static File checkDirectory(File file)
+// throws IllegalArgumentException {
+// String directoryPath = file.getPath();
+// File inDir = file;
+// if(!inDir.isDirectory()){
+// throw new IllegalArgumentException("Not a directory: "+directoryPath );
+// }
+// if (!inDir.canRead()) {
+// throw new IllegalArgumentException("Not a writable directory: "+ directoryPath );
+// }
+// try {
+// directoryPath = inDir.getCanonicalPath();
+// } catch (IOException e) {
+// throw new IllegalArgumentException(e);
+// }
+// /*
+// directoryPath = FilenameUtils.normalize(directoryPath);
+// if (!directoryPath.endsWith(File.separator)){
+// directoryPath = directoryPath + File.separator;
+// }
+// */
+// // test to see if things are still good
+// inDir = new File(directoryPath);
+// if(!inDir.isDirectory()){
+// throw new IllegalArgumentException("Not a directory: "+directoryPath );
+// }
+// if (!inDir.canRead()) {
+// throw new IllegalArgumentException("Not a writable directory: "+ directoryPath );
+// }
+// return new File(directoryPath);
+// }
+//
+// /**
+// * 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;
+// }
+// };
+// }
+//
+//}
More information about the Schmitzm-commits
mailing list