sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1774418 [1/2] - in /sis/branches/JDK8: core/sis-utility/src/main/java/org/apache/sis/util/resources/ core/sis-utility/src/main/java/org/apache/sis/xml/ storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/ storage/sis-xmlstore/sr...
Date Thu, 15 Dec 2016 11:31:18 GMT
Author: desruisseaux
Date: Thu Dec 15 11:31:17 2016
New Revision: 1774418

URL: http://svn.apache.org/viewvc?rev=1774418&view=rev
Log:
Validate the GPX sample file and first draft of GPX 1.1 <metadata> parsing using JAXB.
The <time> element is excluded for now (pending investigation of how to use java.time with JAXB).

Added:
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/JAXB.java
      - copied, changed from r1774377, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataTypes.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/package-info.java
      - copied, changed from r1773845, sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/
    sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/
      - copied from r1774417, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.0/
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.0/metadata.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_metadata100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.0/route.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_route100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.0/track.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_track100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.0/waypoint.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_waypoint100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.1/
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.1/metadata.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_metadata110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.1/route.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_route110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.1/track.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_track110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/1.1/waypoint.xml
      - copied, changed from r1774377, sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/sample_waypoint110.xml
Removed:
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/gpx/
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_metadata100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_metadata110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_route100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_route110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_track100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_track110.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_waypoint100.xml
    sis/branches/JDK8/storage/sis-xmlstore/src/test/resources/org/apache/sis/internal/gpx/sample_waypoint110.xml
Modified:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXReader.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Types.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStream.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java
    sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java
    sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXWriterTest.java

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -545,6 +545,11 @@ public final class Errors extends Indexe
         public static final short NegativeArrayLength_1 = 91;
 
         /**
+         * Nested “{0}” elements are not allowed.
+         */
+        public static final short NestedElementNotAllowed_1 = 167;
+
+        /**
          * No value is associated to “{0}”.
          */
         public static final short NoSuchValue_1 = 92;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Thu Dec 15 11:31:17 2016
@@ -119,6 +119,7 @@ MissingValueInColumn_1            = Miss
 MutuallyExclusiveOptions_2        = Options \u201c{0}\u201d and \u201c{1}\u201d are mutually exclusive.
 NegativeArgument_2                = Argument \u2018{0}\u2019 shall not be negative. The given value was {1}.
 NegativeArrayLength_1             = Can not create a \u201c{0}\u201d array of negative length.
+NestedElementNotAllowed_1         = Nested \u201c{0}\u201d elements are not allowed.
 NodeChildOfItself_1               = Node \u201c{0}\u201d can not be a child of itself.
 NodeHasAnotherParent_1            = Node \u201c{0}\u201d already has another parent.
 NodeHasNoParent_1                 = Node \u201c{0}\u201d has no parent.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Thu Dec 15 11:31:17 2016
@@ -116,6 +116,7 @@ MissingValueInColumn_1            = Il m
 MutuallyExclusiveOptions_2        = Les options \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb sont mutuellement exclusives.
 NegativeArgument_2                = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif. La valeur donn\u00e9e \u00e9tait {1}.
 NegativeArrayLength_1             = Ne peut pas cr\u00e9er un tableau \u00ab\u202f{0}\u202f\u00bb de longueur n\u00e9gative.
+NestedElementNotAllowed_1         = L\u2019imbrication d\u2019\u00e9l\u00e9ments \u00ab\u202f{0}\u202f\u00bb n\u2019est pas autoris\u00e9e.
 NodeChildOfItself_1               = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb ne peut pas \u00eatre un enfant de lui-m\u00eame.
 NodeHasAnotherParent_1            = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb a d\u00e9j\u00e0 un autre parent.
 NodeHasNoParent_1                 = Le n\u0153ud \u00ab\u202f{0}\u202f\u00bb n\u2019a pas de parent.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/XML.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -32,6 +32,8 @@ import javax.xml.bind.Unmarshaller;
 import javax.xml.bind.JAXBException;
 import javax.xml.transform.Source;
 import javax.xml.transform.Result;
+import javax.xml.transform.stax.StAXSource;
+import javax.xml.stream.XMLStreamReader;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.Version;
 import org.apache.sis.util.resources.Errors;
