sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jso...@apache.org
Subject svn commit: r1738548 - in /sis/branches/JDK8/storage/sis-xmlstore/src: main/java/org/apache/sis/internal/gpx/ main/java/org/apache/sis/internal/xml/ test/java/org/apache/sis/internal/gpx/
Date Mon, 11 Apr 2016 08:25:51 GMT
Author: jsorel
Date: Mon Apr 11 08:25:51 2016
New Revision: 1738548

URL: http://svn.apache.org/viewvc?rev=1738548&view=rev
Log:
Add GPX 1.0 and 1.1 writers

Added:
    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/xml/StaxStreamWriter.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/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/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/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java

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=1738548&r1=1738547&r2=1738548&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 Apr 11 08:25:51 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.gpx;
 
 import java.net.URI;
+import java.util.Objects;
 
 /**
  * Copyright object as defined in GPX.
@@ -94,4 +95,33 @@ public class CopyRight {
         return sb.toString();
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final CopyRight other = (CopyRight) obj;
+        if (!Objects.equals(this.author, other.author)) {
+            return false;
+        }
+        if (!Objects.equals(this.year, other.year)) {
+            return false;
+        }
+        if (!Objects.equals(this.license, other.license)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return 44;
+    }
+
 }

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=1738548&r1=1738547&r2=1738548&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 Apr 11 08:25:51 2016
@@ -21,9 +21,11 @@ import com.esri.core.geometry.Point;
 import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
 import java.time.temporal.Temporal;
 import java.time.temporal.TemporalAccessor;
 import java.time.temporal.UnsupportedTemporalTypeException;
@@ -721,13 +723,19 @@ public class GPXReader extends StaxStrea
      */
     private static Temporal parseTime(String dateStr) {
         try{
-            final DateTimeFormatter format = DateTimeFormatter.ISO_DATE;
+            final DateTimeFormatter format = DateTimeFormatter.ISO_INSTANT;
             final TemporalAccessor accessor = format.parse(dateStr);
-            return LocalDate.from(accessor);
-        }catch(UnsupportedTemporalTypeException ex){
-            final DateTimeFormatter format = DateTimeFormatter.ISO_DATE_TIME;
-            final TemporalAccessor accessor = format.parse(dateStr);
-            return LocalDateTime.from(accessor);
+            return Instant.from(accessor);
+        }catch(UnsupportedTemporalTypeException | DateTimeParseException ex){
+            try{
+                final DateTimeFormatter format = DateTimeFormatter.ISO_DATE;
+                final TemporalAccessor accessor = format.parse(dateStr);
+                return LocalDate.from(accessor);
+            }catch(UnsupportedTemporalTypeException | DateTimeParseException e){
+                final DateTimeFormatter format = DateTimeFormatter.ISO_DATE_TIME;
+                final TemporalAccessor accessor = format.parse(dateStr);
+                return LocalDateTime.from(accessor);
+            }
         }
     }
     

