sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1773845 [1/2] - in /sis/branches/JDK8/storage/sis-xmlstore/src: main/java/org/apache/sis/internal/gpx/ test/java/org/apache/sis/internal/gpx/
Date Mon, 12 Dec 2016 18:40:26 GMT
Author: desruisseaux
Date: Mon Dec 12 18:40:26 2016
New Revision: 1773845

URL: http://svn.apache.org/viewvc?rev=1773845&view=rev
Log:
Replace URI by OnlineResource.
Replace GPXVersion by Version.
Move tags in their own class.

Added:
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXStore.java   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Link.java   (with props)
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Tags.java
      - copied, changed from r1773750, sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java
Removed:
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Element.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXVersion.java
Modified:
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Copyright.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/GPXWriter100.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupAsPolylineOperation.java
    sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupPointsAsPolylineOperation.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/Person.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/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/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Constants.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -20,7 +20,9 @@ import org.apache.sis.util.Static;
 
 
 /**
- * GPX XML tag and attribute names.
+ * GPX attribute names in XML files.
+ *
+ * @todo may be refactored.
  *
  * @author  Johann Sorel (Geomatys)
  * @since   0.8
@@ -32,70 +34,20 @@ final class Constants extends Static {
      * Main GPX XML tags.
      */
     /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_GPX = "gpx";
-    /** Used in versions 1.0 and 1.1. */
     public static final String ATT_GPX_VERSION = "version";
     /** Used in versions 1.0 and 1.1. */
     public static final String ATT_GPX_CREATOR = "creator";
 
     /*
-     * Attributes used a bit everywhere.
-     */
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_NAME = "name";
-    /** Used in version 1.0. */
-    public static final String TAG_URL = "url";
-    /** Used in version 1.0. */
-    public static final String TAG_URLNAME = "urlname";
-    /** Used in version 1.1. */
-    public static final String TAG_LINK = "link";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_DESC = "desc";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_CMT = "cmt";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_SRC = "src";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_TYPE = "type";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_NUMBER = "number";
-
-    /*
-     * Metadata tags.
-     */
-    /** Used in version 1.1. */
-    public static final String TAG_METADATA = "metadata";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_METADATA_TIME = "time";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_METADATA_KEYWORDS = "keywords";
-
-    /*
-     * Person tags.
-     */
-    /** Used in version 1.0 (as attribute) and 1.1 (as tag) */
-    public static final String TAG_AUTHOR = "author";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_AUTHOR_EMAIL = "email";
-
-    /*
      * Copyright tags.
      */
     /** Used in version 1.1. */
-    public static final String TAG_COPYRIGHT = "copyright";
-    /** Used in version 1.1. */
-    public static final String TAG_COPYRIGHT_YEAR = "year";
-    /** Used in version 1.1. */
-    public static final String TAG_COPYRIGHT_LICENSE = "license";
-    /** Used in version 1.1. */
     public static final String ATT_COPYRIGHT_AUTHOR = "author";
 
     /*
      * Bounds tags.
      */
     /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_BOUNDS = "bounds";
-    /** Used in versions 1.0 and 1.1. */
     public static final String ATT_BOUNDS_MINLAT = "minlat";
     /** Used in versions 1.0 and 1.1. */
     public static final String ATT_BOUNDS_MINLON = "minlon";
