Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id B0C39200CD1 for ; Wed, 26 Jul 2017 23:00:56 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id AF13716968F; Wed, 26 Jul 2017 21:00:56 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id AE3AF16968E for ; Wed, 26 Jul 2017 23:00:54 +0200 (CEST) Received: (qmail 77080 invoked by uid 500); 26 Jul 2017 21:00:53 -0000 Mailing-List: contact commits-help@sis.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: sis-dev@sis.apache.org Delivered-To: mailing list commits@sis.apache.org Received: (qmail 77071 invoked by uid 99); 26 Jul 2017 21:00:53 -0000 Received: from Unknown (HELO svn01-us-west.apache.org) (209.188.14.144) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 26 Jul 2017 21:00:53 +0000 Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id C566F3A002C for ; Wed, 26 Jul 2017 21:00:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: svn commit: r1803113 - in /sis/trunk: ./ application/ core/sis-build-helper/ core/sis-utility/src/main/java/org/apache/sis/internal/system/ storage/sis-storage/src/main/java/org/apache/sis/internal/storage/ storage/sis-storage/src/main/java/org/apache/... Date: Wed, 26 Jul 2017 21:00:51 -0000 To: commits@sis.apache.org From: desruisseaux@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20170726210052.C566F3A002C@svn01-us-west.apache.org> archived-at: Wed, 26 Jul 2017 21:00:56 -0000 Author: desruisseaux Date: Wed Jul 26 21:00:50 2017 New Revision: 1803113 URL: http://svn.apache.org/viewvc?rev=1803113&view=rev Log: Merge from JDK7 branch. Added: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java - copied, changed from r1803100, sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java - copied, changed from r1803100, sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/MovingFeatureIterator.java Modified: sis/trunk/ (props changed) sis/trunk/application/pom.xml sis/trunk/core/sis-build-helper/pom.xml sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java Propchange: sis/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Wed Jul 26 21:00:50 2017 @@ -1,5 +1,5 @@ /sis/branches/Android:1430670-1480699 /sis/branches/JDK6:1394364-1758914 -/sis/branches/JDK7:1394913-1802943 -/sis/branches/JDK8:1584960-1802940 -/sis/branches/JDK9:1773327-1789983 +/sis/branches/JDK7:1394913-1803100 +/sis/branches/JDK8:1584960-1803097 +/sis/branches/JDK9:1773327-1803064 Modified: sis/trunk/application/pom.xml URL: http://svn.apache.org/viewvc/sis/trunk/application/pom.xml?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/application/pom.xml (original) +++ sis/trunk/application/pom.xml Wed Jul 26 21:00:50 2017 @@ -114,8 +114,8 @@ Sub-modules included in the build in dependency order =========================================================== --> - sis-webapp sis-console + sis-webapp Modified: sis/trunk/core/sis-build-helper/pom.xml URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-build-helper/pom.xml?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/core/sis-build-helper/pom.xml (original) +++ sis/trunk/core/sis-build-helper/pom.xml Wed Jul 26 21:00:50 2017 @@ -111,12 +111,12 @@ Define Maven Mojos and Javadoc taglets f org.apache.maven maven-core - 3.3.9 + 3.5.0 org.apache.maven maven-plugin-api - 3.3.9 + 3.5.0 org.apache.maven.plugin-tools Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java [UTF-8] (original) +++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/OS.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -142,11 +142,11 @@ public enum OS { * * @see System#load(String) */ - private String nativeLibrary(final ClassLoader loader, String name) throws IOException { + private String nativeLibrary(final ClassLoader loader, final String name) throws IOException { if (libdir != null) { final String ext = unix ? ".so" : ".dll"; - name = "native/" + libdir + '/' + name + ext; - final URL res = loader.getResource(name); + final String path = "native/" + libdir + '/' + name + ext; + final URL res = loader.getResource(path); if (res != null) { try { return new File(res.toURI()).getAbsolutePath(); Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/FeatureStore.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -82,10 +82,11 @@ public abstract class FeatureStore exten * If a checked exception occurs during consumption of the returned stream, that exception will * be wrapped in a unchecked {@link org.apache.sis.util.collection.BackingStoreException}. * + * @param parallel {@code true} for a parallel stream, or {@code false} for a sequential stream. * @return a stream over all features in the data store. * @throws DataStoreException if an error occurred while creating the feature stream. * * @todo a future version of this method will take some kind of {@code Query} or {@code Filter} argument. */ - public abstract Stream features() throws DataStoreException; + public abstract Stream features(boolean parallel) throws DataStoreException; } Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -149,6 +149,11 @@ public final class Resources extends Ind public static final short ProcessingExecutedOn_1 = 12; /** + * The “{1}” element must be declared before “{0}”. + */ + public static final short ShallBeDeclaredBefore_2 = 22; + + /** * Can not move backward in the “{0}” stream. */ public static final short StreamIsForwardOnly_1 = 13; Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties [ISO-8859-1] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources.properties [ISO-8859-1] Wed Jul 26 21:00:50 2017 @@ -36,6 +36,7 @@ IllegalOutputTypeForWriter_2 = The InconsistentNameComponents_2 = Components of the \u201c{1}\u201d name are inconsistent with those of the name previously binded in \u201c{0}\u201d data store. MissingSchemeInURI_1 = Missing scheme in \u201c{0}\u201d URI. ProcessingExecutedOn_1 = Processing executed on {0}. +ShallBeDeclaredBefore_2 = The \u201c{1}\u201d element must be declared before \u201c{0}\u201d. StreamIsForwardOnly_1 = Can not move backward in the \u201c{0}\u201d stream. StreamIsReadOnce_1 = The \u201c{0}\u201d data store can be read only once. StreamIsWriteOnce_1 = Can not modify previously written data in \u201c{0}\u201d. Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties [ISO-8859-1] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/Resources_fr.properties [ISO-8859-1] Wed Jul 26 21:00:50 2017 @@ -41,6 +41,7 @@ IllegalOutputTypeForWriter_2 = Le l InconsistentNameComponents_2 = Les \u00e9l\u00e9ments qui composent le nom \u00ab\u202f{1}\u202f\u00bb ne sont pas coh\u00e9rents avec ceux du nom qui avait \u00e9t\u00e9 pr\u00e9c\u00e9demment li\u00e9 dans les donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb. MissingSchemeInURI_1 = Il manque le sch\u00e9ma dans l\u2019URI \u00ab\u202f{0}\u202f\u00bb. ProcessingExecutedOn_1 = Traitement ex\u00e9cut\u00e9 sur {0}. +ShallBeDeclaredBefore_2 = L\u2019\u00e9l\u00e9ment \u00ab\u202f{1}\u202f\u00bb doit \u00eatre d\u00e9clar\u00e9 avant \u00ab\u202f{0}\u202f\u00bb. StreamIsForwardOnly_1 = Ne peut pas reculer dans le flux de donn\u00e9es \u00ab\u202f{0}\u202f\u00bb. StreamIsReadOnce_1 = Les donn\u00e9es de \u00ab\u202f{0}\u202f\u00bb ne peuvent \u00eatre lues qu\u2019une seule fois. StreamIsWriteOnce_1 = Ne peut pas revenir sur les donn\u00e9es d\u00e9j\u00e0 \u00e9crites dans \u00ab\u202f{0}\u202f\u00bb. Copied: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java (from r1803100, sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java) URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java?p2=sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java&p1=sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java&r1=1803100&r2=1803113&rev=1803113&view=diff ============================================================================== --- sis/branches/JDK7/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/FeatureIterator.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -27,9 +27,9 @@ import org.apache.sis.util.collection.Ba import org.apache.sis.internal.jdk8.Spliterator; import org.apache.sis.internal.jdk8.Consumer; import org.apache.sis.internal.jdk8.DateTimeException; -import org.opengis.feature.Feature; -import org.opengis.feature.PropertyType; -import org.opengis.feature.AttributeType; +import org.apache.sis.feature.AbstractFeature; +import org.apache.sis.feature.AbstractIdentifiedType; +import org.apache.sis.feature.DefaultAttributeType; /** @@ -52,7 +52,7 @@ import org.opengis.feature.AttributeType * @since 0.7 * @module */ -class FeatureIterator implements Spliterator { +class FeatureIterator implements Spliterator { /** * Index of the column containing trajectory coordinates. * Columns before the trajectory are Moving Feature identifier {@code mfIdRef}, start time and end time. @@ -94,12 +94,12 @@ class FeatureIterator implements Spliter @SuppressWarnings({"unchecked", "rawtypes", "fallthrough"}) FeatureIterator(final Store store) { this.store = store; - final Collection properties = store.featureType.getProperties(true); + final Collection properties = store.featureType.getProperties(true); converters = new ObjectConverter[properties.size()]; values = new Object[converters.length]; propertyNames = new String[converters.length]; int i = -1; - for (final PropertyType p : properties) { + for (final AbstractIdentifiedType p : properties) { propertyNames[++i] = p.getName().tip().toString(); /* * According Moving Features specification: @@ -137,7 +137,7 @@ class FeatureIterator implements Spliter */ } default: { - c = ObjectConverters.find(String.class, ((AttributeType) p).getValueClass()); + c = ObjectConverters.find(String.class, ((DefaultAttributeType) p).getValueClass()); break; } } @@ -163,7 +163,7 @@ class FeatureIterator implements Spliter * is not guaranteed to cover a strict prefix of the elements. */ @Override - public Spliterator trySplit() { + public Spliterator trySplit() { if (splitCount == null) { splitCount = new AtomicInteger(); } @@ -177,7 +177,7 @@ class FeatureIterator implements Spliter * Executes the given action only on the next feature, if any. */ @Override - public boolean tryAdvance(final Consumer action) { + public boolean tryAdvance(final Consumer action) { try { return read(action, false); } catch (IOException | IllegalArgumentException | DateTimeException e) { @@ -189,7 +189,7 @@ class FeatureIterator implements Spliter * Executes the given action on all remaining features. */ @Override - public void forEachRemaining(final Consumer action) { + public void forEachRemaining(final Consumer action) { try { read(action, true); } catch (IOException | IllegalArgumentException | DateTimeException e) { @@ -215,12 +215,12 @@ class FeatureIterator implements Spliter * @throws IllegalArgumentException if parsing of a number failed, or other error. * @throws DateTimeException if parsing of a date failed. */ - private boolean read(final Consumer action, final boolean all) throws IOException { + private boolean read(final Consumer action, final boolean all) throws IOException { final FixedSizeList elements = new FixedSizeList(values); String line; while ((line = store.readLine()) != null) { Store.split(line, elements); - final Feature feature = store.featureType.newInstance(); + final AbstractFeature feature = store.featureType.newInstance(); int i, n = elements.size(); for (i=0; i entry : builders.entrySet()) { features[n++] = createMovingFeature(entry.getKey(), entry.getValue(), np); } @@ -96,18 +96,18 @@ final class MovingFeatureIterator extend * @param np number of properties, ignoring the ones before the trajectory column. */ @SuppressWarnings("unchecked") - private Feature createMovingFeature(final String featureName, final MovingFeature mf, final int np) { - final Feature feature = store.featureType.newInstance(); + private AbstractFeature createMovingFeature(final String featureName, final MovingFeature mf, final int np) { + final AbstractFeature feature = store.featureType.newInstance(); feature.setPropertyValue(propertyNames[0], featureName); mf.storeTimeRange(propertyNames[1], propertyNames[2], feature); int column = 0; if (store.hasTrajectories()) { mf.storeGeometry(featureName, column, store.spatialDimensionCount(), store.geometries, - (Attribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN]), this); + (AbstractAttribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN]), this); column++; } while (column < np) { - mf.storeAttribute(column, (Attribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN + column])); + mf.storeAttribute(column, (AbstractAttribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN + column])); column++; } return feature; @@ -124,7 +124,7 @@ final class MovingFeatureIterator extend * @throws IllegalArgumentException if parsing of a number failed, or other error. * @throws DateTimeException if parsing of a date failed. */ - boolean readMoving(final Consumer action, final boolean all) throws IOException { + boolean readMoving(final Consumer action, final boolean all) throws IOException { final FixedSizeList elements = new FixedSizeList(values); final int np = values.length - TRAJECTORY_COLUMN; String line; Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/csv/Store.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -16,11 +16,8 @@ */ package org.apache.sis.internal.storage.csv; -import java.util.Map; -import java.util.LinkedHashMap; import java.util.List; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.Locale; import java.util.logging.Level; @@ -50,6 +47,7 @@ import org.apache.sis.internal.storage.i import org.apache.sis.internal.storage.FeatureStore; import org.apache.sis.internal.feature.Geometries; import org.apache.sis.internal.feature.MovingFeature; +import org.apache.sis.internal.storage.Resources; import org.apache.sis.geometry.GeneralEnvelope; import org.apache.sis.metadata.iso.DefaultMetadata; import org.apache.sis.metadata.sql.MetadataStoreException; @@ -61,22 +59,16 @@ import org.apache.sis.storage.StorageCon import org.apache.sis.setup.OptionKey; import org.apache.sis.util.ArraysExt; import org.apache.sis.util.CharSequences; -import org.apache.sis.util.ObjectConverter; -import org.apache.sis.util.ObjectConverters; import org.apache.sis.util.resources.Errors; -import org.apache.sis.util.collection.BackingStoreException; import org.apache.sis.measure.Units; // Branch-dependent imports import org.apache.sis.internal.jdk8.Instant; -import org.apache.sis.feature.AbstractFeature; -import org.apache.sis.feature.AbstractAttribute; -import org.apache.sis.feature.AbstractIdentifiedType; import org.apache.sis.internal.jdk8.DateTimeException; -import org.apache.sis.internal.jdk8.Consumer; -import org.apache.sis.internal.jdk8.Spliterator; import org.apache.sis.internal.jdk8.Stream; import org.apache.sis.internal.jdk8.StreamSupport; +import org.apache.sis.feature.AbstractFeature; +import org.apache.sis.feature.AbstractIdentifiedType; /** @@ -122,13 +114,9 @@ public final class Store extends Feature private static final String TYPE_PREFIX = "xsd:"; /** - * Index of the column containing trajectory coordinates. - * Columns before the trajectory are Moving Feature identifier {@code mfIdRef}, start time and end time. - */ - private static final int TRAJECTORY_COLUMN = 3; - - /** * The reader, set by the constructor and cleared when no longer needed. + * + * @see #readLine() */ private BufferedReader source; @@ -162,6 +150,9 @@ public final class Store extends Feature /** * {@code true} if {@link #featureType} contains a trajectory column. + * This field should be considered immutable after {@code Store} construction. + * + * @see #hasTrajectories() */ private boolean hasTrajectories; @@ -169,13 +160,15 @@ public final class Store extends Feature * The number of dimensions other than time in the coordinate reference system. * Shall be 2 or 3 according Moving Features CSV encoding specification, but Apache SIS * may be tolerant to other values (depending on the backing geometry library). + * + * @see #spatialDimensionCount() */ private short spatialDimensionCount; /** * The factory to use for creating geometries. */ - private final Geometries geometries; + final Geometries geometries; /** * Appearing order of trajectories (time or sequential), or {@code null} if unspecified. @@ -186,6 +179,9 @@ public final class Store extends Feature /** * Specifies how time is encoded in the CSV file, or {@code null} if there is no time. + * This field should be considered immutable after {@code Store} construction. + * + * @see #timeEncoding() */ private TimeEncoding timeEncoding; @@ -198,7 +194,7 @@ public final class Store extends Feature /** * All parsed moving features, or {@code null} if none or if not yet parsed. If {@link #dissociate} - * is {@code false}, then this list will be created by {@link #features()} when first needed. + * is {@code false}, then this list will be created by {@link #features(boolean)} when first needed. */ private transient List movingFeatures; @@ -206,14 +202,16 @@ public final class Store extends Feature * Creates a new CSV store from the given file, URL or stream. * *