Added: 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=1738548&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter100.java Mon Apr 11 08:25:51 2016
@@ -0,0 +1,415 @@
+/*
+ * 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 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;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.Temporal;
+import java.util.Collection;
+import java.util.Iterator;
+import javax.xml.stream.XMLStreamException;
+import static org.apache.sis.internal.gpx.GPXConstants.*;
+import org.apache.sis.internal.xml.StaxStreamWriter;
+
+import org.opengis.geometry.Envelope;
+
+import static org.apache.sis.util.ArgumentChecks.*;
+import org.apache.sis.util.collection.BackingStoreException;
+import org.opengis.feature.Feature;
+import org.opengis.feature.Property;
+
+
+/**
+ * Stax writer class for GPX 1.0 files.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public class GPXWriter100 extends StaxStreamWriter {
+
+    private final String creator;
+    /**
+     * GPX file namespace
+     */
+    protected final String namespace;
+
+    /**
+     *
+     * @param creator file creator
+     */
+    public GPXWriter100(final String creator) {
+        this(GPX_NAMESPACE_V10,creator);
+    }
+
+    /**
+     *
+     * @param namespace gpx namespace
+     * @param creator file creator
+     */
+    protected  GPXWriter100(final String namespace,final String creator) {
+        ensureNonNull("creator", creator);
+        this.creator = creator;
+        this.namespace = namespace;
+    }
+
+    /**
+     *
+     * @return GPX version 1.0
+     */
+    protected String getVersion() {
+        return "1.0";
+    }
+
+    /**
+     * Start gpx document.
+     *
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeStartDocument() throws XMLStreamException {
+        writer.writeStartDocument("UTF-8", "1.0");
+        writer.flush();
+    }
+
+    /**
+     *
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeEndDocument() throws XMLStreamException {
+        writer.writeEndDocument();
+        writer.flush();
+    }
+
+    /**
+     *
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    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.writeDefaultNamespace(namespace);
+        writer.flush();
+    }
+
+    /**
+     * Shortcut methods to write all gpx elements.
+     *
+     * @param metadata can be null
+     * @param wayPoints can be null
+     * @param routes can be null
+     * @param tracks can be null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void write(final MetaData metadata, final Collection<? extends Feature> wayPoints,
+            final Collection<? extends Feature> routes, final Collection<? extends Feature> tracks) throws XMLStreamException {
+
+        writeGPXTag();
+
+        if (metadata != null) {
+            write(metadata);
+        }
+
+        if (wayPoints != null) {
+            final Iterator<? extends Feature> ite = wayPoints.iterator();
+            try {
+                while (ite.hasNext()) {
+                    writeWayPoint(ite.next(), TAG_WPT);
+                }
+            } catch (BackingStoreException ex) {
+                final Throwable cause = ex.getCause();
+                throw (cause instanceof XMLStreamException) ? (XMLStreamException) cause : new XMLStreamException(cause);
+            } finally {
+                if (ite instanceof Closeable) {
+                    try {
+                        ((Closeable) ite).close();
+                    } catch (IOException ex) {
+                        throw new XMLStreamException(ex);
+                    }
+                }
+            }
+        }
+
+        if (routes != null) {
+            final Iterator<? extends Feature> ite = routes.iterator();
+            try {
+                while (ite.hasNext()) {
+                    writeRoute(ite.next());
+                }
+            } catch (BackingStoreException ex) {
+                final Throwable cause = ex.getCause();
+                throw (cause instanceof XMLStreamException) ? (XMLStreamException) cause : new XMLStreamException(cause);
+            } finally {
+                if (ite instanceof Closeable) {
+                    try {
+                        ((Closeable) ite).close();
+                    } catch (IOException ex) {
+                        throw new XMLStreamException(ex);
+                    }
+                }
+            }
+        }
+
+        if (tracks != null) {
+            final Iterator<? extends Feature> ite = tracks.iterator();
+            try {
+                while (ite.hasNext()) {
+                    writeTrack(ite.next());
+                }
+            } catch (BackingStoreException ex) {
+                final Throwable cause = ex.getCause();
+                throw (cause instanceof XMLStreamException) ? (XMLStreamException) cause : new XMLStreamException(cause);
+            } finally {
+                if (ite instanceof Closeable) {
+                    try {
+                        ((Closeable) ite).close();
+                    } catch (IOException ex) {
+                        throw new XMLStreamException(ex);
+                    }
+                }
+            }
+        }
+
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write GPX Metadata.
+     * 
+     * @param metadata no null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void write(final MetaData metadata) throws XMLStreamException {
+        writeSimpleTag(namespace, TAG_NAME, metadata.getName());
+        writeSimpleTag(namespace, TAG_DESC, metadata.getDescription());
+
+        final Person person = metadata.getPerson();
+        if (person != null) {
+            writeSimpleTag(namespace, TAG_AUTHOR, person.getName());
+            writeSimpleTag(namespace, TAG_AUTHOR_EMAIL, person.getEmail());
+        }
+
+        //model is based on 1.1 so not all attributs can be written
+        writeLinkURIs(metadata.getLinks());
+
+        final Temporal d = metadata.getTime();
+        if (d != null) {
+            writeSimpleTag(namespace, TAG_METADATA_TIME, toString(d));
+        }
+
+        writeSimpleTag(namespace, TAG_METADATA_KEYWORDS, metadata.getKeywords());
+        writeBounds(metadata.getBounds());
+        writer.flush();
+    }
+
+    /**
+     * Write a way point.
+     *
+     * @param feature, can be null
+     * @param tagName waypoint tag name, not null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeWayPoint(final Feature feature, final String tagName) throws XMLStreamException {
+        if (feature == null) return;
+
+        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()));
+
+        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));
+
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write a route feature.
+     *
+     * @param feature, can be null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeRoute(final Feature feature) throws XMLStreamException {
+        if (feature == null) return;
+
+        writer.writeStartElement(namespace, TAG_RTE);
+
+        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));
+
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_RTE_RTEPT)) {
+            writeWayPoint((Feature) prop,TAG_RTE_RTEPT);
+        }
+
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write a track feature.
+     *
+     * @param feature track, can be null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeTrack(final Feature feature) throws XMLStreamException {
+        if (feature == null) return;
+
+        writer.writeStartElement(namespace, TAG_TRK);
+
+        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));
+
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_TRK_SEG)) {
+            writeTrackSegment(prop);
+        }
+
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write a track segment feature.
+     * 
+     * @param feature track segment, can be null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    protected void writeTrackSegment(final Feature feature) throws XMLStreamException {
+        if (feature == null) return;
+        writer.writeStartElement(namespace, TAG_TRK_SEG);
+
+        for (Feature prop : (Collection<Feature>)feature.getPropertyValue(TAG_TRK_SEG_PT)) {
+            writeWayPoint((Feature) prop,TAG_TRK_SEG_PT);
+        }
+
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write multiple links.
+     *
+     * @param links links to write
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    protected void writeLinkURIs(final Collection<URI> links) throws XMLStreamException {
+        if (links != null && !links.isEmpty()) {
+            //in gpx 1.0 we only have one link available
+            writeLink(links.iterator().next());
+        }
+    }
+
+    /**
+     * Write a link tag.
+     * 
+     * @param uri 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;
+
+        writer.writeStartElement(namespace, TAG_LINK);
+        writer.writeAttribute(ATT_LINK_HREF, uri.toASCIIString());
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write bounds gpx tag.
+     * 
+     * @param env if null nothing will be written
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    protected void writeBounds(final Envelope env) throws XMLStreamException {
+        if (env == null) return;
+
+        writer.writeStartElement(namespace, TAG_BOUNDS);
+
+        writer.writeAttribute(ATT_BOUNDS_MINLAT, Double.toString(env.getMinimum(1)));
+        writer.writeAttribute(ATT_BOUNDS_MINLON, Double.toString(env.getMinimum(0)));
+        writer.writeAttribute(ATT_BOUNDS_MAXLAT, Double.toString(env.getMaximum(1)));
+        writer.writeAttribute(ATT_BOUNDS_MAXLON, Double.toString(env.getMaximum(0)));
+
+        writer.writeEndElement();
+    }
+
+    /**
+     *
+     * @param tagName property tag name
+     * @param prop can be null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    protected void writeProperty(final String tagName,final Property prop) throws XMLStreamException {
+        if (prop == null) return;
+
+        Object val = prop.getValue();
+        if (val instanceof Temporal) {
+            val = toString((Temporal)val);
+        }
+
+        writeSimpleTag(namespace, tagName, val);
+    }
+
+    /**
+     * Convert temporal object to it's most appropriate ISO-8601 string representation.
+     * 
+     * @param temp not null
+     * @return String representation
+     */
+    protected static String toString(final Temporal temp){
+        if(temp instanceof LocalDate){
+            return DateTimeFormatter.ISO_DATE.format(temp);
+        }else if(temp instanceof LocalDateTime){
+            return DateTimeFormatter.ISO_DATE_TIME.format(temp);
+        }else if(temp instanceof Instant){
+            return DateTimeFormatter.ISO_INSTANT.format(temp);
+        }else{
+            throw new IllegalArgumentException("Unsupported temporal element "+temp.getClass());
+        }
+    }
+}

