sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 07/15: Port bug fixes from 1.0 development branch to 0.8 branch: - omission of redundant parameters in CoordinateOperation WKT - consolidation of logging messages when SIS_DATA is defined but no EPSG database is available
Date Thu, 21 Jun 2018 09:19:47 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to tag 0.8
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 2841d8723ada03eaa333eecd464b3221350da049
Author: Martin Desruisseaux <desruisseaux@apache.org>
AuthorDate: Sat Nov 4 21:51:32 2017 +0000

    Port bug fixes from 1.0 development branch to 0.8 branch:
    - omission of redundant parameters in CoordinateOperation WKT
    - consolidation of logging messages when SIS_DATA is defined but no EPSG database is available
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sis/branches/0.8@1814325 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sis/internal/referencing/WKTUtilities.java     | 29 +++++++++++++
 .../internal/referencing/provider/Molodensky.java  | 45 ++++++++++++++++++-
 .../apache/sis/referencing/AuthorityFactories.java |  4 +-
 .../factory/ConcurrentAuthorityFactory.java        | 25 +++++++++--
 .../sis/referencing/factory/sql/EPSGFactory.java   | 50 ++++++++++++++++------
 .../sis/referencing/factory/sql/EPSGInstaller.java | 13 +++---
 .../operation/AbstractCoordinateOperation.java     | 21 ++++++++-
 .../DefaultConcatenatedOperationTest.java          |  6 +--
 .../java/org/apache/sis/util/logging/Logging.java  |  5 ++-
 9 files changed, 167 insertions(+), 31 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
index 03bd5b6..0ae34c1 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/WKTUtilities.java
@@ -22,7 +22,9 @@ import javax.measure.quantity.Angle;
 import org.opengis.parameter.ParameterValue;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.GeneralParameterDescriptor;
 import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.cs.CoordinateSystem;
 import org.opengis.referencing.cs.CoordinateSystemAxis;
@@ -46,6 +48,7 @@ import org.apache.sis.measure.Units;
 import org.apache.sis.util.Static;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Vocabulary;
+import org.apache.sis.internal.util.Constants;
 
 
 /**
@@ -246,6 +249,32 @@ public final class WKTUtilities extends Static {
     }
 
     /**
+     * Returns {@code true} if the given parameter is defined in the EPSG code space. We
handle EPSG
+     * parameters in a special way because Apache SIS uses the EPSG geodetic dataset as the
primary
+     * source of coordinate operation definitions.
+     *
+     * <p>We intentionally don't define {@code isEPSG(OperationMethod)} method because
the operation
+     * method may be the inverse of an EPSG method (for example "Inverse of Mercator (variant
A)")
+     * which would not be recognized. Instead, {@code isEPSG(method.getParameters())} should
work.</p>
+     *
+     * @param  descriptor   the parameter or group of parameters to inspect.
+     * @param  ifUndefined  the value to return if the code space is undefined.
+     * @return whether the given parameter is an EPSG parameter.
+     */
+    public static boolean isEPSG(final GeneralParameterDescriptor descriptor, final boolean
ifUndefined) {
+        if (descriptor != null) {
+            final ReferenceIdentifier id = descriptor.getName();
+            if (id != null) {
+                final String cs = id.getCodeSpace();
+                if (cs != null) {
+                    return Constants.EPSG.equalsIgnoreCase(cs);
+                }
+            }
+        }
+        return ifUndefined;
+    }
+
+    /**
      * Returns the WKT type of the given interface.
      *
      * For {@link CoordinateSystem} base type, the returned value shall be one of
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
index f2c82c5..d84075e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/Molodensky.java
@@ -19,6 +19,7 @@ package org.apache.sis.internal.referencing.provider;
 import java.util.Map;
 import java.util.Collections;
 import javax.xml.bind.annotation.XmlTransient;
+import javax.measure.Unit;
 import org.opengis.util.FactoryException;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.parameter.ParameterDescriptor;
@@ -34,9 +35,11 @@ import org.apache.sis.referencing.datum.DefaultEllipsoid;
 import org.apache.sis.referencing.operation.transform.MolodenskyTransform;
 import org.apache.sis.internal.referencing.NilReferencingObject;
 import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.measure.Units;
 import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.Debug;
 
 
@@ -226,6 +229,7 @@ public final class Molodensky extends GeocentricAffineBetweenGeographic
{
         final Ellipsoid target = new Ellipsoid(name, ta, tb, -Δa, -Δf);
         source.other = target;
         target.other = source;
+        source.computeDifferences(values);
         return MolodenskyTransform.createGeodeticTransformation(factory,
                 source, sourceDimensions >= 3,
                 target, targetDimensions >= 3,
@@ -258,7 +262,7 @@ public final class Molodensky extends GeocentricAffineBetweenGeographic
{
     @SuppressWarnings("serial")
     private static final class Ellipsoid extends DefaultEllipsoid {
         /** The EPSG parameter values, or NaN if unspecified. */
