sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1730004 - in /sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing: AuthorityFactories.java CRS.java factory/ConcurrentAuthorityFactory.java factory/UnavailableFactoryException.java factory/sql/EPSGFactory.java
Date Fri, 12 Feb 2016 12:13:07 GMT
Author: desruisseaux
Date: Fri Feb 12 12:13:07 2016
New Revision: 1730004

URL: http://svn.apache.org/viewvc?rev=1730004&view=rev
Log:
On failure to get a connection to the EPSG database, log the problem only once before to use
the fallback.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/UnavailableFactoryException.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java?rev=1730004&r1=1730003&r2=1730004&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java
[UTF-8] Fri Feb 12 12:13:07 2016
@@ -19,6 +19,7 @@ package org.apache.sis.referencing;
 import java.util.ServiceLoader;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
+import java.sql.SQLTransientException;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.cs.CSAuthorityFactory;
@@ -30,6 +31,7 @@ import org.apache.sis.internal.system.Lo
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.referencing.factory.MultiAuthoritiesFactory;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.referencing.factory.sql.EPSGFactory;
 import org.apache.sis.util.logging.Logging;
 
@@ -108,9 +110,7 @@ final class AuthorityFactories<T extends
             if (factory == null) try {
                 factory = new EPSGFactory(null);
             } catch (FactoryException e) {
-                final LogRecord record = new LogRecord(Level.CONFIG, e.getLocalizedMessage());
-                record.setLoggerName(Loggers.CRS_FACTORY);
-                Logging.log(CRS.class, "getAuthorityFactory", record);
+                log(Level.CONFIG, e);
                 factory = EPSGFactoryFallback.INSTANCE;
             }
             EPSG[0] = factory;