Added: 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=1738548&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/GPXWriter110.java Mon Apr 11 08:25:51 2016
@@ -0,0 +1,147 @@
+/*
+ * 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.time.temporal.Temporal;
+import java.util.Collection;
+import javax.xml.stream.XMLStreamException;
+import static org.apache.sis.internal.gpx.GPXConstants.*;
+
+
+/**
+ * Stax writer class for GPX 1.1 files.
+ *
+ * @author Johann Sorel (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public class GPXWriter110 extends GPXWriter100{
+
+    /**
+     *
+     * @param creator gpx file creator
+     */
+    public GPXWriter110(final String creator) {
+        super(GPX_NAMESPACE_V11, creator);
+    }
+
+    /**
+     *
+     * @return GPX version 1.1
+     */
+    @Override
+    protected String getVersion() {
+        return "1.1";
+    }
+
+    /**
+     * Write metadata gpx tag.
+     * 
+     * @param metadata not null
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    @Override
+    public void write(final MetaData metadata) throws XMLStreamException {
+        writer.writeStartElement(namespace, TAG_METADATA);
+        writeSimpleTag(namespace, TAG_NAME, metadata.getName());
+        writeSimpleTag(namespace, TAG_DESC, metadata.getDescription());
+        writePerson(metadata.getPerson());
+        writeCopyRight(metadata.getCopyRight());
+        for (URI uri : metadata.getLinks()) {
+            writeLink(uri);
+        }
+
+        final Temporal d = metadata.getTime();
+        if (d != null) {
+            writeSimpleTag(namespace, TAG_METADATA_TIME, toString(d));
+        }
+
+        writeSimpleTag(namespace, TAG_METADATA_KEYWORDS, metadata.getKeywords());
+        writeBounds(metadata.getBounds());
+
+        writer.writeEndElement();
+        writer.flush();
+    }
+
+    /**
+     * Write person gpx ag.
+     *
+     * @param person if null nothing will be written
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    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.getEmail());
+        writeLink(person.getLink());
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write multiple links.
+     * 
+     * @param links links to write
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    @Override
+    protected void writeLinkURIs(final Collection<URI> links) throws XMLStreamException {
+        if (links != null && !links.isEmpty()) {
+            for (URI uri : links) {
+                writeLink(uri);
+            }
+        }
+    }
+
+    /**
+     * Write a link tag.
+     *
+     * @param uri 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;
+
+        writer.writeStartElement(namespace, TAG_LINK);
+        writer.writeAttribute(ATT_LINK_HREF, uri.toASCIIString());
+        writer.writeEndElement();
+    }
+
+    /**
+     * Write copyright xml tag.
+     *
+     * @param copyRight if null nothing will be written
+     * @throws XMLStreamException if underlying xml stax writer encounter an error
+     */
+    public void writeCopyRight(final CopyRight copyRight) throws XMLStreamException {
+        if (copyRight == null) return;
+
+        writer.writeStartElement(namespace, TAG_COPYRIGHT);
+        final String author = copyRight.getAuthor();
+        if (author != null) {
+            writer.writeAttribute(ATT_COPYRIGHT_AUTHOR, author);
+        }
+        writeSimpleTag(namespace, TAG_COPYRIGHT_YEAR, copyRight.getYear());
+        writeSimpleTag(namespace, TAG_COPYRIGHT_LICENSE, copyRight.getLicense());
+        writer.writeEndElement();
+    }
+
+}

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=1738548&r1=1738547&r2=1738548&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] Mon Apr 11 08:25:51 2016
@@ -22,6 +22,7 @@ import java.net.URI;
 import java.time.temporal.Temporal;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import org.apache.sis.io.TableAppender;
 
 import org.opengis.geometry.Envelope;