-        private final double Δa, Δf;
+        private double Δa, Δf;
 
         /** The ellipsoid for which Δa and Δf are valid. */
         Ellipsoid other;
@@ -270,6 +274,45 @@ public final class Molodensky extends GeocentricAffineBetweenGeographic
{
             this.Δf = Δf;
         }
 
+        /**
+         * Computes Δa and Δf now if not already done and tries to store the result in
the given parameters.
+         * The parameters are set in order to complete them when the user specified the OGC
parameters (axis
+         * lengths) and not the EPSG ones (axis and flattening differences).
+         */
+        void computeDifferences(final Parameters values) {
+            if (Double.isNaN(Δa)) {
+                Δa = super.semiMajorAxisDifference(other);
+                setIfPresent(values, AXIS_LENGTH_DIFFERENCE, Δa, getAxisUnit());
+            }
+            if (Double.isNaN(Δf)) {
+                Δf = super.flatteningDifference(other);
+                setIfPresent(values, FLATTENING_DIFFERENCE, Δf, Units.UNITY);
+            }
+        }
+
+        /**
+         * Tries to set the given parameter values. This method should be invoked only when
completing parameters
+         * without explicit values. This approach complete the work done in {@code DefaultMathTransformFactory},
+         * which already completed the {@code src_semi_major}, {@code src_semi_minor}, {@code
tgt_semi_major} and
+         * {@code tgt_semi_minor} parameters.
+         *
+         * @param  values     the group in which to set the parameter values.
+         * @param  parameter  descriptor of the parameter to set.
+         * @param  value      the new value.
+         * @param  unit       unit of measurement for the new value.
+         */
+        private static void setIfPresent(final Parameters values, final ParameterDescriptor<Double>
parameter,
+                final double value, final Unit<?> unit)
+        {
+            try {
+                values.getOrCreate(parameter).setValue(value, unit);
+            } catch (ParameterNotFoundException | InvalidParameterValueException e) {
+                // Nonn-fatal since this attempt was only for information purpose.
+                Logging.recoverableException(Logging.getLogger(Loggers.COORDINATE_OPERATION),
+                        Molodensky.class, "createMathTransform", e);
+            }
+        }
+
         /** Returns Δa as specified in the parameters if possible, or compute it otherwise.
*/
         @Override public double semiMajorAxisDifference(final org.opengis.referencing.datum.Ellipsoid
target) {
             return (target == other && !Double.isNaN(Δa)) ? Δa : super.semiMajorAxisDifference(target);
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
index 51be16c..f412dc8 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
@@ -194,8 +194,10 @@ final class AuthorityFactories<T extends AuthorityFactory> extends
LazySet<T> {
             message = e.toString();
         }
         final LogRecord record = new LogRecord(isWarning ? Level.WARNING : Level.CONFIG,
message);
+        if (isWarning && !(e instanceof UnavailableFactoryException)) {
+            record.setThrown(e);
+        }
         record.setLoggerName(Loggers.CRS_FACTORY);
-        if (isWarning) record.setThrown(e);
         Logging.log(CRS.class, "getAuthorityFactory", record);
     }
 
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
index 09f5122..8ac3a6d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
@@ -28,6 +28,7 @@ import java.util.IdentityHashMap;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.LogRecord;
+import java.util.logging.Level;
 import java.lang.ref.WeakReference;
 import java.lang.ref.PhantomReference;
 import java.io.PrintWriter;
@@ -50,6 +51,7 @@ import org.apache.sis.util.Disposable;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.collection.Cache;
+import org.apache.sis.internal.simple.SimpleCitation;
 import org.apache.sis.internal.system.ReferenceQueueConsumer;
 import org.apache.sis.internal.system.DelayedExecutor;
 import org.apache.sis.internal.system.DelayedRunnable;