@@ -108,77 +60,15 @@ final class Constants extends Static {
      * Link tags.
      */
     /** Used in version 1.1. */
-    public static final String TAG_LINK_TEXT = "text";
-    /** Used in version 1.1. */
-    public static final String TAG_LINK_TYPE = "type";
-    /** Used in version 1.1. */
     public static final String ATT_LINK_HREF = "href";
 
     /*
      * WPT tags.
      */
     /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT = "wpt";
-    /** Used in versions 1.0 and 1.1. */
     public static final String ATT_WPT_LAT = "lat";
     /** Used in versions 1.0 and 1.1. */
     public static final String ATT_WPT_LON = "lon";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_ELE = "ele";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_TIME = "time";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_MAGVAR = "magvar";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_GEOIHEIGHT = "geoidheight";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_SYM = "sym";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_FIX = "fix";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_SAT = "sat";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_HDOP = "hdop";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_VDOP = "vdop";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_PDOP = "pdop";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_AGEOFGPSDATA = "ageofdgpsdata";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_WPT_DGPSID = "dgpsid";
-
-    /*
-     * RTE tags.
-     */
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_RTE = "rte";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_RTE_RTEPT = "rtept";
-
-    /*
-     * TRK tags.
-     */
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_TRK = "trk";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_TRK_SEG = "trkseg";
-    /** Used in versions 1.0 and 1.1. */
-    public static final String TAG_TRK_SEG_PT = "trkpt";
-
-    /**
-     * GPX scope name used for feature type names.
-     */
-    public static final String NAMESPACE = "http://www.topografix.com";
-
-    /**
-     * GPX 1.1 XML namespace.
-     */
-    public static final String NAMESPACE_V11 = "http://www.topografix.com/GPX/1/1";
-    /**
-     * GPX 1.0 XML namespace.
-     */
-    public static final String NAMESPACE_V10 = "http://www.topografix.com/GPX/1/0";
 
     /**
      * Do not allow instantiation of this class.

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Copyright.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Copyright.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Copyright.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Copyright.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -16,13 +16,11 @@
  */
 package org.apache.sis.internal.gpx;
 
-import java.net.URI;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.Objects;
-import org.apache.sis.metadata.iso.citation.DefaultOnlineResource;
 import org.apache.sis.util.iso.SimpleInternationalString;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
@@ -64,7 +62,7 @@ import org.opengis.util.InternationalStr
  * @version 0.8
  * @module
  */
-public final class Copyright extends Element implements LegalConstraints, Responsibility, Party, Citation, CitationDate {
+public final class Copyright implements LegalConstraints, Responsibility, Party, Citation, CitationDate {
     /**
      * The copyright holder.
      * This field is mandatory in principle, but {@code Copyright} implementation is robust to null value.
@@ -90,10 +88,10 @@ public final class Copyright extends Ele
      *
      * @see #getOnlineResources()
      */
-    public URI license;
+    public OnlineResource license;
 
     /**
-     * Creates a new initially empty instance.
+     * Creates an initially empty instance.
      * Callers should set at least the {@link #author} field after construction.
      */
     public Copyright() {
@@ -179,8 +177,8 @@ public final class Copyright extends Ele
      * @see #getOnlineResources()
      */
     @Override
-    public Collection<Citation> getReferences() {
-        return thisOrEmpty(this, year != null || license != null);
+    public Collection<? extends Citation> getReferences() {
+        return thisOrEmpty(year != null || license != null);
     }
 
     /**
@@ -205,8 +203,8 @@ public final class Copyright extends Ele
      * @see #getCitedResponsibleParties()
      */
     @Override
-    public Collection<Responsibility> getResponsibleParties() {
-        return thisOrEmpty(this, author != null);
+    public Collection<? extends Responsibility> getResponsibleParties() {
+        return thisOrEmpty(author != null);
     }
 
 
@@ -248,8 +246,8 @@ public final class Copyright extends Ele
      * @see #getName()
      */
     @Override
-    public Collection<Party> getParties() {
-        return thisOrEmpty(this, author != null);
+    public Collection<? extends Party> getParties() {
+        return thisOrEmpty(author != null);
     }
 
     /**
@@ -315,8 +313,8 @@ public final class Copyright extends Ele
      * @see #getDateType()
      */
     @Override
-    public Collection<CitationDate> getDates() {
-        return thisOrEmpty(this, year != null);
+    public Collection<? extends CitationDate> getDates() {
+        return thisOrEmpty(year != null);
     }
 
     /**
@@ -466,10 +464,15 @@ public final class Copyright extends Ele
      */
     @Override
     public Collection<OnlineResource> getOnlineResources() {
-        if (license != null) {
-            return Collections.singleton(new DefaultOnlineResource(license));
-        }
-        return Collections.emptySet();
+        return (license != null) ? Collections.singleton(license) : Collections.emptySet();
+    }
+
+    /**
+     * Returns this object as a singleton if the given condition is {@code true},
+     * or an empty set if the given condition is {@code false}.
+     */
+    private Collection<Copyright> thisOrEmpty(final boolean condition) {
+        return condition ? Collections.singleton(this) : Collections.emptySet();
     }
 
     /**

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=1773845&r1=1773844&r2=1773845&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] Mon Dec 12 18:40:26 2016
@@ -17,7 +17,6 @@
 package org.apache.sis.internal.gpx;
 
 import java.io.IOException;
-import java.net.URI;
 import java.net.URISyntaxException;
 import java.time.Instant;
 import java.time.LocalDate;
@@ -37,9 +36,9 @@ import org.apache.sis.metadata.iso.exten
 import org.apache.sis.storage.DataStoreException;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.xml.StaxStreamReader;
+import org.apache.sis.util.Version;
 
 import static javax.xml.stream.XMLStreamReader.*;
-import static org.apache.sis.internal.gpx.Constants.*;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
@@ -77,8 +76,9 @@ public class GPXReader extends StaxStrea
     private int wayPointInc = 0;
     private int routeInc = 0;
     private int trackInc = 0;
-    private GPXVersion version = null;
-    private String baseNamespace = NAMESPACE_V11;
+    private Version version;
+    private boolean isRevision;
+    private String baseNamespace = Tags.NAMESPACE_V11;
 
     /**
      * {@inheritDoc }
@@ -98,36 +98,38 @@ searchLoop:
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String typeName = reader.getLocalName();
-                    if (TAG_GPX.equalsIgnoreCase(typeName)) {
+                    if (Tags.GPX.equalsIgnoreCase(typeName)) {
 
                         String str = "1.1";     // Consider 1.1 by default
                         for (int i=0,n=reader.getAttributeCount(); i<n;i++) {
-                            if (ATT_GPX_VERSION.equalsIgnoreCase(reader.getAttributeLocalName(i))) {
+                            if (Constants.ATT_GPX_VERSION.equalsIgnoreCase(reader.getAttributeLocalName(i))) {
                                 str = reader.getAttributeValue(i);
                             }
                         }
 
                         try {
-                            this.version = GPXVersion.toVersion(str);
+                            this.version = new Version(str);
                         } catch (NumberFormatException ex) {
                             throw new XMLStreamException(ex);
                         }
-
-                        if (version == GPXVersion.v1_0_0) {
-                            baseNamespace = NAMESPACE_V10;
+                        isRevision = GPXStore.V1_1.equals(version);
+                        if (isRevision) {
+                            baseNamespace = Tags.NAMESPACE_V11;
+                        } else if (GPXStore.V1_0.equals(version)) {
+                            baseNamespace = Tags.NAMESPACE_V10;
                             //we wont found a metadata tag, must read the tags here.
                             metadata = parseMetadata100();
                             break searchLoop;
-                        } else{
-                            baseNamespace = NAMESPACE_V11;
+                        } else {
+                            throw new DataStoreException("Unsupported version: " + version);
                         }
 
-                    } else if (TAG_METADATA.equalsIgnoreCase(typeName)) {
+                    } else if (Tags.METADATA.equalsIgnoreCase(typeName)) {
                         metadata = parseMetadata110();
                         break searchLoop;
-                    } else if (  TAG_WPT.equalsIgnoreCase(typeName)
-                            || TAG_TRK.equalsIgnoreCase(typeName)
-                            || TAG_RTE.equalsIgnoreCase(typeName)) {
+                    } else if (  Tags.WAY_POINT.equalsIgnoreCase(typeName)
+                            || Tags.TRACKS.equalsIgnoreCase(typeName)
+                            || Tags.ROUTES.equalsIgnoreCase(typeName)) {
                         //there is no metadata tag
                         break searchLoop;
                     }
@@ -140,9 +142,9 @@ searchLoop:
      * Get GPX file version.
      * This method will return a result only if called only after the input has been set.
      *
-     * @return GPXVersion or null if input is not set.
+     * @return Version or null if input is not set.
      */
-    public GPXVersion getVersion() {
+    public Version getVersion() {
         return version;
     }
 
@@ -214,13 +216,13 @@ searchLoop:
             }
             if (type == START_ELEMENT) {
                 final String localName = reader.getLocalName();
-                if (TAG_WPT.equalsIgnoreCase(localName)) {
+                if (Tags.WAY_POINT.equalsIgnoreCase(localName)) {
                     current = parseWayPoint(wayPointInc++);
                     break;
-                } else if (TAG_RTE.equalsIgnoreCase(localName)) {
+                } else if (Tags.ROUTES.equalsIgnoreCase(localName)) {
                     current = parseRoute(routeInc++);
                     break;
-                } else if (TAG_TRK.equalsIgnoreCase(localName)) {
+                } else if (Tags.TRACKS.equalsIgnoreCase(localName)) {
                     current = parseTrack(trackInc++);
                     break;
                 }
@@ -243,33 +245,33 @@ searchLoop:
             switch (type) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_NAME.equalsIgnoreCase(localName)) {
+                    if (Tags.NAME.equalsIgnoreCase(localName)) {
                         metadata.name = reader.getElementText();
-                    } else if (TAG_DESC.equalsIgnoreCase(localName)) {
+                    } else if (Tags.DESCRIPTION.equalsIgnoreCase(localName)) {
                         metadata.description = reader.getElementText();
-                    } else if (TAG_AUTHOR.equalsIgnoreCase(localName)) {
+                    } else if (Tags.AUTHOR.equalsIgnoreCase(localName)) {
                         if (metadata.author == null) metadata.author = new Person();
                         metadata.author.name = reader.getElementText();
-                    } else if (TAG_AUTHOR_EMAIL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.EMAIL.equalsIgnoreCase(localName)) {
                         if (metadata.author == null) metadata.author = new Person();
                         metadata.author.email = reader.getElementText();
-                    } else if (TAG_URL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.URL.equalsIgnoreCase(localName)) {
                         try {
-                            metadata.links.add(new URI(reader.getElementText()));
+                            metadata.links.add(new Link(reader.getElementText()));
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
-                    } else if (TAG_URLNAME.equalsIgnoreCase(localName)) {
+                    } else if (Tags.URL_NAME.equalsIgnoreCase(localName)) {
                         //reader.getElementText();
-                    } else if (TAG_METADATA_TIME.equalsIgnoreCase(localName)) {
+                    } else if (Tags.TIME.equalsIgnoreCase(localName)) {
                         metadata.time = parseTime(reader.getElementText());
-                    } else if (TAG_METADATA_KEYWORDS.equalsIgnoreCase(localName)) {
+                    } else if (Tags.KEYWORDS.equalsIgnoreCase(localName)) {
                         metadata.keywords = reader.getElementText();
-                    } else if (TAG_BOUNDS.equalsIgnoreCase(localName)) {
+                    } else if (Tags.BOUNDS.equalsIgnoreCase(localName)) {
                         metadata.bounds = parseBound();
-                    } else if (  TAG_WPT.equalsIgnoreCase(localName)
-                            || TAG_TRK.equalsIgnoreCase(localName)
-                            || TAG_RTE.equalsIgnoreCase(localName)) {
+                    } else if (  Tags.WAY_POINT.equalsIgnoreCase(localName)
+                            || Tags.TRACKS.equalsIgnoreCase(localName)
+                            || Tags.ROUTES.equalsIgnoreCase(localName)) {
                         //there is no more metadata tags
                         break searchLoop;
                     }
@@ -292,27 +294,27 @@ searchLoop:
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_NAME.equalsIgnoreCase(localName)) {
+                    if (Tags.NAME.equalsIgnoreCase(localName)) {
                         metadata.name = reader.getElementText();
-                    } else if (TAG_DESC.equalsIgnoreCase(localName)) {
+                    } else if (Tags.DESCRIPTION.equalsIgnoreCase(localName)) {
                         metadata.description = reader.getElementText();
-                    } else if (TAG_AUTHOR.equalsIgnoreCase(localName)) {
+                    } else if (Tags.AUTHOR.equalsIgnoreCase(localName)) {
                         metadata.author = parsePerson();
-                    } else if (TAG_COPYRIGHT.equalsIgnoreCase(localName)) {
+                    } else if (Tags.COPYRIGHT.equalsIgnoreCase(localName)) {
                         metadata.copyright = parseCopyright();
-                    } else if (TAG_LINK.equalsIgnoreCase(localName)) {
+                    } else if (Tags.LINK.equalsIgnoreCase(localName)) {
                         metadata.links.add(parseLink());
-                    } else if (TAG_METADATA_TIME.equalsIgnoreCase(localName)) {
+                    } else if (Tags.TIME.equalsIgnoreCase(localName)) {
                         metadata.time = parseTime(reader.getElementText());
-                    } else if (TAG_METADATA_KEYWORDS.equalsIgnoreCase(localName)) {
+                    } else if (Tags.KEYWORDS.equalsIgnoreCase(localName)) {
                         metadata.keywords = reader.getElementText();
-                    } else if (TAG_BOUNDS.equalsIgnoreCase(localName)) {
+                    } else if (Tags.BOUNDS.equalsIgnoreCase(localName)) {
                         metadata.bounds = parseBound();
                     }
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_METADATA.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.METADATA.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the metadata element
                         return metadata;
                     }
@@ -330,17 +332,17 @@ searchLoop:
     private Copyright parseCopyright() throws IOException, XMLStreamException {
         final XMLStreamReader reader = getReader();
         final Copyright copyright = new Copyright();
-        copyright.author = reader.getAttributeValue(null, ATT_COPYRIGHT_AUTHOR);
+        copyright.author = reader.getAttributeValue(null, Constants.ATT_COPYRIGHT_AUTHOR);
 
         while (reader.hasNext()) {
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_COPYRIGHT_YEAR.equalsIgnoreCase(localName)) {
+                    if (Tags.YEAR.equalsIgnoreCase(localName)) {
                         copyright.year = Integer.valueOf(reader.getElementText());
-                    } else if (TAG_COPYRIGHT_LICENSE.equalsIgnoreCase(localName)) {
+                    } else if (Tags.LICENSE.equalsIgnoreCase(localName)) {
                         try {
-                            copyright.license = new URI(reader.getElementText());
+                            copyright.license = new Link(reader.getElementText());
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
@@ -348,7 +350,7 @@ searchLoop:
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_COPYRIGHT.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.COPYRIGHT.equalsIgnoreCase(reader.getLocalName())) {
                         return copyright;
                     }
                     break;
@@ -362,27 +364,27 @@ searchLoop:
      * Parse current URI element.
      * The stax reader must be placed to the start element.
      */
-    private URI parseLink() throws IOException, XMLStreamException {
+    private Link parseLink() throws IOException, XMLStreamException {
         final XMLStreamReader reader = getReader();
-        String text = reader.getAttributeValue(null, ATT_LINK_HREF);
+        String text = reader.getAttributeValue(null, Constants.ATT_LINK_HREF);
         String mime = null;
 
         while (reader.hasNext()) {
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_LINK_TEXT.equalsIgnoreCase(localName) && text==null) {
+                    if (Tags.TEXT.equalsIgnoreCase(localName) && text==null) {
                         text = reader.getElementText();
-                    } else if (TAG_LINK_TYPE.equalsIgnoreCase(localName)) {
+                    } else if (Tags.TYPE.equalsIgnoreCase(localName)) {
                         mime = reader.getElementText();
                     }
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_LINK.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.LINK.equalsIgnoreCase(reader.getLocalName())) {
                         try {
                             // End of the link element
-                            return new URI(text);
+                            return new Link(text);
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
@@ -406,17 +408,17 @@ searchLoop:
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_NAME.equalsIgnoreCase(localName)) {
+                    if (Tags.NAME.equalsIgnoreCase(localName)) {
                         person.name = reader.getElementText();
-                    } else if (TAG_AUTHOR_EMAIL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.EMAIL.equalsIgnoreCase(localName)) {
                         person.email = reader.getElementText();
-                    } else if (TAG_LINK.equalsIgnoreCase(localName)) {
+                    } else if (Tags.LINK.equalsIgnoreCase(localName)) {
                         person.link = parseLink();
                     }
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_AUTHOR.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.AUTHOR.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the author element
                         return person;
                     }
@@ -433,16 +435,16 @@ searchLoop:
      */
     private GeographicBoundingBox parseBound() throws IOException, XMLStreamException {
         final XMLStreamReader reader = getReader();
-        final String xmin = reader.getAttributeValue(null, ATT_BOUNDS_MINLON);
-        final String xmax = reader.getAttributeValue(null, ATT_BOUNDS_MAXLON);
-        final String ymin = reader.getAttributeValue(null, ATT_BOUNDS_MINLAT);
-        final String ymax = reader.getAttributeValue(null, ATT_BOUNDS_MAXLAT);
+        final String xmin = reader.getAttributeValue(null, Constants.ATT_BOUNDS_MINLON);
+        final String xmax = reader.getAttributeValue(null, Constants.ATT_BOUNDS_MAXLON);
+        final String ymin = reader.getAttributeValue(null, Constants.ATT_BOUNDS_MINLAT);
+        final String ymax = reader.getAttributeValue(null, Constants.ATT_BOUNDS_MAXLAT);
 
         if (xmin == null || xmax == null || ymin == null || ymax == null) {
             throw new XMLStreamException("Error in xml file, metadata bounds not defined correctly");
         }
 
-        skipUntilEnd(TAG_BOUNDS);
+        skipUntilEnd(Tags.BOUNDS);
 
         return new DefaultGeographicBoundingBox(
                 Double.parseDouble(xmin),
@@ -464,10 +466,10 @@ searchLoop:
         //we kind the current tag name to know when we reach the end.
         final String tagName = reader.getLocalName();
 
-        List<URI> links = null;
+        List<Link> links = null;
 
-        final String lat = reader.getAttributeValue(null, ATT_WPT_LAT);
-        final String lon = reader.getAttributeValue(null, ATT_WPT_LON);
+        final String lat = reader.getAttributeValue(null, Constants.ATT_WPT_LAT);
+        final String lon = reader.getAttributeValue(null, Constants.ATT_WPT_LON);
 
         if (lat == null || lon == null) {
             throw new XMLStreamException("Error in xml file, way point lat/lon not defined correctly");
@@ -479,48 +481,48 @@ searchLoop:
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_WPT_ELE.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_ELE, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_TIME.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_TIME, parseTime(reader.getElementText()));
-                    } else if (TAG_WPT_MAGVAR.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_MAGVAR, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_GEOIHEIGHT.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_GEOIHEIGHT, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_NAME.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_NAME, reader.getElementText());
-                    } else if (TAG_CMT.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_CMT,reader.getElementText());
-                    } else if (TAG_DESC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_DESC, reader.getElementText());
-                    } else if (TAG_SRC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_SRC, reader.getElementText());
-                    } else if (TAG_LINK.equalsIgnoreCase(localName)) {
+                    if (Tags.ELEVATION.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.ELEVATION, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.TIME.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.TIME, parseTime(reader.getElementText()));
+                    } else if (Tags.MAGNETIC_VAR.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.MAGNETIC_VAR, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.GEOID_HEIGHT.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.GEOID_HEIGHT, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.NAME.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.NAME, reader.getElementText());
+                    } else if (Tags.COMMENT.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.COMMENT,reader.getElementText());
+                    } else if (Tags.DESCRIPTION.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.DESCRIPTION, reader.getElementText());
+                    } else if (Tags.SOURCE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.SOURCE, reader.getElementText());
+                    } else if (Tags.LINK.equalsIgnoreCase(localName)) {
                         if (links == null) links = new ArrayList<>();
                         links.add(parseLink());
-                    } else if (TAG_WPT_SYM.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_SYM, reader.getElementText());
-                    } else if (TAG_TYPE.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_TYPE, reader.getElementText());
-                    } else if (TAG_WPT_FIX.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_FIX, reader.getElementText());
-                    } else if (TAG_WPT_SAT.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_SAT, Integer.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_HDOP.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_HDOP, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_PDOP.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_PDOP, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_VDOP.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_VDOP, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_AGEOFGPSDATA.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_AGEOFGPSDATA, Double.valueOf(reader.getElementText()));
-                    } else if (TAG_WPT_DGPSID.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_WPT_DGPSID, Integer.valueOf(reader.getElementText()));
-                    } else if (version == GPXVersion.v1_0_0 && TAG_URL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.SYMBOL.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.SYMBOL, reader.getElementText());
+                    } else if (Tags.TYPE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.TYPE, reader.getElementText());
+                    } else if (Tags.FIX.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.FIX, reader.getElementText());
+                    } else if (Tags.SATELITTES.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.SATELITTES, Integer.valueOf(reader.getElementText()));
+                    } else if (Tags.HDOP.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.HDOP, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.PDOP.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.PDOP, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.VDOP.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.VDOP, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.AGE_OF_GPS_DATA.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.AGE_OF_GPS_DATA, Double.valueOf(reader.getElementText()));
+                    } else if (Tags.DGPS_ID.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.DGPS_ID, Integer.valueOf(reader.getElementText()));
+                    } else if (!isRevision && Tags.URL.equalsIgnoreCase(localName)) {
                         // GPX 1.0 only
                         if (links == null) links = new ArrayList<>();
                         try {
-                            links.add(new URI(reader.getElementText()));
+                            links.add(new Link(reader.getElementText()));
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
@@ -530,7 +532,7 @@ searchLoop:
                 case END_ELEMENT: {
                     if (tagName.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the way point element
-                        if (links!=null) feature.setPropertyValue(TAG_LINK, links);
+                        if (links!=null) feature.setPropertyValue(Tags.LINK, links);
                         return feature;
                     }
                     break;
@@ -550,36 +552,36 @@ searchLoop:
         feature.setPropertyValue("@identifier", index);
 
         int ptInc = 0;
-        List<URI> links = null;
+        List<Link> links = null;
         List<Feature> wayPoints = null;
 
         while (reader.hasNext()) {
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_RTE_RTEPT.equalsIgnoreCase(localName)) {
+                    if (Tags.ROUTE_POINTS.equalsIgnoreCase(localName)) {
                         if (wayPoints == null) wayPoints = new ArrayList<>();
                         wayPoints.add(parseWayPoint(ptInc++));
-                    } else if (TAG_NAME.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_NAME, reader.getElementText());
-                    } else if (TAG_CMT.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_CMT, reader.getElementText());
-                    } else if (TAG_DESC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_DESC, reader.getElementText());
-                    } else if (TAG_SRC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_SRC, reader.getElementText());
-                    } else if (TAG_LINK.equalsIgnoreCase(localName)) {
+                    } else if (Tags.NAME.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.NAME, reader.getElementText());
+                    } else if (Tags.COMMENT.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.COMMENT, reader.getElementText());
+                    } else if (Tags.DESCRIPTION.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.DESCRIPTION, reader.getElementText());
+                    } else if (Tags.SOURCE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.SOURCE, reader.getElementText());
+                    } else if (Tags.LINK.equalsIgnoreCase(localName)) {
                         if (links == null) links = new ArrayList<>();
                         links.add(parseLink());
-                    } else if (TAG_NUMBER.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_NUMBER, Integer.valueOf(reader.getElementText()));
-                    } else if (TAG_TYPE.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_TYPE, reader.getElementText());
-                    } else if (version == GPXVersion.v1_0_0 && TAG_URL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.NUMBER.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.NUMBER, Integer.valueOf(reader.getElementText()));
+                    } else if (Tags.TYPE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.TYPE, reader.getElementText());
+                    } else if (!isRevision && Tags.URL.equalsIgnoreCase(localName)) {
                         //GPX 1.0 only
                         if (links == null) links = new ArrayList<>();
                         try {
-                            links.add(new URI(reader.getElementText()));
+                            links.add(new Link(reader.getElementText()));
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
@@ -587,17 +589,17 @@ searchLoop:
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_RTE.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.ROUTES.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the route element
-                        if (links!=null) feature.setPropertyValue(TAG_LINK, links);
-                        if (wayPoints!=null) feature.setPropertyValue(TAG_RTE_RTEPT, wayPoints);
+                        if (links!=null) feature.setPropertyValue(Tags.LINK, links);
+                        if (wayPoints!=null) feature.setPropertyValue(Tags.ROUTE_POINTS, wayPoints);
                         return feature;
                     }
                     break;
                 }
             }
         }