@@ -358,8 +360,8 @@ public final class XML extends Static {
     /**
      * Marshall the given object into a string.
      *
-     * @param  object The root of content tree to be marshalled.
-     * @return The XML representation of the given object.
+     * @param  object  the root of content tree to be marshalled.
+     * @return the XML representation of the given object.
      * @throws JAXBException if an error occurred during the marshalling.
      */
     public static String marshal(final Object object) throws JAXBException {
@@ -375,8 +377,8 @@ public final class XML extends Static {
     /**
      * Marshall the given object into a stream.
      *
-     * @param  object The root of content tree to be marshalled.
-     * @param  output The stream where to write.
+     * @param  object  the root of content tree to be marshalled.
+     * @param  output  the stream where to write.
      * @throws JAXBException if an error occurred during the marshalling.
      */
     public static void marshal(final Object object, final OutputStream output) throws JAXBException {
@@ -391,8 +393,8 @@ public final class XML extends Static {
     /**
      * Marshall the given object into a file.
      *
-     * @param  object The root of content tree to be marshalled.
-     * @param  output The file to be written.
+     * @param  object  the root of content tree to be marshalled.
+     * @param  output  the file to be written.
      * @throws JAXBException if an error occurred during the marshalling.
      */
     public static void marshal(final Object object, final File output) throws JAXBException {
@@ -407,8 +409,8 @@ public final class XML extends Static {
     /**
      * Marshall the given object into a path.
      *
-     * @param  object The root of content tree to be marshalled.
-     * @param  output The file to be written.
+     * @param  object  the root of content tree to be marshalled.
+     * @param  output  the file to be written.
      * @throws JAXBException if an error occurred during the marshalling.
      */
     public static void marshal(final Object object, final Path output) throws JAXBException {
@@ -433,9 +435,9 @@ public final class XML extends Static {
      * together with the keys documented in the <cite>supported properties</cite> section of the the
      * {@link Marshaller} class.
      *
-     * @param  object The root of content tree to be marshalled.
-     * @param  output The file to be written.
-     * @param  properties An optional map of properties to give to the marshaller, or {@code null} if none.
+     * @param  object      the root of content tree to be marshalled.
+     * @param  output      the file to be written.
+     * @param  properties  an optional map of properties to give to the marshaller, or {@code null} if none.
      * @throws JAXBException if a property has an illegal value, or if an error occurred during the marshalling.
      *
      * @since 0.4
@@ -459,8 +461,8 @@ public final class XML extends Static {
      * Note that the given argument is the XML document itself,
      * <strong>not</strong> a URL to a XML document.
      *
-     * @param  xml The XML representation of an object.
-     * @return The object unmarshalled from the given input.
+     * @param  xml  the XML representation of an object.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if an error occurred during the unmarshalling.
      */
     public static Object unmarshal(final String xml) throws JAXBException {
@@ -476,8 +478,8 @@ public final class XML extends Static {
     /**
      * Unmarshall an object from the given stream.
      *
-     * @param  input The stream from which to read a XML representation.
-     * @return The object unmarshalled from the given input.
+     * @param  input  the stream from which to read a XML representation.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if an error occurred during the unmarshalling.
      */
     public static Object unmarshal(final InputStream input) throws JAXBException {
@@ -492,8 +494,8 @@ public final class XML extends Static {
     /**
      * Unmarshall an object from the given URL.
      *
-     * @param  input The URL from which to read a XML representation.
-     * @return The object unmarshalled from the given input.
+     * @param  input  the URL from which to read a XML representation.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if an error occurred during the unmarshalling.
      */
     public static Object unmarshal(final URL input) throws JAXBException {
@@ -508,8 +510,8 @@ public final class XML extends Static {
     /**
      * Unmarshall an object from the given file.
      *
-     * @param  input The file from which to read a XML representation.
-     * @return The object unmarshalled from the given input.
+     * @param  input  the file from which to read a XML representation.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if an error occurred during the unmarshalling.
      */
     public static Object unmarshal(final File input) throws JAXBException {
@@ -524,8 +526,8 @@ public final class XML extends Static {
     /**
      * Unmarshall an object from the given path.
      *
-     * @param  input The path from which to read a XML representation.
-     * @return The object unmarshalled from the given input.
+     * @param  input  the path from which to read a XML representation.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if an error occurred during the unmarshalling.
      */
     public static Object unmarshal(final Path input) throws JAXBException {
@@ -551,9 +553,9 @@ public final class XML extends Static {
      * together with the keys documented in the <cite>supported properties</cite> section of the the
      * {@link Unmarshaller} class.
      *
-     * @param  input The file from which to read a XML representation.
-     * @param  properties An optional map of properties to give to the unmarshaller, or {@code null} if none.
-     * @return The object unmarshalled from the given input.
+     * @param  input       the file from which to read a XML representation.
+     * @param  properties  an optional map of properties to give to the unmarshaller, or {@code null} if none.
+     * @return the object unmarshalled from the given input.
      * @throws JAXBException if a property has an illegal value, or if an error occurred during the unmarshalling.
      *
      * @since 0.4
@@ -567,7 +569,14 @@ public final class XML extends Static {
                 unmarshaller.setProperty(entry.getKey(), entry.getValue());
             }
         }
-        final Object object = unmarshaller.unmarshal(input);
+        final Object object;
+        final XMLStreamReader reader;
+        if (input instanceof StAXSource && (reader = ((StAXSource) input).getXMLStreamReader()) != null) {
+            // As of JDK 8, XMLStreamReader is not handled by default unmarshal(Source) implementation.
+            object = unmarshaller.unmarshal(reader);
+        } else {
+            object = unmarshaller.unmarshal(input);
+        }
         pool.recycle(unmarshaller);
         return object;
     }

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java?rev=1774418&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.gpx;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import org.apache.sis.internal.xml.GeographicEnvelope;
+
+
+/**
+ * Geographic bounding box encoded in a GPX file.
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public final class Bounds extends GeographicEnvelope {
+    /**
+     * The western-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     */
+    @XmlAttribute(name = Attributes.MIN_X, required = true)
+    public double westBoundLongitude = Double.NaN;
+
+    /**
+     * The eastern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     */
+    @XmlAttribute(name = Attributes.MAX_X, required = true)
+    public double eastBoundLongitude = Double.NaN;
+
+    /**
+     * The southern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     */
+    @XmlAttribute(name = Attributes.MIN_Y, required = true)
+    public double southBoundLatitude = Double.NaN;
+
+    /**
+     * The northern-most, coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     */
+    @XmlAttribute(name = Attributes.MAX_Y, required = true)
+    public double northBoundLatitude = Double.NaN;
+
+    /**
+     * Creates an initially empty bounds.
+     */
+    public Bounds() {
+    }
+
+    /**
+     * Returns the western-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     *
+     * @return the western-most longitude between -180 and +180°.
+     */
+    @Override
+    public double getWestBoundLongitude() {
+        return westBoundLongitude;
+    }
+
+    /**
+     * Returns the eastern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in longitude in decimal degrees (positive east).
+     *
+     * @return the eastern-most longitude between -180 and +180°.
+     */
+    @Override
+    public double getEastBoundLongitude() {
+        return eastBoundLongitude;
+    }
+
+    /**
+     * Returns the southern-most coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     *
+     * @return the southern-most latitude between -90 and +90°.
+     */
+    @Override
+    public double getSouthBoundLatitude() {
+        return southBoundLatitude;
+    }
+
+    /**
+     * Returns the northern-most, coordinate of the limit of the dataset extent.
+     * The value is expressed in latitude in decimal degrees (positive north).
+     *
+     * @return the northern-most latitude between -90 and +90°.
+     */
+    @Override
+    public double getNorthBoundLatitude() {
+        return northBoundLatitude;
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Bounds.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXReader.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXReader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXReader.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -31,15 +31,18 @@ import java.time.format.DateTimeParseExc
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.UnsupportedTemporalTypeException;
+import javax.xml.transform.stax.StAXSource;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.bind.JAXBException;
 import com.esri.core.geometry.Point;
-import org.opengis.metadata.extent.GeographicBoundingBox;
-import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
-import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.internal.xml.StaxStreamReader;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Version;
+import org.apache.sis.xml.XML;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
@@ -47,13 +50,14 @@ import org.opengis.feature.Feature;
 
 /**
  * Reader for GPX 1.0 and 1.1 files.
+ * This reader is itself an iterator over all features found in the XML file.
  * Usage:
  *
  * {@preformat java
- *     final Reader    reader   = new Reader(dataStore, gpxInput, null);
- *     final Version   version  = reader.getVersion();
- *     final Metadata  metadata = reader.getMetadata();
- *     while(reader.hasNext()) {
+ *     final Reader   reader   = new Reader(dataStore, connector);
+ *     final Version  version  = reader.getVersion();
+ *     final Metadata metadata = reader.getMetadata();
+ *     while (reader.hasNext()) {
  *         Feature feature = reader.next();
  *     }
  * }
@@ -112,72 +116,133 @@ public class GPXReader extends StaxStrea
 
     /**
      * Creates a new GPX reader from the given file, URL, stream or reader object.
-     * See {@linkplain StaxStreamReader#StaxStreamReader super-class constructor}
-     * for more information about constructor arguments.
      *
      * @param  owner      the data store for which this reader is created.
-     * @param  input      value of {@code storage.getStorage()}.
-     * @param  connector  information about the storage (URL, stream, <i>etc</i>), or {@code null} if unknown.
+     * @param  connector  information about the storage (URL, stream, <i>etc</i>).
      * @throws DataStoreException if the input type is not recognized.
      * @throws XMLStreamException if an error occurred while opening the XML file.
+     * @throws JAXBException if an error occurred while parsing GPX 1.1 metadata.
      * @throws EOFException if the file seems to be truncated.
      */
-    public GPXReader(final GPXStore owner, final Object input, final StorageConnector connector)
-            throws DataStoreException, XMLStreamException, EOFException
+    public GPXReader(final GPXStore owner, final StorageConnector connector)
+            throws DataStoreException, XMLStreamException, JAXBException, EOFException
     {
-        super(owner, input, connector);
+        super(owner, connector);
         types = Types.DEFAULT;
         /*
-         * Read metadata immediately. We are especially interrested in the "bounds" tag,
-         * for creating the envelope.
+         * Skip comments, characters, entity declarations, etc. until we find the root element.
+         * If that root is anything other than <gpx>, we consider that this is not a GPX file.
+         */
+        moveToRootElement(GPXReader::isNamespace, Tags.GPX);
+        /*
+         * If a version attribute is found on the <gpx> element, use that value for detecting
+         * the GPX version. Otherwise use the namespace URL.  If the version is not found, we
+         * leave the field to null (we do not assume any version). If a version is specified,
+         * we require major.minor version 1.0 or 1.1 but accept any bug-fix versions.
          */
         final XMLStreamReader reader = getReader();
-readMD: while (reader.hasNext()) {
+        String ver = reader.getAttributeValue(null, Attributes.VERSION);
+        if (ver != null) {
+            version = new Version(ver);
+        } else {
+            final String ns = reader.getNamespaceURI();
+            if (ns != null) switch (ns) {
+                case Tags.NAMESPACE_V10: version = GPXStore.V1_0; break;
+                case Tags.NAMESPACE_V11: version = GPXStore.V1_1; break;
+            }
+        }
+        if (version != null) {
+            isLegacy = version.compareTo(GPXStore.V1_0, 2) <= 0;
+            if (version.compareTo(GPXStore.V1_1, 2) > 0) {
+                throw new DataStoreContentException(errors().getString(
+                        Errors.Keys.UnsupportedFormatVersion_2, owner.getFormatName(), version));
+            }
+        }
+        /*
+         * Read metadata immediately, from current position until the beginning of way points, tracks or routes.
+         * The metadata can appear in two forms:
+         *
+         *   - In GPX 1.0, they are declared directly in the <gpx> body.
+         *     Those elements are parsed in the switch statement below.
+         *
+         *   - In GPX 1.1, they are declared in a <metadata> sub-element and their structure is a little bit
+         *     more elaborated than it was in the previous version. We will use JAXB for parsing them.
+         */
+        while (reader.hasNext()) {
             switch (reader.next()) {
                 case START_ELEMENT: {
-                    if (isGPX(reader)) {
+                    if (isNamespace(reader.getNamespaceURI())) {
                         switch (reader.getLocalName()) {
                             case Tags.GPX: {
-                                String str = "1.1";     // Consider 1.1 by default
-                                final int n=reader.getAttributeCount();
-                                for (int i=0; i<n; i++) {
-                                    if (Attributes.VERSION.equals(reader.getAttributeLocalName(i))) {
-                                        str = reader.getAttributeValue(i);
-                                    }
-                                }
-                                version = new Version(str);
-                                isLegacy = GPXStore.V1_0.equals(version);
-                                if (isLegacy) {
-                                    // we wont found a metadata tag, must read the tags here.
-                                    metadata = parseMetadata100();
-                                    break readMD;
-                                } else if (!GPXStore.V1_1.equals(version)) {
-                                    throw new DataStoreException("Unsupported version: " + version);
+                                throw new DataStoreContentException(errors().getString(
+                                        Errors.Keys.NestedElementNotAllowed_1, Tags.GPX));
+                            }
+                            case Tags.METADATA: {
+                                metadata = (Metadata) XML.unmarshal(new StAXSource(reader), null);
+                                return;
+                            }
+                            case Tags.NAME: {
+                                metadata().name = reader.getElementText();
+                                break;
+                            }
+                            case Tags.DESCRIPTION: {
+                                metadata().description = reader.getElementText();
+                                break;
+                            }
+                            case Tags.AUTHOR: {
+                                if (metadata().author == null) metadata.author = new Person();
+                                metadata.author.name = reader.getElementText();
+                                break;
+                            }
+                            case Tags.EMAIL: {
+                                if (metadata().author == null) metadata.author = new Person();
+                                metadata.author.email = reader.getElementText();
+                                break;
+                            }
+                            case Tags.URL: {
+                                try {
+                                    metadata().links.add(new Link(new URI(reader.getElementText())));
+                                } catch (URISyntaxException ex) {
+                                    throw new XMLStreamException(ex);
                                 }
                                 break;
                             }
-                            case Tags.METADATA: {
-                                metadata = parseMetadata110();
-                                break readMD;
+                            case Tags.URL_NAME: {
+                                //reader.getElementText();
+                                break;
                             }
+                            case Tags.TIME:     metadata().time     = parseTime(reader.getElementText()); break;
+                            case Tags.KEYWORDS: metadata().keywords = Arrays.asList(reader.getElementText().split(" ")); break;
+                            case Tags.BOUNDS:   metadata().bounds   = parseBound(); break;
                             case Tags.WAY_POINT:
                             case Tags.TRACKS:
-                            case Tags.ROUTES: {
-                                break readMD;
-                            }
+                            case Tags.ROUTES: return;
                         }
                     }
+                    break;
+                }
+                case END_ELEMENT: {
+                    if (isNamespace(reader.getNamespaceURI()) && Tags.GPX.equals(reader.getLocalName())) {
+                        // TODO
+                    }
+                    break;
                 }
             }
         }
     }
 
     /**
-     * Returns {@code true} if the current element of the given reader is in the GPX namespace or has no namespace.
+     * Returns {@code true} if the given namespace is a GPX namespace or is null.
      */
-    private static boolean isGPX(final XMLStreamReader reader) {
-        final String ns = reader.getNamespaceURI();
-        return (ns == null) || ns.startsWith(Tags.NAMESPACE);
+    private static boolean isNamespace(final String ns) {
+        return (ns == null) || ns.startsWith(Tags.NAMESPACE + "/GPX/");
+    }
+
+    private Metadata metadata() {
+        if (metadata == null) {
+            metadata = new Metadata();
+        }
+        return metadata;
     }
 
     /**
@@ -276,56 +341,6 @@ readMD: while (reader.hasNext()) {
      * Parse current metadata element.
      * The stax reader must be placed to the start element of the metadata.
      */
-    private Metadata parseMetadata100() throws XMLStreamException, EOFException {
-        final XMLStreamReader reader = getReader();
-        final Metadata metadata = new Metadata();
-readMD: while (reader.hasNext()) {
-            switch (reader.next()) {
-                case START_ELEMENT: {
-                    switch (reader.getLocalName()) {
-                        case Tags.NAME:        metadata.name        = reader.getElementText(); break;
-                        case Tags.DESCRIPTION: metadata.description = reader.getElementText(); break;
-                        case Tags.AUTHOR: {
-                            if (metadata.author == null) metadata.author = new Person();
-                            metadata.author.name = reader.getElementText();
-                            break;
-                        }
-                        case Tags.EMAIL: {
-                            if (metadata.author == null) metadata.author = new Person();
-                            metadata.author.email = reader.getElementText();
-                            break;
-                        }
-                        case Tags.URL: {
-                            try {
-                                metadata.links.add(new Link(new URI(reader.getElementText())));
-                            } catch (URISyntaxException ex) {
-                                throw new XMLStreamException(ex);
-                            }
-                            break;
-                        }
-                        case Tags.URL_NAME: {
-                            //reader.getElementText();
-                            break;
-                        }
-                        case Tags.TIME:     metadata.time     = parseTime(reader.getElementText()); break;
-                        case Tags.KEYWORDS: metadata.keywords = Arrays.asList(reader.getElementText().split(" ")); break;
-                        case Tags.BOUNDS:   metadata.bounds   = parseBound(); break;
-                        case Tags.WAY_POINT:
-                        case Tags.TRACKS:
-                        case Tags.ROUTES:
-                            //there is no more metadata tags
-                            break readMD;
-                    }
-                }
-            }
-        }
-        return metadata;
-    }
-
-    /**
-     * Parse current metadata element.
-     * The stax reader must be placed to the start element of the metadata.
-     */
     private Metadata parseMetadata110() throws XMLStreamException, EOFException {
         final XMLStreamReader reader = getReader();
         final Metadata metadata = new Metadata();
@@ -465,7 +480,7 @@ readMD: while (reader.hasNext()) {
      * Parse current Envelope element.
      * The stax reader must be placed to the start element.
      */
-    private GeographicBoundingBox parseBound() throws XMLStreamException, EOFException {
+    private Bounds parseBound() throws XMLStreamException, EOFException {
         final XMLStreamReader reader = getReader();
         final String xmin = reader.getAttributeValue(null, Attributes.MIN_X);
         final String xmax = reader.getAttributeValue(null, Attributes.MAX_X);
@@ -477,12 +492,12 @@ readMD: while (reader.hasNext()) {
         }
 
         skipUntilEnd(Tags.BOUNDS);
-
-        return new DefaultGeographicBoundingBox(
-                Double.parseDouble(xmin),
-                Double.parseDouble(xmax),
-                Double.parseDouble(ymin),
-                Double.parseDouble(ymax));
+        final Bounds bounds = new Bounds();
+        bounds.westBoundLongitude = Double.parseDouble(xmin);
+        bounds.eastBoundLongitude = Double.parseDouble(xmax);
+        bounds.southBoundLatitude = Double.parseDouble(ymin);
+        bounds.northBoundLatitude = Double.parseDouble(ymax);
+        return bounds;
     }
 
     /**

Copied: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/JAXB.java (from r1774377, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataTypes.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/JAXB.java?p2=sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/JAXB.java&p1=sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataTypes.java&r1=1774377&r2=1774418&rev=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/MetadataTypes.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/JAXB.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -14,11 +14,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.internal.metadata;
+package org.apache.sis.internal.gpx;
 
 import java.util.Collection;
 import org.apache.sis.internal.jaxb.TypeRegistration;
-import org.apache.sis.metadata.iso.DefaultMetadata;
 
 
 /**
@@ -26,16 +25,16 @@ import org.apache.sis.metadata.iso.Defau
  * This class is declared in the {@code META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration} file.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.3
- * @version 0.3
+ * @since   0.8
+ * @version 0.8
  * @module
  */
-public final class MetadataTypes extends TypeRegistration {
+public final class JAXB extends TypeRegistration {
     /**
      * Adds to the given collection the metadata types that should be given to the initial JAXB context.
      */
     @Override
     public void getTypes(final Collection<Class<?>> addTo) {
-        addTo.add(DefaultMetadata.class);
+        addTo.add(Metadata.class);
     }
 }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Metadata.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -26,8 +26,9 @@ import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.io.IOException;
-import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlList;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
 
 import org.opengis.metadata.citation.CitationDate;
 import org.opengis.metadata.citation.DateType;
@@ -35,14 +36,12 @@ import org.opengis.metadata.citation.Onl
 import org.opengis.metadata.citation.Responsibility;
 import org.opengis.metadata.constraint.Constraints;
 import org.opengis.metadata.extent.Extent;
-import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.metadata.identification.Keywords;
 import org.opengis.util.InternationalString;
 
 import org.apache.sis.internal.simple.SimpleMetadata;
 import org.apache.sis.io.TableAppender;
 import org.apache.sis.metadata.iso.citation.DefaultCitationDate;
-import org.apache.sis.metadata.iso.extent.DefaultExtent;
 import org.apache.sis.metadata.iso.identification.DefaultKeywords;
 import org.apache.sis.util.iso.SimpleInternationalString;
 
@@ -75,6 +74,7 @@ import org.apache.sis.util.iso.SimpleInt
  * @version 0.8
  * @module
  */
+@XmlRootElement(name = Tags.METADATA)
 public final class Metadata extends SimpleMetadata {
     /**
      * The name of the GPX file.
@@ -121,7 +121,7 @@ public final class Metadata extends Simp
      *
      * @see #getDates()
      */
-    @XmlElement(name = Tags.TIME)
+//  @XmlElement(name = Tags.TIME)
     public Temporal time;
 
     /**
@@ -140,8 +140,8 @@ public final class Metadata extends Simp
      *
      * @see #getExtents()
      */
-    @XmlElement
-    public GeographicBoundingBox bounds;
+    @XmlElement(name = Tags.BOUNDS)
+    public Bounds bounds;
 
     /**
      * Creates an initially empty metadata object.
@@ -227,11 +227,7 @@ public final class Metadata extends Simp
      */
     @Override
     public Collection<Extent> getExtents() {
-        if (bounds != null) {
-            return Collections.singleton(new DefaultExtent(null, bounds, null, null));
-        } else {
-            return super.getExtents();
-        }
+        return (bounds != null) ? Collections.singleton(bounds) : super.getExtents();
     }
 
     /**
@@ -303,7 +299,7 @@ public final class Metadata extends Simp
     @Override
     public String toString() {
         final StringBuilder buffer = new StringBuilder();
-        buffer.append("GPX metadata");
+        buffer.append("GPX metadata").append(System.lineSeparator());
         final TableAppender table = new TableAppender(buffer);
         table.setMultiLinesCells(true);
         table.appendHorizontalSeparator();
@@ -347,7 +343,7 @@ public final class Metadata extends Simp
      * @param  separator  the separator to insert between each value.
      */
     private static void append(final TableAppender table, final String label, final List<?> values, final String separator) {
-        if (values != null) {
+        if (values != null && !values.isEmpty()) {
             table.append(label).append(':').nextColumn();
             final int n = values.size();
             for (int i=0; i<n; i++) {

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Types.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Types.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Types.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Types.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -99,7 +99,7 @@ final class Types extends Static {
          * This parent has a single property, "@identifier" of type Integer,
          * which is not part of GPX specification.
          *
-         * http://www.topografix.com:GPXEntity
+         * http://www.topografix.com/GPX/GPXEntity
          * ┌─────────────┬─────────┬─────────────┐
          * │ Name        │ Type    │ Cardinality │
          * ├─────────────┼─────────┼─────────────┤
@@ -111,7 +111,7 @@ final class Types extends Static {
         builder.addAttribute(Integer.class).setName(AttributeConvention.IDENTIFIER_PROPERTY);
         final FeatureType parent = builder.build();
         /*
-         * http://www.topografix.com:WayPoint ⇾ GPXEntity
+         * http://www.topografix.com/GPX/WayPoint ⇾ GPXEntity
          * ┌───────────────┬────────────────┬────────────────────────┬─────────────┐
          * │ Name          │ Type           │ XML type               │ Cardinality │
          * ├───────────────┼────────────────┼────────────────────────┼─────────────┤
@@ -164,7 +164,7 @@ final class Types extends Static {
         builder.addAttribute(Integer       .class).setName(Tags.DGPS_ID);
         wayPoint = builder.build();
         /*
-         * http://www.topografix.com:Route ⇾ GPXEntity
+         * http://www.topografix.com/GPX/Route ⇾ GPXEntity
          * ┌─────────────┬────────────────┬────────────────────────┬─────────────┐
          * │ Name        │ Type           │ XML type               │ Cardinality │
          * ├─────────────┼────────────────┼────────────────────────┼─────────────┤
@@ -197,7 +197,7 @@ final class Types extends Static {
         builder.addAssociation(wayPoint).setName(Tags.ROUTE_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
         route = builder.build();
         /*
-         * http://www.topografix.com:TrackSegment ⇾ GPXEntity
+         * http://www.topografix.com/GPX/TrackSegment ⇾ GPXEntity
          * ┌─────────────┬──────────┬─────────────┬─────────────┐
          * │ Name        │ Type     │ XML type    │ Cardinality │
          * ├─────────────┼──────────┼─────────────┼─────────────┤
@@ -216,7 +216,7 @@ final class Types extends Static {
         builder.addAssociation(wayPoint).setName(Tags.TRACK_POINTS).setMaximumOccurs(Integer.MAX_VALUE);
         trackSegment = builder.build();
         /*
-         * http://www.topografix.com:Track ⇾ GPXEntity
+         * http://www.topografix.com/GPX/Track ⇾ GPXEntity
          * ┌─────────────┬────────────────┬────────────────────────┬─────────────┐
          * │ Name        │ Type           │ XML type               │ Cardinality │
          * ├─────────────┼────────────────┼────────────────────────┼─────────────┤

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -66,8 +66,11 @@
 @XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = Tags.NAMESPACE_V11, xmlns = {
     @XmlNs(prefix = "gpx", namespaceURI = Tags.NAMESPACE_V11)
 })
+@XmlAccessorType(XmlAccessType.NONE)
 package org.apache.sis.internal.gpx;
 
 import javax.xml.bind.annotation.XmlNs;
 import javax.xml.bind.annotation.XmlNsForm;
 import javax.xml.bind.annotation.XmlSchema;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java?rev=1774418&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.xml;
+
+import java.util.Collection;
+import java.util.Collections;
+import javax.xml.bind.annotation.XmlTransient;
+import org.apache.sis.geometry.AbstractEnvelope;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.GeographicBoundingBox;
+import org.opengis.metadata.extent.GeographicExtent;
+import org.opengis.metadata.extent.TemporalExtent;
+import org.opengis.metadata.extent.VerticalExtent;
+import org.opengis.util.InternationalString;
+import org.apache.sis.referencing.CommonCRS;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+
+/**
+ * Base class of geographic bounding boxes to expose also as an envelope and an ISO-19115 extent.
+ * This base class does not contain any field. It is aimed to be sub-classed by data stores which
+ * will add their own JAXB annotations. The only methods that subclasses need to implement are:
+ *
+ * <ul>
+ *   <li>{@link #getSouthBoundLatitude()}</li>
+ *   <li>{@link #getNorthBoundLatitude()}</li>
+ *   <li>{@link #getWestBoundLongitude()}</li>
+ *   <li>{@link #getEastBoundLongitude()}</li>
+ * </ul>
+ *
+ * The envelope assumes a two-dimensional WGS84 coordinate reference system with
+ * (<var>latitude</var>, <var>longitude</var>) axis order, as defined by EPSG:4326.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+@XmlTransient
+public abstract class GeographicEnvelope extends AbstractEnvelope implements GeographicBoundingBox, Extent {
+    /**
+     * For subclass constructors.
+     */
+    protected GeographicEnvelope() {
+    }
+
+    /**
+     * Returns the number of dimensions, which is assumed to be 2.
+     * The value returned by this method shall be equals to the value returned by
+     * {@code getCoordinateReferenceSystem().getCoordinateSystem().getDimension()}.
+     *
+     * @return the number of dimensions in this envelope.
+     */
+    @Override
+    public int getDimension() {
+        return 2;
+    }
+
+    /**
+     * Returns the coordinate reference system, or {@code null} if unknown.
+     * The default implementation returns a two-dimensional WGS84 coordinate reference system
+     * with (<var>latitude</var>, <var>longitude</var>) axis order, as defined by EPSG:4326.
+     *
+     * @return the coordinate reference system, or {@code null}.
+     */
+    @Override
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return CommonCRS.WGS84.geographic();
+    }
+
+    /**
+     * Returns the south or west envelope bound.
+     *
+     * @param  dimension  0 for the south bound, 1 for the west bound.
+     * @return the requested envelope bound.
+     * @throws IndexOutOfBoundsException if the given index is not a positive number less than the number of dimensions.
+     */
+    @Override
+    public double getLower(final int dimension) {
+        switch (dimension) {
+            case 0: return getSouthBoundLatitude();
+            case 1: return getWestBoundLongitude();
+            default: throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Returns the north or east envelope bound.
+     *
+     * @param  dimension  0 for the north bound, 1 for the east bound.
+     * @return the requested envelope bound.
+     * @throws IndexOutOfBoundsException if the given index is not a positive number less than the number of dimensions.
+     */
+    @Override
+    public double getUpper(int dimension) {
+        switch (dimension) {
+            case 0: return getNorthBoundLatitude();
+            case 1: return getEastBoundLongitude();
+            default: throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Returns the spatial and temporal extent for the referring object.
+     * The default implementation unconditionally returns {@code null}.
+     *
+     * @return the spatial and temporal extent, or {@code null} in none.
+     */
+    @Override
+    public InternationalString getDescription() {
+        return null;
+    }
+
+    /**
+     * Provides geographic component of the extent of the referring object.
+     * The default implementation returns a singleton containing only this
+     * geographic bounding box.
+     *
+     * @return the geographic extent, or an empty set if none.
+     */
+    @Override
+    public Collection<? extends GeographicExtent> getGeographicElements() {
+        return Collections.singleton(this);
+    }
+
+    /**
+     * Provides temporal component of the extent of the referring object.
+     * The default implementation unconditionally returns an empty set.
+     *
+     * @return the temporal extent, or an empty set if none.
+     */
+    @Override
+    public Collection<? extends TemporalExtent> getTemporalElements() {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Provides vertical component of the extent of the referring object.
+     * The default implementation unconditionally returns an empty set.
+     *
+     * @return the vertical extent, or an empty set if none.
+     */
+    @Override
+    public Collection<? extends VerticalExtent> getVerticalElements() {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Indication of whether the bounding box encompasses an area covered by the data
+     * (<cite>inclusion</cite>) or an area where data is not present (<cite>exclusion</cite>).
+     * The default implementation unconditionally returns {@link Boolean#TRUE}.
+     *
+     * @return {@code true} for inclusion, or {@code false} for exclusion.
+     */
+    @Override
+    public Boolean getInclusion() {
+        return Boolean.TRUE;
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/GeographicEnvelope.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStream.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStream.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStream.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStream.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -96,7 +96,7 @@ abstract class StaxStream implements Aut
     /**
      * Returns the error resources in the current locale.
      */
-    final Errors errors() {
+    protected final Errors errors() {
         return Errors.getResources(owner.getLocale());
     }
 }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java?rev=1774418&r1=1774417&r2=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamReader.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -21,6 +21,7 @@ import java.io.InputStream;
 import java.util.NoSuchElementException;
 import java.io.EOFException;
 import java.io.Reader;
+import java.util.function.Predicate;
 import javax.xml.stream.XMLEventReader;
 import javax.xml.stream.XMLInputFactory;
 import javax.xml.stream.XMLStreamConstants;
@@ -35,9 +36,9 @@ import org.xml.sax.InputSource;
 import org.w3c.dom.Node;
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
+import org.apache.sis.storage.DataStoreContentException;
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Classes;
 
 
@@ -82,32 +83,24 @@ public abstract class StaxStreamReader e
     private XMLStreamReader reader;
 
     /**
+     * Input name (typically filename) for formatting error messages.
+     */
+    protected final String inputName;
+
+    /**
      * Creates a new XML reader from the given file, URL, stream or reader object.
-     * This constructor is used in two ways depending on whether the optional {@code connector} argument is null or not:
-     *
-     * <ul class="verbose">
-     *   <li>If the {@code connector} argument is {@code null}, then the {@code input} argument shall be an instance of
-     *       {@link XMLStreamReader}, {@link XMLEventReader}, {@link InputSource}, {@link InputStream}, {@link Reader},
-     *       {@link Source} or {@link Node}, otherwise a {@link DataStoreException} will be thrown.</li>
-     *
-     *   <li>If the {@code connector} argument is not {@code null}, then the {@code input} argument should be the
-     *       value of {@link StorageConnector#getStorage()} (i.e. the input object as given by the user). If that
-     *       value is not recognized, then this constructor will fallback on {@link StorageConnector#getStorageAs(Class)}
-     *       with the {@link InputStream} type. In any cases, this constructor invokes
-     *       {@link StorageConnector#closeAllExcept(Object)} after the input has been set.</li>
-     * </ul>
      *
      * @param  owner      the data store for which this reader is created.
-     * @param  input      value of {@code storage.getStorage()}.
-     * @param  connector  information about the storage (URL, stream, <i>etc</i>), or {@code null} if unknown.
+     * @param  connector  information about the storage (URL, stream, <i>etc</i>).
      * @throws DataStoreException if the input type is not recognized.
      * @throws XMLStreamException if an error occurred while opening the XML file.
      */
-    protected StaxStreamReader(final StaxDataStore owner, final Object input, final StorageConnector connector)
+    protected StaxStreamReader(final StaxDataStore owner, final StorageConnector connector)
             throws DataStoreException, XMLStreamException
     {
         super(owner);
-        ArgumentChecks.ensureNonNull("input", input);
+        inputName = connector.getStorageName();
+        final Object input = connector.getStorage();
         if      (input instanceof XMLStreamReader) reader = (XMLStreamReader) input;
         else if (input instanceof XMLEventReader)  reader = factory().createXMLStreamReader(new StAXSource((XMLEventReader) input));
         else if (input instanceof InputSource)     reader = factory().createXMLStreamReader(new SAXSource((InputSource) input));
@@ -116,8 +109,8 @@ public abstract class StaxStreamReader e
         else if (input instanceof Source)          reader = factory().createXMLStreamReader((Source) input);
         else if (input instanceof Node)            reader = factory().createXMLStreamReader(new DOMSource((Node) input));
         else {
-            final InputStream in;
-            if (connector == null || (in = connector.getStorageAs(InputStream.class)) == null) {
+            final InputStream in = connector.getStorageAs(InputStream.class);
+            if (in == null) {
                 throw new UnsupportedStorageException(errors().getString(Errors.Keys.IllegalInputTypeForReader_2,
                                                       owner.getFormatName(), Classes.getClass(input)));
             }
@@ -127,9 +120,7 @@ public abstract class StaxStreamReader e
             return;
         }
         initCloseable(input);
-        if (connector != null) {
-            connector.closeAllExcept(input);
-        }
+        connector.closeAllExcept(input);
     }
 
     /**
@@ -149,7 +140,7 @@ public abstract class StaxStreamReader e
         if (reader != null) {
             return reader;
         }
-        throw new XMLStreamException(errors().getString(Errors.Keys.ClosedReader_1, "XML"));
+        throw new XMLStreamException(errors().getString(Errors.Keys.ClosedReader_1, owner.getFormatName()));
     }
 
     /**
@@ -187,6 +178,36 @@ public abstract class StaxStreamReader e
     }
 
     /**
+     * Moves the cursor the the first start element and verifies that it is the expected element.
+     * This method is useful for skipping comments, entity declarations, <i>etc.</i> before the root element.
+     *
+     * <p>If the reader is already on a start element, then this method does not move forward.
+     * Once a root element has been found, this method verifies that the namespace and local name
+     * are the expected ones, or throws an exception otherwise.</p>
+     *
+     * @param  isNamespace  a predicate receiving the namespace in argument (which may be null)
+     *                      and returning whether that namespace is the expected one.
+     * @param  localName    the expected name of the root element.
+     * @throws EOFException if no start element has been found before we reached the end of file.
+     * @throws XMLStreamException if an error occurred while reading the XML stream.
+     * @throws DataStoreContentException if the root element is not the expected one.
+     */
+    protected final void moveToRootElement(final Predicate<String> isNamespace, final String localName)
+            throws EOFException, XMLStreamException, DataStoreContentException
+    {
+        final XMLStreamReader reader = getReader();
+        if (!reader.isStartElement()) {
+            do if (!reader.hasNext()) {
+                throw new EOFException(errors().getString(Errors.Keys.UnexpectedEndOfFile_1, inputName));
+            } while (reader.next() != START_ELEMENT);
+        }
+        if (!isNamespace.test(reader.getNamespaceURI()) || !localName.equals(reader.getLocalName())) {
+            throw new DataStoreContentException(errors().getString(
+                    Errors.Keys.UnexpectedFileFormat_2, owner.getFormatName(), inputName));
+        }
+    }
+
+    /**
      * Skips all remaining elements until we reach the end of the given tag.
      * Nested tags of the same name, if any, are also skipped.
      *
@@ -213,7 +234,7 @@ public abstract class StaxStreamReader e
                 }
             }
         }
-        throw new EOFException(errors().getString(Errors.Keys.UnexpectedEndOfFile_1, tagName));
+        throw new EOFException(errors().getString(Errors.Keys.UnexpectedEndOfFile_1, inputName));
     }
 
     /**

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java?rev=1774418&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.storage.gps;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
+
+
+/**
+ * Type of GPS fix (position derived from measuring external reference points).
+ * The <cite>Standard Positioning Service</cite> (SPS) can be two- or three-dimensional,
+ * or use differential GPS for increased accuracy.
+ * The <cite>Precise Positioning Service</cite> (PPS) is a military signal.
+ *
+ * <p>This enumeration value can be encoded in <a href="https://en.wikipedia.org/wiki/GPS_Exchange_Format">GPS
+ * Exchange Format</a> (GPX) with the following strings: {@code "none"}, {@code "2d"}, {@code "3d"}, {@code "dgps"}
+ * and {@code "pps"}.
+ * When reading such data, {@code Fix} instances can be a
+ * {@linkplain org.apache.sis.feature.DefaultFeatureType#getProperty property value}
+ * of the features returned by the GPX reader.</p>
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public enum Fix {
+    /**
+     * GPS has no fix.
+     * Note that this is a different meaning than "the fix information is unknown".
+     */
+    NONE("none"),
+
+    /**
+     * Two-dimensional fix. This requires the signal of at least 3 satellites.
+     */
+    TWO_DIMENSIONAL("2d"),
+
+    /**
+     * Three-dimensional fix. This requires the signal of at least 4 satellites.
+     */
+    THREE_DIMENSIONAL("3d"),
+
+    /**
+     * Differential Global Positioning Service (DGPS) used.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Differential_GPS">Differential GPS on Wikipedia</a>
+     */
+    DIFFERENTIAL("dgps"),
+
+    /**
+     * Precise Positioning Service (PPS) used. This is a military signal.
+     * (Note: the alternative is <cite>Standard Positioning Service</cite> – SPS).
+     */
+    PRECISE("pps");
+
+    /**
+     * The string representation in GPX format.
+     */
+    private final String gpx;
+
+    /**
+     * Creates a new fix of the given code.
+     */
+    private Fix(final String gpx) {
+        this.gpx = gpx;
+    }
+
+    /**
+     * The GPX names associated to the enumeration values.
+     */
+    private static final Map<String,Fix> VALUES = new HashMap<>(6);
+    static {
+        for (final Fix fix : values()) {
+            VALUES.put(fix.gpx, fix);
+        }
+    }
+
+    /**
+     * Returns the enumeration value from the given GPX name, or {@code null} if none.
+     * Recognized values are {@code "none"}, {@code "2d"}, {@code "3d"}, {@code "dgps"}
+     * and {@code "pps"}, ignoring case.
+     *
+     * @param  name  the GPX name (case insensitive) for which to get an enumeration value.
+     * @return the enumeration value for the given GPX name, or {@code null} if the given name
+     *         was {@code null} or unrecognized.
+     */
+    public static Fix fromGPX(final String name) {
+        if (name == null) return null;
+        return VALUES.get(name.toLowerCase(Locale.US));
+    }
+
+    /**
+     * Returns the string representation in <cite>GPS Exchange Format</cite> (GPX).
+     * Returned value can be {@code "none"}, {@code "2d"}, {@code "3d"}, {@code "dgps"} or {@code "pps"},
+     *
+     * @return the GPX enumeration value.
+     */
+    public String toGPX() {
+        return gpx;
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/Fix.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Copied: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/package-info.java (from r1773845, sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/package-info.java?p2=sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/package-info.java&p1=sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java&r1=1773845&r2=1774418&rev=1774418&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/storage/gps/package-info.java [UTF-8] Thu Dec 15 11:31:17 2016
@@ -17,57 +17,11 @@
 
 
 /**
- * Reads and writes data in GPS Exchange Format (GPX).
- * The GPX format can be used to describe waypoints, tracks, and routes.
- * Example (from Wikipedia):
+ * Structures related to Global Positioning System (GPS).
  *
- * {@preformat xml
- *   <gpx version="1.1" creator="Oregon 400t">
- *     <metadata>
- *       <link href="http://www.garmin.com">
- *         <text>Garmin International</text>
- *       </link>
- *       <time>2009-10-17T22:58:43Z</time>
- *     </metadata>
- *     <trk>
- *       <name>Example GPX Document</name>
- *       <trkseg>
- *         <trkpt lat="47.644548" lon="-122.326897">
- *           <ele>4.46</ele>
- *           <time>2009-10-17T18:37:26Z</time>
- *         </trkpt>
- *         <trkpt lat="47.644548" lon="-122.326897">
- *           <ele>4.94</ele>
- *           <time>2009-10-17T18:37:31Z</time>
- *         </trkpt>
- *         <trkpt lat="47.644548" lon="-122.326897">
- *           <ele>6.87</ele>
- *           <time>2009-10-17T18:37:34Z</time>
- *         </trkpt>
- *       </trkseg>
- *     </trk>
- *   </gpx>
- * }
- *
- * The GPX 1.1 specification enforces the following conventions:
- * <ul>
- *   <li>All coordinates are relative to the WGS84 datum.</li>
- *   <li>All measurements are in metric units.</li>
- * </ul>
- *
- * @see <a href="https://en.wikipedia.org/wiki/GPS_Exchange_Format">GPS Exchange Format on Wikipedia</a>
- * @see <a href="http://www.topografix.com/GPX/1/1/">GPX 1.1 Schema Documentation</a>
- *
- * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
  * @since   0.8
  * @version 0.8
  * @module
  */
-@XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = Tags.NAMESPACE_V11, xmlns = {
-    @XmlNs(prefix = "gpx", namespaceURI = Tags.NAMESPACE_V11)
-})
-package org.apache.sis.internal.gpx;
-
-import javax.xml.bind.annotation.XmlNs;
-import javax.xml.bind.annotation.XmlNsForm;
-import javax.xml.bind.annotation.XmlSchema;
+package org.apache.sis.storage.gps;

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration?rev=1774418&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration [UTF-8] Thu Dec 15 11:31:17 2016
@@ -0,0 +1 @@
+org.apache.sis.internal.gpx.JAXB

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-xmlstore/src/main/resources/META-INF/services/org.apache.sis.internal.jaxb.TypeRegistration
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8



Mime
View raw message