@@ -114,6 +116,12 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
     private static final long DURATION_FOR_LOGGING = 10_000_000L;       // 10 milliseconds.
 
     /**
+     * Sentinel value when {@link #authority} can not be determined because the data access
object
+     * can not be constructed.
+     */
+    private static final Citation UNAVAILABLE = new SimpleCitation("unavailable");
+
+    /**
      * The authority, cached after first requested.
      */
     private transient volatile Citation authority;
@@ -703,7 +711,7 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
     @Override
     public Citation getAuthority() {
         Citation c = authority;
-        if (c == null) try {
+        if (c == null || c == UNAVAILABLE) try {
             final DAO factory = getDataAccess();
             try {
                 /*
@@ -715,8 +723,19 @@ public abstract class ConcurrentAuthorityFactory<DAO extends GeodeticAuthorityFa
                 release("getAuthority", Citation.class, null);
             }
         } catch (FactoryException e) {
-            Logging.unexpectedException(Logging.getLogger(Loggers.CRS_FACTORY),
-                    ConcurrentAuthorityFactory.class, "getAuthority", e);
+            authority = UNAVAILABLE;
+            /*
+             * Use the warning level only on the first failure, then the fine level on all
subsequent failures.
+             * Do not log the stack trace if we failed because of UnavailableFactoryException
since it may be
+             * normal (the EPSG geodetic dataset is optional, even if strongly recommended).
+             */
+            final LogRecord record = new LogRecord(c == null ? Level.WARNING : Level.FINE,
e.getLocalizedMessage());
+            if (!(e instanceof UnavailableFactoryException)) {
+                record.setThrown(e);
+            }
+            record.setLoggerName(Loggers.CRS_FACTORY);
+            Logging.log(ConcurrentAuthorityFactory.class, "getAuthority", record);
+            c = null;
         }
         return c;
     }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
index 860798a..bf9ff38 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
@@ -45,6 +45,7 @@ import org.apache.sis.internal.system.DefaultFactories;
 import org.apache.sis.internal.util.Constants;
 import org.apache.sis.referencing.factory.ConcurrentAuthorityFactory;
 import org.apache.sis.referencing.factory.UnavailableFactoryException;
+import org.apache.sis.util.resources.Messages;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Classes;
@@ -270,7 +271,7 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
                 throw new UnavailableFactoryException(Initializer.unspecified(locale));
             }
         } catch (Exception e) {
-            throw new UnavailableFactoryException(message(e), e);
+            throw new UnavailableFactoryException(canNotUse(e), e);
         }
         dataSource   = ds;
         nameFactory  = factory(NameFactory.class,                "nameFactory",  properties);
@@ -293,12 +294,19 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
     /**
      * Returns the message to put in an {@link UnavailableFactoryException} having the given
exception as its cause.
      */
-    private String message(final Exception e) {
+    private String canNotUse(final Exception e) {
         String message = Exceptions.getLocalizedMessage(e, locale);
         if (message == null) {
             message = Classes.getShortClassName(e);
         }
-        return Resources.forLocale(locale).getString(Resources.Keys.CanNotUseGeodeticParameters_2,
Constants.EPSG, message);
+        return canNotUse(message);
+    }
+
+    /**
+     * Returns the message to put in an {@link UnavailableFactoryException} having the given
cause.
+     */
+    private String canNotUse(final String cause) {
+        return Resources.forLocale(locale).getString(Resources.Keys.CanNotUseGeodeticParameters_2,
Constants.EPSG, cause);
     }
 
     /**
@@ -367,15 +375,18 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
      * See <a href="https://issues.apache.org/jira/browse/LEGAL-183">LEGAL-183</a>
for more information.</p>
      *
      * @param  connection  connection to the database where to create the EPSG schema.
-     * @throws FileNotFoundException if a SQL script has not been found,
-     *         typically because a required resource is not on the classpath.
-     * @throws IOException  if an I/O error occurred while reading a SQL script.
-     * @throws SQLException if an error occurred while writing to the database.
+     * @throws UnavailableFactoryException if installation failed. The exception will have
a
+     *         {@link FileNotFoundException} cause if a SQL script has not been found
+     *         (typically because a required resource is not on the classpath), an
+     *         {@link IOException} if an I/O error occurred while reading a SQL script, or
a
+     *         {@link SQLException} if an error occurred while writing to the database.
      *
      * @see InstallationScriptProvider
      */
-    public synchronized void install(final Connection connection) throws IOException, SQLException
{
+    public synchronized void install(final Connection connection) throws UnavailableFactoryException
{
         ArgumentChecks.ensureNonNull("connection", connection);
+        String    message = null;
+        Exception failure = null;
         try (EPSGInstaller installer = new EPSGInstaller(connection)) {
             final boolean ac = connection.getAutoCommit();
             if (ac) {
@@ -403,9 +414,21 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
                     }
                 }
             } catch (IOException | SQLException e) {
-                installer.logFailure(locale, e);
-                throw e;
+                message = installer.failure(locale, e);
+                failure = e;
             }
+        } catch (SQLException e) {
+            message = Messages.getResources(locale).getString(Messages.Keys.CanNotCreateSchema_1,
Constants.EPSG);
+            failure = e;
+        }
+        if (failure != null) {
+            /*
+             * Derby sometime wraps SQLException into another SQLException.  For making the
stack strace a
+             * little bit simpler, keep only the root cause provided that the exception type
is compatible.
+             */
+            UnavailableFactoryException exception = new UnavailableFactoryException(message,
Exceptions.unwrap(failure));
+            exception.setUnavailableFactory(this);
+            throw exception;
         }
     }
 
