sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1789729 [2/9] - in /sis/branches/JDK9: ./ application/sis-console/ application/sis-console/src/main/java/org/apache/sis/console/ application/sis-console/src/test/java/org/apache/sis/console/ core/ core/sis-feature/src/main/java/org/apache/...
Date Fri, 31 Mar 2017 18:49:18 GMT
Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/FormattableObject.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -17,12 +17,14 @@
 package org.apache.sis.io.wkt;
 
 import java.io.Console;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.concurrent.atomic.AtomicReference;
 import javax.xml.bind.annotation.XmlTransient;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.internal.util.X364;
+import org.apache.sis.internal.util.Constants;
 
 
 /**
@@ -186,7 +188,7 @@ public abstract class FormattableObject
         formatter.configure(convention, null, colorize ? Colors.DEFAULT : null,
                 convention.toUpperCase           ? (byte) +1 : 0,
                 (convention.majorVersion() == 1) ? (byte) -1 : 0,
-                WKTFormat.DEFAULT_INDENTATION);
+                Constants.DEFAULT_INDENTATION);
         if (!strict) {
             formatter.transliterator = Transliterator.IDENTITY;
         }
@@ -207,6 +209,8 @@ public abstract class FormattableObject
             }
             formatter.appendWarnings();
             wkt = formatter.toWKT();
+        } catch (IOException e) {
+            throw new UnformattableObjectException(e);      // Should never happen since we write to a StringBuffer.
         } finally {
             formatter.clear();
         }

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -29,6 +29,7 @@ import java.util.Date;
 import java.text.DateFormat;
 import java.text.NumberFormat;
 import java.text.FieldPosition;
+import java.io.IOException;
 import java.lang.reflect.Array;
 import java.math.RoundingMode;
 import javax.measure.Unit;
@@ -320,7 +321,7 @@ public class Formatter implements Locali
      * Creates a new formatter instance with the default configuration.
      */
     public Formatter() {
-        this(Convention.DEFAULT, Symbols.getDefault(), WKTFormat.DEFAULT_INDENTATION);
+        this(Convention.DEFAULT, Symbols.getDefault(), Constants.DEFAULT_INDENTATION);
     }
 
     /**
@@ -363,7 +364,7 @@ public class Formatter implements Locali
         this.authority     = Convention.DEFAULT.getNameAuthority();
         this.symbols       = symbols;
         this.lineSeparator = this.symbols.lineSeparator();
-        this.indentation   = WKTFormat.DEFAULT_INDENTATION;
+        this.indentation   = Constants.DEFAULT_INDENTATION;
         this.numberFormat  = numberFormat;                      // No clone needed.
         this.dateFormat    = dateFormat;
         this.unitFormat    = unitFormat;
@@ -1618,7 +1619,7 @@ public class Formatter implements Locali
      * Appends the warnings after the WKT string. If there is no warnings, then this method does nothing.
      * If this method is invoked, then it shall be the last method before {@link #toWKT()}.
      */
