sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1728238 [2/2] - in /sis/branches/JDK7: ./ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ core/sis-metadata/src/test/java/org/apache/sis/internal/metad...
Date Tue, 02 Feb 2016 23:39:20 GMT
Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -18,11 +18,14 @@ package org.apache.sis.referencing.facto
 
 import java.util.Collections;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.TimeUnit;
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
 import javax.sql.DataSource;
-import java.util.concurrent.TimeUnit;
+import java.io.IOException;
 import org.opengis.util.NameFactory;
 import org.opengis.util.FactoryException;
 import org.opengis.referencing.crs.CRSFactory;
@@ -41,6 +44,10 @@ import org.apache.sis.referencing.factor
 import org.apache.sis.referencing.factory.UnavailableFactoryException;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Localized;
+import org.apache.sis.util.ObjectConverters;
+
+// Branch-dependent imports
+import java.nio.file.Path;
 
 
 /**
@@ -48,7 +55,19 @@ import org.apache.sis.util.Localized;
  * when first needed using the {@link DataSource} specified at construction time. The geodetic objects are cached
  * for reuse and the idle connections are closed after a timeout.
  *
- * <div class="section">Note for subclasses</div>
+ * <p>If no data source has been specified to the constructor, then {@code EPSGFactory} searches for a
+ * default data source in JNDI, or in the directory given by the {@code SIS_DATA} environment variable,
+ * or in the directory given by the {@code "derby​.system​.home"} property, in that order.
+ * See the {@linkplain org.apache.sis.referencing.factory.sql package documentation} for more information.</p>
+ *
+ * <div class="section">EPSG dataset installation</div>
+ * This class tries to automatically detect the schema that contains the EPSG tables
+ * (see {@link SQLTranslator} for examples of tables to look for). If the tables are not found,
+ * then the {@link #install(Connection)} method will be invoked for creating the EPSG schema.
+ * The {@code install(…)} method can perform its work only if the definition files are reachable
+ * on the classpath, or if the directory containing the files have been specified.
+ *
+ * <div class="section">Data Access Object (DAO)</div>
  * If there is no cached object for a given code, then {@code EPSGFactory} creates an {@link EPSGDataAccess} instance
  * for performing the actual creation work. Developers who need to customize the geodetic object creation can override
  * the {@link #newDataAccess(Connection, SQLTranslator)} method in order to return their own {@link EPSGDataAccess}
@@ -58,6 +77,9 @@ import org.apache.sis.util.Localized;
  * @since   0.7
  * @version 0.7
  * @module
+ *
+ * @see EPSGDataAccess
+ * @see SQLTranslator
  */
 public class EPSGFactory extends ConcurrentAuthorityFactory<EPSGDataAccess> implements CRSAuthorityFactory,
         CSAuthorityFactory, DatumAuthorityFactory, CoordinateOperationAuthorityFactory, Localized
@@ -110,6 +132,32 @@ public class EPSGFactory extends Concurr
     protected final MathTransformFactory mtFactory;
 
     /**
+     * The name of the catalog that contains the EPSG tables, or {@code null} or an empty string.
+     * <ul>
+     *   <li>The {@code ""} value retrieves the EPSG schema without a catalog.</li>
+     *   <li>The {@code null} value means that the catalog name should not be used to narrow the search.</li>
+     * </ul>
+     */
+    private final String catalog;
+
+    /**
+     * The name of the schema that contains the EPSG tables, or {@code null} or an empty string.
+     * <ul>
+     *   <li>The {@code ""} value retrieves the EPSG tables without a schema.
+     *       In such case, table names are prefixed by {@value SQLTranslator#TABLE_PREFIX}.</li>
+     *   <li>The {@code null} value means that the schema name should not be used to narrow the search.
+     *       In such case, {@link SQLTranslator} will tries to automatically detect the schema.</li>
+     * </ul>
+     */
+    private final String schema;
+
+    /**
+     * The path where to search for EPSG definition files if {@code EPSGFactory} needs to create the database,
+     * or {@code null} for searching in the {@linkplain Class#getResource(String) resources} instead.
+     */
+    private final Path scriptDirectory;
+
+    /**
      * The translator from the SQL statements using MS-Access dialect to SQL statements using the dialect
      * of the actual database. If null, will be created when first needed.
      */
@@ -120,76 +168,121 @@ public class EPSGFactory extends Concurr
      *
      * @see #getLocale()
      */
-    private volatile Locale locale;
+    private final Locale locale;
 
     /**
-     * Creates a factory using the default data source and object factories.
-     * Invoking this constructor is equivalent to invoking the constructor below with a all arguments set to null.
+     * Creates a factory using the given configuration. The properties recognized by this constructor
+     * are listed in the table below. Any property not listed below will be ignored by this constructor.
+     * All properties are optional and can {@code null} or omitted, in which case default values are used.
+     * Those default values are implementation-specific and may change in any future SIS version.
      *
-     * @throws FactoryException if the data source can not be obtained.
-     */
-    public EPSGFactory() throws FactoryException {
-        this(null, null, null, null, null, null, null, null);
-    }
-
-    /**
-     * Creates a factory using the given data source and object factories.
+     * <table class="sis">
+     *  <caption>Recognized properties</caption>
+     *  <tr>
+     *   <th>Key</th>
+     *   <th>Value class</th>
+     *   <th>Description</th>
+     *  </tr><tr>
+     *   <td>{@code dataSource}</td>
+     *   <td>{@link DataSource}</td>
+     *   <td>The factory to use for creating {@link Connection}s to the EPSG database.</td>
+     *  </tr><tr>
+     *   <td>{@code nameFactory}</td>
+     *   <td>{@link NameFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.util.GenericName} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code datumFactory}</td>
+     *   <td>{@link DatumAuthorityFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.referencing.datum.Datum} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code csFactory}</td>
+     *   <td>{@link CSAuthorityFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.referencing.cs.CoordinateSystem} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code crsFactory}</td>
+     *   <td>{@link CRSAuthorityFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.referencing.crs.CoordinateReferenceSystem} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code copFactory}</td>
+     *   <td>{@link CoordinateOperationAuthorityFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.referencing.operation.CoordinateOperation} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code mtFactory}</td>
+     *   <td>{@link MathTransformFactory}</td>
+     *   <td>The factory to use for creating {@link org.opengis.referencing.operation.MathTransform} instances.</td>
+     *  </tr><tr>
+     *   <td>{@code catalog}</td>
+     *   <td>{@link String}</td>
+     *   <td>The database catalog that contains the EPSG schema (see {@linkplain #install install}).</td>
+     *  </tr><tr>
+     *   <td>{@code schema}</td>
+     *   <td>{@link String}</td>
+     *   <td>The database schema that contains the EPSG tables (see {@linkplain #install install}).</td>
+     *  </tr><tr>
+     *   <td>{@code scriptDirectory}</td>
+     *   <td>{@link java.nio.file.Path}, {@link java.io.File} or {@link java.net.URL}</td>
+     *   <td>The directory that contains the EPSG definition files (see {@linkplain #install install}).</td>
+     *  </tr><tr>
+     *   <td>{@code locale}</td>
+     *   <td>{@link Locale}</td>
+     *   <td>The locale for producing error messages on a <cite>best effort</cite> basis.</td>
+     *  </tr>
+     * </table>
      *
-     * <div class="section">Default argument values</div>
-     * Any or all arguments given to this constructor can be {@code null}, in which case default values are used.
-     * Those default values are implementation-specific and may change in any future SIS version.
+     * <p>Default values</p>
+     * <ul>
+     *   <li>If no {@code dataSource} is specified, this constructor defaults to the search algorithm described
+     *       in the {@linkplain org.apache.sis.referencing.factory.sql package documentation}.</li>
+     *   <li>If no {@code catalog} or {@code schema} is specified, {@link SQLTranslator} will try to auto-detect
+     *       the schema that contains the EPSG tables.</li>
+     *   <li>If no {@code locale} is specified, this constructor defaults to the
+     *       {@linkplain Locale#getDefault(Locale.Category) display locale}.</li>
+     * </ul>
      *
-     * @param dataSource    The factory to use for creating {@link Connection}s to the EPSG database.
-     * @param nameFactory   The factory to use for creating {@link org.opengis.util.GenericName} instances.
-     * @param datumFactory  The factory to use for creating {@link Datum} instances.
-     * @param csFactory     The factory to use for creating {@link CoordinateSystem} instances.
-     * @param crsFactory    The factory to use for creating {@link CoordinateReferenceSystem} instances.
-     * @param copFactory    The factory to use for creating {@link CoordinateOperation} instances.
-     * @param mtFactory     The factory to use for creating {@link MathTransform} instances.
-     * @param translator    The translator from the SQL statements using MS-Access dialect to SQL statements
-     *                      using the dialect of the actual database.
+     * @param  properties The data source, authority factories and other configuration properties,
+     *                    or {@code null} for the default values.
+     * @throws ClassCastException if a property value is not of the expected class.
+     * @throws IllegalArgumentException if a property value is invalid.
      * @throws FactoryException if an error occurred while creating the EPSG factory.
      */