-        throw new XMLStreamException("Error in xml file, "+TAG_RTE+" tag without end.");
+        throw new XMLStreamException("Error in xml file, "+Tags.ROUTES+" tag without end.");
     }
 
     /**
@@ -615,23 +617,23 @@ searchLoop:
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_TRK_SEG_PT.equalsIgnoreCase(localName)) {
+                    if (Tags.TRACK_POINTS.equalsIgnoreCase(localName)) {
                         if (wayPoints == null) wayPoints = new ArrayList<>();
                         wayPoints.add(parseWayPoint(ptInc++));
                     }
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_TRK_SEG.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.TRACK_SEGMENTS.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the track segment element
-                        if (wayPoints!=null) feature.setPropertyValue(TAG_TRK_SEG_PT, wayPoints);
+                        if (wayPoints!=null) feature.setPropertyValue(Tags.TRACK_POINTS, wayPoints);
                         return feature;
                     }
                     break;
                 }
             }
         }
-        throw new XMLStreamException("Error in xml file, "+TAG_TRK_SEG+" tag without end.");
+        throw new XMLStreamException("Error in xml file, "+Tags.TRACK_SEGMENTS+" tag without end.");
     }
 
     /**
@@ -643,36 +645,36 @@ searchLoop:
         final Feature feature = types.track.newInstance();
         feature.setPropertyValue("@identifier", index);
         int segInc = 0;
-        List<URI> links = null;
+        List<Link> links = null;
         List<Feature> segments = null;
 
         while (reader.hasNext()) {
             switch (reader.next()) {
                 case START_ELEMENT: {
                     final String localName = reader.getLocalName();
-                    if (TAG_TRK_SEG.equalsIgnoreCase(localName)) {
+                    if (Tags.TRACK_SEGMENTS.equalsIgnoreCase(localName)) {
                         if (segments == null) segments = new ArrayList<>();
                         segments.add(parseTrackSegment(segInc++));
-                    } else if (TAG_NAME.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_NAME, reader.getElementText());
-                    } else if (TAG_CMT.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_CMT, reader.getElementText());
-                    } else if (TAG_DESC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_DESC, reader.getElementText());
-                    } else if (TAG_SRC.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_SRC, reader.getElementText());
-                    } else if (TAG_LINK.equalsIgnoreCase(localName)) {
+                    } else if (Tags.NAME.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.NAME, reader.getElementText());
+                    } else if (Tags.COMMENT.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.COMMENT, reader.getElementText());
+                    } else if (Tags.DESCRIPTION.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.DESCRIPTION, reader.getElementText());
+                    } else if (Tags.SOURCE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.SOURCE, reader.getElementText());
+                    } else if (Tags.LINK.equalsIgnoreCase(localName)) {
                         if (links == null) links = new ArrayList<>();
                         links.add(parseLink());
-                    } else if (TAG_NUMBER.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_NUMBER, Integer.valueOf(reader.getElementText()));
-                    } else if (TAG_TYPE.equalsIgnoreCase(localName)) {
-                        feature.setPropertyValue(TAG_TYPE, reader.getElementText());
-                    } else if (version == GPXVersion.v1_0_0 && TAG_URL.equalsIgnoreCase(localName)) {
+                    } else if (Tags.NUMBER.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.NUMBER, Integer.valueOf(reader.getElementText()));
+                    } else if (Tags.TYPE.equalsIgnoreCase(localName)) {
+                        feature.setPropertyValue(Tags.TYPE, reader.getElementText());
+                    } else if (!isRevision && Tags.URL.equalsIgnoreCase(localName)) {
                         // GPX 1.0 only
                         if (links == null) links = new ArrayList<>();
                         try {
-                            links.add(new URI(reader.getElementText()));
+                            links.add(new Link(reader.getElementText()));
                         } catch (URISyntaxException ex) {
                             throw new XMLStreamException(ex);
                         }
@@ -680,17 +682,17 @@ searchLoop:
                     break;
                 }
                 case END_ELEMENT: {
-                    if (TAG_TRK.equalsIgnoreCase(reader.getLocalName())) {
+                    if (Tags.TRACKS.equalsIgnoreCase(reader.getLocalName())) {
                         // End of the track element
-                        if (links!=null) feature.setPropertyValue(TAG_LINK, links);
-                        if (segments!=null) feature.setPropertyValue(TAG_TRK_SEG, segments);
+                        if (links!=null) feature.setPropertyValue(Tags.LINK, links);
+                        if (segments!=null) feature.setPropertyValue(Tags.TRACK_SEGMENTS, segments);
                         return feature;
                     }
                     break;
                 }
             }
         }
-        throw new XMLStreamException("Error in xml file, "+TAG_TRK+" tag without end.");
+        throw new XMLStreamException("Error in xml file, "+Tags.TRACKS+" tag without end.");
     }
 
     /**

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXStore.java?rev=1773845&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXStore.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXStore.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -0,0 +1,42 @@
+/*
+ * 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 org.apache.sis.storage.DataStore;
+import org.apache.sis.util.Version;
+
+
+/**
+ * A data store backed by GeoTIFF files.
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+abstract class GPXStore extends DataStore {
+    /**
+     * The "1.0" version.
+     */
+    static final Version V1_0 = new Version("1.0");
+
+    /**
+     * The "1.1" version.
+     */
+    static final Version V1_1 = new Version("1.1");
+}

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

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

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -20,7 +20,6 @@ package org.apache.sis.internal.gpx;
 import com.esri.core.geometry.Point;
 import java.io.Closeable;
 import java.io.IOException;
