sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1792288 - in /sis/branches/JDK8: core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/ core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/ ...
Date Sat, 22 Apr 2017 13:50:01 GMT
Author: desruisseaux
Date: Sat Apr 22 13:50:00 2017
New Revision: 1792288

URL: http://svn.apache.org/viewvc?rev=1792288&view=rev
Log:
When parsing GeoTIFF keys for building a CRS, we need a mapping from projection parameter numerical codes (e.g. 3080) to parameter name (e.g. "NatOriginLong").
As a side effect of this work, review the behavior of Parameters.parameterIfExit(String) method regarding ambiguous names.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
    sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameToIdentifier.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -41,7 +41,7 @@ import static org.apache.sis.util.Charac
  * Current version does not yet work with URN or HTTP syntax.</p>
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.4
  * @module
  */
@@ -207,6 +207,32 @@ public final class NameToIdentifier impl
     }
 
     /**
+     * Returns {@code true} if the given identifier to search matches one of the object identifiers.
+     *
+     * @param  identifiers  the identifiers to compare against {@code toSearch}.
+     * @param  toSearch     the identifier to check for equality.
+     * @return {@code true} if the identifier to search is found in the given set of identifiers.
+     *
+     * @since 0.8
+     */
+    public static boolean isHeuristicMatchForIdentifier(final Iterable<? extends Identifier> identifiers, final String toSearch) {
+        if (toSearch != null && identifiers != null) {
+            for (int s = toSearch.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR); s >= 0;
+                     s = toSearch.indexOf(DefaultNameSpace.DEFAULT_SEPARATOR, s))
+            {
+                final String codespace = toSearch.substring(0, s).trim();
+                final String code = toSearch.substring(++s).trim();
+                for (final Identifier id : identifiers) {
+                    if (codespace.equalsIgnoreCase(id.getCodeSpace()) && code.equalsIgnoreCase(id.getCode())) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
      * Returns {@code true} if the given {@linkplain org.apache.sis.referencing.AbstractIdentifiedObject#getName()
      * primary name} or one of the given aliases matches the given name. The comparison ignores case, some Latin
      * diacritical signs and any characters that are not letters or digits.
@@ -222,28 +248,30 @@ public final class NameToIdentifier impl
     public static boolean isHeuristicMatchForName(final Identifier name, final Collection<GenericName> aliases,
             CharSequence toSearch, final Simplifier simplifier)
     {
-        toSearch = simplifier.apply(toSearch);
-        if (name != null) {                                                                 // Paranoiac check.
-            final CharSequence code = simplifier.apply(name.getCode());
-            if (code != null) {                                                             // Paranoiac check.
-                if (CharSequences.equalsFiltered(toSearch, code, LETTERS_AND_DIGITS, true)) {
-                    return true;
-                }
+        if (toSearch != null) {
+            CharSequence code = (name != null) ? name.getCode() : null;
+            if (toSearch.equals(code)) {
+                return true;                                                    // Optimization for a common case.
             }
-        }
-        if (aliases != null) {
-            for (final GenericName alias : aliases) {
-                if (alias != null) {                                                        // Paranoiac check.
-                    final CharSequence tip = simplifier.apply(alias.tip().toString());
-                    if (CharSequences.equalsFiltered(toSearch, tip, LETTERS_AND_DIGITS, true)) {
-                        return true;
+            toSearch = simplifier.apply(toSearch);
+            code     = simplifier.apply(code);
+            if (CharSequences.equalsFiltered(toSearch, code, LETTERS_AND_DIGITS, true)) {
+                return true;
+            }
+            if (aliases != null) {
+                for (final GenericName alias : aliases) {
+                    if (alias != null) {                                                        // Paranoiac check.
+                        final CharSequence tip = simplifier.apply(alias.tip().toString());
+                        if (CharSequences.equalsFiltered(toSearch, tip, LETTERS_AND_DIGITS, true)) {
+                            return true;
+                        }
+                        /*
+                         * Note: a previous version compared also the scoped names. We removed that part,
+                         * because experience has shown that this method is used only for the "code" part
+                         * of an object name. If we really want to compare scoped name, it would probably
+                         * be better to take a GenericName argument instead than String.
+                         */
                     }
-                    /*
-                     * Note: a previous version compared also the scoped names. We removed that part,
-                     * because experience has shown that this method is used only for the "code" part
-                     * of an object name. If we really want to compare scoped name, it would probably
-                     * be better to take a GenericName argument instead than String.
-                     */
                 }
             }
         }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -25,7 +25,6 @@ import javax.measure.Unit;
 import javax.measure.quantity.Length;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
-import org.opengis.metadata.Identifier;
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.crs.CRSFactory;
@@ -59,7 +58,6 @@ import org.apache.sis.internal.system.Op
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.util.ArraysExt;
-import org.apache.sis.util.iso.DefaultNameSpace;
 import org.apache.sis.util.Deprecable;
 
 
@@ -131,14 +129,6 @@ public class ReferencingServices extends
     public static final String CS_FACTORY = "csFactory";
 
     /**
-     * The separator character between an identifier and its namespace in the argument given to
-     * {@link #getOperationMethod(Iterable, String)}. For example this is the separator in {@code "EPSG:9807"}.
-     *
-     * This is defined as a constant for now, but we may make it configurable in a future version.
-     */
-    private static final char IDENTIFIER_SEPARATOR = DefaultNameSpace.DEFAULT_SEPARATOR;
-
-    /**
      * The services, fetched when first needed.
      */
     private static volatile ReferencingServices instance;
@@ -645,33 +635,6 @@ public class ReferencingServices extends
     }
 
     /**
-     * Returns {@code true} if the name or an identifier of the given method matches the given {@code identifier}.
-     *
-     * @param  method      the method to test for a match.
-     * @param  identifier  the name or identifier of the operation method to search.
-     * @return {@code true} if the given method is a match for the given identifier.
-     *
-     * @since 0.6
-     */
-    private boolean matches(final OperationMethod method, final String identifier) {
-        if (isHeuristicMatchForName(method, identifier)) {
-            return true;
-        }
-        for (int s = identifier.indexOf(IDENTIFIER_SEPARATOR); s >= 0;
-                 s = identifier.indexOf(IDENTIFIER_SEPARATOR, s))
-        {
-            final String codespace = identifier.substring(0, s).trim();
-            final String code = identifier.substring(++s).trim();
-            for (final Identifier id : method.getIdentifiers()) {
-                if (codespace.equalsIgnoreCase(id.getCodeSpace()) && code.equalsIgnoreCase(id.getCode())) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
      * Returns the operation method for the specified name or identifier. The given argument shall be either a
      * method name (e.g. <cite>"Transverse Mercator"</cite>) or one of its identifiers (e.g. {@code "EPSG:9807"}).
      *
@@ -687,7 +650,9 @@ public class ReferencingServices extends
     public final OperationMethod getOperationMethod(final Iterable<? extends OperationMethod> methods, final String identifier) {
         OperationMethod fallback = null;
         for (final OperationMethod method : methods) {
-            if (matches(method, identifier)) {
+            if (isHeuristicMatchForName(method, identifier) ||
+                    NameToIdentifier.isHeuristicMatchForIdentifier(method.getIdentifiers(), identifier))
+            {
                 /*
                  * Stop the iteration at the first non-deprecated method.
                  * If we find only deprecated methods, take the first one.

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -348,7 +348,7 @@ public final class Citations extends Sta
      *
      * @since 0.4
      */
-    public static final IdentifierSpace<Integer> GEOTIFF = new CitationConstant.Authority<>("GeoTIFF");
+    public static final IdentifierSpace<Integer> GEOTIFF = new CitationConstant.Authority<>(Constants.GEOTIFF);
 
     /**
      * The authority for identifiers of objects defined by the <a href="http://trac.osgeo.org/proj/">Proj.4</a> project.

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -55,7 +55,7 @@ public final strictfp class CitationsTes
         assertSame(IOGP,             fromName("OGP"));
         assertSame(ESRI,             fromName("ESRI"));          // Handled in a way very similar to "OGC".
         assertSame(NETCDF,           fromName("NetCDF"));
-        assertSame(GEOTIFF,          fromName("GeoTIFF"));
+        assertSame(GEOTIFF,          fromName(Constants.GEOTIFF));
         assertSame(PROJ4,            fromName("Proj.4"));
         assertSame(PROJ4,            fromName("Proj4"));
         assertSame(MAP_INFO,         fromName("MapInfo"));

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -24,7 +24,10 @@ import javax.measure.quantity.Angle;
 import org.opengis.annotation.UML;
 import org.opengis.annotation.Specification;
 import org.opengis.metadata.Identifier;
+import org.opengis.metadata.citation.Citation;
 import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.GeneralParameterDescriptor;
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
 import org.opengis.referencing.IdentifiedObject;
@@ -36,6 +39,7 @@ import org.apache.sis.internal.system.De
 import org.apache.sis.util.Static;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.referencing.CommonCRS;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
@@ -396,4 +400,34 @@ public final class ReferencingUtilities
                 factory.createDefiningConversion(properties,
                         factory.getOperationMethod(parameters.getDescriptor().getName().getCode()), parameters), cs);
     }
+
+    /**
+     * Returns the mapping between parameter identifiers and parameter names as defined by the given authority.
+     * This method assumes that the identifiers of all parameters defined by that authority are numeric.
+     * Examples of authorities defining numeric parameters are EPSG and GeoTIFF.
+     *
+     * @param  parameters  the parameters for which to get a mapping from identifiers to names.
+     * @param  authority   the authority defining the parameters.
+     * @return mapping from parameter identifiers to parameter names defined by the given authority.
+     * @throws NumberFormatException if a parameter identifier of the given authority is not numeric.
+     * @throws IllegalArgumentException if the same identifier is used for two or more parameters.
+     *
+     * @since 0.8
+     */
+    public static Map<Integer,String> identifierToName(final ParameterDescriptorGroup parameters, final Citation authority) {
+        final Map<Integer,String> mapping = new HashMap<>();
+        for (final GeneralParameterDescriptor descriptor : parameters.descriptors()) {
+            final Identifier id = IdentifiedObjects.getIdentifier(descriptor, authority);
+            if (id != null) {
+                String name = IdentifiedObjects.getName(descriptor, authority);
+                if (name == null) {
+                    name = IdentifiedObjects.getName(descriptor, null);
+                }
+                if (mapping.put(Integer.valueOf(id.getCode()), name) != null) {
+                    throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedIdentifier_1, id));
+                }
+            }
+        }
+        return mapping;
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/SignReversalComment.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -23,7 +23,7 @@ import org.apache.sis.util.iso.AbstractI
 
 
 /**
- * Comments telling whether a parameter value use the same sign or the opposite sign for the inverse operation.
+ * Comments telling whether a parameter value uses the same sign or the opposite sign for the inverse operation.
  * Those comments are used for encoding the {@code PARAM_SIGN_REVERSAL} boolean value in the
  * {@code [Coordinate_Operation Parameter Usage]} table of the EPSG dataset.
  *

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/DefaultParameterValueGroup.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -22,6 +22,7 @@ import java.util.LinkedList;
 import java.util.Map;
 import java.util.IdentityHashMap;
 import java.util.Iterator;
+import java.util.Objects;
 import java.io.Serializable;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
@@ -43,9 +44,6 @@ import org.apache.sis.util.resources.Err
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 
-// Branch-dependent imports
-import java.util.Objects;
-
 
 /**
  * A group of related parameter values. Parameter groups have some similarities with {@code java.util.Map}:
@@ -103,7 +101,7 @@ import java.util.Objects;
  * <p>Calls to {@code values().clear()} restore this {@code DefaultParameterValueGroup} to its initial state.</p>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
- * @version 0.7
+ * @version 0.8
  *
  * @see DefaultParameterDescriptorGroup
  * @see DefaultParameterValue
@@ -283,48 +281,41 @@ public class DefaultParameterValueGroup
      */
     @Override
     ParameterValue<?> parameterIfExist(final String name) throws ParameterNotFoundException {
-        final ParameterValueList values = this.values; // Protect against accidental changes.
+        final ParameterValueList values = this.values;          // Protect against accidental changes.
         /*
-         * Quick search for an exact match. By invoking 'descriptor(i)' instead of 'get(i)',
-         * we avoid the creation of mandatory ParameterValue which was deferred. If we find
-         * a matching name, the ParameterValue will be lazily created (if not already done)
-         * by the call to 'get(i)'.
+         * Search for an exact match. By invoking 'descriptor(i)' instead of 'get(i)', we avoid the
+         * creation of mandatory ParameterValue which was deferred. If we find a matching name, the
+         * ParameterValue will be lazily created (if not already done) by the call to 'get(i)'.
          */
-        final int size = values.size();
-        for (int i=0; i<size; i++) {
-            final GeneralParameterDescriptor descriptor = values.descriptor(i);
-            if (descriptor instanceof ParameterDescriptor<?>) {
-                if (name.equals(descriptor.getName().toString())) {
-                    return (ParameterValue<?>) values.get(i);
-                }
-            }
-        }
-        /*
-         * More costly search, including aliases, before to give up.
-         */
-        int fallback  = -1;
+        int index     = -1;
         int ambiguity = -1;
+        final int size = values.size();
         for (int i=0; i<size; i++) {
             final GeneralParameterDescriptor descriptor = values.descriptor(i);
             if (descriptor instanceof ParameterDescriptor<?>) {
                 if (IdentifiedObjects.isHeuristicMatchForName(descriptor, name)) {
-                    if (fallback < 0) {
-                        fallback = i;
+                    if (index < 0) {
+                        index = i;
                     } else {
                         ambiguity = i;
                     }
                 }
             }
         }
-        if (fallback >= 0) {
-            if (ambiguity < 0) {
-                return (ParameterValue<?>) values.get(fallback);   // May lazily create a ParameterValue.
-            }
-            throw new ParameterNotFoundException(Errors.format(Errors.Keys.AmbiguousName_3,
-                    IdentifiedObjects.toString(values.descriptor(fallback) .getName()),
-                    IdentifiedObjects.toString(values.descriptor(ambiguity).getName()), name), name);
+        if (ambiguity < 0) {
+            return (index >= 0) ? (ParameterValue<?>) values.get(index) : null;     // May lazily create a ParameterValue.
+        }
+        final GeneralParameterDescriptor d1 = values.descriptor(index);
+        final GeneralParameterDescriptor d2 = values.descriptor(ambiguity);
+        final String message;
+        if (d1 == d2) {
+            message = Errors.format(Errors.Keys.MultiOccurenceValueAtIndices_3, name, index, ambiguity);
+        } else {
+            message = Errors.format(Errors.Keys.AmbiguousName_3,
+                        IdentifiedObjects.toString(d1.getName()),
+                        IdentifiedObjects.toString(d2.getName()), name);
         }
-        return null;
+        throw new ParameterNotFoundException(message, name);
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/parameter/Parameters.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -37,15 +37,13 @@ import org.apache.sis.util.ObjectConvert
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.Debug;
 
-import static org.apache.sis.referencing.IdentifiedObjects.isHeuristicMatchForName;
-
 
 /**
  * Convenience methods for fetching parameter values despite the variations in parameter names, value types and units.
  * See {@link DefaultParameterValueGroup} javadoc for a description of the standard way to get and set a particular
  * parameter in a group. The remaining of this javadoc is specific to Apache SIS.
  *
- * <div class="section">Convenience static methods</div>
+ * <div class="section">Convenience methods</div>
  * This class provides the following convenience static methods:
  * <ul>
  *   <li>{@link #cast(ParameterValue, Class) cast(…, Class)} for type safety with parameterized types.</li>
@@ -54,32 +52,8 @@ import static org.apache.sis.referencing
  *   <li>{@link #copy(ParameterValueGroup, ParameterValueGroup)} for copying values into an existing instance.</li>
  * </ul>
  *
- *
- * <div class="section">Fetching parameter values despite different names, types or units</div>
- * The common way to get a parameter is to invoke the {@link #parameter(String)} method.
- * This {@code Parameters} class provides an alternative way, using a {@link ParameterDescriptor} argument
- * instead than a {@code String}. The methods in this class use the additional information provided by the
- * descriptor for choosing a {@code String} argument that the above-cited {@code parameter(String)} method
- * is more likely to know (by giving preference to a {@linkplain DefaultParameterDescriptor#getName() name}
- * or {@linkplain DefaultParameterDescriptor#getAlias() alias} defined by a common
- * {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier#getAuthority() authority}),
- * and for applying type and unit conversions.
- *
- * <div class="note"><b>Example:</b>
- * The same parameter may be known under different names. For example the
- * {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#getSemiMajorAxis()
- * length of the semi-major axis of the ellipsoid} is commonly known as {@code "semi_major"}.
- * But that parameter can also be named {@code "semi_major_axis"}, {@code "earth_radius"} or simply {@code "a"}
- * in other libraries. When fetching parameter values, we do not always know in advance which of the above-cited
- * names is recognized by an arbitrary {@code ParameterValueGroup} implementation.
- *
- * <p>This uncertainty is mitigated with the Apache SIS implementation since
- * {@link DefaultParameterValueGroup#parameter(String)} compares the given {@code String} argument
- * against all parameter's {@linkplain DefaultParameterDescriptor#getAlias() aliases} in addition
- * to the {@linkplain DefaultParameterDescriptor#getName() name}.
- * However we do not have the guarantee that all implementations do that.</p></div>
- *
- * The method names in this class follow the names of methods provided by the {@link ParameterValue} interface.
+ * Most instance methods in this class follow the same naming pattern
+ * than the methods provided by the {@link ParameterValue} interface.
  * Those methods are themselves inspired by JDK methods:
  *
  * <table class="sis">
@@ -95,21 +69,38 @@ import static org.apache.sis.referencing
  * </table>
  *
  *
+ * <div class="section">Fetching parameter values despite different names, types or units</div>
+ * The common way to get a parameter is to invoke the {@link #parameter(String)} method.
+ * This {@code Parameters} class provides alternative ways, using a {@link ParameterDescriptor} argument
+ * instead than a {@code String} argument. Those descriptors provide additional information like the various
+ * {@linkplain DefaultParameterDescriptor#getAlias() aliases} under which the same parameter may be known.
+ * By using this information, {@code Parameters} can choose the most appropriate parameter name or alias
+ * (by searching for a common {@linkplain org.apache.sis.metadata.iso.ImmutableIdentifier#getAuthority() authority})
+ * when it delegates its work to the {@code parameter(String)} method.
+ *
+ * <div class="note"><b>Example:</b>
+ * The same parameter may be known under different names. For example the
+ * {@linkplain org.apache.sis.referencing.datum.DefaultEllipsoid#getSemiMajorAxis()
+ * length of the semi-major axis of the ellipsoid} is commonly known as {@code "semi_major"}.
+ * But that parameter can also be named {@code "semi_major_axis"}, {@code "earth_radius"} or simply {@code "a"}
+ * in other libraries. When fetching parameter values, we do not always know in advance which of the above-cited
+ * names is recognized by an arbitrary {@code ParameterValueGroup} instance.</div>
+ *
+ * {@code Parameters} uses also the descriptor information for applying type and unit conversions
+ * (i.e. returned values are converted to the units of measurement specified by the given parameter descriptor).
+ *
+ *
  * <div class="section">Note for subclass implementors</div>
+ * This class does not implement any method from the {@link ParameterValueGroup} interface
+ * (this class is not named “{@code AbstractParameterValueGroup}” for that reason).
+ * Extending this class or extending {@link Object} make almost no difference for implementors;
+ * {@code Parameters} purpose is mostly to extend the API for users convenience.
  * All methods in this class get their information from the {@link ParameterValueGroup} methods.
- * In addition, each method in this class is isolated from all others: overriding one method has
- * no impact on other methods.
- *
- * <div class="note"><b>Note on this class name:</b>
- * Despite implementing the {@link ParameterValueGroup} interface, this class is not named
- * {@code AbstractParameterValueGroup} because it does not implement any method from the interface.
- * Extending this class or extending {@link Object} make almost no difference for implementors.
- * The intend of this {@code Parameters} class is rather to extend the API with methods
- * that are convenient for the way Apache SIS uses parameters.
- * In other words, this class is intended for users rather than implementors.</div>
+ * In addition, unless otherwise specified, methods in this class is isolated from all others:
+ * overriding one method has no impact on other methods.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.4
  * @module
  */
@@ -347,13 +338,14 @@ public abstract class Parameters impleme
      * If no name or alias for this group's authority can be found, then the primary name will be returned.
      *
      * @param  source  the parameter for which the name is wanted.
-     * @return the name of the given parameter.
+     * @return the name of the given parameter. May be {@code null} if there is no name at all,
+     *         but such nameless descriptors are not legal.
      */
     private String getName(final GeneralParameterDescriptor source) {
         final ParameterDescriptorGroup descriptor = getDescriptor();
-        if (descriptor != null) {   // Paranoiac check (should never be null)
+        if (descriptor != null) {                                   // Paranoiac check (should never be null)
             final Identifier group = descriptor.getName();
-            if (group != null) {    // Paranoiac check (should never be null)
+            if (group != null) {                                    // Paranoiac check (should never be null)
                 final Citation authority = group.getAuthority();
                 final String name = IdentifiedObjects.getName(source, authority);
                 if (name != null || authority == null) {
@@ -372,30 +364,52 @@ public abstract class Parameters impleme
      */
     @SuppressWarnings("null")
     ParameterValue<?> parameterIfExist(final String name) throws ParameterNotFoundException {
-        ParameterValue<?> fallback  = null;
+        int i1 = 0, i2 = 0;
+        ParameterValue<?> first     = null;
         ParameterValue<?> ambiguity = null;
-        for (final GeneralParameterValue value : values()) {
+        final List<GeneralParameterValue> values = values();
+        final int size = values.size();
+        for (int i=0; i<size; i++) {
+            final GeneralParameterValue value = values.get(i);
             if (value instanceof ParameterValue<?>) {
                 final ParameterValue<?> param = (ParameterValue<?>) value;
-                final ParameterDescriptor<?> descriptor = param.getDescriptor();
-                if (name.equals(descriptor.getName().toString())) {
-                    return param;
-                }
-                if (isHeuristicMatchForName(descriptor, name)) {
-                    if (fallback == null) {
-                        fallback = param;
+                if (IdentifiedObjects.isHeuristicMatchForName(param.getDescriptor(), name)) {
+                    if (first == null) {
+                        first = param;
+                        i1 = i;
                     } else {
                         ambiguity = param;
+                        i2 = i;
                     }
                 }
             }
         }
-        if (ambiguity != null) {
-            throw new ParameterNotFoundException(Errors.format(Errors.Keys.AmbiguousName_3,
-                    IdentifiedObjects.toString(fallback .getDescriptor().getName()),
-                    IdentifiedObjects.toString(ambiguity.getDescriptor().getName()), name), name);
+        /*
+         * If there is no ambiguity, we are done. In case of ambiguity we should throw an exception.
+         * However we will not throw the exception if this method is invoked from the getParameter(…)
+         * method of a Parameters instance wrapping a non-SIS implementation. The reason is that for
+         * foreigner implementations, the package-private getParameter(…) method will conservatively
+         * delegate to the public parameter(…) method, in case the implementor overrides it. But for
+         * Apache SIS implementations in this package, we rely on the exception being thrown.
+         *
+         * Note that all classes in this package except UnmodifiableParameterValueGroup override this
+         * method in a way that unconditionally throw the exception.  UnmodifiableParameterValueGroup
+         * is the class that needs the exception to be thrown.
+         */
+        if (ambiguity == null || !isKnownImplementation()) {
+            return first;
+        }
+        final GeneralParameterDescriptor d1 = first    .getDescriptor();
+        final GeneralParameterDescriptor d2 = ambiguity.getDescriptor();
+        final String message;
+        if (d1 == d2) {
+            message = Errors.format(Errors.Keys.MultiOccurenceValueAtIndices_3, name, i1, i2);
+        } else {
+            message = Errors.format(Errors.Keys.AmbiguousName_3,
+                        IdentifiedObjects.toString(d1.getName()),
+                        IdentifiedObjects.toString(d2.getName()), name);
         }
-        return fallback;
+        throw new ParameterNotFoundException(message, name);
     }
 
     /**
@@ -474,6 +488,8 @@ public abstract class Parameters impleme
      *         default value} otherwise (which may be {@code null}).
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      *
+     * @see #getMandatoryValue(ParameterDescriptor)
+     * @see #getOrCreate(ParameterDescriptor)
      * @see DefaultParameterValueGroup#parameter(String)
      * @see DefaultParameterValue#getValue()
      *
@@ -511,6 +527,9 @@ public abstract class Parameters impleme
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      * @throws IllegalStateException if the value is not defined and there is no default value.
      *
+     * @see #getValue(ParameterDescriptor)
+     * @see #getOrCreate(ParameterDescriptor)
+     *
      * @since 0.7
      */
     public <T> T getMandatoryValue(final ParameterDescriptor<T> parameter) throws ParameterNotFoundException {
@@ -693,6 +712,8 @@ public abstract class Parameters impleme
      * @return the requested parameter instance.
      * @throws ParameterNotFoundException if the given {@code parameter} name or alias is not legal for this group.
      *
+     * @see #getValue(ParameterDescriptor)
+     * @see #getMandatoryValue(ParameterDescriptor)
      * @see DefaultParameterValueGroup#parameter(String)
      *
      * @since 0.6

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/parameter/ParametersTest.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -157,7 +157,7 @@ public final strictfp class ParametersTe
         final ParameterValueGroup source = descriptor.createValue();
         final ParameterValueGroup sourceSubgroup = source.addGroup(subgroupName);
         final ParameterValue<?> o1 = sourceSubgroup.parameter("Optional 4");
-        final ParameterValue<?> o2 = o1.getDescriptor().createValue(); // See ParameterFormatTest.testMultiOccurrence()
+        final ParameterValue<?> o2 = o1.getDescriptor().createValue();      // See ParameterFormatTest.testMultiOccurrence()
         sourceSubgroup.parameter("Mandatory 2").setValue(20);
         sourceSubgroup.values().add(o2);
         o1.setValue(40);
@@ -169,8 +169,8 @@ public final strictfp class ParametersTe
          */
         final ParameterValueGroup target = descriptor.createValue();
         final ParameterValueGroup targetSubgroup = target.addGroup(subgroupName);
-        targetSubgroup.parameter("Mandatory 1").setValue(-10);  // We expect this value to be overwritten.
-        targetSubgroup.parameter("Optional 3") .setValue( 30);  // We expect this value to be preserved.
+        targetSubgroup.parameter("Mandatory 1").setValue(-10);      // We expect this value to be overwritten.
+        targetSubgroup.parameter("Optional 3") .setValue( 30);      // We expect this value to be preserved.
         target.parameter("A parent parameter") .setValue("A value to be overwritten");
         /*
          * The actual test.
@@ -179,12 +179,11 @@ public final strictfp class ParametersTe
         assertSame(sourceSubgroup, TestUtilities.getSingleton(source.groups(subgroupName)));
         assertSame(targetSubgroup, TestUtilities.getSingleton(target.groups(subgroupName)));
         assertEquals("A value from the source", target.parameter("A parent parameter").getValue());
-        assertEquals("Mandatory 1", 10, targetSubgroup.parameter("Mandatory 1").intValue());
-        assertEquals("Mandatory 2", 20, targetSubgroup.parameter("Mandatory 2").intValue());
-        assertEquals("Optional 3",  30, targetSubgroup.parameter("Optional 3") .intValue());
-        assertEquals("Optional 4",  40, targetSubgroup.parameter("Optional 4") .intValue());
-        assertEquals("Optional 4 (second occurrence)", 50,
-                ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
+        assertEquals("Mandatory 1",    10, targetSubgroup.parameter("Mandatory 1").intValue());
+        assertEquals("Mandatory 2",    20, targetSubgroup.parameter("Mandatory 2").intValue());
+        assertEquals("Optional 3",     30, targetSubgroup.parameter("Optional 3") .intValue());
+        assertEquals("Optional 4",     40, ((ParameterValue<?>) targetSubgroup.values().get(3)).intValue());
+        assertEquals("Optional 4 bis", 50, ((ParameterValue<?>) targetSubgroup.values().get(4)).intValue());
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Constants.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -47,6 +47,11 @@ public final class Constants extends Sta
     /**
      * The {@value} code space.
      */
+    public static final String GEOTIFF = "GeoTIFF";
+
+    /**
+     * The {@value} code space.
+     */
     public static final String EPSG = "EPSG";
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -535,6 +535,12 @@ public final class Errors extends Indexe
         public static final short MissingValueInColumn_1 = 90;
 
         /**
+         * Can not return a single value for “{0}” because there is at least two occurrences, at
+         * indices {1} and {2}.
+         */
+        public static final short MultiOccurenceValueAtIndices_3 = 173;
+
+        /**
          * Options “{0}” and “{1}” are mutually exclusive.
          */
         public static final short MutuallyExclusiveOptions_2 = 91;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Sat Apr 22 13:50:00 2017
@@ -117,6 +117,7 @@ MissingRequiredModule_1           = This
 MissingValueForOption_1           = Missing value for \u201c{0}\u201d option.
 MissingValueForProperty_1         = Missing value for \u201c{0}\u201d property.
 MissingValueInColumn_1            = Missing value in the \u201c{0}\u201d column.
+MultiOccurenceValueAtIndices_3    = Can not return a single value for \u201c{0}\u201d because there is at least two occurrences, at indices {1} and {2}.
 MutuallyExclusiveOptions_2        = Options \u201c{0}\u201d and \u201c{1}\u201d are mutually exclusive.
 NegativeArgument_2                = Argument \u2018{0}\u2019 shall not be negative. The given value was {1}.
 NegativeArrayLength_1             = Can not create a \u201c{0}\u201d array of negative length.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Sat Apr 22 13:50:00 2017
@@ -114,6 +114,7 @@ MissingRequiredModule_1           = Cett
 MissingValueForOption_1           = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour l\u2019option \u00ab\u202f{0}\u202f\u00bb.
 MissingValueForProperty_1         = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb.
 MissingValueInColumn_1            = Il manque une valeur dans la colonne \u00ab\u202f{0}\u202f\u00bb.
+MultiOccurenceValueAtIndices_3    = Ne peut pas retourner une valeur unique pour \u00ab\u202f{0}\u202f\u00bb parce qu\u2019il y a au moins deux occurrences, aux index {1} et {2}.
 MutuallyExclusiveOptions_2        = Les options \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb sont mutuellement exclusives.
 NegativeArgument_2                = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre n\u00e9gatif. La valeur donn\u00e9e \u00e9tait {1}.
 NegativeArrayLength_1             = Ne peut pas cr\u00e9er un tableau \u00ab\u202f{0}\u202f\u00bb de longueur n\u00e9gative.

Modified: sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-earth-observation/src/main/java/org/apache/sis/storage/earthobservation/LandsatReader.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -511,8 +511,8 @@ final class LandsatReader {
              * Value is "GEOTIFF".
              */
             case "OUTPUT_FORMAT": {
-                if ("GeoTIFF".equalsIgnoreCase(value)) {
-                    value = "GeoTIFF";                      // Because 'metadata.setFormat(…)' is case-sensitive.
+                if (Constants.GEOTIFF.equalsIgnoreCase(value)) {
+                    value = Constants.GEOTIFF;              // Because 'metadata.setFormat(…)' is case-sensitive.
                 }
                 try {
                     metadata.setFormat(value);

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -155,6 +155,11 @@ public final class Resources extends Ind
         public static final short UnexpectedTileCount_3 = 18;
 
         /**
+         * TIFF file “{0}” uses an unknown coordinate reference system.
+         */
+        public static final short UnknownCRS_1 = 22;
+
+        /**
          * Coordinate system kind {0} is unsupported.
          */
         public static final short UnsupportedCoordinateSystemKind_1 = 19;
@@ -168,6 +173,11 @@ public final class Resources extends Ind
          * Unsupported storage location for the “{0}” GeoTIFF value.
          */
         public static final short UnsupportedGeoKeyStorage_1 = 21;
+
+        /**
+         * TIFF file “{0}” uses an unsupported map projection.
+         */
+        public static final short UnsupportedProjectionMethod_1 = 23;
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources.properties [ISO-8859-1] Sat Apr 22 13:50:00 2017
@@ -37,6 +37,8 @@ RandomizedProcessApplied          = A ra
 UnexpectedListOfValues_2          = A single value was expected for the \u201c{0}\u201d key but {1} values have been found.
 UnexpectedParameter_2             = The \u201c{1}\u201d parameter was not expected for the \u201c{0}\u201d projection method.
 UnexpectedTileCount_3             = Found {2} tiles or strips in the \u201c{0}\u201d file while {1} were expected.
+UnknownCRS_1                      = TIFF file \u201c{0}\u201d uses an unknown coordinate reference system.
 UnsupportedCoordinateSystemKind_1 = Coordinate system kind {0} is unsupported.
 UnsupportedGeoKeyDirectory_1      = Version {0}\u00a0of GeoTIFF key directory is not supported.
 UnsupportedGeoKeyStorage_1        = Unsupported storage location for the \u201c{0}\u201d GeoTIFF value.
+UnsupportedProjectionMethod_1     = TIFF file \u201c{0}\u201d uses an unsupported map projection.

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/internal/geotiff/Resources_fr.properties [ISO-8859-1] Sat Apr 22 13:50:00 2017
@@ -42,6 +42,8 @@ RandomizedProcessApplied          = Un p
 UnexpectedListOfValues_2          = Une seule valeur \u00e9tait attendue pour la cl\u00e9 \u00ab\u202f{0}\u202f\u00bb, mais on en a trouv\u00e9es {1}.
 UnexpectedParameter_2             = Le param\u00e8tre \u00ab\u202f{1}\u202f\u00bb est inattendu pour la m\u00e9thode de projection \u00ab\u202f{0}\u202f\u00bb.
 UnexpectedTileCount_3             = {2} tuiles ont \u00e9t\u00e9 trouv\u00e9es dans le fichier \u00ab\u202f{0}\u202f\u00bb alors qu\u2019on en attendait {1}.
+UnknownCRS_1                      = Le fichier TIFF \u00ab\u202f{0}\u202f\u00bb utilise un syst\u00e8me de r\u00e9f\u00e9rence des coordonn\u00e9es inconnu.
 UnsupportedCoordinateSystemKind_1 = Le type de syst\u00e8me de coordonn\u00e9es {0} n\u2019est pas support\u00e9.
 UnsupportedGeoKeyDirectory_1      = La version {0} du r\u00e9pertoire de cl\u00e9s GeoTIFF n\u2019est pas support\u00e9e.
 UnsupportedGeoKeyStorage_1        = La valeur GeoTIFF \u00ab\u202f{0}\u202f\u00bb utilise un mode de stockage non-support\u00e9.
+UnsupportedProjectionMethod_1     = Le fichier TIFF \u00ab\u202f{0}\u202f\u00bb utilise une projection cartographique non-support\u00e9e.

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/CRSBuilder.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -82,6 +82,7 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
 import org.apache.sis.referencing.factory.GeodeticObjectFactory;
 import org.apache.sis.io.TableAppender;
+import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.Debug;
@@ -247,6 +248,13 @@ final class CRSBuilder {
     private Identifier lastName;
 
     /**
+     * {@code true} when an exception has been thrown but this {@code CRSBuilder} already reported a warning,
+     * so there is no need for the caller to report a warning again. {@code CRSBuilder} sometime reports warnings
+     * itself when it can provide a better warning message than what the caller can do.
+     */
+    boolean alreadyReported;
+
+    /**
      * Creates a new builder of coordinate reference systems.
      *
      * @param reader  where to report warnings if any.
@@ -391,6 +399,7 @@ final class CRSBuilder {
             return Integer.parseInt(value.toString());
         } catch (NumberFormatException e) {
             invalidValue(key, value);
+            alreadyReported = true;
             throw e;
         }
     }
@@ -414,6 +423,7 @@ final class CRSBuilder {
             return Double.parseDouble(value.toString());
         } catch (NumberFormatException e) {
             invalidValue(key, value);
+            alreadyReported = true;
             throw e;
         }
     }
@@ -432,6 +442,7 @@ final class CRSBuilder {
         if (value != null) {
             return value;
         }
+        alreadyReported = true;
         throw new NoSuchElementException(missingValue(key));
     }
 
@@ -450,6 +461,7 @@ final class CRSBuilder {
         if (!Double.isNaN(value)) {
             return value;
         }
+        alreadyReported = true;
         throw new NoSuchElementException(missingValue(key));
     }
 
@@ -971,6 +983,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.Ellipsoid);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
@@ -1053,6 +1066,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeodeticDatum);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeodeticDatum));
             }
             case GeoCodes.userDefined: {
@@ -1219,6 +1233,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeographicType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeographicType));
             }
             case GeoCodes.userDefined: {
@@ -1287,6 +1302,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.GeographicType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.GeographicType));
             }
             case GeoCodes.userDefined: {
@@ -1374,6 +1390,7 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.ProjectedCSType);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.ProjectedCSType));
             }
             case GeoCodes.userDefined: {
@@ -1437,6 +1454,7 @@ final class CRSBuilder {
      * @param  linearUnit   the linear unit of easting and northing values.
      * @throws NoSuchElementException if a mandatory value is missing.
      * @throws NumberFormatException if a numeric value was stored as a string and can not be parsed.
+     * @throws ParameterNotFoundException if the GeoTIFF file defines an unexpected map projection parameter.
      * @throws ClassCastException if an object defined by an EPSG code is not of the expected type.
      * @throws FactoryException if an error occurred during objects creation with the factories.
      */
@@ -1446,13 +1464,15 @@ final class CRSBuilder {
         final int epsg = getAsInteger(GeoKeys.Projection);
         switch (epsg) {
             case GeoCodes.undefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.Projection));
             }
             case GeoCodes.userDefined: {
                 final Unit<Angle>         azimuthUnit = createUnit(GeoKeys.AzimuthUnits, (short) 0, Angle.class, Units.DEGREE);
                 final String              type        = getMandatoryString(GeoKeys.CoordTrans);
-                final OperationMethod     method      = operationFactory().getOperationMethod(type);
+                final OperationMethod     method      = operationFactory().getOperationMethod(Constants.GEOTIFF + ':' + type);
                 final ParameterValueGroup parameters  = method.getParameters().createValue();
+                final Map<Integer,String> toNames     = ReferencingUtilities.identifierToName(parameters.getDescriptor(), Citations.GEOTIFF);
                 final Iterator<Map.Entry<Short,Object>> it = geoKeys.entrySet().iterator();
                 while (it.hasNext()) {
                     final Unit<?> unit;
@@ -1465,9 +1485,15 @@ final class CRSBuilder {
                         case GeoKeys.AZIMUTH: unit = azimuthUnit; break;
                         default: continue;
                     }
+                    String paramName = toNames.get(Short.toUnsignedInt(key));
+                    if (paramName == null) {
+                        paramName = GeoKeys.name(key);
+                        throw new ParameterNotFoundException(reader.errors().getString(
+                                Errors.Keys.UnexpectedParameter_1, paramName), paramName);
+                    }
                     final double value = ((Number) entry.getValue()).doubleValue();
                     it.remove();
-                    parameters.parameter("GeoTIFF:" + key).setValue(value, unit);
+                    parameters.parameter(paramName).setValue(value, unit);
                 }
                 final Conversion c = operationFactory().createDefiningConversion(properties(name), method, parameters);
                 lastName = c.getName();
@@ -1546,6 +1572,7 @@ final class CRSBuilder {
         switch (epsg) {
             case GeoCodes.undefined:
             case GeoCodes.userDefined: {
+                alreadyReported = true;
                 throw new NoSuchElementException(missingValue(GeoKeys.VerticalDatum));
             }
             default: {

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStore.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -33,6 +33,7 @@ import org.apache.sis.storage.DataStoreC
 import org.apache.sis.storage.UnsupportedStorageException;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.internal.storage.MetadataBuilder;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.metadata.sql.MetadataStoreException;
 import org.apache.sis.storage.DataStoreClosedException;
 import org.apache.sis.util.resources.Errors;
@@ -107,7 +108,7 @@ public class GeoTiffStore extends DataSt
             final Reader reader = reader();
             final MetadataBuilder builder = reader.metadata;
             try {
-                builder.setFormat("GeoTIFF");
+                builder.setFormat(Constants.GEOTIFF);
             } catch (MetadataStoreException e) {
                 warning(null, e);
             }
@@ -136,7 +137,7 @@ public class GeoTiffStore extends DataSt
     private Reader reader() throws DataStoreException {
         final Reader r = reader;
         if (r == null) {
-            throw new DataStoreClosedException(getLocale(), "GeoTIFF", StandardOpenOption.READ);
+            throw new DataStoreClosedException(getLocale(), Constants.GEOTIFF, StandardOpenOption.READ);
         }
         return r;
     }

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GeoTiffStoreProvider.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -26,6 +26,7 @@ import org.apache.sis.storage.ProbeResul
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.internal.storage.Capabilities;
 import org.apache.sis.internal.storage.Capability;
+import org.apache.sis.internal.util.Constants;
 
 
 /**
@@ -69,7 +70,7 @@ public class GeoTiffStoreProvider extend
      */
     @Override
     public String getShortName() {
-        return "GeoTIFF";
+        return Constants.GEOTIFF;
     }
 
     /**

Modified: sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java?rev=1792288&r1=1792287&r2=1792288&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/ImageFileDirectory.java [UTF-8] Sat Apr 22 13:50:00 2017
@@ -28,6 +28,9 @@ import javax.measure.Unit;
 import javax.measure.quantity.Length;
 import org.opengis.metadata.citation.DateType;
 import org.opengis.util.FactoryException;
+import org.opengis.util.NoSuchIdentifierException;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.internal.geotiff.Resources;
 import org.apache.sis.internal.storage.io.ChannelDataInput;
 import org.apache.sis.storage.DataStoreException;
@@ -1034,10 +1037,16 @@ final class ImageFileDirectory {
             try {
                 metadata.add(helper.build(geoKeyDirectory, numericGeoParameters, asciiGeoParameters));
                 helper.complete(metadata);
-            } catch (ClassCastException e) {
-                reader.owner.warning(null, e);
-            } catch (NumberFormatException | NoSuchElementException e) {
-                // Ignore - a warning with a better message has already been emitted.
+            } catch (NoSuchIdentifierException | ParameterNotFoundException e) {
+                short key = Resources.Keys.UnsupportedProjectionMethod_1;
+                if (e instanceof NoSuchAuthorityCodeException) {
+                    key = Resources.Keys.UnknownCRS_1;
+                }
+                reader.owner.warning(reader.resources().getString(key, reader.owner.getDisplayName()), e);
+            } catch (IllegalArgumentException | NoSuchElementException | ClassCastException e) {
+                if (!helper.alreadyReported) {
+                    reader.owner.warning(null, e);
+                }
             }
             geoKeyDirectory      = null;            // Not needed anymore, so let GC do its work.
             numericGeoParameters = null;



Mime
View raw message