@@ -238,4 +239,48 @@ public class MetaData {
         return writer.getBuffer().toString();
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final MetaData other = (MetaData) obj;
+        if (!Objects.equals(this.name, other.name)) {
+            return false;
+        }
+        if (!Objects.equals(this.description, other.description)) {
+            return false;
+        }
+        if (!Objects.equals(this.keywords, other.keywords)) {
+            return false;
+        }
+        if (!Objects.equals(this.person, other.person)) {
+            return false;
+        }
+        if (!Objects.equals(this.copyRight, other.copyRight)) {
+            return false;
+        }
+        if (!Objects.equals(this.links, other.links)) {
+            return false;
+        }
+        if (!Objects.equals(this.time, other.time)) {
+            return false;
+        }
+        if (!Objects.equals(this.bounds, other.bounds)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return 43;
+    }
+
 }

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Person.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Person.java?rev=1738548&r1=1738547&r2=1738548&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Person.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/gpx/Person.java [UTF-8] Mon Apr 11 08:25:51 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.gpx;
 
 import java.net.URI;
+import java.util.Objects;
 
 /**
  * Person object as defined in GPX.
@@ -94,4 +95,33 @@ public class Person {
         return sb.toString();
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final Person other = (Person) obj;
+        if (!Objects.equals(this.name, other.name)) {
+            return false;
+        }
+        if (!Objects.equals(this.email, other.email)) {
+            return false;
+        }
+        if (!Objects.equals(this.link, other.link)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return 45;
+    }
+
 }

Added: sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamWriter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamWriter.java?rev=1738548&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamWriter.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/xml/StaxStreamWriter.java Mon Apr 11 08:25:51 2016
@@ -0,0 +1,254 @@
+/*
+ * 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.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.HashMap;
+import java.util.Map;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Result;
+import org.apache.sis.xml.Namespaces;
+
+
+/**
+ * An abstract class for all stax stream writer.<br>
+ * Writers for a given specification should extend this class and
+ * provide appropriate write methods.<br>
+ * <br>
+ * Example : <br>
+ * <pre>
+ * {@code
+ * public class UserWriter extends StaxStreamWriter{
+ *
+ *   public void write(User user) throws XMLStreamException{
+ *      //casual stax writing operations
+ *      writer.writeStartElement(...
+ *   }
+ * }
+ * }
+ * </pre>
+ * And should be used like : <br>
+ * <pre>
+ * {@code
+ * final UserWriter instance = new UserWriter();
+ * try{
+ *     instance.setOutput(stream);
+ *     instance.write(aUser);
+ * }finally{
+ *     instance.dispose();
+ * }
+ * }
+ * </pre>
+ *
+ * @author Johann Sorel (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public abstract class StaxStreamWriter extends AbstractConfigurable implements AutoCloseable {
+
+    /**
+     * Underlying stax writer.
+     */
+    protected XMLStreamWriter writer;
+
+    /**
+     * Store the output stream if it was generated by the parser itself.
+     * It will closed on the dispose method or when a new input is set.
+     */
+    private OutputStream targetStream;
+
+    private int lastUnknowPrefix = 0;
+
+    private final Map<String, String> unknowNamespaces = new HashMap<>();
+
+    /**
+     * Acces the underlying stax writer.
+     * This method is used when several writer are wrapping a single writer.
+     * Like when an Symbology Encoding writer wraps a Filter writer.
+     * <br>
+     * It can also be used to write tag before or after this writer is used.
+     *
+     * @return underlying stax writer, can be null if input has not been set
+     */
+    public XMLStreamWriter getWriter() {
+        return writer;
+    }
+
+    /**
+     * close potentiel previous stream and cache if there are some.
+     * This way the writer can be reused for a different output later.
+     * The underlying stax writer will be closed.
+     * @throws java.io.IOException if previous source stream caused an exception on close
+     * @throws javax.xml.stream.XMLStreamException if previous stax reader caused an exception on close
+     */
+    public void reset() throws IOException, XMLStreamException {
+        if (writer != null) {
+            writer.close();
+            writer = null;
+        }
+        if (targetStream != null) {
+            targetStream.close();
+            targetStream = null;
+        }
+    }
+
+    /**
+     * Release potentiel locks or opened stream.
+     * Must be called when the writer is not needed anymore.
+     * It should not be used after this method has been called.
+     * @throws java.io.IOException if previous source stream caused an exception on close
+     * @throws javax.xml.stream.XMLStreamException if previous stax reader caused an exception on close
+     */
+    @Override
+    public void close() throws Exception{
+        reset();
+    }
+
+    /**
+     * Set the output for this writer.<br>
+     * Handle types are :<br>
+     * - java.io.File<br>
+     * - java.io.Writer<br>
+     * - java.io.OutputStream<br>
+     * - javax.xml.stream.XMLStreamWriter<br>
+     * - javax.xml.transform.Result<br>
+     *
+     * @param output output object
+     * @throws IOException if output is not supported or caused an error
+     * @throws XMLStreamException if output is not a valid XML stream, or closing previous stream caused an error
+     */
+    public void setOutput(Object output) throws IOException, XMLStreamException {
+        reset();
+
+        if (output instanceof XMLStreamWriter) {
+            writer = (XMLStreamWriter) output;
+            return;
+        }
+
+        if (output instanceof File) {
+            targetStream = new FileOutputStream((File)output);
+            final BufferedOutputStream bout = new BufferedOutputStream(targetStream);
+            output = bout;
+        }
+        if (output instanceof Path) {
+            targetStream = Files.newOutputStream((Path) output, StandardOpenOption.CREATE, StandardOpenOption.WRITE);
+            final BufferedOutputStream bout = new BufferedOutputStream(targetStream);
+            output = bout;
+        }
+
+        writer = toWriter(output);
+    }
+
+    /**
+     * Write a new tag with the text corresponding to the given value.
+     * The tag won't be written if the value is null.
+     * @param namespace : namespace of the wanted tag
+     * @param localName : local name of the wanted tag
+     * @param value : text value to write
+     * @throws XMLStreamException if underlying stax stream raised an error
+     */
+    protected void writeSimpleTag(final String namespace, final String localName, final Object value) throws XMLStreamException {
+        if (value != null) {
+            writer.writeStartElement(namespace, localName);
+            writer.writeCharacters(value.toString());
+            writer.writeEndElement();
+        }
+    }
+
+    /**
+     * Creates a new XMLStreamWriter.
+     * @param output output object
+     * @return XMLStreamWriter
+     * @throws XMLStreamException if the output is not handled
+     */
+    private static XMLStreamWriter toWriter(final Object output) throws XMLStreamException {
+        final XMLOutputFactory XMLfactory = XMLOutputFactory.newInstance();
+        XMLfactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+
+        if (output instanceof OutputStream) {
+            return XMLfactory.createXMLStreamWriter((OutputStream)output,"UTF-8");
+        } else if(output instanceof Result) {
+            return XMLfactory.createXMLStreamWriter((Result)output);
+        } else if(output instanceof Writer) {
+            return XMLfactory.createXMLStreamWriter((Writer)output);
+        } else {
+            throw new XMLStreamException("Output type is not supported : "+ output);
+        }
+    }
+
+    /**
+     * Returns the prefix for the given namespace.
+     *
+     * @param namespace The namespace for which we want the prefix.
+     * @return namespace prefix
+     */
+    protected Prefix getPrefix(final String namespace) {
+        String prefix = Namespaces.getPreferredPrefix(namespace, null);
+        /*
+         * temporary hack todo remove
+         */
+        if ("http://www.opengis.net/gml/3.2".equals(namespace)) {
+            return new Prefix(false, "gml");
+        }
+        boolean unknow = false;
+        if (prefix == null) {
+            prefix = unknowNamespaces.get(namespace);
+            if (prefix == null) {
+                prefix = "ns" + lastUnknowPrefix;
+                lastUnknowPrefix++;
+                unknow = true;
+                unknowNamespaces.put(namespace, prefix);
+            }
+        }
+        return new Prefix(unknow, prefix);
+    }
+
+    /**
+     * Inner class for handling prefix and if it is already known.
+     */
+    protected final class Prefix {
+        /**
+         * True if prefix in unknown, not mapped to any namespace
+         */
+        public boolean unknow;
+        /**
+         * Namespace prefix.
+         */
+        public String prefix;
+
+        /**
+         *
+         * @param unknow if prefix is mapped to a namespace
+         * @param prefix prefix text
+         */
+        public Prefix(final boolean unknow, final String prefix) {
+            this.prefix = prefix;
+            this.unknow = unknow;
+        }
+    }
+}