@@ -119,13 +119,49 @@ final class AuthorityFactories<T extends
     }
 
     /**
-     * Returns the EPSG factory. This method tries to instantiate an {@link EPSGFactory}
if possible,
-     * or an {@link EPSGFactoryFallback} otherwise.
+     * Returns the fallback to use if the authority factory is not available. Unless the
problem may be temporary,
+     * this method replaces the {@link EPSGFactory} instance by {@link EPSGFactoryFallback}
in order to prevent
+     * the same exception to be thrown and logged on every calls to {@link CRS#forCode(String)}.
+     */
+    static CRSAuthorityFactory fallback(final UnavailableFactoryException e) throws UnavailableFactoryException
{
+        final boolean isTransient = (e.getCause() instanceof SQLTransientException);
+        final AuthorityFactory unavailable = e.getUnavailableFactory();
+        final CRSAuthorityFactory factory;
+        synchronized (EPSG) {
+            if (unavailable != EPSG[0]) {
+                throw e;                                // Exception did not come from a
factory that we control.
+            }
+            factory = EPSGFactoryFallback.INSTANCE;
+            if (!isTransient) {
+                ALL.reload();
+                EPSG[0] = factory;
+            }
+        }
+        log(Level.WARNING, e);
+        return factory;
+    }
+
+    /**
+     * Logs the given exception at the given level. This method pretends that the logging
come from
+     * {@link CRS#getAuthorityFactory(String)}, which is the public facade for {@link #EPSG()}.
+     */
+    private static void log(final Level level, final Exception e) {
+        final LogRecord record = new LogRecord(level, e.getLocalizedMessage());
+        record.setLoggerName(Loggers.CRS_FACTORY);
+        Logging.log(CRS.class, "getAuthorityFactory", record);
+    }
+
+    /**
+     * Invoked by {@link LazySet} for adding the EPSG factory before any other factory fetched
by {@code ServiceLoader}.
+     * We put the EPSG factory first because it is often used anyway even for {@code CRS}
and {@code AUTO} namespaces.
+     *
+     * <p>This method tries to instantiate an {@link EPSGFactory} if possible,
+     * or an {@link EPSGFactoryFallback} otherwise.</p>
      */
     @Override
     @SuppressWarnings("unchecked")
     protected T[] initialValues() {
-        EPSG();                         // Force creation of EPSG factory if not already
done.
+        EPSG();                         // Force EPSGFactory instantiation if not already
done.
         return (T[]) EPSG;
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1730004&r1=1730003&r2=1730004&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
[UTF-8] Fri Feb 12 12:13:07 2016
@@ -51,6 +51,7 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.crs.DefaultVerticalCRS;
 import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.Static;
@@ -148,7 +149,11 @@ public final class CRS extends Static {
             throws NoSuchAuthorityCodeException, FactoryException
     {
         ArgumentChecks.ensureNonNull("code", code);
-        return AuthorityFactories.ALL.createCoordinateReferenceSystem(code);
+        try {
+            return AuthorityFactories.ALL.createCoordinateReferenceSystem(code);
+        } catch (UnavailableFactoryException e) {
+            return AuthorityFactories.fallback(e).createCoordinateReferenceSystem(code);
+        }
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java?rev=1730004&r1=1730003&r2=1730004&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/ConcurrentAuthorityFactory.java
[UTF-8] Fri Feb 12 12:13:07 2016
@@ -386,8 +386,10 @@ public abstract class ConcurrentAuthorit
                 if (usage == null) {
                     final DAO factory = newDataAccess();
                     if (factory == null) {
-                        throw new UnavailableFactoryException(Errors.format(
+                        UnavailableFactoryException e = new UnavailableFactoryException(Errors.format(
                                 Errors.Keys.FactoryNotFound_1, GeodeticAuthorityFactory.class));
+                        e.setUnavailableFactory(this);
+                        throw e;
                     }
                     usage = new DataAccessRef<>(factory);
                 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/UnavailableFactoryException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/UnavailableFactoryException.java?rev=1730004&r1=1730003&r2=1730004&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/UnavailableFactoryException.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/UnavailableFactoryException.java
[UTF-8] Fri Feb 12 12:13:07 2016
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.referencing.factory;
 
+import org.opengis.referencing.AuthorityFactory;
+
 
 /**
  * Thrown when a factory can not be created because a resource is missing.
@@ -27,7 +29,7 @@ package org.apache.sis.referencing.facto
  * By contrast, {@link MissingFactoryResourceException} means that at least one particular
object
  * can not be created, but other objects may be okay.
  *
- * @author  Martin Desruisseaux (IRD)
+ * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.7
  * @version 0.7
  * @module
@@ -41,6 +43,11 @@ public class UnavailableFactoryException
     private static final long serialVersionUID = -661925454228937249L;
 
     /**
+     * The factory that can not perform its work, or {@code null} if unknown.
+     */
+    private AuthorityFactory factory;
+
+    /**
      * Construct an exception with no detail message.
      */
     public UnavailableFactoryException() {
@@ -69,4 +76,33 @@ public class UnavailableFactoryException
     public UnavailableFactoryException(String message, Throwable cause) {
         super(message, cause);
     }
+
+    /**
+     * Specifies which factory is unavailable. This information can be provided when the
exception occurred
+     * at some later stage <em>after</em> the factory construction (never inside
the factory constructor),
+     * for example the first time that the factory tried to create an object.
+     *
+     * <div class="note"><b>Example:</b>
+     * {@link org.apache.sis.referencing.factory.sql.EPSGFactory} may have been successfully
created with
+     * a valid {@link javax.sql.DataSource}. But the call to {@link javax.sql.DataSource#getConnection()}
+     * happens only later (the first time that user invokes a method requiring a search in
the database).
+     * In case of failure to connect to the database, user may discover late that the factory
is actually
+     * unavailable. User may want to be informed about which factory is unavailable, for
example in order
+     * to remove it from the list of factory managed by {@link MultiAuthoritiesFactory}.</div>
+     *
+     * @param factory The factory which is unavailable.
+     */
+    public void setUnavailableFactory(final AuthorityFactory factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * Returns the factory which has been found unavailable, or {@code null} if unspecified.
+     * See {@link #setUnavailableFactory(AuthorityFactory)} for more details.
+     *
+     * @return The factory that should be considered as unavailable.
+     */
+    public AuthorityFactory getUnavailableFactory() {
+        return factory;
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1730004&r1=1730003&r2=1730004&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
[UTF-8] Fri Feb 12 12:13:07 2016
@@ -402,6 +402,7 @@ public class EPSGFactory extends Concurr
      */
     @Override
     protected EPSGDataAccess newDataAccess() throws FactoryException {
+        UnavailableFactoryException exception;
         Connection connection = null;
         try {
             connection = dataSource.getConnection();
@@ -424,17 +425,20 @@ public class EPSGFactory extends Concurr
             }
             if (tr.isTableFound()) {
                 return newDataAccess(connection, tr);
+            } else {
+                connection.close();
+                exception = new UnavailableFactoryException(SQLTranslator.tableNotFound(locale));
             }
-            connection.close();
         } catch (Exception e) {                     // Really want to catch all exceptions
here.
             if (connection != null) try {
                 connection.close();
             } catch (SQLException e2) {
                 e.addSuppressed(e2);
             }
-            throw new UnavailableFactoryException(e.getLocalizedMessage(), e);
+            exception = new UnavailableFactoryException(e.getLocalizedMessage(), e);
         }
-        throw new UnavailableFactoryException(SQLTranslator.tableNotFound(locale));
+        exception.setUnavailableFactory(this);
+        throw exception;
     }
 
     /**



Mime
View raw message