sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1728389 - in /sis/branches/JDK8/core: sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/ sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/ s...
Date Wed, 03 Feb 2016 22:51:43 GMT
Author: desruisseaux
Date: Wed Feb  3 22:51:42 2016
New Revision: 1728389

URL: http://svn.apache.org/viewvc?rev=1728389&view=rev
Log:
Minor adjustments in EPSGInstaller test and in documentation.

Modified:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ScriptRunner.java
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/Initializer.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -343,7 +343,7 @@ public abstract class Initializer {
      * @return The data source.
      * @throws Exception if the data source can not be created.
      */
-    public static DataSource forJavaDB(final String path) throws Exception {
+    static DataSource forJavaDB(final String path) throws Exception {
         try {
             return forJavaDB(path, Thread.currentThread().getContextClassLoader());
         } catch (ClassNotFoundException e) {
@@ -397,14 +397,24 @@ public abstract class Initializer {
             try {
                 ds.getConnection().close();     // Does the actual shutdown.
             } catch (SQLException e) {          // This is the expected exception.
-                Level level = Level.CONFIG;
-                if (e.getErrorCode() != 45000 || !"08006".equals(e.getSQLState())) {
-                    level = Level.WARNING;
+                final LogRecord record = new LogRecord(Level.CONFIG, e.getLocalizedMessage());
+                if (!isNormalShutdown(e)) {
+                    record.setLevel(Level.WARNING);
+                    record.setThrown(e);
                 }
-                final LogRecord record = new LogRecord(level, e.getLocalizedMessage());
                 record.setLoggerName(Loggers.SQL);
                 Logging.log(Initializer.class, "shutdown", record);
             }
         }
     }
+
+    /**
+     * Returns {@code true} if the given exception is the one that we expect in a normal
shutdown of a Derby database.
+     *
+     * @param e The exception thrown by Derby.
+     * @return {@code true} if the exception indicates a successful shutdown.
+     */
+    static boolean isNormalShutdown(final SQLException e) {
+        return e.getErrorCode() == 45000 && "08006".equals(e.getSQLState());
+    }
 }

Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ScriptRunner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ScriptRunner.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ScriptRunner.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/ScriptRunner.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -19,7 +19,6 @@ package org.apache.sis.internal.metadata
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Locale;
-import java.util.function.BiFunction;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
@@ -35,6 +34,9 @@ import org.apache.sis.util.ArgumentCheck
 import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.resources.Errors;
 
+// Branch-specific imports
+import java.util.function.BiFunction;
+
 
 /**
  * Run SQL scripts. The script is expected to use a standardized syntax, where the {@value
#QUOTE} character

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -18,6 +18,7 @@ package org.apache.sis.internal.metadata
 
 import java.sql.SQLException;
 import javax.sql.DataSource;
+import org.apache.sis.util.Debug;
 import org.apache.sis.internal.system.DataDirectory;
 
 import static org.junit.Assume.*;
@@ -38,6 +39,17 @@ import java.nio.file.Path;
  */
 public final strictfp class TestDatabase {
     /**
+     * Data source to an alternative database to use for testing purpose.
+     * If {@code null}, an in-memory Derby or JavaDB database will be used.
+     *
+     * This field is occasionally set to a non-null value (e.g. a connection to a PostgreSQL
database) only for
+     * debugging purpose. In such case, it is developer responsibility to ensure that the
appropriate driver is
+     * registered in his development environment (we may not declare them in the {@code pom.xml}
file).
+     */
+    @Debug
+    private static final DataSource TEST_DATABASE = null;
+
+    /**
      * Do not allow (for now) instantiation of this class.
      */
     private TestDatabase() {
@@ -67,6 +79,9 @@ public final strictfp class TestDatabase
      * @throws Exception if an error occurred while creating the database.
      */
     public static DataSource create(final String name) throws Exception {
+        if (TEST_DATABASE != null) {
+            return TEST_DATABASE;
+        }
         final DataSource ds;
         try {
             ds = Initializer.forJavaDB("memory:" + name);
@@ -85,12 +100,15 @@ public final strictfp class TestDatabase
      * @throws Exception if an error occurred while dropping the database.
      */
     public static void drop(final DataSource ds) throws Exception {
+        if (ds == TEST_DATABASE) {
+            return;
+        }
         ds.getClass().getMethod("setCreateDatabase", String.class).invoke(ds, "no");
         ds.getClass().getMethod("setConnectionAttributes", String.class).invoke(ds, "drop=true");
         try {
             ds.getConnection();
         } catch (SQLException e) {          // This is the expected exception.
-            if (e.getErrorCode() != 45000 || !"08006".equals(e.getSQLState())) {
+            if (!Initializer.isNormalShutdown(e)) {
                 throw e;
             }
         }

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=1728389&r1=1728388&r2=1728389&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] Wed Feb  3 22:51:42 2016
@@ -415,7 +415,7 @@ public class EPSGFactory extends Concurr
                         try {
                             if (!tr.isTableFound()) {
                                 install(connection);
-                                tr.setup(connection.getMetaData());   // Set only on success.
+                                tr.setup(connection.getMetaData());         // Set only on
success.
                             }
                         } finally {
                             translator = tr;        // Set only after installation in order
to block other threads.

Modified: 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/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
[UTF-8] Wed Feb  3 22:51:42 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.util.CharSequences;
 
 
 /**
@@ -169,6 +170,14 @@ final class EPSGInstaller extends Script
      */
     @Override
     protected int execute(final StringBuilder sql) throws SQLException, IOException {
+        /*
+         * The SQL scripts provided by EPSG contains some lines with only a "COMMIT" statement.
+         * This statement is not understood by all databases, and interferes with our calls
to
+         * setAutoCommit(false) ... commit() / rollback().
+         */
+        if (CharSequences.equalsIgnoreCase(sql, "COMMIT")) {
+            return 0;
+        }
         if (statementToSkip != null && statementToSkip.reset(sql).matches()) {
             return 0;
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/SQLTranslator.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -58,13 +58,15 @@ import java.util.function.Function;
  *   <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)
- * scripts for PostgreSQL, MySQL and Oracle databases. But the table names and some column
names in those scripts differ
- * from the ones used in the MS-Access database. The following table summarizes the name
changes:
+ * In addition to the file in MS-Access format, EPSG also provides the dataset as SQL files
for PostgreSQL,
+ * MySQL and Oracle databases. Those SQL files are used as both <cite>Data Description
Language</cite> (DDL)
+ * and <cite>Data Manipulation Language</cite> (DML).
+ * But the table names and some column names in those scripts differ from the ones used in
the MS-Access database.
+ * The following table summarizes the name changes:
  *
  * <table class="sis">
  *   <caption>Table and column names</caption>
- *   <tr><th>Element</th><th>Name in MS-Access database</th>
                   <th>Name in DDL scripts</th></tr>
+ *   <tr><th>Element</th><th>Name in MS-Access database</th>
                   <th>Name in SQL scripts</th></tr>
  *   <tr><td>Table</td>  <td>{@code Alias}</td>           
                     <td>{@code epsg_alias}</td></tr>
  *   <tr><td>Table</td>  <td>{@code Area}</td>            
                     <td>{@code epsg_area}</td></tr>
  *   <tr><td>Table</td>  <td>{@code Coordinate Axis}</td> 
                     <td>{@code epsg_coordinateaxis}</td></tr>
@@ -191,8 +193,8 @@ public class SQLTranslator implements Fu
 
     /**
      * 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.
+     * 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
SQL scripts.
      *
      * <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.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -46,7 +46,7 @@ public final strictfp class EPSGInstalle
      */
     @Test
     public void testCreationOnDerby() throws Exception {
-        final Path scripts = TestDatabase.directory("Scripts");
+        final Path scripts = TestDatabase.directory("ExternalSources");
         final DataSource ds = TestDatabase.create("test");
         try (Connection c = ds.getConnection()) {
             try (EPSGInstaller installer = new EPSGInstaller(c)) {

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java?rev=1728389&r1=1728388&r2=1728389&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/report/CoordinateReferenceSystems.java
[UTF-8] Wed Feb  3 22:51:42 2016
@@ -198,7 +198,7 @@ public strictfp class CoordinateReferenc
                 row.remark = i18n.toString(getLocale());
             }
         }
-        return row;
+        return new ByName(row);
     }
 
     /**
@@ -232,6 +232,152 @@ public strictfp class CoordinateReferenc
             }
         }
         row.remark = message;
-        return row;
+        return new ByName(row);
+    }
+
+    /**
+     * A row with an natural ordering that use the first part of the name before to use the
authority code.
+     * We use only the part of the name prior some keywords (e.g. {@code "zone"}).
+     * For example if the following codes:
+     *
+     * {@preformat text
+     *    EPSG:32609    WGS 84 / UTM zone 9N
+     *    EPSG:32610    WGS 84 / UTM zone 10N
+     * }
+     *
+     * We compare only the "WGS 84 / UTM" string, then the code. This is a reasonably easy
way to keep a more
+     * natural ordering ("9" sorted before "10", "UTM North" projections kept together and
same for South).
+     */
+    private static final class ByName extends Row {
+        /**
+         * The keywords before which to cut the name. The main intend here is to preserve
the
+         * "far west", "west", "central west", "central", "central east", "east", "far east"
order.
+         */
+        private static final String[] CUT_BEFORE = {
+            " far west",        // "MAGNA-SIRGAS / Colombia Far West zone"
+            " far east",
+            " west",            // "Bogota 1975 / Colombia West zone"
+            " east",            // "Bogota 1975 / Colombia East Central zone"
+            " central",         // "Korean 1985 / Central Belt" (between "East Belt" and
"West Belt")
+            " old central",     // "NAD Michigan / Michigan Old Central"
+            " bogota zone",     // "Bogota 1975 / Colombia Bogota zone"
+            // Do not declare "North" and "South" as it causes confusion with "WGS 84 / North
Pole" and other cases.
+        };
+
+        /**
+         * The keywords after which to cut the name.
+         *
+         * Note: alphabetical sorting of Roman numbers work for zones from I to VIII inclusive.
+         * If there is more zones (for example with "JGD2000 / Japan Plane Rectangular"),
then
+         * we need to cut before those numbers in order to use sorting by EPSG codes instead.
+         *
+         * Note 2: if alphabetical sorting is okay for Roman numbers, it is actually preferable
+         * because it give better position of names with height like "zone II + NGF IGN69
height".
+         */
+        private static final String[] CUT_AFTER = {
+            " cs ",                     // "JGD2000 / Japan Plane Rectangular CS IX"
+            " tm",                      // "ETRS89 / TM35FIN(E,N)" — we want to not interleave
them between "TM35" and "TM36".
+            " dktm",                    // "ETRS89 / DKTM1 + DVR90 height"
+            "-gk",                      // "ETRS89 / ETRS-GK19FIN"
+//          " philippines zone ",       // "Luzon 1911 / Philippines zone IV"
+//          " california zone ",        // "NAD27 / California zone V"
+//          " ngo zone ",               // "NGO 1948 (Oslo) / NGO zone I"
+//          " lambert zone ",           // "NTF (Paris) / Lambert zone II + NGF IGN69 height"
+            "fiji 1956 / utm zone "     // Two zones: 60S and 1S with 60 before 1.
+        };
+
+        /**
+         * A string derived from the {@link #name} to use for sorting.
+         */
+        private final String reducedName;
+
+        /**
+         * Creates a new row as a copy of the given row, but with a different natural ordering.
+         */
+        ByName(final Row row) {
+            super(row);
+            /*
+             * Get a copy of the name in all lower case.
+             */
+            final StringBuilder b = new StringBuilder(name);
+            for (int i=0; i<b.length(); i++) {
+                b.setCharAt(i, Character.toLowerCase(b.charAt(i)));
+            }
+            /*
+             * Cut the string to a shorter length if we find a keyword.
+             * This will result in many string equals, which will then be sorted by EPSG
codes.
+             * This is useful when the EPSG codes give a better ordering than the alphabetic
one
+             * (for example with Roman numbers).
+             */
+            int s = 0;
+            for (final String keyword : CUT_BEFORE) {
+                int i = b.lastIndexOf(keyword);
+                if (i > 0 && (s == 0 || i < s)) s = i;
+            }
+            for (final String keyword : CUT_AFTER) {
+                int i = b.lastIndexOf(keyword);
+                if (i >= 0) {
+                    i += keyword.length();
+                    if (i > s) s = i;
+                }
+            }
+            if (s != 0) b.setLength(s);
+            uniformizeZoneNumber(b);
+            reducedName = b.toString();
+        }
+
+        /**
+         * If the string ends with a number optionally followed by "N" or "S", replaces the
hemisphere
+         * symbol by a sign and makes sure that the number uses at least 3 digits (e.g. "2N"
→ "+002").
+         */
+        private static void uniformizeZoneNumber(final StringBuilder b) {
+            if (b.indexOf("/") < 0) {
+                /*
+                 * Do not process names like "WGS 84". We want to process only names like
"WGS 84 / UTM zone 2N",
+                 * otherwise the replacement of "WGS 84" by "WGS 084" causes unexpected sorting.
+                 */
+                return;
+            }
+            int  i = b.length();
+            char c = b.charAt(i - 1);
+            if (c == ')') {
+                // Ignore suffix like " (ftUS)".
+                i = b.lastIndexOf(" (");
+                if (i < 0) return;
+                c = b.charAt(i - 1);
+            }
+            char sign;
+            switch (c) {
+                default:            sign =  0;       break;
+                case 'e': case 'n': sign = '+'; i--; break;
+                case 'w': case 's': sign = '-'; i--; break;
+            }
+            int upper = i;
+            do {
+                if (i == 0) return;
+                c = b.charAt(--i);
+            } while (c >= '0' && c <= '9');
+            switch (upper - ++i) {
+                case 2: b.insert(i,  '0'); upper++;  break;     // Found 2 digits.
+                case 1: b.insert(i, "00"); upper+=2; break;     // Only one digit found.
+                case 0: return;                                 // No digit.
+            }
+            if (sign != 0) {
+                b.insert(i, sign);
+                upper++;
+            }
+            b.setLength(upper);
+        }
+
+        /**
+         * Compares this row wit the given row for ordering by name.
+         */
+        @Override public int compareTo(final Row o) {
+            int n = reducedName.compareTo(((ByName) o).reducedName);
+            if (n == 0) {
+                n = super.compareTo(o);
+            }
+            return n;
+        }
     }
 }



Mime
View raw message