-import java.net.URI;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -34,7 +33,6 @@ import org.apache.sis.internal.xml.StaxS
 import org.apache.sis.util.collection.BackingStoreException;
 
 import static org.apache.sis.util.ArgumentChecks.*;
-import static org.apache.sis.internal.gpx.Constants.*;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
@@ -62,7 +60,7 @@ public class GPXWriter100 extends StaxSt
      * @param creator file creator
      */
     public GPXWriter100(final String creator, final Object output) throws IOException, XMLStreamException {
-        this(NAMESPACE_V10, creator, output);
+        this(Tags.NAMESPACE_V10, creator, output);
     }
 
     /**
@@ -110,9 +108,9 @@ public class GPXWriter100 extends StaxSt
      */
     public void writeGPXTag() throws XMLStreamException {
         writer.setDefaultNamespace(namespace);
-        writer.writeStartElement(namespace, TAG_GPX);
-        writer.writeAttribute(ATT_GPX_VERSION, getVersion());
-        writer.writeAttribute(ATT_GPX_CREATOR, creator);
+        writer.writeStartElement(namespace, Tags.GPX);
+        writer.writeAttribute(Constants.ATT_GPX_VERSION, getVersion());
+        writer.writeAttribute(Constants.ATT_GPX_CREATOR, creator);
         writer.writeDefaultNamespace(namespace);
         writer.flush();
     }