-    public EPSGFactory(final DataSource                 dataSource,
-                       final NameFactory                nameFactory,
-                       final DatumFactory               datumFactory,
-                       final CSFactory                  csFactory,
-                       final CRSFactory                 crsFactory,
-                       final CoordinateOperationFactory copFactory,
-                       final MathTransformFactory       mtFactory,
-                       final SQLTranslator              translator)
-            throws FactoryException
-    {
+    public EPSGFactory(Map<String,?> properties) throws FactoryException {
         super(EPSGDataAccess.class);
-        if (dataSource != null) {
-            this.dataSource = dataSource;
-        } else try {
-            this.dataSource = Initializer.getDataSource();
-            if (this.dataSource == null) {
-                throw new UnavailableFactoryException(Initializer.unspecified(null));
+        if (properties == null) {
+            properties = Collections.emptyMap();
+        }
+        DataSource ds   = (DataSource) properties.get("dataSource");
+        Locale locale   = ObjectConverters.convert(properties.get("locale"),  Locale.class);
+        schema          = ObjectConverters.convert(properties.get("schema"),  String.class);
+        catalog         = ObjectConverters.convert(properties.get("catalog"), String.class);
+        scriptDirectory = ObjectConverters.convert(properties.get("scriptDirectory"), Path.class);
+        if (locale == null) {
+            locale = Locale.getDefault(Locale.Category.DISPLAY);
+        }
+        this.locale = locale;
+        if (ds == null) try {
+            ds = Initializer.getDataSource();
+            if (ds == null) {
+                throw new UnavailableFactoryException(Initializer.unspecified(locale));
             }
         } catch (Exception e) {
             throw new UnavailableFactoryException(e.getLocalizedMessage(), e);
         }
-        this.nameFactory  = factory(NameFactory.class, nameFactory);
-        this.datumFactory = factory(DatumFactory.class, datumFactory);
-        this.csFactory    = factory(CSFactory.class, csFactory);
-        this.crsFactory   = factory(CRSFactory.class, crsFactory);
-        this.copFactory   = factory(CoordinateOperationFactory.class, copFactory);
-        this.mtFactory    = factory(MathTransformFactory.class, mtFactory);
-        this.translator   = translator;
-        this.locale       = Locale.getDefault(Locale.Category.DISPLAY);
+        dataSource   = ds;
+        nameFactory  = factory(NameFactory.class,                "nameFactory",  properties);
+        datumFactory = factory(DatumFactory.class,               "datumFactory", properties);
+        csFactory    = factory(CSFactory.class,                  "csFactory",    properties);
+        crsFactory   = factory(CRSFactory.class,                 "crsFactory",   properties);
+        copFactory   = factory(CoordinateOperationFactory.class, "copFactory",   properties);
+        mtFactory    = factory(MathTransformFactory.class,       "mtFactory",    properties);
         super.setTimeout(10, TimeUnit.SECONDS);
     }
 
     /**
-     * Returns the given factory if non-null, or the default factory instance otherwise.
+     * Returns the factory for the given key if it exists, or the default factory instance otherwise.
      */
-    private static <F> F factory(final Class<F> type, F factory) {
-        if (factory == null) {
-            factory = DefaultFactories.forBuildin(type);
-        }
-        return factory;
+    private static <F> F factory(final Class<F> type, final String key, final Map<String,?> properties) {
+        final F factory = type.cast(properties.get(key));
+        return (factory != null) ? factory : DefaultFactories.forBuildin(type);
     }
 
     /**
@@ -214,15 +307,80 @@ public class EPSGFactory extends Concurr
     }
 
     /**
-     * Sets the locale to use for producing error messages.
-     * The given locale will be honored on a <cite>best effort</cite> basis.
-     * It does not change the way data are read from the EPSG database.
+     * Creates the EPSG schema in the database and populates the tables with geodetic definitions.
+     * This method is invoked automatically when {@link #newDataAccess()} detects that the EPSG dataset is not installed.
+     * Users can also invoke this method explicitely if they wish to force the dataset installation.
      *
-     * @param locale The new locale to use for error message.
-     */
-    public void setLocale(final Locale locale) {
-        ArgumentChecks.ensureNonNull("locale", locale);
-        this.locale = locale;
+     * <p>This method uses the following properties from the map specified at
+     * {@linkplain #EPSGFactory(Map) construction time}:</p>
+     *
+     * <ul class="verbose">
+     *   <li><b>{@code catalog}:</b><br>
+     *     a {@link String} giving the name of the database catalog where to create the EPSG schema.
+     *     If non-null, that catalog shall exist prior this method call (this method does not create any catalog).
+     *     If no catalog is specified or if the catalog is an empty string,
+     *     then the EPSG schema will be created without catalog.
+     *     If the database does not {@linkplain DatabaseMetaData#supportsCatalogsInTableDefinitions() support
+     *     catalogs in table definitions} or in {@linkplain DatabaseMetaData#supportsCatalogsInDataManipulation()
+     *     data manipulation}, then this property is ignored.</li>
+     *
+     *   <li><b>{@code schema}:</b><br>
+     *     a {@link String} giving the name of the database schema where to create the EPSG tables.
+     *     That schema shall <strong>not</strong> exist prior this method call;
+     *     the schema will be created by this {@code install(…)} method.
+     *     If no schema is specified or if the schema an empty string, then the tables will be created without schema.
+     *     If the database does not {@linkplain DatabaseMetaData#supportsSchemasInTableDefinitions() support
+     *     schemas in table definitions} or in {@linkplain DatabaseMetaData#supportsSchemasInDataManipulation()
+     *     data manipulation}, then this property is ignored.</li>
+     *
+     *   <li><b>{@code scriptDirectory}:</b><br>
+     *     a {@link java.nio.file.Path}, {@link java.io.File} or {@link java.net.URL} to a directory containing
+     *     the SQL scripts to execute. If non-null, that directory shall contain at least files matching the
+     *     {@code *Tables*.sql}, {@code *Data*.sql} and {@code *FKeys*.sql} patterns (those files are provided by EPSG).
+     *     Files matching the {@code *Patches*.sql}, {@code *Indexes*.sql} and {@code *Grant*.sql} patterns
+     *     (provided by Apache SIS) are optional but recommended.
+     *     If no directory is specified, then this method will search for resources provided by the
+     *     {@code geotk-epsg.jar} bundle.</li>
+     * </ul>
+     *
+     * <p><b>Legal constraint:</b>
+     * the EPSG dataset can not be distributed with Apache SIS at this time for licensing reasons.
+     * Users need to either install the dataset manually (for example with the help of this method),
+     * or add on the classpath a non-Apache bundle like {@code geotk-epsg.jar}.
+     * 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 IOException if the SQL script can not be found or an I/O error occurred while reading them.
+     * @throws SQLException if an error occurred while writing to the database.
+     */
+    public synchronized void install(final Connection connection) throws IOException, SQLException {
+        ArgumentChecks.ensureNonNull("connection", connection);
+        try (EPSGInstaller installer = new EPSGInstaller(connection)) {
+            final boolean ac = connection.getAutoCommit();
+            if (ac) {
+                connection.setAutoCommit(false);
+            }
+            boolean success = false;
+            try {
+                if (schema != null) {
+                    installer.setSchema(schema);
+                }
+                installer.run(scriptDirectory);
+                success = true;
+            } finally {
+                if (ac) {
+                    if (success) {
+                        connection.commit();
+                    } else {
+                        connection.rollback();
+                    }
+                    connection.setAutoCommit(true);
+                }
+                if (!success) {
+                    installer.logFailure(locale);
+                }
+            }
+        }
     }
 
     /**
@@ -230,9 +388,14 @@ public class EPSGFactory extends Concurr
      * This method is invoked automatically when a new worker is required, either because the previous
      * one has been disposed after its timeout or because a new one is required for concurrency.
      *
-     * <p>The default implementation gets a new connection from the {@link #dataSource} and delegates to
-     * {@link #newDataAccess(Connection, SQLTranslator)}, which provides an easier overriding point
-     * for subclasses wanting to return a custom {@link EPSGDataAccess} instance.</p>
+     * <p>The default implementation performs the following steps:</p>
+     * <ol>
+     *   <li>Gets a new connection from the {@link #dataSource}.</li>
+     *   <li>If this method is invoked for the first time, verifies if the EPSG tables exists.
+     *       If the tables are not found, invokes {@link #install(Connection)}.</li>
+     *   <li>Delegates to {@link #newDataAccess(Connection, SQLTranslator)}, which provides an easier
+     *       overriding point for subclasses wanting to return a custom {@link EPSGDataAccess} instance.</li>
+     * </ol>
      *
      * @return Data Access Object (DAO) to use in {@code createFoo(String)} methods.
      * @throws FactoryException if the constructor failed to connect to the EPSG database.
@@ -248,12 +411,23 @@ public class EPSGFactory extends Concurr
                 synchronized (this) {
                     tr = translator;
                     if (tr == null) {
-                        translator = tr = new SQLTranslator(connection.getMetaData());
+                        tr = new SQLTranslator(connection.getMetaData(), catalog, schema);
+                        try {
+                            if (!tr.isTableFound()) {
+                                install(connection);
+                                tr.setup(connection.getMetaData());   // Set only on success.
+                            }
+                        } finally {
+                            translator = tr;        // Set only after installation in order to block other threads.
+                        }
                     }
                 }
             }
-            return newDataAccess(connection, tr);
-        } catch (Exception e) {
+            if (tr.isTableFound()) {
+                return newDataAccess(connection, tr);
+            }
+            connection.close();
+        } catch (Exception e) {                     // Really want to catch all exceptions here.
             if (connection != null) try {
                 connection.close();
             } catch (SQLException e2) {
@@ -261,6 +435,7 @@ public class EPSGFactory extends Concurr
             }
             throw new UnavailableFactoryException(e.getLocalizedMessage(), e);
         }
+        throw new UnavailableFactoryException(SQLTranslator.tableNotFound(locale));
     }
 
     /**

Copied: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java (from r1728236, sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java?p2=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java&p1=sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java&r1=1728236&r2=1728238&rev=1728238&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -41,6 +41,7 @@ import org.apache.sis.util.logging.Perfo
 // Branch-specific imports
 import java.nio.file.Files;
 import java.nio.file.Path;
+import org.apache.sis.internal.jdk8.BiFunction;
 
 
 /**
@@ -157,7 +158,11 @@ final class EPSGInstaller extends Script
             replace(SQLTranslator.TABLE_PREFIX + "supersession",               "Supersession");
             replace(SQLTranslator.TABLE_PREFIX + "unitofmeasure",              "Unit of Measure");
             replace(SQLTranslator.TABLE_PREFIX + "versionhistory",             "Version History");
-            modifyReplacements((String key, String value) -> schema + '.' + identifierQuote + value + identifierQuote);
+            modifyReplacements(new BiFunction<String,String,String>() {
+                @Override public String apply(String key, String value) {
+                    return schema + '.' + identifierQuote + value + identifierQuote;
+                }
+            });
         }
     }
 

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -18,12 +18,10 @@ package org.apache.sis.referencing.facto
 
 import java.util.Map;
 import java.util.HashMap;
-import java.util.Collections;
 import java.util.Locale;
 import java.sql.DatabaseMetaData;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.SQLDataException;
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.resources.Errors;
@@ -57,7 +55,7 @@ import org.apache.sis.internal.jdk8.JDK8
  *   <li>{@code SELECT * FROM "Coordinate Reference System"}</li>
  *   <li>{@code SELECT * FROM epsg_coordinatereferencesystem} (in the default schema)</li>
  *   <li>{@code SELECT * FROM epsg.coordinatereferencesystem} (in the {@code "epsg"} schema)</li>
- *   <li>{@code SELECT * FROM "EPSG"."Coordinate Reference System"}</li>
+ *   <li>{@code SELECT * FROM epsg."Coordinate Reference System"}</li>
  * </ul></div>
  *
  * In addition to the MS-Access format, EPSG also provides the dataset as <cite>Data Description Language</cite> (DDL)
@@ -88,8 +86,8 @@ import org.apache.sis.internal.jdk8.JDK8
  *   <tr><td>Column</td> <td>{@code ORDER}</td>                                 <td>{@code coord_axis_order}</td></tr>
  * </table>
  *
- * This class auto-detects the schema where the EPSG database seems to be located and whether the table names
- * are the ones used by EPSG in the MS-Access version or the PostgreSQL, MySQL or Oracle version of the database.
+ * By default this class auto-detects the schema that contains the EPSG tables and whether the table names are
+ * the ones used by EPSG in the MS-Access version or the PostgreSQL, MySQL or Oracle version of the database.
  * Consequently it is legal to use the MS-Access table names, which are more readable, in a PostgreSQL database.
  *
  * <div class="section">Thread safety</div>
@@ -129,10 +127,34 @@ public class SQLTranslator {
     static final String TABLE_PREFIX = "epsg_";
 
     /**
-     * The name of the schema where the tables are located, or {@code null} if none.
-     * In the later case, table names are prefixed by {@value #TABLE_PREFIX}.
+     * The name of the catalog that contains the EPSG tables, or {@code null} or an empty string.
+     * <ul>
+     *   <li>The {@code ""} value retrieves the EPSG schema without a catalog.</li>
+     *   <li>The {@code null} value means that the catalog name should not be used to narrow the search.</li>
+     * </ul>
+     *
+     * <p><b>Consider this field as final.</b> This field is non-final only for construction convenience,
+     * or for updating after the {@link EPSGInstaller} class created the database.</p>
+     *
+     * @see #getCatalog()
      */
-    private final String schema;
+    private String catalog;
+
+    /**
+     * The name of the schema that contains the EPSG tables, or {@code null} or an empty string.
+     * <ul>
+     *   <li>The {@code ""} value retrieves the EPSG tables without a schema.
+     *       In such case, table names are prefixed by {@value #TABLE_PREFIX}.</li>
+     *   <li>The {@code null} value means that the schema name should not be used to narrow the search.
+     *       In such case, {@code SQLTranslator} will tries to automatically detect the schema.</li>
+     * </ul>
+     *
+     * <p><b>Consider this field as final.</b> This field is non-final only for construction convenience,
+     * or for updating after the {@link EPSGInstaller} class created the database.</p>
+     *
+     * @see #getSchema()
+     */
+    private String schema;
 
     /**
      * Mapping from words used in the MS-Access database to words used in the ANSI versions of EPSG databases.
@@ -148,7 +170,8 @@ public class SQLTranslator {
      * {@code true} if this class needs to quote table names. This quoting should be done only if the database
      * uses the MS-Access table names, even if we are targeting a PostgreSQL, MySQL or Oracle database.
      *
-     * <p><b>Consider this field as final.</b> This field is non-final only for construction convenience.</p>
+     * <p><b>Consider this field as final.</b> This field is non-final only for construction convenience,
+     * or for updating after the {@link EPSGInstaller} class created the database.</p>
      */
     private boolean quoteTableNames;
 
@@ -159,73 +182,138 @@ public class SQLTranslator {
     private final String quote;
 
     /**
-     * Creates a new adapter for the database described by the given metadata.
-     * This constructor:
+     * {@code true} if one of the {@link #SENTINEL} tables exist.
+     * If {@code false}, then {@link EPSGInstaller} needs to be run.
      *
-     * <ul>
-     *   <li>gets the characters to use for quoting identifiers,</li>
-     *   <li>finds the schema where are located the EPSG tables,</li>
-     *   <li>detects if the table names are the ones used in MS-Access database or in the DDL scripts.</li>
-     * </ul>
+     * @see #isTableFound()
+     */
+    private boolean isTableFound;
+
+    /**
+     * Creates a new SQL translator for the database described by the given metadata.
+     * This constructor detects automatically the dialect: the characters to use for quoting identifiers, and whether
+     * the table names are the ones used in the MS-Access database or in the Data Definition Language (DDL) scripts.
      *
-     * <div class="note"><b>API design note:</b>
-     * this constructor is for sub-classing only. Otherwise, instances of {@code SQLTranslator} should not need to be
-     * created explicitely since instantiations are performed automatically by {@link EPSGFactory} when first needed.</div>
+     * <p>If the given catalog or schema name is non-null, then the {@linkplain DatabaseMetaData#getTables
+     * search for EPSG tables} will be restricted to the catalog or schema of that name.
+     * An empty string ({@code ""}) means to search for tables without catalog or schema.
+     * A {@code null} value means that the catalog or schema should not be used to narrow the search.</p>
      *
-     * @param  md Information about the database.
+     * @param  md      Information about the database.
+     * @param  catalog The catalog where to look for EPSG schema, or {@code null} if any.
+     * @param  schema  The schema where to look for EPSG tables, or {@code null} if any.
      * @throws SQLException if an error occurred while querying the database metadata.
      */
-    protected SQLTranslator(final DatabaseMetaData md) throws SQLException {
+    public SQLTranslator(final DatabaseMetaData md, final String catalog, final String schema) throws SQLException {
         ArgumentChecks.ensureNonNull("md", md);
-        quote = md.getIdentifierQuoteString();
-        schema = findSchema(md);
-        if (quoteTableNames) {
-            /*
-             * MS-Access database uses a column named "ORDER" in the "Coordinate Axis" table.
-             * This column has been renamed "coord_axis_order" in DLL scripts.
-             * We need to check which name our current database uses.
-             */
-            try (ResultSet result = md.getColumns(null, schema, "Coordinate Axis", "ORDER")) {
-                if (result.next()) {
-                    accessToAnsi = Collections.emptyMap();
-                } else {
-                    accessToAnsi = Collections.singletonMap("ORDER", "coord_axis_order");
-                }
-            }
-        } else {
-            accessToAnsi = new HashMap<>(4);
-            accessToAnsi.put("ORDER",                "coord_axis_order");     // A column, not a table.
-            accessToAnsi.put("Coordinate_Operation", "coordoperation");
-            accessToAnsi.put("Parameter",            "param");
-        }
-    };
+        quote = md.getIdentifierQuoteString().trim();
+        accessToAnsi = new HashMap<>(4);
+        this.catalog = catalog;
+        this.schema  = schema;
+        setup(md);
+    }
 
     /**
-     * Returns the schema where the EPSG tables seems to be located.
+     * Sets the value of all non-final fields. This method performs two steps:
+     *
+     * <ol class="verbose">
+     *   <li>Finds the schema that seems to contain the EPSG tables. If there is more than one schema containing the
+     *       tables, gives precedence to the schema named "EPSG" if one is found. If there is no schema named "EPSG",
+     *       takes an arbitrary schema. It may be the empty string if the tables are not contained in a schema.</li>
+     *
+     *   <li>Fills the {@link #accessToAnsi} map. That map translates the table and column names used in the SQL
+     *       statements into the names used by the database. Two conventions are understood: the names used in
+     *       the MS-Access database or the names used in the SQL scripts. Both of them are distributed by EPSG.</li>
+     * </ol>
      */
-    private String findSchema(final DatabaseMetaData md) throws SQLException {
+    final void setup(final DatabaseMetaData md) throws SQLException {
         final boolean toUpperCase = md.storesUpperCaseIdentifiers();
         for (int i = SENTINEL.length; --i >= 0;) {
             String table = SENTINEL[i];
             if (toUpperCase && i != MIXED_CASE) {
                 table = table.toUpperCase(Locale.US);
             }
-            try (ResultSet result = md.getTables(null, null, table, null)) {
+            try (ResultSet result = md.getTables(catalog, schema, table, null)) {
                 if (result.next()) {
+                    isTableFound    = true;
                     quoteTableNames = (i == MIXED_CASE);
-                    /*
-                     * If there is more than one schema containing the tables, give precedence to the schema
-                     * named "EPSG" if one is found. If there is no "EPSG" schema, take an arbitrary schema.
-                     */
-                    String schema;
                     do {
-                        schema = result.getString("TABLE_SCHEM");
+                        catalog = result.getString("TABLE_CAT");
+                        schema  = result.getString("TABLE_SCHEM");
                     } while (!Constants.EPSG.equalsIgnoreCase(schema) && result.next());
-                    return schema;
+                    if (schema == null) schema = "";
+                    break;
                 }
             }
         }
-        throw new SQLDataException(Errors.format(Errors.Keys.TableNotFound_1, SENTINEL[MIXED_CASE]));
+        /*
+         * At this point the catalog and schema have been found or confirmed, or are still null
+         * if we did not found them. Now fill the 'accessToAnsi' map.
+         */
+        boolean translateColumns = true;
+        accessToAnsi.clear();
+        if (quoteTableNames) {
+            /*
+             * MS-Access database uses a column named "ORDER" in the "Coordinate Axis" table.
+             * This column has been renamed "coord_axis_order" in DLL scripts.
+             * We need to check which name our current database uses.
+             */
+            try (ResultSet result = md.getColumns(catalog, schema, "Coordinate Axis", "ORDER")) {
+                translateColumns = !result.next();
+            }
+        } else {
+            accessToAnsi.put("Coordinate_Operation", "coordoperation");
+            accessToAnsi.put("Parameter", "param");
+        }
+        if (translateColumns) {
+            accessToAnsi.put("ORDER", "coord_axis_order");
+        }
+    };
+
+    /**
+     * Returns the catalog that contains the EPSG schema. This is the catalog specified at construction time
+     * if it was non-null, or the catalog discovered by the constructor otherwise.
+     * Note that this method may still return {@code null} if the EPSG tables were not found or if the database
+     * does not {@linkplain DatabaseMetaData#supportsCatalogsInDataManipulation() supports catalogs}.
+     *
+     * @return The catalog that contains the EPSG schema, or {@code null}.
+     */
+    public String getCatalog() {
+        return catalog;
+    }
+
+    /**
+     * Returns the schema that contains the EPSG tables. This is the schema specified at construction time
+     * if it was non-null, or the schema discovered by the constructor otherwise.
+     * Note that this method may still return {@code null} if the EPSG tables were not found or if the database
+     * does not {@linkplain DatabaseMetaData#supportsSchemasInDataManipulation() supports schemas}.
+     *
+     * @return The schema that contains the EPSG tables, or {@code null}.
+     */
+    public String getSchema() {
+        return schema;
+    }
+
+    /**
+     * Returns whether the EPSG tables have been found.
+     * If {@code false}, then {@link EPSGInstaller} needs to be run.
+     */
+    final boolean isTableFound() {
+        return isTableFound;
+    }
+
+    /**
+     * Returns the error message for the exception to throw if the EPSG tables are not found and we can not create them.
+     */
+    static String tableNotFound(final Locale locale) {
+        return Errors.getResources(locale).getString(Errors.Keys.TableNotFound_1, SENTINEL[MIXED_CASE]);
+    }
+
+    /**
+     * If the given string is empty, returns {@code null} instead.
+     */
+    private static String nonEmpty(final String s) {
+        return (s != null && !s.isEmpty()) ? s : null;
     }
 
     /**
@@ -236,7 +324,9 @@ public class SQLTranslator {
      * @return The SQL statement adapted to the dialect of the target database.
      */
     public String apply(final String sql) {
-        if (schema == null && accessToAnsi.isEmpty() && quote.trim().isEmpty()) {
+        final String catalog = nonEmpty(this.catalog);
+        final String schema  = nonEmpty(this.schema);
+        if (quote.isEmpty() && accessToAnsi.isEmpty() && schema == null && catalog == null) {
             return sql;
         }
         final StringBuilder ansi = new StringBuilder(sql.length() + 16);
@@ -261,6 +351,9 @@ public class SQLTranslator {
             if (CharSequences.isUpperCase(name)) {
                 ansi.append(JDK8.getOrDefault(accessToAnsi, name, name));
             } else {
+                if (catalog != null) {
+                    ansi.append(quote).append(catalog).append(quote).append('.');
+                }
                 if (schema != null) {
                     ansi.append(quote).append(schema).append(quote).append('.');
                 }

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/package-info.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -17,10 +17,12 @@
 
 /**
  * Factories for geodetic objects defined in a SQL database.
- * Every classes in this package require a connection to a database, which may be on Apache Derby (a.k.a. JavaDB),
- * PostgreSQL or MS-Access. The connection is obtained by the first of the following data sources which is found:
+ * The main class in this package is {@link org.apache.sis.referencing.factory.sql.EPSGFactory},
+ * which requires a {@link javax.sql.DataSource} providing connections to an EPSG database.
+ * By default Apache SIS used Apache Derby (a.k.a. JavaDB), but the database can also be PostgreSQL or MS-Access.
+ * The connection is obtained by the first of the following data sources which is found:
  *
- * <ol>
+ * <ol class="verbose">
  *   <li>If a {@linkplain javax.naming.InitialContext JNDI context} exists,
  *       the {@link javax.sql.DataSource} registered under the {@code "java:comp/env/jdbc/SpatialMetadata"} name.</li>
  *   <li>If the {@code SIS_DATA} {@linkplain System#getenv(String) environment variable} is defined,
@@ -38,12 +40,18 @@
  * A widely-used factory is the <a href="http://www.epsg.org">EPSG geodetic dataset</a>.
  * EPSG codes are numerical identifiers.
  * For example {@code "EPSG::4326"} is the EPSG identifier for the <cite>"WGS 84"</cite> geographic CRS.
- * However, the Apache SIS implementation accepts names as well as numeric identifiers.
- * For example {@code createProjectedCRS("NTF (Paris) / Lambert zone II")} and {@code createProjectedCRS("27572")}
- * both fetch the same object. However names may be ambiguous since the same name may be used for more than one object.
+ * As an extension, the Apache SIS implementation accepts names as well as numeric identifiers.
+ * For example the two following method calls fetch the same object:
+ *
+ * <ul>
+ *   <li>{@code createProjectedCRS("NTF (Paris) / Lambert zone II")}</li>
+ *   <li>{@code createProjectedCRS("27572")}</li>
+ * </ul>
+ *
+ * However names may be ambiguous since the same name may be used for more than one object.
  * This is the case of <cite>"WGS 84"</cite> for example. If such an ambiguity is found, an exception will be thrown.
  *
- * <p>When an error is discovered in a Coordinate Reference System definition, the EPSG group does not apply the
+ * <p>When an error is discovered in a Coordinate Reference System (CRS) definition, the EPSG group does not apply the
  * correction directly on the erroneous object (unless the correction is very minor).
  * Instead, the erroneous object is deprecated and a new one is created.
  * Apache SIS handles deprecated objects as below:</p>
@@ -51,8 +59,7 @@
  * <ul>
  *   <li>Deprecated objects are not listed in the collection returned by the
  *       {@link org.apache.sis.referencing.factory.sql.EPSGDataAccess#getAuthorityCodes getAuthorityCodes(…)} method.</li>
- *   <li>However if the code of a deprecated object is given directly to {@code getAuthorityCodes(…).contains(…)},
- *       {@code getDescriptionText(…)} or any {@code createFoo(…)} method, it will be recognized.</li>
+ *   <li>All method expecting an EPSG code in argument accept also the codes of deprecated objects.</li>
  *   <li>If a deprecated object is created by a call to {@code createFoo(…)}, a warning will be logged
  *       with a message proposing a replacement.</li>
  * </ul>

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2001.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2001.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2001.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2001.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -73,7 +73,7 @@ public final strictfp class GIGS2001 ext
     @BeforeClass
     public static void createFactory() throws FactoryException {
         if (INSTANCE == null) try {
-            INSTANCE = new EPSGFactory();
+            INSTANCE = new EPSGFactory(null);
         } catch (UnavailableFactoryException e) {
             final String message = e.toString();
             if (!message.equals(failure)) {

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -16,9 +16,11 @@
  */
 package org.apache.sis.referencing.factory.sql;
 
+import java.util.Map;
 import java.util.Set;
 import java.util.List;
 import java.util.Locale;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Collections;
 import javax.measure.unit.Unit;
@@ -102,8 +104,12 @@ public final strictfp class EPSGFactoryT
     @BeforeClass
     public static void createFactory() throws FactoryException {
         final GeodeticObjectFactory f = new GeodeticObjectFactory();
+        final Map<String,Object> properties = new HashMap<>(6);
+        assertNull(properties.put("datumFactory", f));
+        assertNull(properties.put("csFactory", f));
+        assertNull(properties.put("crsFactory", f));
         try {
-            factory = new EPSGFactory(null, null, f, f, f, null, null, null);
+            factory = new EPSGFactory(properties);
         } catch (UnavailableFactoryException e) {
             Logging.getLogger(Loggers.CRS_FACTORY).warning(e.toString());
             // Leave INSTANCE to null. This will have the effect of skipping tests.

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java?rev=1728238&r1=1728236&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateOperationMethods.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -49,6 +49,9 @@ import org.apache.sis.util.ArraysExt;
 import org.apache.sis.util.Characters;
 import org.apache.sis.util.Numbers;
 
+// Branch-dependent imports
+import org.apache.sis.internal.jdk8.JDK8;
+
 
 /**
  * Generates a list of projection parameters in a HTML page. This class is used for updating the
@@ -76,15 +79,21 @@ public strictfp class CoordinateOperatio
     public static void main(final String[] args) throws IOException {
         final MathTransformFactory factory = DefaultFactories.forBuildin(MathTransformFactory.class);
         final List<OperationMethod> methods = new ArrayList<>(factory.getAvailableMethods(SingleOperation.class));
-        methods.removeIf((method) -> method.getClass().getName().endsWith("Mock"));
-        Collections.sort(methods, (final OperationMethod o1, final OperationMethod o2) -> {
-            int c = category(o1) - category(o2);
-            if (c == 0) {  // If the two methods are in the same category, sort by name.
-                final String n1 = o1.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
-                final String n2 = o2.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
-                c = n1.compareTo(n2);
+        JDK8.removeIf(methods, new org.apache.sis.internal.jdk8.Predicate<OperationMethod>() {
+            @Override public boolean test(OperationMethod method) {
+                return method.getClass().getName().endsWith("Mock");
+            }
+        });
+        Collections.sort(methods, new java.util.Comparator<OperationMethod>() {
+            @Override public int compare(OperationMethod o1, OperationMethod o2) {
+                int c = category(o1) - category(o2);
+                if (c == 0) {  // If the two methods are in the same category, sort by name.
+                    final String n1 = o1.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
+                    final String n2 = o2.getName().getCode().replace('(',' ').replace(')',' ').replace('_',' ');
+                    c = n1.compareTo(n2);
+                }
+                return c;
             }
-            return c;
         });
         try (final CoordinateOperationMethods writer = new CoordinateOperationMethods()) {
             writer.writeIndex(methods);
@@ -328,7 +337,7 @@ public strictfp class CoordinateOperatio
             writeName(param);
             String remarks = toLocalizedString(param.getRemarks());
             if (remarks != null) {
-                Integer index = footnotes.putIfAbsent(remarks, footnotes.size() + 1);
+                Integer index = JDK8.putIfAbsent(footnotes, remarks, footnotes.size() + 1);
                 if (index == null) {
                     index = footnotes.size();
                 }

Modified: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -201,6 +201,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.factory.IdentifiedObjectFinderTest.class,
     org.apache.sis.referencing.factory.MultiAuthoritiesFactoryTest.class,
     org.apache.sis.referencing.factory.sql.EPSGFactoryTest.class,
+    org.apache.sis.referencing.factory.sql.EPSGInstallerTest.class,
     org.apache.sis.referencing.EPSGFactoryFallbackTest.class,
     org.apache.sis.referencing.AuthorityFactoriesTest.class,
     org.apache.sis.referencing.CRSTest.class,
@@ -217,7 +218,7 @@ import org.junit.BeforeClass;
     org.apache.sis.geometry.CurveExtremumTest.class,
     org.apache.sis.geometry.EnvelopesTest.class,
 
-    org.apache.sis.distance.LatLonPointRadiusTest.class, // Pending refactoring in a geometry package.
+    org.apache.sis.distance.LatLonPointRadiusTest.class,        // Pending refactoring in a geometry package.
 
     org.apache.sis.referencing.operation.builder.LinearTransformBuilderTest.class,
     org.apache.sis.internal.referencing.ServicesForMetadataTest.class,

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/JDK8.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -219,6 +219,22 @@ public final class JDK8 {
     }
 
     /**
+     * Replaces the values for all entries in the given map.
+     *
+     * @param  <K>      The type of keys.
+     * @param  <V>      The type of values.
+     * @param  map      The map from where to replace the values.
+     * @param  function The function performing the value replacements.
+     *
+     * @since 0.7
+     */
+    public static <K,V> void replaceAll(final Map<K,V> map, BiFunction<? super K, ? super V, ? extends V> function) {
+        for (final Map.Entry<K,V> entry : map.entrySet()) {
+            entry.setValue(function.apply(entry.getKey(), entry.getValue()));
+        }
+    }
+
+    /**
      * Atomically computes and stores the value for the given key. This is a substitute for
      * {@link ConcurrentMap#compute(java.lang.Object, java.util.function.BiFunction)}
      * on pre-JDK8 branches.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DataDirectory.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -114,7 +114,7 @@ public enum DataDirectory {
     public static synchronized Path getRootDirectory() {
         if (rootDirectory == null) try {
             final String dir = System.getenv(ENV);
-            if (dir == null) {
+            if (dir == null || dir.isEmpty()) {
                 warning("getRootDirectory", null, Messages.Keys.DataDirectoryNotSpecified_1, ENV);
             } else try {
                 final Path path = Paths.get(dir);

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/MetadataServices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/MetadataServices.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/MetadataServices.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/MetadataServices.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.util;
 
+import java.util.Locale;
 import org.opengis.metadata.citation.Citation;
 import org.apache.sis.internal.simple.CitationConstant;
 import org.apache.sis.internal.system.Modules;
@@ -111,4 +112,23 @@ public class MetadataServices extends Op
     public Citation createCitation(final String key) {
         return null;
     }
+
+    /**
+     * Returns information about the Apache SIS configuration to be reported in {@link org.apache.sis.setup.About}.
+     * This method is invoked only for aspects that depends on other modules than {@code sis-utility}.
+     *
+     * <p>Current keys are:</p>
+     * <ul>
+     *   <li>{@code "EPSG"}: version of EPSG database.</li>
+     * </ul>
+     *
+     * @param  key A key identifying the information to return.
+     * @param  locale Language to use if possible.
+     * @return The information, or {@code null} if none.
+     *
+     * @see org.apache.sis.internal.metadata.ReferencingServices#getInformation(String)
+     */
+    public String getInformation(String key, Locale locale) {
+        return null;
+    }
 }

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/setup/About.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -48,6 +48,8 @@ import org.apache.sis.util.resources.Voc
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTables;
 import org.apache.sis.util.collection.DefaultTreeTable;
+import org.apache.sis.internal.util.MetadataServices;
+import org.apache.sis.internal.util.Constants;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.Shutdown;
@@ -233,6 +235,13 @@ fill:   for (int i=0; ; i++) {
                     break;
                 }
                 case 4: {
+                    if (sections.contains(VERSIONS)) {
+                        nameKey = Vocabulary.Keys.GeodeticDataset;
+                        value = MetadataServices.getInstance().getInformation(Constants.EPSG, locale);
+                    }
+                    break;
+                }
+                case 5: {
                     newSection = LOCALIZATION;
                     if (sections.contains(LOCALIZATION)) {
                         final Locale current = Locale.getDefault();
@@ -247,7 +256,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 5: {
+                case 6: {
                     if (sections.contains(LOCALIZATION)) {
                         final TimeZone current = TimeZone.getDefault();
                         if (current != null) {
@@ -268,7 +277,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 6: {
+                case 7: {
                     if (sections.contains(LOCALIZATION)) {
                         nameKey = Vocabulary.Keys.CurrentDateTime;
                         final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, formatLocale);
@@ -279,7 +288,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 7: {
+                case 8: {
                     if (sections.contains(LOCALIZATION)) {
                         final Charset current = Charset.defaultCharset();
                         if (current != null) {
@@ -299,7 +308,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 8: {
+                case 9: {
                     newSection = LOGGING;
                     if (sections.contains(LOGGING)) {
                         nameKey = Vocabulary.Keys.Implementation;
@@ -308,7 +317,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 9: {
+                case 10: {
                     if (sections.contains(LOGGING)) {
                         nameKey = Vocabulary.Keys.Level;
                         final Level level = Logging.getLogger("").getLevel();   // Root logger level.
@@ -325,7 +334,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 10: {
+                case 11: {
                     newSection = PATHS;
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.UserHome;
@@ -333,14 +342,14 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 11: {
+                case 12: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.CurrentDirectory;
                         value = getProperty("user.dir");
                     }
                     break;
                 }
-                case 12: {
+                case 13: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.DataDirectory;
                         value = System.getenv(DataDirectory.ENV);
@@ -357,21 +366,21 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 13: {
+                case 14: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.TemporaryFiles;
                         value = getProperty("java.io.tmpdir");
                     }
                     break;
                 }
-                case 14: {
+                case 15: {
                     if (sections.contains(PATHS)) {
                         nameKey = Vocabulary.Keys.JavaHome;
                         value = javaHome = getProperty("java.home");
                     }
                     break;
                 }
-                case 15: {
+                case 16: {
                     newSection = LIBRARIES;
                     if (sections.contains(LIBRARIES)) {
                         nameKey = Vocabulary.Keys.JavaExtensions;
@@ -379,7 +388,7 @@ fill:   for (int i=0; ; i++) {
                     }
                     break;
                 }
-                case 16: {
+                case 17: {
                     if (sections.contains(LIBRARIES)) {
                         nameKey = Vocabulary.Keys.Classpath;
                         value = classpath(getProperty("java.class.path"), false);
@@ -546,7 +555,7 @@ pathTree:   for (int j=0; ; j++) {
         for (final Map.Entry<File,CharSequence> entry : files.entrySet()) {
             CharSequence title = entry.getValue();
             if (title != null) {
-                continue; // This file has already been processed by a recursive method invocation.
+                continue;               // This file has already been processed by a recursive method invocation.
             }
             final File file = entry.getKey();
             if (file.isFile() && file.canRead()) {
@@ -570,7 +579,7 @@ pathTree:   for (int j=0; ; j++) {
                             if (classpath(attributes.getValue(Attributes.Name.CLASS_PATH),
                                     file.getParentFile(), false, files))
                             {
-                                break; // Necessary for avoiding ConcurrentModificationException.
+                                break;          // Necessary for avoiding ConcurrentModificationException.
                             }
                         }
                     }
@@ -607,7 +616,7 @@ pathTree:   for (int j=0; ; j++) {
             if (s1 >= 0) {
                 final int s0 = CharSequences.lastIndexOf(name, File.separatorChar, 0, s1) + 1;
                 final StringBuilder buffer = new StringBuilder(s2 - s0).append(name, s0, s2);
-                buffer.setCharAt(s1-s0, '-');
+                buffer.setCharAt(s1 - s0, '-');
                 if (CharSequences.regionMatches(name, s2+1, buffer)) {
                     buffer.setLength(0);
                     node.setValue(NAME, buffer.append(name, 0, s0).append("(…)").append(name, s2, length));

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -276,6 +276,11 @@ public final class Errors extends Indexe
         public static final short EmptyProperty_1 = 23;
 
         /**
+         * An error occurred in file “{0}” at Line {1}.
+         */
+        public static final short ErrorInFileAtLine_2 = 216;
+
+        /**
          * Error in “{0}”: {1}
          */
         public static final short ErrorIn_2 = 190;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -67,6 +67,7 @@ EmptyDictionary                   = The
 EmptyEnvelope2D                   = Envelope must be at least two-dimensional and non-empty.
 EmptyProperty_1                   = Property named \u201c{0}\u201d shall not be empty.
 ErrorIn_2                         = Error in \u201c{0}\u201d: {1}
+ErrorInFileAtLine_2               = An error occurred in file \u201c{0}\u201d at Line {1}.
 ExcessiveArgumentSize_3           = Argument \u2018{0}\u2019 shall not contain more than {1} elements. A number of {2} is excessive.
 ExcessiveListSize_2               = A size of {1} elements is excessive for the \u201c{0}\u201d list.
 ExcessiveNumberOfDimensions_1     = For this algorithm, {0} is an excessive number of dimensions.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -64,6 +64,7 @@ EmptyDictionary                   = Le d
 EmptyEnvelope2D                   = L\u2019enveloppe doit avoir au moins deux dimensions et ne pas \u00eatre vide.
 EmptyProperty_1                   = La propri\u00e9t\u00e9 nomm\u00e9e \u00ab\u202f{0}\u202f\u00bb ne doit pas \u00eatre vide.
 ErrorIn_2                         = Erreur dans \u00ab\u202f{0}\u202f\u00bb\u2008: {1}
+ErrorInFileAtLine_2               = Une erreur est survenue dans le fichier \u00ab\u202f{0}\u202f\u00bb \u00e0 la ligne {1}.
 ExcessiveArgumentSize_3           = L\u2019argument \u2018{0}\u2019 ne peut pas contenir plus de {1} \u00e9l\u00e9ments. Un nombre de {2} est excessif.
 ExcessiveListSize_2               = Une taille de {1} \u00e9l\u00e9ments est excessive pour la liste \u00ab\u202f{0}\u202f\u00bb.
 ExcessiveNumberOfDimensions_1     = Pour cet algorithme, {0} est un trop grand nombre de dimensions.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -67,6 +67,11 @@ public final class Messages extends Inde
         public static final short AmbiguousEllipsoid_1 = 30;
 
         /**
+         * Can not create the {0} schema in database.
+         */
+        public static final short CanNotCreateSchema_1 = 41;
+
+        /**
          * Can not instantiate the object of type ‘{0}’ identified by “{1}”. Reason is:{2}
          */
         public static final short CanNotInstantiateForIdentifier_3 = 35;
@@ -113,6 +118,11 @@ public final class Messages extends Inde
         public static final short CreatedNamedObject_2 = 16;
 
         /**
+         * Creating {0} schema in the “{1}” database.
+         */
+        public static final short CreatingSchema_2 = 39;
+
+        /**
          * {0} dataset version {1} on “{2}” version {3}.
          */
         public static final short DataBase_4 = 28;
@@ -193,6 +203,11 @@ public final class Messages extends Inde
         public static final short IncompleteParsing_1 = 14;
 
         /**
+         * Inserted {0} records in {1} seconds.
+         */
+        public static final short InsertDuration_2 = 40;
+
+        /**
          * No object associated to the “{0}” JNDI name.
          */
         public static final short JNDINotSpecified_1 = 32;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -16,6 +16,7 @@
 #
 AlreadyRegistered_2              = {0} \u201c{1}\u201d is already registered. The second instance will be ignored.
 AmbiguousEllipsoid_1             = Ambiguity between inverse flattening and semi minor axis length for \u201c{0}\u201d. Using inverse flattening.
+CanNotCreateSchema_1             = Can not create the {0} schema in database.
 # In following message, the first characters of parameter {2} should be a line separator ("\r", "\n" or "\r\n").
 CanNotInstantiateForIdentifier_3 = Can not instantiate the object of type \u2018{0}\u2019 identified by \u201c{1}\u201d. Reason is:{2}
 ChangedContainerCapacity_2       = Changed the container capacity from {0} to {1} elements.
@@ -26,6 +27,7 @@ CreatedNamedObject_2             = Creat
 CreatedIdentifiedObject_3        = Created an instance of \u2018{0}\u2019 named \u201c{1}\u201d with the \u201c{2}\u201d identifier.
 CreateDuration_2                 = Created an instance of \u2018{0}\u2019 in {1} seconds.
 CreateDurationFromIdentifier_3   = Created an instance of \u2018{0}\u2019 from the \u201c{1}\u201d identifier in {2} seconds.
+CreatingSchema_2                 = Creating {0} schema in the \u201c{1}\u201d database.
 DataBase_4                       = {0} dataset version {1} on \u201c{2}\u201d version {3}.
 DataDirectory_2                  = Environment variable {0} specifies the \u201c{1}\u201d data directory.
 DataDirectoryDoesNotExist_2      = The {0} environment variable is defined, but the given \u201c{1}\u201d value is not an existing directory.
@@ -41,6 +43,7 @@ IgnoredPropertiesAfterFirst_1    = Ignor
 IgnoredPropertyAssociatedTo_1    = Ignored property associated to \u2018{0}\u2019.
 IgnoredServiceProvider_3         = More than one service provider of type \u2018{0}\u2019 are declared for \u201c{1}\u201d. Only the first provider (an instance of \u2018{2}\u2019) will be used.
 IncompleteParsing_1              = Parsing of \u201c{0}\u201d done, but some elements were ignored.
+InsertDuration_2                 = Inserted {0} records in {1} seconds.
 JNDINotSpecified_1               = No object associated to the \u201c{0}\u201d JNDI name.
 LoadingDatumShiftFile_1          = Loading datum shift file \u201c{0}\u201d.
 LocalesDiscarded                 = Text were discarded for some locales.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -23,6 +23,7 @@
 #
 AlreadyRegistered_2              = Le {0} \u00ab\u202f{1}\u202f\u00bb est d\u00e9j\u00e0 inscrit dans le registre. La seconde instance sera ignor\u00e9e.
 AmbiguousEllipsoid_1             = Ambigu\u00eft\u00e9 entre l\u2019aplatissement et la longueur du semi-axe mineur pour \u00ab\u202f{0}\u202f\u00bb. Utilise l\u2019aplatissement.
+CanNotCreateSchema_1             = Ne peut pas cr\u00e9er le sch\u00e9ma {0} dans la base de donn\u00e9es.
 # In following message, the first characters of parameter {2} should be a line separator ("\r", "\n" or "\r\n").
 CanNotInstantiateForIdentifier_3 = Ne peut pas cr\u00e9er l\u2019objet de type \u2018{0}\u2019 identifi\u00e9 par \u00ab\u202f{1}\u202f\u00bb. La raison est\u00a0:{2}
 ChangedContainerCapacity_2       = Changement de la capacit\u00e9 du conteneur de {0} vers {1} \u00e9l\u00e9ments.
@@ -33,6 +34,7 @@ CreatedNamedObject_2             = Cr\u0
 CreatedIdentifiedObject_3        = Cr\u00e9ation d\u2019une instance de \u2018{0}\u2019 nomm\u00e9e \u00ab\u202f{1}\u202f\u00bb avec l\u2019identifiant \u00ab\u202f{2}\u202f\u00bb.
 CreateDuration_2                 = Cr\u00e9ation d\u2019une instance de \u2018{0}\u2019 en {1} secondes.
 CreateDurationFromIdentifier_3   = Cr\u00e9ation d\u2019une instance de \u2018{0}\u2019 \u00e0 partir de l\u2019identifiant \u00ab\u202f{1}\u202f\u00bb en {2} secondes.
+CreatingSchema_2                 = Cr\u00e9ation du sch\u00e9ma {0} dans la base de donn\u00e9es \u00ab\u202f{1}\u202f\u00bb.
 DataBase_4                       = Base de donn\u00e9es {0} version {1} sur \u00ab\u202f{2}\u202f\u00bb version {3}.
 DataDirectory_2                  = La variable environnementale {0} sp\u00e9cifie le r\u00e9pertoire de donn\u00e9es \u00ab\u202f{1}\u202f\u00bb.
 DataDirectoryDoesNotExist_2      = La variable environnementale {0} est bien d\u00e9finie, mais sa valeur \u00ab\u202f{1}\u202f\u00bb n\u2019est pas un r\u00e9pertoire existant.
@@ -48,6 +50,7 @@ IgnoredPropertiesAfterFirst_1    = Des p
 IgnoredPropertyAssociatedTo_1    = Une propri\u00e9t\u00e9 associ\u00e9e \u00e0 \u2018{0}\u2019 a \u00e9t\u00e9 ignor\u00e9e.
 IgnoredServiceProvider_3         = Plusieurs fournisseurs de service de type \u2018{0}\u2019 sont d\u00e9clar\u00e9s pour \u00ab\u202f{1}\u202f\u00bb. Seul le premier fournisseur (une instance de \u2018{2}\u2019) sera utilis\u00e9.
 IncompleteParsing_1              = La lecture de \u00ab\u202f{0}\u202f\u00bb a \u00e9t\u00e9 faite, mais en ignorant certains \u00e9l\u00e9ments.
+InsertDuration_2                 = {0} enregistrements ont \u00e9t\u00e9 ajout\u00e9s en {1} secondes.
 JNDINotSpecified_1               = Aucun objet n\u2019est associ\u00e9 au nom JNDI \u00ab\u202f{0}\u202f\u00bb.
 LoadingDatumShiftFile_1          = Chargement du fichier de changement de r\u00e9f\u00e9rentiel \u00ab\u202f{0}\u202f\u00bb.
 LocalesDiscarded                 = Des textes ont \u00e9t\u00e9 ignor\u00e9s pour certaines langues.

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.java [UTF-8] Tue Feb  2 23:39:20 2016
@@ -206,6 +206,11 @@ public final class Vocabulary extends In
         public static final short EllipsoidalHeight = 18;
 
         /**
+         * Geodetic dataset
+         */
+        public static final short GeodeticDataset = 95;
+
+        /**
          * Height
          */
         public static final short Height = 69;

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -44,6 +44,7 @@ DittoMark               = \u2033
 DublinJulian            = Dublin Julian
 Ellipsoid               = Ellipsoid
 EllipsoidalHeight       = Ellipsoidal height
+GeodeticDataset         = Geodetic dataset
 Height                  = Height
 Identifier              = Identifier
 Implementation          = Implementation

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Vocabulary_fr.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -51,6 +51,7 @@ DittoMark               = \u2033
 DublinJulian            = Julien Dublin
 Ellipsoid               = Ellipso\u00efde
 EllipsoidalHeight       = Hauteur ellipso\u00efdale
+GeodeticDataset         = Base de donn\u00e9es g\u00e9od\u00e9sique
 Height                  = Hauteur
 Identifier              = Identifiant
 Implementation          = Impl\u00e9mentation

Modified: sis/branches/JDK7/ide-project/NetBeans/build.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/build.xml?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/build.xml (original)
+++ sis/branches/JDK7/ide-project/NetBeans/build.xml Tue Feb  2 23:39:20 2016
@@ -152,6 +152,13 @@
       </fileset>
     </concat>
 
+    <!-- Initializer implementations to be loaded by ServiceLoader. -->
+    <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.internal.metadata.sql.Initializer" encoding="UTF-8" fixlastline="yes">
+      <fileset dir="${project.root}">
+        <include name="*/*/src/main/resources/META-INF/services/org.apache.sis.internal.metadata.sql.Initializer"/>
+      </fileset>
+    </concat>
+
     <!-- DataStoreProvider implementations to be loaded by ServiceLoader. -->
     <concat destfile="${build.classes.dir}/META-INF/services/org.apache.sis.storage.DataStoreProvider" encoding="UTF-8" fixlastline="yes">
       <fileset dir="${project.root}">

Modified: sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties?rev=1728238&r1=1728237&r2=1728238&view=diff
==============================================================================
--- sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] (original)
+++ sis/branches/JDK7/ide-project/NetBeans/nbproject/project.properties [ISO-8859-1] Tue Feb  2 23:39:20 2016
@@ -86,8 +86,8 @@ rome.version         = 0.9
 jdom1.version        = 1.0
 jdom2.version        = 2.0.4
 jee.version          = 6.0
-osgi.version         = 5.0.0
-netcdf.version       = 4.6.2
+osgi.version         = 6.0.0
+netcdf.version       = 4.6.3
 joda-time.version    = 2.2
 httpclient.version   = 4.3.6
 slf4j.version        = 1.7.7



Mime
View raw message