@@ -455,7 +478,7 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
                 return newDataAccess(connection, tr);
             } else {
                 connection.close();
-                exception = new UnavailableFactoryException(SQLTranslator.tableNotFound(locale));
+                exception = new UnavailableFactoryException(canNotUse(SQLTranslator.tableNotFound(locale)));
             }
         } catch (Exception e) {                     // Really want to catch all exceptions
here.
             if (connection != null) try {
@@ -463,11 +486,14 @@ public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess>
impl
             } catch (SQLException e2) {
                 e.addSuppressed(e2);
             }
+            if (e instanceof FactoryException) {
+                throw (FactoryException) e;
+            }
             /*
              * Derby sometime wraps SQLException into another SQLException.  For making the
stack strace a
              * little bit simpler, keep only the root cause provided that the exception type
is compatible.
              */
-            exception = new UnavailableFactoryException(message(e), Exceptions.unwrap(e));
+            exception = new UnavailableFactoryException(canNotUse(e), Exceptions.unwrap(e));
         }
         exception.setUnavailableFactory(this);
         throw exception;
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
index 7d611cf..5cb3915 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
@@ -25,7 +25,6 @@ import java.sql.SQLException;
 import java.util.StringTokenizer;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
-import java.util.logging.LogRecord;
 import java.io.BufferedReader;
 import org.apache.sis.util.StringBuilders;
 import org.apache.sis.internal.metadata.sql.ScriptRunner;
@@ -280,18 +279,16 @@ final class EPSGInstaller extends ScriptRunner {
     }
 
     /**
-     * Logs a message reporting the failure to create EPSG database. This method is invoked
when {@link EPSGFactory}
-     * caught an exception. This log completes rather than replaces the exception message
since {@code EPSGFactory}
-     * lets the exception propagate. Another code (for example {@link org.apache.sis.referencing.CRS#forCode(String)})
-     * may catch that exception and log another record with the exception message.
+     * Creates a message reporting the failure to create EPSG database. This method is invoked
when {@link EPSGFactory}
+     * caught an exception. This method completes the exception message with the file name
and line number where the
+     * error occurred, if such information is available.
      */
-    final void logFailure(final Locale locale, final Exception cause) {
+    final String failure(final Locale locale, final Exception cause) {
         String message = Messages.getResources(locale).getString(Messages.Keys.CanNotCreateSchema_1,
EPSG);
         String status = status(locale);
         if (status != null) {
             message = message + ' ' + status;
         }
-        message = Exceptions.formatChainedMessages(locale, message, cause);
-        InstallationScriptProvider.log(new LogRecord(Level.WARNING, message));
+        return Exceptions.formatChainedMessages(locale, message, cause);
     }
 }
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
index c16e1f2..8831d30 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
@@ -53,6 +53,7 @@ import org.apache.sis.util.collection.Containers;
 import org.apache.sis.util.UnsupportedImplementationException;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.parameter.Parameterized;