-    final void appendWarnings() {
+    final void appendWarnings() throws IOException {
         final Warnings warnings = this.warnings;                    // Protect against accidental changes.
         if (warnings != null) {
             final StringBuffer buffer = this.buffer;
@@ -1627,7 +1628,7 @@ public class Formatter implements Locali
             if (colors != null) {
                 buffer.append(X364.BACKGROUND_RED.sequence()).append(X364.BOLD.sequence()).append(' ');
             }
-            buffer.append(Vocabulary.getResources(locale).getLabel(Vocabulary.Keys.Warnings));
+            Vocabulary.getResources(locale).appendLabel(Vocabulary.Keys.Warnings, buffer);
             if (colors != null) {
                 buffer.append(' ').append(X364.RESET.sequence()).append(X364.FOREGROUND_RED.sequence());
             }

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/io/wkt/WKTFormat.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -44,6 +44,7 @@ import org.apache.sis.measure.UnitFormat
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.StandardDateFormat;
 
 
@@ -121,15 +122,14 @@ public class WKTFormat extends CompoundF
     /**
      * The indentation value to give to the {@link #setIndentation(int)}
      * method for formatting the complete object on a single line.
+     *
+     * @see #getIndentation()
+     * @see #setIndentation(int)
+     * @see org.apache.sis.setup.OptionKey#INDENTATION
      */
     public static final int SINGLE_LINE = -1;
 
     /**
-     * The default indentation value.
-     */
-    static final byte DEFAULT_INDENTATION = 2;
-
-    /**
      * The symbols to use for this formatter.
      * The same object is also referenced in the {@linkplain #parser} and {@linkplain #formatter}.
      * It appears here for serialization purpose.
@@ -240,7 +240,7 @@ public class WKTFormat extends CompoundF
         symbols      = Symbols.getDefault();
         keywordCase  = KeywordCase.DEFAULT;
         keywordStyle = KeywordStyle.DEFAULT;
-        indentation  = DEFAULT_INDENTATION;
+        indentation  = Constants.DEFAULT_INDENTATION;
     }
 
     /**
@@ -537,6 +537,8 @@ public class WKTFormat extends CompoundF
      * The {@value #SINGLE_LINE} value means that the whole WKT is to be formatted on a single line.
      *
      * @param  indentation  the new indentation to use.
+     *
+     * @see org.apache.sis.setup.OptionKey#INDENTATION
      */
     public void setIndentation(final int indentation) {
         ArgumentChecks.ensureBetween("indentation", SINGLE_LINE, Byte.MAX_VALUE, indentation);
@@ -698,10 +700,12 @@ public class WKTFormat extends CompoundF
     /**
      * Creates an object from the given character sequence.
      * The parsing begins at the index given by the {@code pos} argument.
+     * After successful parsing, {@link ParsePosition#getIndex()} gives the position after the last parsed character.
+     * In case of error, {@link ParseException#getErrorOffset()} gives the position of the first illegal character.
      *
      * @param  wkt  the character sequence for the object to parse.
      * @param  pos  the position where to start the parsing.
-     * @return the parsed object.
+     * @return the parsed object (never {@code null}).
      * @throws ParseException if an error occurred while parsing the WKT.
      */
     @Override

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/CacheKey.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/CacheKey.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/CacheKey.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/CacheKey.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata;
 
+import org.apache.sis.util.Classes;
 import org.apache.sis.util.Debug;
 import org.apache.sis.util.resources.Errors;
 
@@ -96,9 +97,9 @@ final class CacheKey {
     @Debug
     @Override
     public String toString() {
-        String name = (type != null) ? type.getCanonicalName() : "null";
+        String name = Classes.getShortName(type);
         if (propertyType != Object.class) {
-            name = name + " as " + propertyType.getSimpleName();
+            name = name + " as " + Classes.getShortName(propertyType);
         }
         return name;
     }

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -360,11 +360,12 @@ public class MetadataStandard implements
             if (v instanceof PropertyAccessor) {
                 return v;
             }
+            final Class<?> standardImpl = getImplementation(type);
             final PropertyAccessor accessor;
             if (SpecialCases.isSpecialCase(type)) {
-                accessor = new SpecialCases(citation, type, key.type);
+                accessor = new SpecialCases(citation, type, k.type, standardImpl);
             } else {
-                accessor = new PropertyAccessor(citation, type, key.type);
+                accessor = new PropertyAccessor(citation, type, k.type, standardImpl);
             }
             return accessor;
         });
@@ -588,7 +589,7 @@ public class MetadataStandard implements
 
     /**
      * Returns the implementation class for the given interface, or {@code null} if none.
-     * The default implementation returns {@code null} if every cases. Subclasses shall
+     * The default implementation returns {@code null} in every cases. Subclasses shall
      * override this method in order to map GeoAPI interfaces to their implementation.
      *
      * @param  <T>   the compile-time {@code type}.

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -83,7 +83,7 @@ import static org.apache.sis.util.collec
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.8
  * @module
  */
 @XmlTransient
@@ -165,10 +165,17 @@ public abstract class ModifiableMetadata
      * </ul>
      *
      * @return an unmodifiable copy of this metadata.
+     *
+     * @see MetadataCopier
      */
     public AbstractMetadata unmodifiable() {
-        // Reminder: 'unmodifiable' is reset to null by checkWritePermission().
-        if (unmodifiable == null) {
+        /*
+         * The 'unmodifiable' field is reset to null by checkWritePermission().
+         * However this is not sufficient since the setter method of some child
+         * could have been invoked without invoking any setter method on 'this'.
+         * So we also need to perform an equality check.
+         */
+        if (unmodifiable == null || (unmodifiable != this && unmodifiable != FREEZING && !equals(unmodifiable))) {
             final ModifiableMetadata candidate;
             try {
                 /*
@@ -232,9 +239,8 @@ public abstract class ModifiableMetadata
     }
 
     /**
-     * Checks if changes in the metadata are allowed. All {@code setFoo(...)} methods in
-     * subclasses should invoke this method (directly or indirectly) before to apply any
-     * change.
+     * Checks if changes in the metadata are allowed. All {@code setFoo(…)} methods in subclasses
+     * shall invoke this method (directly or indirectly) before to apply any change.
      *
      * @throws UnmodifiableMetadataException if this metadata is unmodifiable.
      *
@@ -388,7 +394,7 @@ public abstract class ModifiableMetadata
             if (unmodifiable == FREEZING) {
                 /*
                  * freeze() method is under progress. The source collection is already
-                 * an unmodifiable instance created by Cloner.clone(Object).
+                 * an unmodifiable instance created by Freezer.clone(Object).
                  */
                 assert collectionType(elementType).isInstance(source);
                 return (Collection<E>) source;
@@ -671,6 +677,7 @@ public abstract class ModifiableMetadata
      * Creates a <strong>shallow</strong> copy of this metadata.
      * The clone operation is required for the internal working of the {@link #unmodifiable()} method,
      * which needs <em>shallow</em> copies of metadata entities.
+     * For deep copies, see {@link MetadataCopier}.
      *
      * <div class="section">API note</div>
      * While {@link Cloneable}, the {@code ModifiableMetadata} subclasses should not provide
@@ -684,6 +691,9 @@ public abstract class ModifiableMetadata
      *
      * @return a <em>shallow</em> copy of this metadata.
      * @throws CloneNotSupportedException if the clone is not supported.
+     *
+     * @see #unmodifiable()
+     * @see MetadataCopier
      */
     @Override
     protected ModifiableMetadata clone() throws CloneNotSupportedException {

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -81,7 +81,7 @@ import static org.apache.sis.util.collec
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.8
  * @module
  */
 class PropertyAccessor {
@@ -238,13 +238,15 @@ class PropertyAccessor {
      * @param  standard        the standard which define the {@code type} interface.
      * @param  type            the interface implemented by the metadata class.
      * @param  implementation  the class of metadata implementations, or {@code type} if none.
+     * @param  standardImpl    the implementation specified by the {@link MetadataStandard}, or {@code null} if none.
+     *                         This is the same than {@code implementation} unless a custom implementation is used.
      */
-    PropertyAccessor(final Citation standard, final Class<?> type, final Class<?> implementation) {
+    PropertyAccessor(final Citation standard, final Class<?> type, final Class<?> implementation, final Class<?> standardImpl) {
         assert type.isAssignableFrom(implementation) : implementation;
         this.standard       = standard;
         this.type           = type;
         this.implementation = implementation;
-        this.getters        = getGetters(type, implementation);
+        this.getters        = getGetters(type, implementation, standardImpl);
         int allCount = getters.length;
         int standardCount = allCount;
         if (allCount != 0 && getters[allCount-1] == EXTRA_GETTER) {
@@ -400,9 +402,10 @@ class PropertyAccessor {
      *
      * @param  type            the metadata interface.
      * @param  implementation  the class of metadata implementations, or {@code type} if none.
+     * @param  standardImpl    the implementation specified by the {@link MetadataStandard}, or {@code null} if none.
      * @return the getters declared in the given interface (never {@code null}).
      */
-    private static Method[] getGetters(final Class<?> type, final Class<?> implementation) {
+    private static Method[] getGetters(final Class<?> type, final Class<?> implementation, final Class<?> standardImpl) {
         /*
          * Indices map is used for choosing what to do in case of name collision.
          */
@@ -466,7 +469,7 @@ class PropertyAccessor {
          * keep the extra methods last. The code checking for the extra methods require
          * them to be last.
          */
-        Arrays.sort(getters, 0, count, new PropertyComparator(implementation));
+        Arrays.sort(getters, 0, count, new PropertyComparator(implementation, standardImpl));
         if (!hasExtraGetter) {
             if (getters.length == count) {
                 getters = Arrays.copyOf(getters, count+1);
@@ -1161,7 +1164,7 @@ class PropertyAccessor {
         assert implementation.isInstance(metadata) : metadata;
         if (setters != null) try {
             final Object[] arguments = new Object[1];
-            final Cloner cloner = new Cloner();
+            final Freezer freezer = new Freezer();
             for (int i=0; i<allCount; i++) {
                 final Method setter = setters[i];
                 if (setter != null) {
@@ -1180,7 +1183,7 @@ class PropertyAccessor {
                     }
                     final Method getter = getters[i];
                     final Object source = get(getter, metadata);
-                    final Object target = cloner.clone(source);
+                    final Object target = freezer.clone(source);
                     if (source != target) {
                         arguments[0] = target;
                         set(setter, metadata, arguments);
@@ -1201,6 +1204,42 @@ class PropertyAccessor {
     }
 
     /**
+     * Returns a potentially deep copy of the given metadata object.
+     *
+     * @param  metadata   the metadata object to copy.
+     * @param  copies     a map of metadata objects already copied.
+     * @return a copy of the given metadata object, or {@code metadata} itself if there is
+     *         no known implementation class or that implementation has no setter method.
+     * @throws Exception if an error occurred while creating the copy. This include any
+     *         checked checked exception that the no-argument constructor may throw.
+     */
+    final Object copy(final Object metadata, final MetadataCopier copier) throws Exception {
+        if (setters == null) {
+            return metadata;
+        }
+        Object copy = copier.copies.get(metadata);
+        if (copy == null) {
+            copy = implementation.newInstance();
+            copier.copies.put(metadata, copy);              // Need to be first in case of cyclic graphs.
+            final Object[] arguments = new Object[1];
+            for (int i=0; i<allCount; i++) {
+                final Method setter = setters[i];
+                if (setter != null && !setter.isAnnotationPresent(Deprecated.class)) {
+                    Object value = get(getters[i], metadata);
+                    if (value != null) {
+                        value = copier.copyAny(elementTypes[i], value);
+                        if (value != null) {
+                            arguments[0] = value;
+                            set(setter, copy, arguments);
+                        }
+                    }
+                }
+            }
+        }
+        return copy;
+    }
+
+    /**
      * Computes a hash code for the specified metadata. The hash code is defined as the sum
      * of hash code values of all non-empty properties, plus the hash code of the interface.
      * This is a similar contract than {@link java.util.Set#hashCode()} (except for the interface)

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -44,7 +44,7 @@ import org.opengis.annotation.Obligation
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.5
+ * @version 0.8
  * @module
  */
 final class PropertyComparator implements Comparator<Method> {
@@ -92,10 +92,32 @@ final class PropertyComparator implement
      * Creates a new comparator for the given implementation class.
      *
      * @param implementation  the implementation class, or the interface if the implementation class is unknown.
+     * @param standardImpl    the implementation specified by the {@link MetadataStandard}, or {@code null} if none.
+     *                        This is the same than {@code implementation} unless a custom implementation is used.
      */
-    PropertyComparator(Class<?> implementation) {
-        this.implementation = implementation;
+    PropertyComparator(Class<?> implementation, final Class<?> standardImpl) {
         order = new HashMap<>();
+        defineOrder(implementation, order);
+        if (order.isEmpty() && standardImpl != null && !standardImpl.isAssignableFrom(implementation)) {
+            /*
+             * We enter in this block only if the user specified its own metadata implementation and that
+             * custom implementation does not have any JAXB @XmlType annotation. In such case this method
+             * can not sort the properties. So we will use the class defined by org.apache.sis.metadata.iso
+             * instead.
+             */
+            implementation = standardImpl;
+            defineOrder(implementation, order);
+        }
+        this.implementation = implementation;
+    }
+
+    /**
+     * Uses the {@link XmlType} annotation for defining the property order.
+     *
+     * @param implementation  the implementation class where to search for {@code XmlType} annotation.
+     * @param order           the {@link #order} map where to store the properties order.
+     */
+    private static void defineOrder(Class<?> implementation, final Map<Object,Integer> order) {
         do {
             final XmlType xml = implementation.getAnnotation(XmlType.class);
             if (xml != null) {

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/SpecialCases.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -31,7 +31,7 @@ import org.apache.sis.util.collection.Ba
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.8
  * @module
  */
 final class SpecialCases extends PropertyAccessor {
@@ -47,9 +47,11 @@ final class SpecialCases extends Propert
      * @param  type            the interface implemented by the metadata, which must be
      *                         the value returned by {@link #getStandardType(Class, String)}.
      * @param  implementation  the class of metadata implementations, or {@code type} if none.
+     * @param  standardImpl    the implementation specified by the {@link MetadataStandard}, or {@code null} if none.
+     *                         This is the same than {@code implementation} unless a custom implementation is used.
      */
-    SpecialCases(final Citation standard, final Class<?> type, final Class<?> implementation) {
-        super(standard, type, implementation);
+    SpecialCases(final Citation standard, final Class<?> type, final Class<?> implementation, final Class<?> standardImpl) {
+        super(standard, type, implementation, standardImpl);
         assert isSpecialCase(type) : type;
         westBoundLongitude = indexOf("westBoundLongitude", true);
         eastBoundLongitude = indexOf("eastBoundLongitude", true);

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/StandardImplementation.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -66,7 +66,7 @@ final class StandardImplementation exten
      * But maybe the most interesting property is that it allocates less objects since {@code IdentityHashMap}
      * implementation doesn't need the chain of objects created by {@code HashMap}.</div>
      */
-    private final transient Map<Class<?>,Class<?>> implementations; // written by reflection on deserialization.
+    private final transient Map<Class<?>,Class<?>> implementations;     // written by reflection on deserialization.
 
     /**
      * Creates a new instance working on implementation of interfaces defined in the
@@ -161,7 +161,7 @@ final class StandardImplementation exten
                         Logging.recoverableException(Logging.getLogger(Modules.METADATA),
                                 MetadataStandard.class, "getImplementation", e);
                     }
-                    implementations.put(type, Void.TYPE); // Marker for "class not found".
+                    implementations.put(type, Void.TYPE);                       // Marker for "class not found".
                 }
             }
         }

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/TreeNodeChildren.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -114,7 +114,7 @@ final class TreeNodeChildren extends Abs
         this.parent   = parent;
         this.metadata = metadata;
         this.accessor = accessor;
-        children = new TreeNode[accessor.count()];
+        this.children = new TreeNode[accessor.count()];
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/UnmodifiableMetadataException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/UnmodifiableMetadataException.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/UnmodifiableMetadataException.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/UnmodifiableMetadataException.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -22,8 +22,8 @@ package org.apache.sis.metadata;
  * This exception may happen in the following scenarios:
  *
  * <ul>
- *   <li>A metadata instance was initially {@linkplain org.apache.sis.metadata.ModifiableMetadata
- *       modifiable}, but that instance has since be declared unmodifiable.</li>
+ *   <li>A metadata instance was initially {@linkplain org.apache.sis.metadata.ModifiableMetadata modifiable},
+ *       but that instance has since be declared unmodifiable.</li>
  *   <li>A write operation has been attempted on the {@linkplain AbstractMetadata#asMap() map view},
  *       but the metadata object has no corresponding setter methods.</li>
  * </ul>

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -196,6 +196,7 @@ public class DefaultGeographicBoundingBo
      * @param  object  the metadata to copy values from, or {@code null} if none.
      *
      * @see #castOrCopy(GeographicBoundingBox)
+     * @see #setBounds(GeographicBoundingBox)
      */
     public DefaultGeographicBoundingBox(final GeographicBoundingBox object) {
         super(object);
@@ -489,8 +490,8 @@ public class DefaultGeographicBoundingBo
     }
 
     /**
-     * Constructs a geographic bounding box from the specified envelope. If the envelope contains
-     * a CRS, then the bounding box may be projected to a geographic CRS. Otherwise, the envelope
+     * Sets the bounding box to the specified envelope. If the envelope contains* a CRS,
+     * then the bounding box may be projected to a geographic CRS. Otherwise, the envelope
      * is assumed already in appropriate CRS.
      *
      * <p>When coordinate transformation is required, the target geographic CRS is not necessarily

Modified: sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.ArrayList;
 import javax.measure.Unit;
 import org.opengis.geometry.Envelope;
+import org.opengis.geometry.DirectPosition;
 import org.opengis.temporal.TemporalPrimitive;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.metadata.extent.VerticalExtent;
@@ -36,6 +37,7 @@ import org.opengis.referencing.crs.Coord
 import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.datum.VerticalDatumType;
 import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.metadata.InvalidMetadataException;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.measure.MeasurementRange;
@@ -409,6 +411,30 @@ public final class Extents extends Stati
     }
 
     /**
+     * Returns the position at the median longitude and latitude values of the given bounding box.
+     * This method does not check the {@linkplain DefaultGeographicBoundingBox#getInclusion() inclusion} status.
+     * This method takes in account bounding boxes that cross the anti-meridian.
+     *
+     * @param  bbox  the bounding box for which to get the median longitude and latitude values, or {@code null}.
+     * @return a median position of the given bounding box, or {@code null} if none.
+     */
+    public static DirectPosition centroid(final GeographicBoundingBox bbox) {
+        if (bbox != null) {
+            double y    = (bbox.getNorthBoundLatitude() + bbox.getSouthBoundLatitude()) / 2;
+            double x    =  bbox.getWestBoundLongitude();
+            double xmax =  bbox.getEastBoundLongitude();
+            if (xmax < x) {
+                xmax += (Longitude.MAX_VALUE - Longitude.MIN_VALUE);
+            }
+            x = Longitude.normalize((x + xmax) / 2);
+            if (Double.isFinite(x) || Double.isFinite(y)) {
+                return ReferencingServices.getInstance().geographic(x, y);
+            }
+        }
+        return null;
+    }
+
+    /**
      * Returns the intersection of the given geographic bounding boxes. If any of the arguments is {@code null},
      * then this method returns the other argument (which may be null). Otherwise this method returns a box which
      * is the intersection of the two given boxes.

Modified: sis/branches/JDK9/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/main/resources/org/apache/sis/metadata/sql/Create.sql [UTF-8] Fri Mar 31 18:49:16 2017
@@ -95,19 +95,22 @@ INSERT INTO metadata."CI_Party" (ID, "na
   ('Apache', 'The Apache Software Foundation'),
   ('OGC',    'Open Geospatial Consortium'),
   ('ISO',    'International Organization for Standardization'),
-  ('IOGP',   'International Association of Oil & Gas producers');
+  ('IOGP',   'International Association of Oil & Gas producers'),
+  ('NATO',   'North Atlantic Treaty Organization');
 
 INSERT INTO metadata."CI_Responsibility" (ID, "party", "role") VALUES
   ('Apache', 'Apache', 'principalInvestigator'),
   ('OGC',    'OGC',    'principalInvestigator'),
   ('ISO',    'ISO',    'principalInvestigator'),
-  ('IOGP',   'IOGP',   'principalInvestigator');
+  ('IOGP',   'IOGP',   'principalInvestigator'),
+  ('NATO',   'NATO',   'principalInvestigator');
 
 INSERT INTO metadata."CI_Citation" (ID, "edition", "citedResponsibleParty", "title") VALUES
   ('SIS',         NULL,                  'Apache',  'Apache Spatial Information System'),
   ('ISO 19115-1', 'ISO 19115-1:2014(E)', 'ISO',     'Geographic Information — Metadata Part 1: Fundamentals'),
   ('ISO 19115-2', 'ISO 19115-2:2009(E)', 'ISO',     'Geographic Information — Metadata Part 2: Extensions for imagery and gridded data'),
-  ('EPSG',        NULL,                  'IOGP',    'EPSG Geodetic Parameter Dataset');
+  ('EPSG',        NULL,                  'IOGP',    'EPSG Geodetic Parameter Dataset'),
+  ('MGRS',        NULL,                  'NATO',    'Military Grid Reference System');
 
 
 --

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -21,6 +21,7 @@ import java.util.Locale;
 import java.util.Iterator;
 import java.util.Collections;
 import java.nio.charset.StandardCharsets;
+import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.content.ContentInformation;
 import org.opengis.metadata.content.CoverageDescription;
 import org.opengis.metadata.content.FeatureCatalogueDescription;
@@ -36,7 +37,6 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.Assert.*;
-import org.opengis.metadata.citation.Citation;
 
 
 /**

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataTestCase.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -189,7 +189,7 @@ public abstract strictfp class MetadataT
                 final Class<?> impl = getImplementation(type);
                 if (impl != null) {
                     assertTrue(type.isAssignableFrom(impl));
-                    testPropertyValues(new PropertyAccessor(standard.getCitation(), type, impl));
+                    testPropertyValues(new PropertyAccessor(standard.getCitation(), type, impl, impl));
                 }
             }
         }

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -92,7 +92,7 @@ public final strictfp class PropertyAcce
      * Creates a new property accessor for the {@link DefaultCitation} class.
      */
     private static PropertyAccessor createPropertyAccessor() {
-        return new PropertyAccessor(HardCodedCitations.ISO_19115, Citation.class, DefaultCitation.class);
+        return new PropertyAccessor(HardCodedCitations.ISO_19115, Citation.class, DefaultCitation.class, DefaultCitation.class);
     }
 
     /**
@@ -200,7 +200,7 @@ public final strictfp class PropertyAcce
     @Test
     @DependsOnMethod("testConstructor")
     public void testConstructorWithInheritance() {
-        assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19115, DataIdentification.class, DefaultDataIdentification.class),
+        assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19115, DataIdentification.class, DefaultDataIdentification.class, DefaultDataIdentification.class),
         //……Declaring type………………………Method………………………………………………………………………JavaBeans………………………………………………………UML identifier………………………………………Sentence……………………………………………………………Type………………………………………………………………
             Identification.class, "getCitation",                   "citation",                   "citation",                  "Citation",                     Citation.class,
             Identification.class, "getAbstract",                   "abstract",                   "abstract",                  "Abstract",                     InternationalString.class,
@@ -238,7 +238,7 @@ public final strictfp class PropertyAcce
     @DependsOnMethod("testConstructorWithInheritance")
     public void testConstructorWithCovariantReturnType() {
         final Class<?> type = GeographicCRS.class;
-        assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19111, type, type),
+        assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19111, type, type, type),
         //……Declaring type……………………………Method……………………………………………JavaBeans……………………………UML identifier………………Sentence…………………………………Type…………………………………………………………
             GeographicCRS.class,    "getCoordinateSystem", "coordinateSystem", "coordinateSystem", "Coordinate system",  EllipsoidalCS.class,       // Covariant return type
             GeodeticCRS.class,      "getDatum",            "datum",            "datum",            "Datum",              GeodeticDatum.class,       // Covariant return type
@@ -368,7 +368,7 @@ public final strictfp class PropertyAcce
     @DependsOnMethod("testSet")
     public void testSetDeprecated() {
         final PropertyAccessor accessor = new PropertyAccessor(HardCodedCitations.ISO_19115,
-                CoverageDescription.class, DefaultCoverageDescription.class);
+                CoverageDescription.class, DefaultCoverageDescription.class, DefaultCoverageDescription.class);
         final int indexOfDeprecated  = accessor.indexOf("contentType", true);
         final int indexOfReplacement = accessor.indexOf("attributeGroup", true);
         assertTrue("Deprecated elements shall be sorted after non-deprecated ones.",

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/SpecialCasesTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -57,7 +57,7 @@ public final strictfp class SpecialCases
      */
     public SpecialCasesTest() {
         accessor = new SpecialCases(HardCodedCitations.ISO_19115,
-                GeographicBoundingBox.class, DefaultGeographicBoundingBox.class);
+                GeographicBoundingBox.class, DefaultGeographicBoundingBox.class, DefaultGeographicBoundingBox.class);
     }
 
     /**

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -86,10 +86,10 @@ public final strictfp class TreeTableFor
             "  ├─Title…………………………………………………………………………… Undercurrent\n" +
             "  ├─Alternate title………………………………………………… Andākarento\n" +
             "  ├─Identifier\n" +
-            "  │   ├─Code…………………………………………………………………… 9782505004509\n" +
             "  │   ├─Authority\n" +
             "  │   │   ├─Title……………………………………………………… International Standard Book Number\n" +
             "  │   │   └─Alternate title…………………………… ISBN\n" +
+            "  │   ├─Code…………………………………………………………………… 9782505004509\n" +
             "  │   └─Code space…………………………………………………… ISBN\n"+
             "  ├─Cited responsible party (1 of 2)\n" +
             "  │   ├─Party\n" +

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBoxTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -21,11 +21,12 @@ import org.opengis.metadata.extent.Geogr
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.test.DependsOnMethod;
+import org.apache.sis.test.TestUtilities;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static java.lang.Double.NaN;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
 
 
 /**
@@ -33,7 +34,7 @@ import static org.junit.Assert.*;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.8
  * @module
  */
 public final strictfp class DefaultGeographicBoundingBoxTest extends TestCase {
@@ -418,4 +419,31 @@ public final strictfp class DefaultGeogr
             Boolean.TRUE
         }, map.values().toArray());
     }
+
+    /**
+     * Tests the {@code toString()} implementation of a custom geographic bounding box inside a {@link DefaultExtent}.
+     * In a previous Apache SIS version, those properties were not properly sorted.
+     *
+     * @since 0.8
+     */
+    @Test
+    public void testToString() {
+        final GeographicBoundingBox bbox = new GeographicBoundingBox() {
+            @Override public double getWestBoundLongitude() {return -40;}
+            @Override public double getEastBoundLongitude() {return  50;}
+            @Override public double getSouthBoundLatitude() {return -20;}
+            @Override public double getNorthBoundLatitude() {return  45;}
+            @Override public Boolean getInclusion() {return Boolean.TRUE;}
+        };
+        final DefaultExtent extent = new DefaultExtent(null, bbox, null, null);
+        assertSame(bbox, TestUtilities.getSingleton(extent.getGeographicElements()));
+        assertMultilinesEquals(
+                "Extent\n" +
+                "  └─Geographic element\n" +
+                "      ├─West bound longitude…… 40°W\n" +
+                "      ├─East bound longitude…… 50°E\n" +
+                "      ├─South bound latitude…… 20°S\n" +
+                "      ├─North bound latitude…… 45°N\n" +
+                "      └─Extent type code……………… true\n", extent.toString());
+    }
 }

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -22,6 +22,7 @@ import java.util.Collections;
 import javax.measure.Unit;
 import javax.measure.UnitConverter;
 import javax.measure.IncommensurableException;
+import org.opengis.geometry.DirectPosition;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.apache.sis.measure.Units;
 import org.apache.sis.measure.MeasurementRange;
@@ -149,4 +150,26 @@ public final strictfp class ExtentsTest
         assertTrue(DefaultGeographicBoundingBoxTest.isSpanningAntiMeridian(box));
         assertEquals(9845438, Extents.area(box) / 1E6, 1);                              // Compare in km²
     }
+
+    /**
+     * Tests the {@link Extents#centroid(GeographicBoundingBox)} method. This method is defined here but executed from
+     * the {@link org.apache.sis.internal.referencing.ServicesForMetadataTest} class in {@code sis-referencing} module.
+     * This method can not be executed in the {@code sis-metadata} module because it has a dependency to a referencing
+     * implementation class.
+     *
+     * @since 0.8
+     */
+    public static void testCentroid() {
+        final DefaultGeographicBoundingBox bbox = new DefaultGeographicBoundingBox(140, 160, 30, 50);
+        DirectPosition pos = Extents.centroid(bbox);
+        assertEquals("longitude", 150, pos.getOrdinate(0), STRICT);
+        assertEquals("latitude",   40, pos.getOrdinate(1), STRICT);
+        /*
+         * Test crossing anti-meridian.
+         */
+        bbox.setEastBoundLongitude(-160);
+        pos = Extents.centroid(bbox);
+        assertEquals("longitude", 170, pos.getOrdinate(0), STRICT);
+        assertEquals("latitude",   40, pos.getOrdinate(1), STRICT);
+    }
 }

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/lineage/DefaultProcessStepTest.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -18,10 +18,11 @@ package org.apache.sis.metadata.iso.line
 
 import javax.xml.bind.JAXBException;
 import org.apache.sis.util.iso.SimpleInternationalString;
+import org.apache.sis.internal.jaxb.gmi.LE_ProcessStep;
 import org.apache.sis.test.XMLTestCase;
 import org.junit.Test;
 
-import static org.junit.Assert.*;
+import static org.opengis.test.Assert.*;
 
 
 /**
@@ -30,7 +31,7 @@ import static org.junit.Assert.*;
  * @author  Cédric Briançon (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.8
  * @module
  */
 public final strictfp class DefaultProcessStepTest extends XMLTestCase {
@@ -59,7 +60,13 @@ public final strictfp class DefaultProce
         assertMarshalEqualsFile(XML_FILE, processStep, "xlmns:*", "xsi:schemaLocation");
         /*
          * XML unmarshalling: ensure that we didn't lost any information.
+         * Note that since the XML uses the <gmi:…> namespace, we got an instance of LE_ProcessStep, which
+         * in SIS implementation does not carry any useful information; it is just a consequence of the way
+         * namespaces are managed. We will convert to the parent DefaultProcessStep type before comparison.
          */
-        assertEquals(processStep, unmarshalFile(DefaultProcessStep.class, XML_FILE));
+        DefaultProcessStep step = unmarshalFile(DefaultProcessStep.class, XML_FILE);
+        assertInstanceOf("The unmarshalled object is expected to be in GMI namespace.", LE_ProcessStep.class, step);
+        step = new DefaultProcessStep(step);
+        assertEquals(processStep, step);
     }
 }

Modified: sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -52,6 +52,7 @@ import org.junit.BeforeClass;
     org.apache.sis.metadata.MetadataStandardTest.class,
     org.apache.sis.metadata.PrunerTest.class,
     org.apache.sis.metadata.AbstractMetadataTest.class,
+    org.apache.sis.metadata.MetadataCopierTest.class,
     org.apache.sis.internal.metadata.MergerTest.class,
 
     // XML marshalling.

Modified: sis/branches/JDK9/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml (original)
+++ sis/branches/JDK9/core/sis-metadata/src/test/resources/org/apache/sis/metadata/iso/lineage/ProcessStep.xml Fri Mar 31 18:49:16 2017
@@ -18,7 +18,7 @@
   under the License.
 -->
 
-<gmd:LI_ProcessStep
+<gmi:LE_ProcessStep
     xmlns:gmd = "http://www.isotc211.org/2005/gmd"
     xmlns:gco = "http://www.isotc211.org/2005/gco"
     xmlns:gmi = "http://www.isotc211.org/2005/gmi"
@@ -39,4 +39,4 @@
       </gmi:procedureDescription>
     </gmi:LE_Processing>
   </gmi:processingInformation>
-</gmd:LI_ProcessStep>
+</gmi:LE_ProcessStep>

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -1121,7 +1121,7 @@ public abstract class AbstractEnvelope i
      * @return this envelope as a {@code BOX} or {@code BOX3D} (most typical dimensions) element.
      *
      * @see GeneralEnvelope#GeneralEnvelope(CharSequence)
-     * @see org.apache.sis.measure.CoordinateFormat
+     * @see CoordinateFormat
      * @see org.apache.sis.io.wkt
      */
     static String toString(final Envelope envelope, final boolean isSimplePrecision) {

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition1D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -42,6 +42,7 @@ import static org.apache.sis.util.Argume
  *
  * @see DirectPosition2D
  * @see GeneralDirectPosition
+ * @see CoordinateFormat
  */
 public class DirectPosition1D extends AbstractDirectPosition implements Serializable, Cloneable {
     /**
@@ -99,7 +100,7 @@ public class DirectPosition1D extends Ab
      * @throws MismatchedDimensionException if the given point is not one-dimensional.
      *
      * @see #toString()
-     * @see org.apache.sis.measure.CoordinateFormat
+     * @see CoordinateFormat
      */
     public DirectPosition1D(final CharSequence wkt) throws IllegalArgumentException {
         final double[] ordinates = parse(wkt);

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/DirectPosition2D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -66,6 +66,7 @@ import static org.apache.sis.util.Argume
  * @see DirectPosition1D
  * @see GeneralDirectPosition
  * @see Point2D
+ * @see CoordinateFormat
  */
 public class DirectPosition2D extends Point2D.Double implements DirectPosition, Cloneable {
     /**
@@ -156,7 +157,7 @@ public class DirectPosition2D extends Po
      * @throws MismatchedDimensionException if the given point is not two-dimensional.
      *
      * @see #toString()
-     * @see org.apache.sis.measure.CoordinateFormat
+     * @see CoordinateFormat
      */
     public DirectPosition2D(final CharSequence wkt) throws IllegalArgumentException {
         final double[] ordinates = AbstractDirectPosition.parse(wkt);

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelope2D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -98,13 +98,12 @@ import static org.apache.sis.geometry.Ab
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Johann Sorel (Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.8
  * @module
  *
  * @see GeneralEnvelope
  * @see org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox
  */
-@SuppressWarnings("CloneableClassWithoutClone")    // No additional fields compared to parent.
 public class Envelope2D extends Rectangle2D.Double implements Envelope, Emptiable, Cloneable {
     /**
      * Serial number for inter-operability with different versions.
@@ -284,6 +283,29 @@ public class Envelope2D extends Rectangl
     }
 
     /**
+     * Sets this envelope to the given rectangle. If the given rectangle is also an instance of {@link Envelope}
+     * (typically as another {@code Envelope2D}) and has a non-null Coordinate Reference System (CRS), then the
+     * CRS of this envelope will be set to the CRS of the given envelope.
+     *
+     * @param rect  the rectangle to copy coordinates from.
+     *
+     * @since 0.8
+     */
+    @Override
+    public void setRect(final Rectangle2D rect) {
+        if (rect == this) {
+            return;         // Optimization for methods chaining like env.setRect(Shapes.transform(…, env))
+        }
+        if (rect instanceof Envelope) {
+            final CoordinateReferenceSystem envelopeCRS = ((Envelope) rect).getCoordinateReferenceSystem();
+            if (envelopeCRS != null) {
+                setCoordinateReferenceSystem(envelopeCRS);
+            }
+        }
+        super.setRect(rect);
+    }
+
+    /**
      * Returns the number of dimensions, which is always 2.
      *
      * @return always 2 for bi-dimensional objects.
@@ -444,6 +466,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMinimum(int) minimal} ordinate value for dimension 0.
+     * The default implementation invokes <code>{@linkplain #getMinimum(int) getMinimum}(0)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #x x})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the minimal ordinate value for dimension 0.
      */
@@ -454,6 +479,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMinimum(int) minimal} ordinate value for dimension 1.
+     * The default implementation invokes <code>{@linkplain #getMinimum(int) getMinimum}(1)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #y y})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the minimal ordinate value for dimension 1.
      */
@@ -464,6 +492,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMaximum(int) maximal} ordinate value for dimension 0.
+     * The default implementation invokes <code>{@linkplain #getMaximum(int) getMinimum}(0)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #x x} + {@linkplain #width width})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the maximal ordinate value for dimension 0.
      */
@@ -474,6 +505,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMaximum(int) maximal} ordinate value for dimension 1.
+     * The default implementation invokes <code>{@linkplain #getMaximum(int) getMinimum}(1)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #y y} + {@linkplain #height height})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the maximal ordinate value for dimension 1.
      */
@@ -484,6 +518,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMedian(int) median} ordinate value for dimension 0.
+     * The default implementation invokes <code>{@linkplain #getMedian(int) getMedian}(0)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #x x} + {@linkplain #width width}/2)
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the median ordinate value for dimension 0.
      */
@@ -494,6 +531,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getMedian(int) median} ordinate value for dimension 1.
+     * The default implementation invokes <code>{@linkplain #getMedian(int) getMedian}(1)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #y y} + {@linkplain #height height}/2)
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the median ordinate value for dimension 1.
      */
@@ -504,6 +544,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getSpan(int) span} for dimension 0.
+     * The default implementation invokes <code>{@linkplain #getSpan(int) getSpan}(0)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #width width})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the span for dimension 0.
      */
@@ -514,6 +557,9 @@ public class Envelope2D extends Rectangl
 
     /**
      * Returns the {@linkplain #getSpan(int) span} for dimension 1.
+     * The default implementation invokes <code>{@linkplain #getSpan(int) getSpan}(1)</code>.
+     * The result is the standard {@link Rectangle2D} value (namely {@linkplain #height height})
+     * only if the envelope is not spanning the anti-meridian.
      *
      * @return the span for dimension 1.
      */
@@ -756,7 +802,7 @@ public class Envelope2D extends Rectangl
             final Envelope2D env = (Envelope2D) rect;
             return intersects(env.x, env.y, env.width, env.height);
         }
-        return super.contains(rect);
+        return super.intersects(rect);
     }
 
     /**
@@ -885,7 +931,7 @@ public class Envelope2D extends Rectangl
      */
     @Override
     public Envelope2D createUnion(final Rectangle2D rect) {
-        final Envelope2D union = (Envelope2D) clone();
+        final Envelope2D union = clone();
         union.add(rect);
         assert union.isEmpty() || (union.contains(this) && union.contains(rect)) : union;
         return union;
@@ -1090,6 +1136,16 @@ public class Envelope2D extends Rectangl
     }
 
     /**
+     * Returns a clone of this envelope.
+     *
+     * @return a clone of this envelope.
+     */
+    @Override
+    public Envelope2D clone() {
+        return (Envelope2D) super.clone();
+    }
+
+    /**
      * Formats this envelope as a "{@code BOX}" element.
      * The output is of the form "{@code BOX(}{@linkplain #getLowerCorner()
      * lower corner}{@code ,}{@linkplain #getUpperCorner() upper corner}{@code )}".

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralDirectPosition.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -57,6 +57,7 @@ import static org.apache.sis.util.Argume
  *
  * @see DirectPosition1D
  * @see DirectPosition2D
+ * @see CoordinateFormat
  */
 public class GeneralDirectPosition extends AbstractDirectPosition implements Serializable, Cloneable {
     /**
@@ -108,10 +109,16 @@ public class GeneralDirectPosition exten
      * Consequently, callers shall not recycle the same array for creating many instances.
      *
      * <div class="note"><b>Implementation note:</b>
-     * The array is not cloned because this is usually not needed, especially in the context of variable
+     * the array is not cloned because this is usually not needed, especially in the context of variable
      * argument lengths since the array is often created implicitly. Furthermore the {@link #ordinates}
      * field is public, so cloning the array would not protect the state of this object anyway.</div>
      *
+     * <p><b>Caution:</b> if only one number is specified, make sure that the number type is {@code double},
+     * {@code float} or {@code long} otherwise the {@link #GeneralDirectPosition(int)} constructor would be
+     * invoked with a very different meaning. For example for creating a one-dimensional coordinate initialized
+     * to the ordinate value 100, use <code>new GeneralDirectPosition(100<u>.0</u>)</code>, <strong>not</strong>
+     * {@code new GeneralDirectPosition(100)}, because the later would actually create a position with 100 dimensions.</p>
+     *
      * @param ordinates  the ordinate values. This array is <strong>not</strong> cloned.
      */
     public GeneralDirectPosition(final double... ordinates) {
@@ -145,7 +152,7 @@ public class GeneralDirectPosition exten
      * @throws IllegalArgumentException if the given string can not be parsed.
      *
      * @see #toString()
-     * @see org.apache.sis.measure.CoordinateFormat
+     * @see CoordinateFormat
      */
     public GeneralDirectPosition(final CharSequence wkt) throws IllegalArgumentException {
         if ((ordinates = parse(wkt)) == null) {

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -391,6 +391,9 @@ public class GeneralEnvelope extends Arr
      *         the expected number of dimensions.
      */
     public void setEnvelope(final Envelope envelope) throws MismatchedDimensionException {
+        if (envelope == this) {
+            return;     // Optimization for methods chaining like env.setEnvelope(Envelopes.transform(env, crs))
+        }
         ensureNonNull("envelope", envelope);
         final int beginIndex = beginIndex();
         final int dimension = endIndex() - beginIndex;

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -386,6 +386,7 @@ public final class Shapes2D extends Stat
      * @see #transform(MathTransform2D, Rectangle2D, Rectangle2D)
      * @see Envelopes#transform(CoordinateOperation, Envelope)
      */
+    @SuppressWarnings("null")
     public static Rectangle2D transform(final CoordinateOperation operation,
                                         final Rectangle2D         envelope,
                                               Rectangle2D         destination)

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/geometry/package-info.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -81,7 +81,7 @@
  *       than an inclusion area.</li>
  * </ul>
  *
- * @author Martin Desruisseaux (IRD, Geomatys)
+ * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
  * @version 0.8
  * @module

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtendedPrecisionMatrix.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -25,12 +25,19 @@ import org.opengis.referencing.operation
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.6
+ * @version 0.8
  * @module
  */
 public interface ExtendedPrecisionMatrix extends Matrix {
     /**
      * A sentinel value for {@link org.apache.sis.referencing.operation.matrix.Matrices#create(int, int, Number[])}
+     * meaning that we request an extended precision matrix with all elements initialized to zero.
+     * This is a non-public feature because we try to hide our extended-precision mechanism from the users.
+     */
+    Number[] ZERO = new Number[0];
+
+    /**
+     * A sentinel value for {@link org.apache.sis.referencing.operation.matrix.Matrices#create(int, int, Number[])}
      * meaning that we request an extended precision matrix initialized to the identity (or diagonal) matrix.
      * This is a non-public feature because we try to hide our extended-precision mechanism from the users.
      */

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/GeodeticObjectBuilder.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -45,6 +45,7 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.internal.referencing.provider.PolarStereographicA;
 import org.apache.sis.measure.Latitude;
 import org.apache.sis.referencing.Builder;
 import org.apache.sis.referencing.CommonCRS;
@@ -230,27 +231,68 @@ public class GeodeticObjectBuilder exten
      *
      * <blockquote><table class="sis">
      *   <caption>Transverse Mercator parameters</caption>
-     *   <tr><th>Parameter name</th>                 <th>Value</th></tr>
+     *   <tr><th>Parameter name</th>                 <th>Parameter value</th></tr>
      *   <tr><td>Latitude of natural origin</td>     <td>Given latitude, snapped to 0° in the UTM case</td></tr>
      *   <tr><td>Longitude of natural origin</td>    <td>Given longitude, optionally snapped to a UTM zone</td></tr>
-     *   <tr><td>Scale factor at natural origin</td> <td>0.9996</td></tr>
-     *   <tr><td>False easting</td>                  <td>500000 metres</td></tr>
+     *   <tr><td>Scale factor at natural origin</td> <td>0.9996 in UTM case</td></tr>
+     *   <tr><td>False easting</td>                  <td>500000 metres in UTM case</td></tr>
      *   <tr><td>False northing</td>                 <td>0 (North hemisphere) or 10000000 (South hemisphere) metres</td></tr>
      * </table></blockquote>
      *
-     * @param  isUTM      if {@code true}, the given central meridian will be snapped to the central meridian of a UTM zone.
+     * Note that calculation of UTM zone contains special cases for Norway and Svalbard.
+     * If not desired, those exceptions can be avoided by making sure that the given latitude is below 56°N.
+     *
+     * <p>If the given {@code zoner} is {@link TransverseMercator.Zoner#ANY ANY}, then this method will use the given
+     * latitude and longitude verbatim (without snapping them to a zone) but will still use the UTM scale factor,
+     * false easting and false northing.
+     *
+     * @param  zoner      whether to use UTM or MTM zones, or {@code ANY} for using arbitrary central meridian.
      * @param  latitude   the latitude in the center of the desired projection.
      * @param  longitude  the longitude in the center of the desired projection.
      * @return {@code this}, for method calls chaining.
      * @throws FactoryException if the operation method for the Transverse Mercator projection can not be obtained.
+     *
+     * @see CommonCRS#UTM(double, double)
      */
-    public GeodeticObjectBuilder setTransverseMercator(boolean isUTM, double latitude, double longitude)
+    public GeodeticObjectBuilder setTransverseMercator(TransverseMercator.Zoner zoner, double latitude, double longitude)
             throws FactoryException
     {
         ArgumentChecks.ensureBetween("latitude",   Latitude.MIN_VALUE,     Latitude.MAX_VALUE,     latitude);
         ArgumentChecks.ensureBetween("longitude", -Formulas.LONGITUDE_MAX, Formulas.LONGITUDE_MAX, longitude);
         setConversionMethod(TransverseMercator.NAME);
-        setConversionName(TransverseMercator.setParameters(parameters, isUTM, latitude, longitude));
+        setConversionName(zoner.setParameters(parameters, latitude, longitude));
+        return this;
+    }
+
+    /**
+     * Sets the operation method, parameters and conversion name for a Polar Stereographic projection.
+     * This convenience method delegates to the following methods:
+     *
+     * <ul>
+     *   <li>{@link #setConversionName(String)} with a name like <cite>"Universal Polar Stereographic North"</cite>,
+     *       depending on the argument given to this method.</li>
+     *   <li>{@link #setConversionMethod(String)} with the name of the Polar Stereographic (variant A) projection method.</li>
+     *   <li>{@link #setParameter(String, double, Unit)} for each of the parameters enumerated below:</li>
+     * </ul>
+     *
+     * <blockquote><table class="sis">
+     *   <caption>Universal Polar Stereographic parameters</caption>
+     *   <tr><th>Parameter name</th>                 <th>Parameter value</th></tr>
+     *   <tr><td>Latitude of natural origin</td>     <td>90°N or 90°S</td></tr>
+     *   <tr><td>Longitude of natural origin</td>    <td>0°</td></tr>
+     *   <tr><td>Scale factor at natural origin</td> <td>0.994</td></tr>
+     *   <tr><td>False easting</td>                  <td>2000000 metres</td></tr>
+     *   <tr><td>False northing</td>                 <td>2000000 metres</td></tr>
+     * </table></blockquote>
+     *
+     * @param  north  {@code true} for North pole, or {@code false} for South pole.
+     * @return {@code this}, for method calls chaining.
+     * @throws FactoryException if the operation method for the Polar Stereographic (variant A)
+     *         projection can not be obtained.
+     */
+    public GeodeticObjectBuilder setPolarStereographic(final boolean north) throws FactoryException {
+        setConversionMethod(PolarStereographicA.NAME);
+        setConversionName(PolarStereographicA.setParameters(parameters, north));
         return this;
     }
 

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingTypes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingTypes.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingTypes.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingTypes.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -21,6 +21,8 @@ import org.apache.sis.internal.jaxb.Type
 import org.apache.sis.parameter.DefaultParameterValue;
 import org.apache.sis.parameter.DefaultParameterValueGroup;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
+import org.apache.sis.referencing.AbstractReferenceSystem;
+import org.opengis.referencing.ReferenceSystem;
 
 
 /**
@@ -29,7 +31,7 @@ import org.apache.sis.referencing.Abstra
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.4
- * @version 0.4
+ * @version 0.8
  * @module
  */
 public final class ReferencingTypes extends TypeRegistration {
@@ -37,9 +39,32 @@ public final class ReferencingTypes exte
      * Adds to the given collection the referencing types that should be given to the initial JAXB context.
      */
     @Override
-    public void getTypes(final Collection<Class<?>> addTo) {
+    protected void getTypes(final Collection<Class<?>> addTo) {
         addTo.add(AbstractIdentifiedObject.class);
         addTo.add(DefaultParameterValue.class);
         addTo.add(DefaultParameterValueGroup.class);
     }
+
+    /**
+     * Notifies that the {@code sis-referencing} module can marshal arbitrary implementations
+     * of some coordinate reference system interfaces.
+     *
+     * @return {@code true}.
+     */
+    @Override
+    protected boolean canMarshalInterfaces() {
+        return true;
+    }
+
+    /**
+     * Ensures that the given value is an instance of a class that can be marshalled,
+     * or returns {@code null} if the type is not handled by this method.
+     *
+     * @param  value  the value to marshal.
+     * @return the given value as a type that can be marshalled, or {@code null}.
+     */
+    @Override
+    public Object toImplementation(final Object value) {
+        return (value instanceof ReferenceSystem) ? AbstractReferenceSystem.castOrCopy((ReferenceSystem) value) : null;
+    }
 }

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -321,6 +321,11 @@ public final class Resources extends Ind
         public static final short NoSuchOperationMethod_1 = 50;
 
         /**
+         * No horizontal component found in the “{0}” coordinate reference system.
+         */
+        public static final short NonHorizontalCRS_1 = 71;
+
+        /**
          * Non invertible {0}×{1} matrix.
          */
         public static final short NonInvertibleMatrix_2 = 51;

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] Fri Mar 31 18:49:16 2017
@@ -73,6 +73,7 @@ MissingSpatioTemporalDimension_1  = No s
 MissingValueForParameter_1        = Missing value for \u201c{0}\u201d parameter.
 NoConvergence                     = No convergence.
 NoConvergenceForPoints_2          = No convergence for points {0} and {1}.
+NonHorizontalCRS_1                = No horizontal component found in the \u201c{0}\u201d coordinate reference system.
 NonInvertibleMatrix_2             = Non invertible {0}\u00d7{1} matrix.
 NonInvertibleOperation_1          = Can not invert the \u201c{0}\u201d operation.
 NonInvertibleTransform            = Transform is not invertible.

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] Fri Mar 31 18:49:16 2017
@@ -78,6 +78,7 @@ MissingSpatioTemporalDimension_1  = Aucu
 MissingValueForParameter_1        = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb.
 NoConvergence                     = Le calcul ne converge pas.
 NoConvergenceForPoints_2          = Le calcul ne converge pas pour les points {0} et {1}.
+NonHorizontalCRS_1                = Aucune composante horizontale n\u2019a \u00e9t\u00e9 trouv\u00e9e dans le syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es \u00ab\u202f{0}\u202f\u00bb.
 NonInvertibleMatrix_2             = Matrice {0}\u00d7{1} non inversible.
 NonInvertibleOperation_1          = Ne peut pas inverser l\u2019op\u00e9ration \u00ab\u202f{0}\u202f\u00bb.
 NonInvertibleTransform            = La transformation n\u2019est pas inversible.

Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -22,6 +22,8 @@ import java.util.Iterator;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Locale;
+import java.util.TimeZone;
+import java.text.Format;
 import javax.measure.Unit;
 import javax.measure.quantity.Length;
 
@@ -57,9 +59,12 @@ import org.opengis.metadata.citation.Onl
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.opengis.metadata.extent.GeographicExtent;
 import org.opengis.metadata.extent.VerticalExtent;
+import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.Envelope;
 
 import org.apache.sis.geometry.Envelopes;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.geometry.CoordinateFormat;
 import org.apache.sis.referencing.CRS;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.IdentifiedObjects;
@@ -98,7 +103,7 @@ import org.apache.sis.util.Utilities;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.5
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final class ServicesForMetadata extends ReferencingServices {
@@ -390,6 +395,21 @@ public final class ServicesForMetadata e
         }
     }
 
+    /**
+     * Creates a two-dimensional geographic position associated to the default geographic CRS.
+     * Axis order is (longitude, latitude).
+     *
+     * @param  λ  the longitude value.
+     * @param  φ  the latitude value.
+     * @return the direct position for the given geographic coordinate.
+     *
+     * @since 0.8
+     */
+    @Override
+    public DirectPosition geographic(final double λ, final double φ) {
+        return new DirectPosition2D(CommonCRS.defaultGeographic(), λ, φ);
+    }
+
 
 
 
@@ -558,6 +578,20 @@ public final class ServicesForMetadata e
     }
 
     /**
+     * Creates a format for {@link DirectPosition} instances.
+     *
+     * @param  locale    the locale for the new {@code Format}, or {@code null} for {@code Locale.ROOT}.
+     * @param  timezone  the timezone, or {@code null} for UTC.
+     * @return a {@link org.apache.sis.geometry.CoordinateFormat}.
+     *
+     * @since 0.8
+     */
+    @Override
+    public Format createCoordinateFormat(final Locale locale, final TimeZone timezone) {
+        return new CoordinateFormat(locale, timezone);
+    }
+
+    /**
      * Returns an axis direction from a pole along a meridian.
      * The given meridian is usually, but not necessarily, relative to the Greenwich meridian.
      *



Mime
View raw message