sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1723645 - 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-metadata/src/test/java/org/apache/sis/test/suite/ sis-referencing/s...
Date Fri, 08 Jan 2016 00:44:02 GMT
Author: desruisseaux
Date: Fri Jan  8 00:44:01 2016
New Revision: 1723645

URL: http://svn.apache.org/viewvc?rev=1723645&view=rev
Log:
More lenient lookup of CRS by their name.

Added:
    sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
  (with props)
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java

Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java?rev=1723645&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
(added)
+++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
[UTF-8] Fri Jan  8 00:44:01 2016
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.metadata.sql;
+
+import org.apache.sis.util.Static;
+import org.apache.sis.util.Characters;
+import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.Workaround;
+
+
+/**
+ * Utilities relative to the SQL language.
+ *
+ *     <strong>DO NOT USE</strong>
+ *
+ * This class is for Apache SIS internal usage and may change in any future version.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final class SQLUtilities extends Static {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private SQLUtilities() {
+    }
+
+    /**
+     * Returns a string like the given string but with all characters that are not letter
or digit
+     * replaced by the wildcard % character.
+     *
+     * <p>This method avoid to put a % symbol as the first character, since it prevent
some databases
+     * to use their index.</p>
+     *
+     * @param identifier The identifier to get as a SQL LIKE pattern.
+     * @return The given identifier as a SQL LIKE pattern.
+     */
+    public static String toLikePattern(final String identifier) {
+        boolean isLetterOrDigit = false;
+        final StringBuilder buffer = new StringBuilder(identifier.length());
+        for (int c, i = 0; i < identifier.length(); i += Character.charCount(c)) {
+            c = identifier.codePointAt(i);
+            if (Character.isLetterOrDigit(c)) {
+                buffer.appendCodePoint(c);
+                isLetterOrDigit = true;
+            } else if (isLetterOrDigit) {
+                isLetterOrDigit = false;
+                buffer.append('%');
+            } else {
+                final int p = buffer.length();
+                if (p == 0 || buffer.charAt(p-1) != '%') {
+                    buffer.appendCodePoint(c != '%' ? c : '_');
+                }
+            }
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Workaround for what seems to be a Derby 10.11 bug, which seems to behave as if the
LIKE pattern
+     * had a trailing % wildcard. This can be verified with the following query on the EPSG
database:
+     *
+     * {@preformat sql
+     *   SELECT COORD_REF_SYS_CODE, COORD_REF_SYS_NAME FROM EPSG."Coordinate Reference System"
+     *    WHERE COORD_REF_SYS_NAME LIKE 'NTF%Paris%Lambert%zone%I'
+     * }
+     *
+     * which returns "NTF (Paris) / Lambert zone I" as expected but also zones II and III.
+     *
+     * @param  expected The string to search.
+     * @param  actual The string found in the database.
+     * @return {@code true} if the given string can be accepted.
+     */
+    @Workaround(library = "Derby", version = "10.11")
+    public static boolean filterFalsePositive(final String expected, final String actual)
{
+        return CharSequences.equalsFiltered(expected, actual, Characters.Filter.LETTERS_AND_DIGITS,
false);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/SQLUtilities.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java?rev=1723645&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
(added)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
Fri Jan  8 00:44:01 2016
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.metadata.sql;
+
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests the {@link SQLUtilities} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.7
+ * @version 0.7
+ * @module
+ */
+public final strictfp class SQLUtilitiesTest extends TestCase {
+    /**
+     * Tests {@link SQLUtilities#toLikePattern(String)}.
+     */
+    @Test
+    public void testToLikePattern() {
+        assertEquals("WGS84",                       SQLUtilities.toLikePattern("WGS84"));
+        assertEquals("WGS%84",                      SQLUtilities.toLikePattern("WGS 84"));
+        assertEquals("A%text%with%random%symbols%", SQLUtilities.toLikePattern("A text !*
with_random:/symbols;+"));
+        assertEquals("*_+_=With%non%letter%start",  SQLUtilities.toLikePattern("*_+%=With
non-letter  start"));
+    }
+}

Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/SQLUtilitiesTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1723645&r1=1723644&r2=1723645&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
[UTF-8] Fri Jan  8 00:44:01 2016
@@ -26,7 +26,7 @@ import org.junit.BeforeClass;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.6
+ * @version 0.7
  * @module
  */
 @Suite.SuiteClasses({
@@ -99,7 +99,9 @@ import org.junit.BeforeClass;
     org.apache.sis.io.wkt.TransliteratorTest.class,
     org.apache.sis.io.wkt.ColorsTest.class,
     org.apache.sis.io.wkt.FormatterTest.class,
-    org.apache.sis.io.wkt.ElementTest.class
+    org.apache.sis.io.wkt.ElementTest.class,
+
+    org.apache.sis.internal.metadata.sql.SQLUtilitiesTest.class
 })
 public final strictfp class MetadataTestSuite extends TestSuite {
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1723645&r1=1723644&r2=1723645&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
[UTF-8] Fri Jan  8 00:44:01 2016
@@ -69,6 +69,7 @@ import org.opengis.referencing.Identifie
 import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.apache.sis.internal.metadata.ReferencingServices;
 import org.apache.sis.internal.metadata.TransformationAccuracy;
+import org.apache.sis.internal.metadata.sql.SQLUtilities;
 import org.apache.sis.internal.referencing.DeprecatedCode;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.system.Loggers;
@@ -108,8 +109,6 @@ import org.apache.sis.util.collection.Co
 import org.apache.sis.measure.MeasurementRange;
 import org.apache.sis.measure.Units;
 
-// Branch-dependent imports
-
 
 /**
  * <cite>Data Access Object</cite> (DAO) creating geodetic objects from a JDBC
connection to an EPSG database.
@@ -595,16 +594,19 @@ addURIs:    for (int i=0; ; i++) {
                     }
                 }
                 if (statement == null) {
-                    final String query = "SELECT " + codeColumn + " FROM [" + table + "]
WHERE " + nameColumn + " = ?";
-                    statement = connection.prepareStatement(translator.apply(query));
+                    statement = connection.prepareStatement(translator.apply(
+                            "SELECT " + codeColumn + ", " + nameColumn +
+                            " FROM [" + table + "] WHERE " + nameColumn + " LIKE ?"));
                     statements.put(KEY, statement);
                     lastTableForName = table;
                 }
-                statement.setString(1, code);
+                statement.setString(1, SQLUtilities.toLikePattern(code));
                 Integer resolved = null;
                 try (ResultSet result = statement.executeQuery()) {
                     while (result.next()) {
-                        resolved = ensureSingleton(getOptionalInteger(result, 1), resolved,
code);
+                        if (SQLUtilities.filterFalsePositive(code, result.getString(2)))
{
+                            resolved = ensureSingleton(getOptionalInteger(result, 1), resolved,
code);
+                        }
                     }
                 }
                 if (resolved != null) {
@@ -1080,8 +1082,12 @@ addURIs:    for (int i=0; ; i++) {
                     continue;
                 }
                 query.setLength(queryStart);
-                query.append(table.codeColumn).append(" FROM ").append(table.table)
-                        .append(" WHERE ").append(column).append(" = ?");
+                query.append(table.codeColumn);
+                if (!isPrimaryKey) {
+                    query.append(", ").append(column);      // Only for filterFalsePositive(…).
+                }
+                query.append(" FROM ").append(table.table)
+                     .append(" WHERE ").append(column).append(isPrimaryKey ? " = ?" : " LIKE
?");
                 try (PreparedStatement stmt = connection.prepareStatement(translator.apply(query.toString())))
{
                     /*
                      * Check if at least one record is found for the code or the name.
@@ -1090,12 +1096,14 @@ addURIs:    for (int i=0; ; i++) {
                     if (isPrimaryKey) {
                         stmt.setInt(1, pk);
                     } else {
-                        stmt.setString(1, code);
+                        stmt.setString(1, SQLUtilities.toLikePattern(code));
                     }
                     Integer present = null;
                     try (ResultSet result = stmt.executeQuery()) {
                         while (result.next()) {
-                            present = ensureSingleton(getOptionalInteger(result, 1), present,
code);
+                            if (isPrimaryKey || SQLUtilities.filterFalsePositive(code, result.getString(2)))
{
+                                present = ensureSingleton(getOptionalInteger(result, 1),
present, code);
+                            }
                         }
                     }
                     if (present != null) {

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java?rev=1723645&r1=1723644&r2=1723645&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java
[UTF-8] Fri Jan  8 00:44:01 2016
@@ -347,6 +347,8 @@ public final strictfp class EPSGFactoryT
          */
         assertSame(crs, factory.createObject("27571"));
         assertSame(crs, factory.createObject("NTF (Paris) / Lambert zone I"));
+        assertSame(crs, factory.createProjectedCRS("NTF Paris Lambert zone I"));
+        assertSame(crs, factory.createObject("NTF Paris Lambert zone I"));
     }
 
     /**



Mime
View raw message