@@ -139,7 +137,7 @@ public class GPXWriter100 extends StaxSt
             final Iterator<? extends Feature> ite = wayPoints.iterator();
             try {
                 while (ite.hasNext()) {
-                    writeWayPoint(ite.next(), TAG_WPT);
+                    writeWayPoint(ite.next(), Tags.WAY_POINT);
                 }
             } catch (BackingStoreException ex) {
                 final Throwable cause = ex.getCause();
@@ -205,22 +203,22 @@ public class GPXWriter100 extends StaxSt
      * @throws XMLStreamException if underlying xml stax writer encounter an error
      */
     public void write(final Metadata metadata) throws XMLStreamException {
-        writeSimpleTag(namespace, TAG_NAME, metadata.name);
-        writeSimpleTag(namespace, TAG_DESC, metadata.description);
+        writeSimpleTag(namespace, Tags.NAME, metadata.name);
+        writeSimpleTag(namespace, Tags.DESCRIPTION, metadata.description);
 
         if (metadata.author != null) {
-            writeSimpleTag(namespace, TAG_AUTHOR, metadata.author.name);
-            writeSimpleTag(namespace, TAG_AUTHOR_EMAIL, metadata.author.email);
+            writeSimpleTag(namespace, Tags.AUTHOR, metadata.author.name);
+            writeSimpleTag(namespace, Tags.EMAIL, metadata.author.email);
         }
 
         //model is based on 1.1 so not all attributs can be written
         writeLinkURIs(metadata.links);
 
         if (metadata.time != null) {
-            writeSimpleTag(namespace, TAG_METADATA_TIME, toString(metadata.time));
+            writeSimpleTag(namespace, Tags.TIME, toString(metadata.time));
         }
 
-        writeSimpleTag(namespace, TAG_METADATA_KEYWORDS, metadata.keywords);
+        writeSimpleTag(namespace, Tags.KEYWORDS, metadata.keywords);
         writeBounds(metadata.bounds);
         writer.flush();
     }
@@ -238,27 +236,27 @@ public class GPXWriter100 extends StaxSt
         writer.writeStartElement(namespace, tagName);
 
         final Point pt = (Point) feature.getProperty("@geometry").getValue();
-        writer.writeAttribute(ATT_WPT_LAT, Double.toString(pt.getY()));
-        writer.writeAttribute(ATT_WPT_LON, Double.toString(pt.getX()));
+        writer.writeAttribute(Constants.ATT_WPT_LAT, Double.toString(pt.getY()));
+        writer.writeAttribute(Constants.ATT_WPT_LON, Double.toString(pt.getX()));
 
-        writeProperty(TAG_WPT_ELE,          feature.getProperty(TAG_WPT_ELE));
-        writeProperty(TAG_WPT_TIME,         feature.getProperty(TAG_WPT_TIME));
-        writeProperty(TAG_WPT_MAGVAR,       feature.getProperty(TAG_WPT_MAGVAR));
-        writeProperty(TAG_WPT_GEOIHEIGHT,   feature.getProperty(TAG_WPT_GEOIHEIGHT));
-        writeProperty(TAG_NAME,             feature.getProperty(TAG_NAME));
-        writeProperty(TAG_CMT,              feature.getProperty(TAG_CMT));
-        writeProperty(TAG_DESC,             feature.getProperty(TAG_DESC));
-        writeProperty(TAG_SRC,              feature.getProperty(TAG_SRC));
-        writeLinkURIs((Collection<URI>)     feature.getPropertyValue(TAG_LINK));
-        writeProperty(TAG_WPT_SYM,          feature.getProperty(TAG_WPT_SYM));
-        writeProperty(TAG_TYPE,             feature.getProperty(TAG_TYPE));
-        writeProperty(TAG_WPT_FIX,          feature.getProperty(TAG_WPT_FIX));
-        writeProperty(TAG_WPT_SAT,          feature.getProperty(TAG_WPT_SAT));
-        writeProperty(TAG_WPT_HDOP,         feature.getProperty(TAG_WPT_HDOP));
-        writeProperty(TAG_WPT_VDOP,         feature.getProperty(TAG_WPT_VDOP));
-        writeProperty(TAG_WPT_PDOP,         feature.getProperty(TAG_WPT_PDOP));
-        writeProperty(TAG_WPT_AGEOFGPSDATA, feature.getProperty(TAG_WPT_AGEOFGPSDATA));
-        writeProperty(TAG_WPT_DGPSID,       feature.getProperty(TAG_WPT_DGPSID));
+        writeProperty(Tags.ELEVATION,       feature.getProperty(Tags.ELEVATION));
+        writeProperty(Tags.TIME,            feature.getProperty(Tags.TIME));
+        writeProperty(Tags.MAGNETIC_VAR,    feature.getProperty(Tags.MAGNETIC_VAR));
+        writeProperty(Tags.GEOID_HEIGHT,    feature.getProperty(Tags.GEOID_HEIGHT));
+        writeProperty(Tags.NAME,            feature.getProperty(Tags.NAME));
+        writeProperty(Tags.COMMENT,         feature.getProperty(Tags.COMMENT));
+        writeProperty(Tags.DESCRIPTION,     feature.getProperty(Tags.DESCRIPTION));
+        writeProperty(Tags.SOURCE,          feature.getProperty(Tags.SOURCE));
+        writeLinkURIs((Collection<Link>)    feature.getPropertyValue(Tags.LINK));
+        writeProperty(Tags.SYMBOL,          feature.getProperty(Tags.SYMBOL));
+        writeProperty(Tags.TYPE,            feature.getProperty(Tags.TYPE));
+        writeProperty(Tags.FIX,             feature.getProperty(Tags.FIX));
+        writeProperty(Tags.SATELITTES,      feature.getProperty(Tags.SATELITTES));
+        writeProperty(Tags.HDOP,            feature.getProperty(Tags.HDOP));
+        writeProperty(Tags.VDOP,            feature.getProperty(Tags.VDOP));
+        writeProperty(Tags.PDOP,            feature.getProperty(Tags.PDOP));
+        writeProperty(Tags.AGE_OF_GPS_DATA, feature.getProperty(Tags.AGE_OF_GPS_DATA));
+        writeProperty(Tags.DGPS_ID,         feature.getProperty(Tags.DGPS_ID));
 
         writer.writeEndElement();
     }