If the CSV file is known to be a Moving Feature file, then the given connector should - * have an {@link org.apache.sis.setup.OptionKey#ENCODING} associated to the UTF-8 value.

+ * have an {@link org.apache.sis.setup.OptionKey#ENCODING} value set to UTF-8.

* - * @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified. - * @param connector information about the storage (URL, stream, etc). - * @param dissociate {@code true} for forcing the creation of a different {@code Feature} instance for each line. + * @param provider the factory that created this {@code DataStore} instance, or {@code null} if unspecified. + * @param connector information about the storage (URL, stream, etc). + * @param immediate {@code true} for forcing the creation of a distinct {@code Feature} instance for each line. * @throws DataStoreException if an error occurred while opening the stream. */ - public Store(final StoreProvider provider, final StorageConnector connector, boolean dissociate) throws DataStoreException { + public Store(final StoreProvider provider, final StorageConnector connector, final boolean immediate) + throws DataStoreException + { super(provider, connector); final Reader r = connector.getStorageAs(Reader.class); connector.closeAllExcept(r); @@ -222,10 +220,10 @@ public final class Store extends Feature } source = (r instanceof BufferedReader) ? (BufferedReader) r : new LineNumberReader(r); geometries = Geometries.implementation(connector.getOption(OptionKey.GEOMETRY_LIBRARY)); - this.dissociate = dissociate; - GeneralEnvelope envelope = null; + dissociate = immediate; + GeneralEnvelope envelope = null; DefaultFeatureType featureType = null; - Foliation foliation = null; + Foliation foliation = null; try { final List elements = new ArrayList<>(); source.mark(1024); @@ -243,7 +241,11 @@ public final class Store extends Feature if (envelope != null) { throw new DataStoreContentException(duplicated("@stboundedby")); } - envelope = parseEnvelope(elements); + if (featureType != null) { + throw new DataStoreContentException(Resources.forLocale(getLocale()) + .getString(Resources.Keys.ShallBeDeclaredBefore_2, "@columns", "@stboundedby")); + } + envelope = parseEnvelope(elements); // Also set 'timeEncoding' and 'spatialDimensionCount'. dissociate |= (timeEncoding == null); // Need to be updated before parseFeatureType(…) execution. break; } @@ -296,6 +298,8 @@ public final class Store extends Feature * @stboundedby, urn:ogc:def:crs:CRS:1.3:84, 2D, 50.23 9.23, 50.31 9.27, 2012-01-17T12:33:41Z, 2012-01-17T12:37:00Z, sec * } * + * This method sets {@link #timeEncoding} and {@link #spatialDimensionCount} as a side-effect. + * * @param elements the line elements. The first elements should be {@code "@stboundedby"}. * @return the envelope, or {@code null} if the given list does not contain enough elements. */ @@ -450,6 +454,9 @@ public final class Store extends Feature * @columns, mfidref, trajectory, state,xsd:token, "type code",xsd:integer * } * + * This method needs {@link #timeEncoding} and {@link #dissociate} to be computed. + * This methods sets {@link #hasTrajectories} as a side-effect. + * * @param elements the line elements. The first element should be {@code "@columns"}. * @return the column metadata, or {@code null} if the given list does not contain enough elements. */ @@ -531,6 +538,7 @@ public final class Store extends Feature /** * Creates a property type for the given name and type. + * This is a helper method for {@link #parseFeatureType(List)}. */ private static AbstractIdentifiedType createProperty(final String name, final Class type, final int minOccurrence, final int maxOccurrence, final DefaultAttributeType[] characteristics) @@ -620,6 +628,7 @@ public final class Store extends Feature /** * Returns the stream of features. * + * @param parallel {@code true} for a parallel stream, or {@code false} for a sequential stream. * @return a stream over all features in the CSV file. * @throws DataStoreException if an error occurred while creating the feature stream. * @@ -627,12 +636,17 @@ public final class Store extends Feature * @todo If sequential order, publish Feature as soon as identifier changed. */ @Override - public synchronized Stream features() throws DataStoreException { + public synchronized Stream features(final boolean parallel) throws DataStoreException { + /* + * If the user asks for one feature instance per line, then we can return a FeatureIter instance directly. + * Since each feature is fully constructed from a single line and each line are read atomically, we can + * parallelize this mode. + */ if (dissociate) { - return StreamSupport.stream(new Iter(), false); + return StreamSupport.stream(new FeatureIterator(this), parallel); } if (movingFeatures == null) try { - final Iter iter = new Iter(); + final MovingFeatureIterator iter = new MovingFeatureIterator(this); iter.readMoving(null, true); movingFeatures = UnmodifiableArrayList.wrap(iter.createMovingFeatures()); } catch (IOException | IllegalArgumentException | DateTimeException e) { @@ -642,300 +656,13 @@ public final class Store extends Feature } /** - * Implementation of the iterator returned by {@link #features()}. - */ - private final class Iter implements Spliterator, Consumer { - /** - * Converters from string representations to the values to store in the {@link #values} array. - */ - private final ObjectConverter[] converters; - - /** - * All values found in a row. We need to remember those values between different executions - * of the {@link #tryAdvance(Consumer)} method because the Moving Feature Specification said: - * "If the value equals the previous value, the text for the value can be omitted." - */ - private final Object[] values; - - /** - * Name of the property where to store a value. - */ - private final String[] propertyNames; - - /** - * Identifier of the feature in process of being parsed. - */ - private String identifier; - - /** - * Where to store the property values and the trajectory of the feature in process of being parsed. - */ - private MovingFeature builder; - - /** - * All builders by feature name (not only the one being parsed). - */ - private final Map builders; - - /** - * Creates a new iterator. - */ - @SuppressWarnings({"unchecked", "rawtypes", "fallthrough"}) - Iter() { - final Collection properties = featureType.getProperties(true); - converters = new ObjectConverter[properties.size()]; - values = new Object[converters.length]; - propertyNames = new String[converters.length]; - int i = -1; - for (final AbstractIdentifiedType p : properties) { - propertyNames[++i] = p.getName().tip().toString(); - /* - * According Moving Features specification: - * Column 0 is the feature identifier (mfidref). There is nothing special to do here. - * Column 1 is the start time. - * Column 2 is the end time. - * Column 3 is the trajectory. - * Columns 4+ are custom attributes. - */ - final ObjectConverter c; - switch (i) { - case 1: // Fall through - case 2: { - if (timeEncoding != null) { - c = timeEncoding; - break; - } - /* - * If there is no time columns, then this column may be the trajectory (note that allowing - * CSV files without time is obviously a departure from Moving Features specification. - * The intend is to have a CSV format applicable to other features than moving ones). - * Fall through in order to process trajectory. - */ - } - case TRAJECTORY_COLUMN: { - if (hasTrajectories) { - c = GeometryParser.INSTANCE; - break; - } - /* - * If there is no trajectory columns, than this column is a custum attribute. - * CSV files without trajectories are not compliant with Moving Feature spec., - * but we try to keep this reader a little bit more generic. - */ - } - default: { - c = ObjectConverters.find(String.class, ((DefaultAttributeType) p).getValueClass()); - break; - } - } - converters[i] = c; - } - builders = new LinkedHashMap<>(); - } - - /** - * Creates all moving features. - * This method can only be invoked after {@link #readMoving(Consumer, boolean)} completion. - * This method is ignored if the CSV file contains only static features. - */ - AbstractFeature[] createMovingFeatures() { - int n = 0; - final int np = values.length - TRAJECTORY_COLUMN; - final AbstractFeature[] features = new AbstractFeature[builders.size()]; - for (final Map.Entry entry : builders.entrySet()) { - features[n++] = createMovingFeature(entry.getKey(), entry.getValue(), np); - } - return features; - } - - /** - * Creates the moving feature of the given name. - * This method can only be invoked after {@link #readMoving(Consumer, boolean)}. - * - * @param featureName name of the feature to create. - * @param np number of properties, ignoring the ones before the trajectory column. - */ - @SuppressWarnings("unchecked") - private AbstractFeature createMovingFeature(final String featureName, final MovingFeature mf, final int np) { - final AbstractFeature feature = featureType.newInstance(); - feature.setPropertyValue(propertyNames[0], featureName); - mf.storeTimeRange(propertyNames[1], propertyNames[2], feature); - int column = 0; - if (hasTrajectories) { - mf.storeGeometry(featureName, column, spatialDimensionCount, geometries, - (AbstractAttribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN]), this); - column++; - } - while (column < np) { - mf.storeAttribute(column, (AbstractAttribute) feature.getProperty(propertyNames[TRAJECTORY_COLUMN + column])); - column++; - } - return feature; - } - - /** - * Executes the given action for the next moving feature or for all remaining moving features. - * This method assumes that the 4 first columns are as documented in the constructor. - * - * @param action the action to execute as soon as the {@code mfidref} change, or {@code null} if none. - * @param all {@code true} for executing the given action on all remaining features. - * @return {@code false} if there is no remaining feature after this method call. - * @throws IOException if an I/O error occurred while reading a feature. - * @throws IllegalArgumentException if parsing of a number failed, or other error. - * @throws DateTimeException if parsing of a date failed. - */ - boolean readMoving(final Consumer action, final boolean all) throws IOException { - final FixedSizeList elements = new FixedSizeList(values); - final int np = values.length - TRAJECTORY_COLUMN; - String line; - while ((line = source.readLine()) != null) { - split(line, elements); - int n = elements.size(); - for (int i=0; iMulti-threading: - * There is no need for {@code synchronize(Store.this)} statement since this method uses only final and - * either immutable or thread-safe objects from {@link Store}. The only object that need synchronization - * is {@link Store#source}, which is already synchronized.

- * - * @param action the action to execute. - * @param all {@code true} for executing the given action on all remaining features. - * @return {@code false} if there is no remaining feature after this method call. - * @throws IOException if an I/O error occurred while reading a feature. - * @throws IllegalArgumentException if parsing of a number failed, or other error. - * @throws DateTimeException if parsing of a date failed. - */ - private boolean read(final Consumer action, final boolean all) throws IOException { - final FixedSizeList elements = new FixedSizeList(values); - String line; - while ((line = source.readLine()) != null) { - split(line, elements); - final AbstractFeature feature = featureType.newInstance(); - int i, n = elements.size(); - for (i=0; i action) { - try { - return read(action, false); - } catch (IOException | IllegalArgumentException | DateTimeException e) { - throw new BackingStoreException(canNotParseFile(), e); - } - } - - /** - * Executes the given action on all remaining features. - */ - @Override - public void forEachRemaining(final Consumer action) { - try { - read(action, true); - } catch (IOException | IllegalArgumentException | DateTimeException e) { - throw new BackingStoreException(canNotParseFile(), e); - } - } - - /** - * Current implementation can not split this iterator. - */ - @Override - public Spliterator trySplit() { - return null; - } - - /** - * We do not know the number of features. - */ - @Override - public long estimateSize() { - return Long.MAX_VALUE; - } - - /** - * Returns the characteristics of the iteration over feature instances. - * The iteration is assumed {@link #ORDERED} in the declaration order in the CSV file. - * The iteration is {@link #NONNULL} (i.e. {@link #tryAdvance(Consumer)} is not allowed - * to return null value) and {@link #IMMUTABLE} (i.e. we do not support modification of - * the CSV file while an iteration is in progress). - * - * @return characteristics of iteration over the features in the CSV file. - */ - @Override - public int characteristics() { - return ORDERED | NONNULL | IMMUTABLE; - } - - /** - * Invoked when a warning occurred while computing the geometry. - */ - @Override - public void accept(final LogRecord warning) { - warning.setSourceClassName(Store.class.getName()); - warning.setSourceMethodName("stream"); - listeners.warning(warning); - } - } - - /** * Splits the content of the given line around the column separator. * Quotes are taken in account. The elements are added in the given list. * * @param line the line to parse. * @param elements an initially empty list where to add elements. */ - private static void split(final String line, final List elements) { + static void split(final String line, final List elements) { int startAt = 0; boolean isQuoting = false; // If a quote has been opened and not yet closed. boolean hasQuotes = false; // If the value contains at least one quote (not used for quoting the value). @@ -996,6 +723,34 @@ public final class Store extends Feature } /** + * Returns {@code true} if {@link #featureType} contains a trajectory column. + */ + final boolean hasTrajectories() { + return hasTrajectories; + } + + /** + * Returns the number of dimensions other than time in the coordinate reference system. + */ + final int spatialDimensionCount() { + return spatialDimensionCount; + } + + /** + * Returns an indication of how time is encoded in the CSV file, or {@code null} if there is no time. + */ + final TimeEncoding timeEncoding() { + return timeEncoding; + } + + /** + * Reads the next line from the source CSV file. + */ + final String readLine() throws IOException { + return source.readLine(); + } + + /** * Returns an error message for a duplicated element. */ private String duplicated(final String name) { @@ -1018,6 +773,16 @@ public final class Store extends Feature } /** + * Logs a warning as if it originated from the {@link #features(boolean)} method. + * This is a callback method for {@link FeatureIterator}. + */ + final void log(final LogRecord warning) { + warning.setSourceClassName(Store.class.getName()); + warning.setSourceMethodName("features"); + listeners.warning(warning); + } + + /** * Closes this data store and releases any underlying resources. * * @throws DataStoreException if an error occurred while closing this data store. Modified: sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/main/java/org/apache/sis/storage/StorageConnector.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -474,8 +474,6 @@ public class StorageConnector implements ByteBuffer buffer = getOption(OptionKey.BYTE_BUFFER); if (buffer == null) { buffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); - // TODO: we do not create direct buffer yet, but this is something - // we may want to consider in a future SIS version. } if (asImageInputStream) { asDataInput = new ChannelImageInputStream(name, channel, buffer, false); Modified: sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] (original) +++ sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/csv/StoreTest.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -100,7 +100,7 @@ public final strictfp class StoreTest ex } /** - * Verifies the feature type, then tests {@link Store#features()}. + * Verifies the feature type, then tests {@link Store#features(boolean)}. * * @throws DataStoreException if an error occurred while parsing the data. */ @@ -109,7 +109,7 @@ public final strictfp class StoreTest ex try (Store store = new Store(null, new StorageConnector(testData()), true)) { verifyFeatureType(store.featureType, double[].class, 1); assertEquals("foliation", Foliation.TIME, store.foliation); - final Iterator it = store.features().iterator(); + final Iterator it = store.features(false).iterator(); assertPropertyEquals(it.next(), "a", "12:33:51", "12:36:11", new double[] {11, 2, 12, 3}, "walking", 1); assertPropertyEquals(it.next(), "b", "12:33:51", "12:36:51", new double[] {10, 2, 11, 3}, "walking", 2); assertPropertyEquals(it.next(), "a", "12:36:11", "12:36:51", new double[] {12, 3, 10, 3}, "walking", 2); @@ -138,7 +138,7 @@ public final strictfp class StoreTest ex try (Store store = new Store(null, new StorageConnector(testData()), false)) { verifyFeatureType(store.featureType, Polyline.class, Integer.MAX_VALUE); assertEquals("foliation", Foliation.TIME, store.foliation); - final Iterator it = store.features().iterator(); + final Iterator it = store.features(false).iterator(); assertPropertyEquals(it.next(), "a", "12:33:51", "12:36:51", new double[] {11, 2, 12, 3, 10, 3}, singletonList("walking"), Arrays.asList(1, 2)); assertPropertyEquals(it.next(), "b", "12:33:51", "12:36:51", new double[] {10, 2, 11, 3}, singletonList("walking"), singletonList(2)); assertPropertyEquals(it.next(), "c", "12:33:51", "12:36:51", new double[] {12, 1, 10, 2, 11, 3}, singletonList("vehicle"), singletonList(1)); Modified: sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java [UTF-8] (original) +++ sis/trunk/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/gpx/Store.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -182,11 +182,12 @@ public final class Store extends StaxDat /** * Returns the stream of features. * + * @param parallel ignored in current implementation. * @return a stream over all features in the XML file. * @throws DataStoreException if an error occurred while creating the feature stream. */ @Override - public synchronized Stream features() throws DataStoreException { + public synchronized Stream features(final boolean parallel) throws DataStoreException { Reader r = reader; reader = null; if (r == null) try { Modified: sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java URL: http://svn.apache.org/viewvc/sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java?rev=1803113&r1=1803112&r2=1803113&view=diff ============================================================================== --- sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java [UTF-8] (original) +++ sis/trunk/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/ReaderTest.java [UTF-8] Wed Jul 26 21:00:50 2017 @@ -224,7 +224,7 @@ public final strictfp class ReaderTest e try (Store reader = create("1.0/waypoint.xml")) { verifyAlmostEmptyMetadata((Metadata) reader.getMetadata()); assertEquals("version", StoreProvider.V1_0, reader.getVersion()); - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyPoint(it.next(), 0, false); verifyPoint(it.next(), 1, false); @@ -245,7 +245,7 @@ public final strictfp class ReaderTest e try (Store reader = create("1.1/waypoint.xml")) { verifyAlmostEmptyMetadata((Metadata) reader.getMetadata()); assertEquals("version", StoreProvider.V1_1, reader.getVersion()); - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyPoint(it.next(), 0, true); verifyPoint(it.next(), 1, true); @@ -266,7 +266,7 @@ public final strictfp class ReaderTest e try (Store reader = create("1.0/route.xml")) { verifyAlmostEmptyMetadata((Metadata) reader.getMetadata()); assertEquals("version", StoreProvider.V1_0, reader.getVersion()); - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyRoute(it.next(), false, 1); verifyEmpty(it.next(), "rtept"); @@ -295,7 +295,7 @@ public final strictfp class ReaderTest e * This verification is shared by {@link #testRoute110()} and {@link #testSequentialReads()}. */ static void verifyRoute110(final Store reader) throws DataStoreException { - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyRoute(it.next(), true, 3); verifyEmpty(it.next(), "rtept"); @@ -373,7 +373,7 @@ public final strictfp class ReaderTest e try (Store reader = create("1.0/track.xml")) { verifyAlmostEmptyMetadata((Metadata) reader.getMetadata()); assertEquals("version", StoreProvider.V1_0, reader.getVersion()); - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyTrack(it.next(), false, 1); verifyEmpty(it.next(), "trkseg"); @@ -393,7 +393,7 @@ public final strictfp class ReaderTest e try (Store reader = create("1.1/track.xml")) { verifyAlmostEmptyMetadata((Metadata) reader.getMetadata()); assertEquals("version", StoreProvider.V1_1, reader.getVersion()); - try (Stream features = reader.features()) { + try (Stream features = reader.features(false)) { final Iterator it = features.iterator(); verifyTrack(it.next(), true, 3); verifyEmpty(it.next(), "trkseg"); @@ -610,13 +610,13 @@ public final strictfp class ReaderTest e @DependsOnMethod("testSequentialReads") public void testConcurrentReads() throws DataStoreException { try (Store reader = createFromURL()) { - final Stream f1 = reader.features(); + final Stream f1 = reader.features(false); final Iterator i1 = f1.iterator(); verifyRoute(i1.next(), true, 3); - final Stream f2 = reader.features(); + final Stream f2 = reader.features(false); final Iterator i2 = f2.iterator(); verifyEmpty(i1.next(), "rtept"); - final Stream f3 = reader.features(); + final Stream f3 = reader.features(false); final Iterator i3 = f3.iterator(); verifyRoute(i2.next(), true, 3); verifyRoute(i3.next(), true, 3);