Modified: sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java?rev=1738548&r1=1738547&r2=1738548&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXReaderTest.java [UTF-8] Mon Apr 11 08:25:51 2016
@@ -17,6 +17,7 @@
 package org.apache.sis.internal.gpx;
 
 import com.esri.core.geometry.Point;
+import java.io.IOException;
 import java.net.URI;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
@@ -25,6 +26,7 @@ import java.time.temporal.TemporalAccess
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import javax.xml.stream.XMLStreamException;
 import org.apache.sis.geometry.GeneralEnvelope;
 import org.apache.sis.geometry.ImmutableEnvelope;
 import org.apache.sis.referencing.CommonCRS;
@@ -50,11 +52,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.0.0 metadata tag parsing.
+     * 
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testMetadataRead100() throws Exception{
+    public void testMetadataRead100() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_metadata100.xml"));
 
@@ -79,11 +83,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.1.0 metadata tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testMetadataRead110() throws Exception{
+    public void testMetadataRead110() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_metadata110.xml"));
 
@@ -113,11 +119,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.0.0 way point tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testWayPointRead100() throws Exception{
+    public void testWayPointRead100() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_waypoint100.xml"));
 
@@ -144,11 +152,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.1.0 way point tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testWayPointRead110() throws Exception{
+    public void testWayPointRead110() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_waypoint110.xml"));
 
@@ -177,11 +187,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version v1.0.0 route tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testRouteRead100() throws Exception{
+    public void testRouteRead100() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_route100.xml"));
 
@@ -244,11 +256,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.1.0 route tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testRouteRead110() throws Exception{
+    public void testRouteRead110() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_route110.xml"));
 
@@ -313,11 +327,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.0.0 track tag parsing.
+     *
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testTrackRead100() throws Exception{
+    public void testTrackRead100() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_track100.xml"));
 
@@ -386,11 +402,13 @@ public class GPXReaderTest {
 
     /**
      * Test gpx version 1.1.0 track tag parsing.
+     * 
+     * @throws java.lang.Exception if reader failed to be created or failed at reading
      */
     @Test
-    public void testTrackRead110() throws Exception{
+    public void testTrackRead110() throws Exception {
 
-        try(final GPXReader reader = new GPXReader()){
+        try (final GPXReader reader = new GPXReader()) {
             reader.setInput(GPXReaderTest.class.getResource(
                     "/org/apache/sis/gpx/sample_track110.xml"));
 
@@ -459,8 +477,8 @@ public class GPXReaderTest {
         }
     }
 
-    private void checkPoint(final Feature f, final int num, final boolean v11) throws Exception{
-        if(num == 0){
+    private void checkPoint(final Feature f, final int num, final boolean v11) throws Exception {
+        if (num == 0) {
             assertEquals(0,                     f.getPropertyValue("index"));
             assertEquals(15.0,                  ((Point)f.getPropertyValue("geometry")).getX(), DELTA);
             assertEquals(10.0,                  ((Point)f.getPropertyValue("geometry")).getY(), DELTA);
@@ -483,12 +501,12 @@ public class GPXReaderTest {
             assertEquals(256,                   f.getPropertyValue("dgpsid"));
 
             final List<URI> links = new ArrayList<>((Collection)f.getPropertyValue("link"));
-            if(v11){
+            if (v11) {
                 assertEquals(3,links.size());
                 assertEquals("http://first-adress1.org", links.get(0).toString());
                 assertEquals("http://first-adress2.org", links.get(1).toString());
                 assertEquals("http://first-adress3.org", links.get(2).toString());
-            }else{
+            } else {
                 assertEquals(1,links.size());
                 assertEquals("http://first-adress1.org", links.get(0).toString());
             }
@@ -499,7 +517,7 @@ public class GPXReaderTest {
             assertEquals(bbox.getMinimum(1), 10.0d, DELTA);
             assertEquals(bbox.getMaximum(1), 10.0d, DELTA);
 
-        }else if(num == 1){
+        } else if (num == 1) {
             assertEquals(1,                     f.getPropertyValue("index"));
             assertEquals(25.0,                  ((Point)f.getPropertyValue("geometry")).getX(), DELTA);
             assertEquals(20.0,                  ((Point)f.getPropertyValue("geometry")).getY(), DELTA);
@@ -530,7 +548,7 @@ public class GPXReaderTest {
             assertEquals(bbox.getMinimum(1), 20.0d, DELTA);
             assertEquals(bbox.getMaximum(1), 20.0d, DELTA);
 
-        }else if(num == 2){
+        } else if (num == 2) {
             assertEquals(2,                     f.getPropertyValue("index"));
             assertEquals(35.0,                  ((Point)f.getPropertyValue("geometry")).getX(), DELTA);
             assertEquals(30.0,                  ((Point)f.getPropertyValue("geometry")).getY(), DELTA);
@@ -553,11 +571,11 @@ public class GPXReaderTest {
             assertEquals(456,                   f.getPropertyValue("dgpsid"));
 
             final List<URI> links = new ArrayList<>((Collection)f.getPropertyValue("link"));
-            if(v11){
+            if (v11) {
                 assertEquals(2,links.size());
                 assertEquals("http://third-adress1.org", links.get(0).toString());
                 assertEquals("http://third-adress2.org", links.get(1).toString());
-            }else{
+            } else {
                 assertEquals(1,links.size());
                 assertEquals("http://third-adress1.org", links.get(0).toString());
             }
@@ -568,7 +586,7 @@ public class GPXReaderTest {
             assertEquals(bbox.getMinimum(1), 30.0d, DELTA);
             assertEquals(bbox.getMaximum(1), 30.0d, DELTA);
 
-        }else{
+        } else {
             fail("unexpected point number :" + num);
         }
     }

Added: sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXWriterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXWriterTest.java?rev=1738548&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXWriterTest.java (added)
+++ sis/branches/JDK8/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/gpx/GPXWriterTest.java Mon Apr 11 08:25:51 2016
@@ -0,0 +1,269 @@
+/*
+ * 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 com.esri.core.geometry.Point;
+import java.io.File;
+import java.net.URI;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.apache.sis.geometry.GeneralEnvelope;
+import org.apache.sis.geometry.ImmutableEnvelope;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.apache.sis.internal.gpx.GPXConstants.*;
+import org.opengis.feature.Feature;
+
+/**
+ * GPX Writer tests.
+ * 
+ * @author Johann Sorel (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public class GPXWriterTest {
+
+
+    /**
+     * Test writing gpx metadata.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testWritingMetadata() throws Exception {
+        final File f = new File("output.xml");
+        f.deleteOnExit();
+        if (f.exists()) f.delete();
+        final GPXWriter110 writer = new GPXWriter110("Geotoolkit.org");
+        writer.setOutput(f);
+
+        final Person person = new Person();
+        person.setName("Jean-Pierre");
+        person.setEmail("jean-pierre@test.com");
+        person.setLink(new URI("http://son-site.com"));
+
+        final CopyRight copyright = new CopyRight();
+        copyright.setAuthor("GNU");
+        copyright.setYear(2010);
+        copyright.setLicense(new URI("http://gnu.org"));
+
+        final GeneralEnvelope bounds = new GeneralEnvelope(GPXConstants.GPX_CRS);
+        bounds.setRange(0, -10, 20);
+        bounds.setRange(1, -30, 40);
+
+        final MetaData metaData = new MetaData();
+        metaData.setName("name");
+        metaData.setDescription("description");
+        metaData.setPerson(person);
+        metaData.setCopyRight(copyright);
+        metaData.getLinks().addAll(Arrays.asList(new URI("http://adress1.org"),new URI("http://adress2.org")));
+        metaData.setTime(Instant.now());
+        metaData.setKeywords("test,sample");
+        metaData.setBounds(new ImmutableEnvelope(bounds));
+
+        writer.writeStartDocument();
+        writer.write(metaData, null, null, null);
+        writer.writeEndDocument();
+        writer.close();
+
+        try (GPXReader reader = new GPXReader()) {
+            reader.setInput(f);
+            assertEquals(metaData, reader.getMetadata());
+        }
+
+        if (f.exists()) f.delete();
+    }
+
+    /**
+     * Test writing the various gpx feature types.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testWritingFeatures() throws Exception {
+
+        final File f = new File("output.xml");
+        f.deleteOnExit();
+        if (f.exists()) f.delete();
+        final GPXWriter110 writer = new GPXWriter110("Geotoolkit.org");
+        writer.setOutput(f);
+
+        //way points -----------------------------------------------------------
+        Feature point1 = TYPE_WAYPOINT.newInstance();
+        point1.setPropertyValue("index", 0);
+        point1.setPropertyValue("geometry", new Point(-10, 10));
+        point1.setPropertyValue("ele", 15.6);
+        point1.setPropertyValue("time", LocalDate.now());
+        point1.setPropertyValue("magvar", 31.7);
+        point1.setPropertyValue("geoidheight", 45.1);
+        point1.setPropertyValue("name", "fds");
+        point1.setPropertyValue("cmt", "fdrt");
+        point1.setPropertyValue("desc", "ffe");
+        point1.setPropertyValue("src", "aaz");
+        point1.setPropertyValue("link", Collections.singletonList(new URI("http://test.com")));
+        point1.setPropertyValue("sym", "fdsg");
+        point1.setPropertyValue("type", "klj");
+        point1.setPropertyValue("fix", "yy");
+        point1.setPropertyValue("sat", 12);
+        point1.setPropertyValue("hdop", 45.2);
+        point1.setPropertyValue("vdop", 16.7);
+        point1.setPropertyValue("pdop", 14.3);
+        point1.setPropertyValue("ageofdgpsdata", 78.9);
+        point1.setPropertyValue("dgpsid", 6);
+        Feature point2 = TYPE_WAYPOINT.newInstance();
+        point2.setPropertyValue("index", 1);
+        point2.setPropertyValue("geometry", new Point(-15, 15));
+        point2.setPropertyValue("ele", 15.6);
+        point2.setPropertyValue("time", LocalDate.now());
+        point2.setPropertyValue("magvar", 31.7);
+        point2.setPropertyValue("geoidheight", 45.1);
+        point2.setPropertyValue("name", "fds");
+        point2.setPropertyValue("cmt", "fdrt");
+        point2.setPropertyValue("desc", "ffe");
+        point2.setPropertyValue("src", "aaz");
+        point2.setPropertyValue("link", Collections.singletonList(new URI("http://test.com")));
+        point2.setPropertyValue("sym", "fdsg");
+        point2.setPropertyValue("type", "klj");
+        point2.setPropertyValue("fix", "yy");
+        point2.setPropertyValue("sat", 12);
+        point2.setPropertyValue("hdop", 45.2);
+        point2.setPropertyValue("vdop", 16.7);
+        point2.setPropertyValue("pdop", 14.3);
+        point2.setPropertyValue("ageofdgpsdata", 78.9);
+        point2.setPropertyValue("dgpsid", 6);
+        Feature point3 = TYPE_WAYPOINT.newInstance();
+        point3.setPropertyValue("index", 2);
+        point3.setPropertyValue("geometry", new Point(-20, 20));
+        point3.setPropertyValue("ele", 15.6);
+        point3.setPropertyValue("time", LocalDate.now());
+        point3.setPropertyValue("magvar", 31.7);
+        point3.setPropertyValue("geoidheight", 45.1);
+        point3.setPropertyValue("name", "fds");
+        point3.setPropertyValue("cmt", "fdrt");
+        point3.setPropertyValue("desc", "ffe");
+        point3.setPropertyValue("src", "aaz");
+        point3.setPropertyValue("link", Collections.singletonList(new URI("http://test.com")));
+        point3.setPropertyValue("sym", "fdsg");
+        point3.setPropertyValue("type", "klj");
+        point3.setPropertyValue("fix", "yy");
+        point3.setPropertyValue("sat", 12);
+        point3.setPropertyValue("hdop", 45.2);
+        point3.setPropertyValue("vdop", 16.7);
+        point3.setPropertyValue("pdop", 14.3);
+        point3.setPropertyValue("ageofdgpsdata", 78.9);
+        point3.setPropertyValue("dgpsid", 6);
+
+        final List<Feature> wayPoints = new ArrayList<>();
+        wayPoints.add(point1);
+        wayPoints.add(point2);
+        wayPoints.add(point3);
+
+        //routes ---------------------------------------------------------------
+        final Feature route1 = TYPE_ROUTE.newInstance();
+        route1.setPropertyValue("index", 0);
+        route1.setPropertyValue("name", "tt");
+        route1.setPropertyValue("cmt", "cc");
+        route1.setPropertyValue("desc", "des");
+        route1.setPropertyValue("src", "src");
+        route1.setPropertyValue("link", Collections.singletonList(new URI("http://test.com")));
+        route1.setPropertyValue("number", 15);
+        route1.setPropertyValue("type", "test");
+        route1.setPropertyValue("rtept", wayPoints);
+        final Feature route2 = TYPE_ROUTE.newInstance();
+        route2.setPropertyValue("index", 1);
+        route2.setPropertyValue("name", "tt2");
+        route2.setPropertyValue("cmt", "cc2");
+        route2.setPropertyValue("desc", "des2");
+        route2.setPropertyValue("src", "src2");
+        route2.setPropertyValue("link", Collections.singletonList(new URI("http://test2.com")));
+        route2.setPropertyValue("number", 15);
+        route2.setPropertyValue("type", "test2");
+        route2.setPropertyValue("rtept", wayPoints);
+
+        final List<Feature> routes = new ArrayList<>();
+        routes.add(route1);
+        routes.add(route2);
+
+        //tracks ---------------------------------------------------------------
+        final List<Feature> segments = new ArrayList<>();
+        final Feature seg1 = TYPE_TRACK_SEGMENT.newInstance();
+        seg1.setPropertyValue("index", 0);
+        seg1.setPropertyValue("trkpt", wayPoints);
+        final Feature seg2 = TYPE_TRACK_SEGMENT.newInstance();
+        seg2.setPropertyValue("index", 1);
+        seg2.setPropertyValue("trkpt", wayPoints);
+        final Feature seg3 = TYPE_TRACK_SEGMENT.newInstance();
+        seg3.setPropertyValue("index", 2);
+        seg3.setPropertyValue("trkpt", wayPoints);
+        
+        final Feature track1 = TYPE_TRACK.newInstance();
+        track1.setPropertyValue("index", 0);
+        track1.setPropertyValue("name", "tc");
+        track1.setPropertyValue("cmt", "cc");
+        track1.setPropertyValue("desc", "des");
+        track1.setPropertyValue("src", "src");
+        track1.setPropertyValue("link", Collections.singletonList(new URI("http://test4.com")));
+        track1.setPropertyValue("number", 15);
+        track1.setPropertyValue("type", "test");
+        track1.setPropertyValue("trkseg", segments);
+        final Feature track2 = TYPE_TRACK.newInstance();
+        track2.setPropertyValue("index", 1);
+        track2.setPropertyValue("name", "tc2");
+        track2.setPropertyValue("cmt", "cc2");
+        track2.setPropertyValue("desc", "des2");
+        track2.setPropertyValue("src", "src2");
+        track2.setPropertyValue("link", Collections.singletonList(new URI("http://test5.com")));
+        track2.setPropertyValue("number", 15);
+        track2.setPropertyValue("type", "test2");
+        track2.setPropertyValue("trkseg", segments);
+
+        final List<Feature> tracks = new ArrayList<>();
+        tracks.add(track1);
+        tracks.add(track2);
+
+
+        writer.writeStartDocument();
+        writer.write(null, wayPoints, routes, tracks);
+        writer.writeEndDocument();
+        writer.close();
+
+        final GPXReader reader = new GPXReader();
+        reader.setInput(f);
+
+        //testing on toString since JTS geometry always fail on equals method.
+        assertEquals(point1.toString(), reader.next().toString());
+        assertEquals(point2.toString(), reader.next().toString());
+        assertEquals(point3.toString(), reader.next().toString());
+        assertEquals(route1.toString(), reader.next().toString());
+        assertEquals(route2.toString(), reader.next().toString());
+        assertEquals(track1.toString(), reader.next().toString());
+        assertEquals(track2.toString(), reader.next().toString());
+        assertFalse(reader.hasNext());
+
+        reader.close();
+
+        if (f.exists()) f.delete();
+    }
+
+
+}



Mime
View raw message