@@ -272,18 +270,18 @@ public class GPXWriter100 extends StaxSt
     public void writeRoute(final Feature feature) throws XMLStreamException {
         if (feature == null) return;
 
-        writer.writeStartElement(namespace, TAG_RTE);
+        writer.writeStartElement(namespace, Tags.ROUTES);
 
-        writeProperty(TAG_NAME,             feature.getProperty(TAG_NAME));
-        writeProperty(TAG_CMT,              feature.getProperty(TAG_CMT));
-        writeProperty(TAG_DESC,             feature.getProperty(TAG_DESC));
-        writeProperty(TAG_SRC,              feature.getProperty(TAG_SRC));
-        writeLinkURIs((Collection<URI>)     feature.getPropertyValue(TAG_LINK));
-        writeProperty(TAG_NUMBER,           feature.getProperty(TAG_NUMBER));
-        writeProperty(TAG_TYPE,             feature.getProperty(TAG_TYPE));
+        writeProperty(Tags.NAME,         feature.getProperty(Tags.NAME));
+        writeProperty(Tags.COMMENT,      feature.getProperty(Tags.COMMENT));
+        writeProperty(Tags.DESCRIPTION,  feature.getProperty(Tags.DESCRIPTION));
+        writeProperty(Tags.SOURCE,       feature.getProperty(Tags.SOURCE));
+        writeLinkURIs((Collection<Link>) feature.getPropertyValue(Tags.LINK));
+        writeProperty(Tags.NUMBER,       feature.getProperty(Tags.NUMBER));
+        writeProperty(Tags.TYPE,         feature.getProperty(Tags.TYPE));
 
-        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_RTE_RTEPT)) {
-            writeWayPoint((Feature) prop,TAG_RTE_RTEPT);
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(Tags.ROUTE_POINTS)) {
+            writeWayPoint((Feature) prop,Tags.ROUTE_POINTS);
         }
 
         writer.writeEndElement();
@@ -298,17 +296,17 @@ public class GPXWriter100 extends StaxSt
     public void writeTrack(final Feature feature) throws XMLStreamException {
         if (feature == null) return;
 
-        writer.writeStartElement(namespace, TAG_TRK);
+        writer.writeStartElement(namespace, Tags.TRACKS);
 
-        writeProperty(TAG_NAME,             feature.getProperty(TAG_NAME));
-        writeProperty(TAG_CMT,              feature.getProperty(TAG_CMT));
-        writeProperty(TAG_DESC,             feature.getProperty(TAG_DESC));
-        writeProperty(TAG_SRC,              feature.getProperty(TAG_SRC));
-        writeLinkURIs((Collection<URI>)     feature.getPropertyValue(TAG_LINK));
-        writeProperty(TAG_NUMBER,           feature.getProperty(TAG_NUMBER));
-        writeProperty(TAG_TYPE,             feature.getProperty(TAG_TYPE));
+        writeProperty(Tags.NAME,         feature.getProperty(Tags.NAME));
+        writeProperty(Tags.COMMENT,      feature.getProperty(Tags.COMMENT));
+        writeProperty(Tags.DESCRIPTION,  feature.getProperty(Tags.DESCRIPTION));
+        writeProperty(Tags.SOURCE,       feature.getProperty(Tags.SOURCE));
+        writeLinkURIs((Collection<Link>) feature.getPropertyValue(Tags.LINK));
+        writeProperty(Tags.NUMBER,       feature.getProperty(Tags.NUMBER));
+        writeProperty(Tags.TYPE,         feature.getProperty(Tags.TYPE));
 
-        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_TRK_SEG)) {
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(Tags.TRACK_SEGMENTS)) {
             writeTrackSegment(prop);
         }
 
@@ -323,10 +321,10 @@ public class GPXWriter100 extends StaxSt
      */
     protected void writeTrackSegment(final Feature feature) throws XMLStreamException {
         if (feature == null) return;
-        writer.writeStartElement(namespace, TAG_TRK_SEG);
+        writer.writeStartElement(namespace, Tags.TRACK_SEGMENTS);
 
-        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_TRK_SEG_PT)) {
-            writeWayPoint((Feature) prop,TAG_TRK_SEG_PT);
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(Tags.TRACK_POINTS)) {
+            writeWayPoint((Feature) prop,Tags.TRACK_POINTS);
         }
 
         writer.writeEndElement();
@@ -338,7 +336,7 @@ public class GPXWriter100 extends StaxSt
      * @param links links to write
      * @throws XMLStreamException if underlying xml stax writer encounter an error
      */