+import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.referencing.cs.CoordinateSystems;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.operation.transform.MathTransforms;
@@ -64,6 +65,7 @@ import org.apache.sis.internal.referencing.Resources;
 import org.apache.sis.internal.referencing.WKTUtilities;
 import org.apache.sis.internal.metadata.WKTKeywords;
 import org.apache.sis.internal.metadata.MetadataUtilities;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 import org.apache.sis.internal.system.Semaphores;
@@ -963,10 +965,27 @@ check:      for (int isTarget=0; ; isTarget++) {        // 0 == source
check; 1
                 parameters = null;
             }
             if (parameters != null) {
+                /*
+                 * Format the parameter values. Apache SIS uses the EPSG geodetic dataset
as the main source of
+                 * parameter definitions. When a parameter is defined by both OGC and EPSG
with different names,
+                 * the Formatter class is responsible for choosing an appropriate name. But
when the difference
+                 * is more fundamental, we may have duplication. For example in the "Molodensky"
operation, OGC
+                 * uses source and target axis lengths while EPSG uses only difference between
those lengths.
+                 * In this case, OGC and EPSG parameters are defined separately and are redundant.
To simplify
+                 * the CoordinateOperation WKT, we omit non-EPSG parameters when we have
determined that we are
+                 * about to describe an EPSG operation. We could generalize this filtering
to any authority, but
+                 * we don't because few authorities are as complete as EPSG, so other authorities
are more likely
+                 * to mix EPSG or someone else components with their own. Note also that
we don't apply filtering
+                 * on MathTransform WKT neither for more reliable debugging.
+                 */
+                final boolean filter = WKTUtilities.isEPSG(parameters.getDescriptor(), false)
&&   // NOT method.getName()
+                        Constants.EPSG.equalsIgnoreCase(Citations.getCodeSpace(formatter.getNameAuthority()));
                 formatter.newLine();
                 formatter.indent(+1);
                 for (final GeneralParameterValue param : parameters.values()) {
-                    WKTUtilities.append(param, formatter);
+                    if (!filter || WKTUtilities.isEPSG(param.getDescriptor(), true)) {
+                        WKTUtilities.append(param, formatter);
+                    }
                 }
                 formatter.indent(-1);
             }
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
index 7c46ad0..9db7789 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperationTest.java
@@ -43,7 +43,7 @@ import static org.apache.sis.test.TestUtilities.getSingleton;
  * Tests the {@link DefaultConcatenatedOperation} class.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.7
+ * @version 0.8
  * @since   0.7
  * @module
  */
@@ -114,9 +114,7 @@ public final strictfp class DefaultConcatenatedOperationTest extends XMLTestCase
                 "      Axis[“Latitude (B)”, north, Unit[“degree”, 0.017453292519943295]],\n"
+
                 "      Axis[“Ellipsoidal height (h)”, up, Unit[“metre”, 1]]]],\n"
+
                 "  CoordinateOperationStep[“Geographic to geocentric”,\n" +
-                "    Method[“Geographic/geocentric conversions”],\n" +
-                "      Parameter[“semi_major”, 6377397.155, Unit[“metre”, 1]],\n"
+
-                "      Parameter[“semi_minor”, 6356078.962818189, Unit[“metre”, 1]]],\n"
+
+                "    Method[“Geographic/geocentric conversions”]],\n" +         // Omit
non-EPSG parameters for EPSG method.
                 "  CoordinateOperationStep[“Tokyo to JGD2000 (GSI)”,\n" +
                 "    Method[“Geocentric translations”],\n" +
                 "      Parameter[“X-axis translation”, -146.414],\n" +
diff --git a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
index f9f7934..dbbef43 100644
--- a/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
+++ b/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
@@ -241,13 +241,16 @@ public final class Logging extends Static {
      * @param  record  the record where to set the class and method names.
      * @return the record to use for logging the record.
      */
-    static Logger inferCaller(Logger logger, String classe, String method,
+    private static Logger inferCaller(Logger logger, String classe, String method,
             final StackTraceElement[] trace, final LogRecord record)
     {
         for (final StackTraceElement element : trace) {
             /*
              * Search for the first stack trace element with a classname matching the expected
one.
              * We compare against the name of the class given in argument if it was non-null.
+             *
+             * Note: a previous version also compared logger name with package name.
+             * This has been removed because those names are only loosely related.
              */
             final String classname = element.getClassName();
             if (classe != null) {


Mime
View raw message