-    protected void writeLinkURIs(final Collection<URI> links) throws XMLStreamException {
+    protected void writeLinkURIs(final Collection<Link> links) throws XMLStreamException {
         if (links != null && !links.isEmpty()) {
             //in gpx 1.0 we only have one link available
             writeLink(links.iterator().next());
@@ -348,14 +346,14 @@ public class GPXWriter100 extends StaxSt
     /**
      * Write a link tag.
      *
-     * @param uri if null nothing will be written
+     * @param link if null nothing will be written
      * @throws XMLStreamException if underlying xml stax writer encounter an error
      */
-    protected void writeLink(final URI uri) throws XMLStreamException {
-        if (uri == null) return;
+    protected void writeLink(final Link link) throws XMLStreamException {
+        if (link == null) return;
 
-        writer.writeStartElement(namespace, TAG_LINK);
-        writer.writeAttribute(ATT_LINK_HREF, uri.toASCIIString());
+        writer.writeStartElement(namespace, Tags.LINK);
+        writer.writeAttribute(Constants.ATT_LINK_HREF, link.uri.toASCIIString());
         writer.writeEndElement();
     }
 
@@ -368,12 +366,12 @@ public class GPXWriter100 extends StaxSt
     protected void writeBounds(final GeographicBoundingBox env) throws XMLStreamException {
         if (env == null) return;
 
-        writer.writeStartElement(namespace, TAG_BOUNDS);
+        writer.writeStartElement(namespace, Tags.BOUNDS);
 
-        writer.writeAttribute(ATT_BOUNDS_MINLAT, Double.toString(env.getSouthBoundLatitude()));
-        writer.writeAttribute(ATT_BOUNDS_MINLON, Double.toString(env.getWestBoundLongitude()));
-        writer.writeAttribute(ATT_BOUNDS_MAXLAT, Double.toString(env.getNorthBoundLatitude()));
-        writer.writeAttribute(ATT_BOUNDS_MAXLON, Double.toString(env.getEastBoundLongitude()));
+        writer.writeAttribute(Constants.ATT_BOUNDS_MINLAT, Double.toString(env.getSouthBoundLatitude()));
+        writer.writeAttribute(Constants.ATT_BOUNDS_MINLON, Double.toString(env.getWestBoundLongitude()));
+        writer.writeAttribute(Constants.ATT_BOUNDS_MAXLAT, Double.toString(env.getNorthBoundLatitude()));
+        writer.writeAttribute(Constants.ATT_BOUNDS_MAXLON, Double.toString(env.getEastBoundLongitude()));
 
         writer.writeEndElement();
     }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -16,14 +16,11 @@
  */
 package org.apache.sis.internal.gpx;
 
-import java.net.URI;
 import java.time.temporal.Temporal;
 import java.util.Collection;
 import java.io.IOException;
 import javax.xml.stream.XMLStreamException;
 
-import static org.apache.sis.internal.gpx.Constants.*;
-
 
 /**
  * Stax writer class for GPX 1.1 files.
@@ -39,7 +36,7 @@ public class GPXWriter110 extends GPXWri
      * @param creator gpx file creator
      */
     public GPXWriter110(final String creator, final Object output) throws IOException, XMLStreamException {
-        super(NAMESPACE_V11, creator, output);
+        super(Tags.NAMESPACE_V11, creator, output);
     }
 
     /**
@@ -59,21 +56,21 @@ public class GPXWriter110 extends GPXWri
      */
     @Override
     public void write(final Metadata metadata) throws XMLStreamException {
-        writer.writeStartElement(namespace, TAG_METADATA);
-        writeSimpleTag(namespace, TAG_NAME, metadata.name);
-        writeSimpleTag(namespace, TAG_DESC, metadata.description);
+        writer.writeStartElement(namespace, Tags.METADATA);
+        writeSimpleTag(namespace, Tags.NAME, metadata.name);
+        writeSimpleTag(namespace, Tags.DESCRIPTION, metadata.description);
         writePerson(metadata.author);
         writeCopyright(metadata.copyright);
-        for (URI uri : metadata.links) {
+        for (Link uri : metadata.links) {
             writeLink(uri);
         }
 
         final Temporal d = metadata.time;
         if (d != null) {
-            writeSimpleTag(namespace, TAG_METADATA_TIME, toString(d));
+            writeSimpleTag(namespace, Tags.TIME, toString(d));
         }
 
-        writeSimpleTag(namespace, TAG_METADATA_KEYWORDS, metadata.keywords);
+        writeSimpleTag(namespace, Tags.KEYWORDS, metadata.keywords);
         writeBounds(metadata.bounds);
 
         writer.writeEndElement();
@@ -89,9 +86,9 @@ public class GPXWriter110 extends GPXWri
     protected void writePerson(final Person person) throws XMLStreamException {
         if (person == null) return;
 
-        writer.writeStartElement(namespace, TAG_AUTHOR);
-        writeSimpleTag(namespace, TAG_NAME, person.getName());
-        writeSimpleTag(namespace, TAG_AUTHOR_EMAIL, person.email);
+        writer.writeStartElement(namespace, Tags.AUTHOR);
+        writeSimpleTag(namespace, Tags.NAME, person.getName());
+        writeSimpleTag(namespace, Tags.EMAIL, person.email);
         writeLink(person.link);
         writer.writeEndElement();
     }
@@ -103,10 +100,10 @@ public class GPXWriter110 extends GPXWri
      * @throws XMLStreamException if underlying xml stax writer encounter an error
      */
     @Override
-    protected void writeLinkURIs(final Collection<URI> links) throws XMLStreamException {
+    protected void writeLinkURIs(final Collection<Link> links) throws XMLStreamException {
         if (links != null && !links.isEmpty()) {
-            for (URI uri : links) {
-                writeLink(uri);
+            for (Link link : links) {
+                writeLink(link);
             }
         }
     }
@@ -114,15 +111,15 @@ public class GPXWriter110 extends GPXWri
     /**
      * Write a link tag.
      *
-     * @param uri if null nothing will be written
+     * @param link if null nothing will be written
      * @throws XMLStreamException if underlying xml stax writer encounter an error
      */
     @Override
-    protected void writeLink(final URI uri) throws XMLStreamException {
-        if (uri == null) return;
+    protected void writeLink(final Link link) throws XMLStreamException {
+        if (link == null) return;
 
-        writer.writeStartElement(namespace, TAG_LINK);
-        writer.writeAttribute(ATT_LINK_HREF, uri.toASCIIString());
+        writer.writeStartElement(namespace, Tags.LINK);
+        writer.writeAttribute(Constants.ATT_LINK_HREF, link.uri.toASCIIString());
         writer.writeEndElement();
     }
 
@@ -135,13 +132,13 @@ public class GPXWriter110 extends GPXWri
     public void writeCopyright(final Copyright copyRight) throws XMLStreamException {
         if (copyRight == null) return;
 
-        writer.writeStartElement(namespace, TAG_COPYRIGHT);
+        writer.writeStartElement(namespace, Tags.COPYRIGHT);
         final String author = copyRight.author;
         if (author != null) {
-            writer.writeAttribute(ATT_COPYRIGHT_AUTHOR, author);
+            writer.writeAttribute(Constants.ATT_COPYRIGHT_AUTHOR, author);
         }
-        writeSimpleTag(namespace, TAG_COPYRIGHT_YEAR, copyRight.year);
-        writeSimpleTag(namespace, TAG_COPYRIGHT_LICENSE, copyRight.license);
+        writeSimpleTag(namespace, Tags.YEAR, copyRight.year);
+        writeSimpleTag(namespace, Tags.LICENSE, copyRight.license);
         writer.writeEndElement();
     }
 

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupAsPolylineOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupAsPolylineOperation.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupAsPolylineOperation.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupAsPolylineOperation.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -27,12 +27,13 @@ import org.apache.sis.feature.AbstractOp
 import org.apache.sis.feature.DefaultAttributeType;
 import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.internal.feature.FeatureUtilities;
+import org.apache.sis.util.resources.Errors;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;
 import org.opengis.feature.Property;
+import org.opengis.feature.Attribute;
 import org.opengis.feature.AttributeType;
-import org.opengis.feature.MultiValuedPropertyException;
 
 
 /**
@@ -67,19 +68,24 @@ class GroupAsPolylineOperation extends A
      * The type of the values computed by this operation. The name of this type presumes
      * that the result will be assigned to the "geometry" attribute of the feature type.
      */
-    private static final AttributeType<Polyline> RESULT_TYPE = new DefaultAttributeType<>(
+    static final AttributeType<Polyline> RESULT_TYPE = new DefaultAttributeType<>(
             Collections.singletonMap(NAME_KEY, AttributeConvention.ENVELOPE_PROPERTY), Polyline.class, 1, 1, null);
 
-    private final String[] path;
+    /**
+     * Name of the property to follow in order to get the geometries to add to a polyline.
+     * This property shall be a feature association, usually with [0 … ∞] cardinality.
+     */
+    final String association;
 
     /**
+     * Creates a new operation which will look for geometries in the given feature association.
      *
-     * @param identification operation identification parameters
-     * @param attributePath names of the properties to group
+     * @param  identification  name and other information to be given to this operation.
+     * @param  association     name of the property to follow in order to get the geometries to add to a polyline.
      */
-    GroupAsPolylineOperation(Map<String,?> identification, String... attributePath) {
+    GroupAsPolylineOperation(final Map<String,?> identification, final String association) {
         super(identification);
-        this.path = attributePath;
+        this.association = association;
     }
 
     /**
@@ -91,80 +97,89 @@ class GroupAsPolylineOperation extends A
     }
 
     /**
-     * {@inheritDoc }
+     * Returns the expected result type.
      */
     @Override
-    public AttributeType<Polyline> getResult() {
+    public final AttributeType<Polyline> getResult() {
         return RESULT_TYPE;
     }
 
     /**
-     * {@inheritDoc}
+     * Executes the operation on the specified feature with the specified parameters.
+     * If the geometries have changed since last time this method has been invoked,
+     * the result will be recomputed.
      */
     @Override
-    public Property apply(Feature feature, ParameterValueGroup parameters) {
-        return new GeomAtt(feature);
-    }
-
-    void addGeometry(Polyline geom, final Object propVal, final boolean first) {
-        geom.add((Polyline) propVal, false);
-    }
-
-    final boolean explore(final Feature att, final int depth, Polyline geom, boolean first) {
-        if (depth == path.length - 1) {
-            // We are on the field that hold the geometry points
-            for (final Object propVal : asCollection(att, path[depth])) {
-                addGeometry(geom, propVal, first);
-                first = false;
-            }
-        } else {
-            // Explore children
-            int d = depth + 1;
-            for (final Object prop : asCollection(att, path[depth])) {
-                final Feature child = (Feature) prop;
-                first = explore(child, d, geom, first);
-            }
-        }
-        return first;
+    public final Property apply(Feature feature, ParameterValueGroup parameters) {
+        return new Result(feature);
     }
 
-    private static Collection<?> asCollection(Feature att, String property) {
-        final Object value = att.getPropertyValue(property);
-        if (value == null) {
-            return Collections.emptyList();
-        }
-        if (value instanceof Collection<?>) {
-            return (Collection<?>) value;
-        }
-        return Collections.singletonList(value);
+    /**
+     * Invoked for every geometric objects to put in a single polyline.
+     *
+     * @param addTo     where to add the geometry object.
+     * @param geometry  the point or polyline to add to {@code addTo}.
+     * @param isFirst   whether {@code geometry} is the first object added to the given polyline.
+     */
+    void addGeometry(final Polyline addTo, final Object geometry, final boolean isFirst) {
+        addTo.add((Polyline) geometry, false);
     }
 
 
     /**
-     * Operation attribute.
-     * Value is calculated each time it is accessed.
+     * The attribute resulting from execution if the {@link GroupAsPolylineOperation}.
+     * The value is computed when first requested, then cached for this {@code Result} instance only.
+     * Note that the cache is not used when {@link #apply(Feature, ParameterValueGroup)} is invoked,
+     * causing a new value to be computed again. The intend is to behave as if the operation has been
+     * executed at {@code apply(…)} invocation time, even if we deferred the actual execution.
      */
-    private final class GeomAtt extends AbstractAttribute<Polyline> {
-
+    private final class Result extends AbstractAttribute<Polyline> {
+        /**
+         * For cross-version compatibility.
+         */
         private static final long serialVersionUID = -8872834506769732436L;
 
+        /**
+         * The feature on which to execute the operation.
+         */
         private final Feature feature;
 
-        GeomAtt(final Feature feature) {
-            super(getResult());
+        /**
+         * The result, computed when first needed.
+         */
+        private transient Polyline geometry;
+
+        /**
+         * Creates a new result for an execution on the given feature.
+         * The actual computation is deferred to the first call of {@link #getValue()}.
+         */
+        Result(final Feature feature) {
+            super(RESULT_TYPE);
             this.feature = feature;
         }
 
+        /**
+         * Computes the geometry from all points of polylines found in the associated feature.
+         */
         @Override
-        public Polyline getValue() throws MultiValuedPropertyException {
-            final Polyline geom = new Polyline();
-            explore(feature, 0, geom, true);
-            return geom;
+        public Polyline getValue() {
+            if (geometry == null) {
+                boolean isFirst = true;
+                geometry = new Polyline();
+                for (final Object child : (Collection<?>) feature.getPropertyValue(association)) {
+                    addGeometry(geometry, ((Feature) child).getPropertyValue("@geometry"), isFirst);
+                    isFirst = false;
+                }
+            }
+            return geometry;
         }
 
+        /**
+         * Does not allow modification of this attribute.
+         */
         @Override
         public void setValue(Polyline value) {
-            throw new UnsupportedOperationException("Operation attribute can not be set.");
+            throw new UnsupportedOperationException(Errors.format(Errors.Keys.UnmodifiableObject_1, Attribute.class));
         }
     }
 }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupPointsAsPolylineOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupPointsAsPolylineOperation.java?rev=1773845&r1=1773844&r2=1773845&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupPointsAsPolylineOperation.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GroupPointsAsPolylineOperation.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -17,17 +17,11 @@
 package org.apache.sis.internal.gpx;
 
 import java.util.Map;
-import java.util.Collections;
 import com.esri.core.geometry.Point;
 import com.esri.core.geometry.Polyline;
 import org.opengis.parameter.ParameterDescriptorGroup;
-import org.apache.sis.feature.DefaultAttributeType;
-import org.apache.sis.internal.feature.AttributeConvention;
 import org.apache.sis.internal.feature.FeatureUtilities;
 
-// Branch-dependent imports
-import org.opengis.feature.AttributeType;
-
 
 /**
  * Creates a single (Multi){@code Polyline} instance from a sequence of points stored in another property.
@@ -58,19 +52,13 @@ final class GroupPointsAsPolylineOperati
     private static final ParameterDescriptorGroup EMPTY_PARAMS = FeatureUtilities.parameters("GroupPoints");
 
     /**
-     * The type of the values computed by this operation. The name of this type presumes
-     * that the result will be assigned to the "geometry" attribute of the feature type.
-     */
-    private static final AttributeType<Polyline> RESULT_TYPE = new DefaultAttributeType<>(
-            Collections.singletonMap(NAME_KEY, AttributeConvention.ENVELOPE_PROPERTY), Polyline.class, 1, 1, null);
-
-    /**
+     * Creates a new operation which will look for geometries in the given feature association.
      *
-     * @param identification operation identification parameters
-     * @param attributePath names of the properties to group
+     * @param  identification  name and other information to be given to this operation.
+     * @param  association     name of the property to follow in order to get the geometries to add to a polyline.
      */
-    GroupPointsAsPolylineOperation(Map<String,?> identification, String... attributePath) {
-        super(identification, attributePath);
+    GroupPointsAsPolylineOperation(final Map<String,?> identification, final String association) {
+        super(identification, association);
     }
 
     /**
@@ -82,14 +70,13 @@ final class GroupPointsAsPolylineOperati
     }
 
     /**
-     * {@inheritDoc}
+     * Invoked for every points to put in a single polyline.
+     *
+     * @param addTo     where to add the points.
+     * @param geometry  the point to add to {@code addTo}.
+     * @param isFirst   whether {@code geometry} is the first object added to the given polyline.
      */
     @Override
-    public AttributeType<Polyline> getResult() {
-        return RESULT_TYPE;
-    }
-
-    @Override
     void addGeometry(Polyline geom, final Object propVal, final boolean first) {
         if (first) {
             geom.startPath(((Point) propVal));

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Link.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Link.java?rev=1773845&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Link.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Link.java [UTF-8] Mon Dec 12 18:40:26 2016
@@ -0,0 +1,172 @@
+/*
+ * 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 java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Objects;
+import org.opengis.util.InternationalString;
+import org.opengis.metadata.citation.OnLineFunction;
+import org.opengis.metadata.citation.OnlineResource;
+
+
+/**
+ * Link to a resource in a GPX file.
+ * This element provides 3 properties:
+ *
+ * <ul>
+ *   <li>The {@linkplain #uri}, which is the only mandatory property.</li>
+ * </ul>
+ *
+ * Those properties can be read or modified directly. All methods defined in this class are bridges to
+ * the ISO 19115 metadata model and can be ignored if the user only wants to manipulate the GPX model.
+ *
+ * @author  Johann Sorel (Geomatys)
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public final class Link implements OnlineResource {
+    /**
+     * The link value.
+     */
+    public URI uri;
+
+    /**
+     * Creates an initially empty instance.
+     * Callers should set at least the {@link #uri} field after construction.
+     */
+    public Link() {
+    }
+
+    /**
+     * Creates a new instance initialized to the given URI.
+     *
+     * @param  uri  the URI.
+     * @throws URISyntaxException if the given URI is invalid.
+     */
+    public Link(final String uri) throws URISyntaxException {
+        this.uri = new URI(uri);
+    }
+
+    /**
+     * Returns the link value.
+     *
+     * @return {@link #uri}.
+     */
+    @Override
+    public URI getLinkage() {
+        return uri;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return connection protocol to be used.
+     */
+    @Override
+    public String getProtocol() {
+        return null;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return application profile that can be used with the online resource.
+     */
+    @Override
+    public String getApplicationProfile() {
+        return null;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return name of the online resource.
+     */
+    @Override
+    public InternationalString getName() {
+        return null;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return text description of what the online resource is/does.
+     */
+    @Override
+    public InternationalString getDescription() {
+        return null;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return function performed by the online resource.
+     */
+    @Override
+    public OnLineFunction getFunction() {
+        return null;
+    }
+
+    /**
+     * ISO 19115 metadata property not specified by GPX.
+     *
+     * @return request used to access the resource, or {@code null}.
+     */
+    @Override
+    public String getProtocolRequest() {
+        return null;
+    }
+
+    /**
+     * Compares this {@code Link} with the given object for equality.
+     *
+     * @param  obj  the object to compare with this {@code Link}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Link) {
+            final Link that = (Link) obj;
+            return Objects.equals(this.uri, that.uri);
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hash code value for this {@code Link}.
+     *
+     * @return a hash code value.
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(uri);
+    }
+
+    /**
+     * Returns the string representation of {@link #uri}, or {@code null} if {@code uri} is null.
+     * This method is intended to allow direct usage of {@code Link} in code that format arbitrary {@link Object}.
+     *
+     * @return the URI, or {@code null}.
+     */
+    @Override
+    public String toString() {
+        return (uri != null) ? uri.toString() : null;
+    }
+}

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

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



Mime
View raw message