sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1747422 - in /sis/branches/JDK8: application/sis-console/src/main/java/org/apache/sis/console/ application/sis-console/src/test/java/org/apache/sis/console/ application/sis-openoffice/src/main/java/org/apache/sis/openoffice/ core/sis-refer...
Date Wed, 08 Jun 2016 17:08:04 GMT
Author: desruisseaux
Date: Wed Jun  8 17:08:03 2016
New Revision: 1747422

URL: http://svn.apache.org/viewvc?rev=1747422&view=rev
Log:
Better inference of whether an argument given to an application (console or OpenOffice add-ins)
should be understood as an AUTHORITY:CODE pattern or a PROTOCOL:FILE pattern.

Added:
    sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/CodeType.java
      - copied, changed from r1747421, sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
  (with props)
Removed:
    sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java
Modified:
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
    sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
    sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
    sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
    sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
    sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
[UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/MetadataCommand.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -16,11 +16,8 @@
  */
 package org.apache.sis.console;
 
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Set;
 import java.io.Console;
 import java.io.IOException;
 import javax.xml.bind.Marshaller;
@@ -39,6 +36,7 @@ import org.apache.sis.referencing.CRS;
 import org.apache.sis.storage.DataStore;
 import org.apache.sis.storage.DataStores;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.internal.storage.CodeType;
 import org.apache.sis.util.collection.TableColumn;
 import org.apache.sis.util.collection.TreeTable;
 import org.apache.sis.util.collection.TreeTableFormat;
@@ -58,18 +56,6 @@ import org.apache.sis.xml.XML;
  */
 class MetadataCommand extends CommandRunner {
     /**
-     * The protocol part of the filename to be recognized as a CRS authority.
-     * In such case, this class will delegate to {@link CRS#forCode(String)}
-     * instead of opening the file.
-     */
-    static final Set<String> AUTHORITIES = new HashSet<>(Arrays.asList("URN",
"EPSG", "CRS", "AUTO", "AUTO2"));
-
-    /**
-     * Length of the longest authority name declared in {@link #AUTHORITIES}.
-     */
-    static final int MAX_AUTHORITY_LENGTH = 5;
-
-    /**
      * The output format.
      */
     static enum Format {
@@ -142,39 +128,7 @@ class MetadataCommand extends CommandRun
     }
 
     /**
-     * Returns {@code true} if the given argument begins with one of the known authorities
-     * ("URN", "EPSG", "CRS", "AUTO", <i>etc.</i>).
-     */
-    static boolean isAuthorityCode(final String code) {
-        final char[] authority = new char[MAX_AUTHORITY_LENGTH];
-        final int length = code.length();
-        int p = 0, i = 0;
-        while (i < length) {
-            final int c = code.codePointAt(i);
-            if (c == ':') {
-                if (!AUTHORITIES.contains(new String(authority, 0, p))) {
-                    break;
-                }
-                return true;
-            }
-            if (!Character.isWhitespace(c)) {
-                if (p >= MAX_AUTHORITY_LENGTH || !Character.isLetterOrDigit(c)) {
-                    break;
-                }
-                /*
-                 * Casting to char is okay because AUTHORITIES contains only ASCII values.
-                 * If 'c' was a supplemental Unicode value, then the result of the cast
-                 * would not match any AUTHORITIES value anyway.
-                 */
-                authority[p++] = (char) Character.toUpperCase(c);
-            }
-            i += Character.charCount(c);
-        }
-        return false;
-    }
-
-    /**
-     * If the given argument begins with one of the known authorities ("URN", "EPSG", "CRS",
"AUTO", <i>etc.</i>),
+     * If the given argument seems to be an authority code ("URN", "EPSG", "CRS", "AUTO",
<i>etc.</i>),
      * delegates to {@link CRS#forCode(String)}. Otherwise reads the metadata using a datastore.
      *
      * @return A {@link Metadata} or {@link CoordinateReferenceSystem} instance, or {@code
null} if none.
@@ -189,7 +143,7 @@ class MetadataCommand extends CommandRun
             return null;
         } else {
             final String file = files.get(0);
-            if (isAuthorityCode(file)) {
+            if (CodeType.guess(file).isCRS) {
                 return CRS.forCode(file);
             } else {
                 try (DataStore store = DataStores.open(file)) {

Modified: sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
[UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/main/java/org/apache/sis/console/TransformCommand.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -53,6 +53,7 @@ import org.apache.sis.geometry.Immutable
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.DirectPositionView;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
+import org.apache.sis.internal.storage.CodeType;
 import org.apache.sis.internal.util.PatchedUnitFormat;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.referencing.CRS;
@@ -164,7 +165,7 @@ final class TransformCommand extends Met
             final String name = option.label();
             throw new InvalidOptionException(Errors.format(Errors.Keys.MissingValueForOption_1,
name), name);
         }
-        if (isAuthorityCode(identifier)) try {
+        if (CodeType.guess(identifier).isCRS) try {
             return CRS.forCode(identifier);
         } catch (NoSuchAuthorityCodeException e) {
             final String name = option.label();

Modified: sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/application/sis-console/src/test/java/org/apache/sis/console/MetadataCommandTest.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -37,19 +37,6 @@ import static org.junit.Assert.*;
 @DependsOn(CommandRunnerTest.class)
 public final strictfp class MetadataCommandTest extends TestCase {
     /**
-     * Verifies the {@link MetadataCommand#MAX_AUTHORITY_LENGTH} value.
-     */
-    @Test
-    public void verifyMaxAuthorityLength() {
-        int length = 0;
-        for (final String authority : MetadataCommand.AUTHORITIES) {
-            final int c = authority.length();
-            if (c > length) length = c;
-        }
-        assertEquals("MAX_AUTHORITY_LENGTH", length, MetadataCommand.MAX_AUTHORITY_LENGTH);
-    }
-
-    /**
      * Tests the sub-command on a NetCDF file.
      *
      * @throws Exception Should never happen.

Modified: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
[UTF-8] (original)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Referencing.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -18,6 +18,7 @@ package org.apache.sis.openoffice;
 
 import java.text.ParseException;
 
+import org.opengis.metadata.Metadata;
 import org.opengis.util.FactoryException;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.extent.Extent;
@@ -38,6 +39,10 @@ import org.apache.sis.util.Classes;
 import org.apache.sis.util.collection.Cache;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.PatchedUnitFormat;
+import org.apache.sis.internal.storage.CodeType;
+import org.apache.sis.storage.DataStore;
+import org.apache.sis.storage.DataStores;
+import org.apache.sis.storage.DataStoreException;
 
 
 /**
@@ -128,10 +133,14 @@ public class Referencing extends CalcAdd
      * This method caches the result.
      *
      * @param  codeOrPath  the code allocated by an authority, or the path to a file.
+     * @param  type        how to interpret {@code codeOrPath}, or {@code null} for guessing.
      * @return the identified object for the given code.
      * @throws FactoryException if an error occurred while creating the object.
+     * @throws DataStoreException if an error occurred while reading a data file.
      */
-    private static IdentifiedObject getIdentifiedObject(final String codeOrPath) throws FactoryException
{
+    private IdentifiedObject getIdentifiedObject(final String codeOrPath, CodeType type)
+            throws FactoryException, DataStoreException
+    {
         final CacheKey<IdentifiedObject> key = new CacheKey<>(IdentifiedObject.class,
codeOrPath, null, null);
         IdentifiedObject object = key.peek();
         if (object == null) {
@@ -139,9 +148,34 @@ public class Referencing extends CalcAdd
             try {
                 object = handler.peek();
                 if (object == null) {
-                    switch (CodeType.guess(codeOrPath)) {
-                        case URN: object = CRS.getAuthorityFactory(null).createObject(codeOrPath);
break;
-                        default:  object = CRS.forCode(codeOrPath); break;
+                    if (type == null) {
+                        type = CodeType.guess(codeOrPath);
+                    }
+                    if (type.equals(CodeType.URN)) {
+                        object = CRS.getAuthorityFactory(null).createObject(codeOrPath);
+                    } else if (type.isCRS) {
+                        object = CRS.forCode(codeOrPath);
+                    } else {
+                        /*
+                         * Apparently not an AUTHORITY:CODE string.
+                         * Try to read a dataset from a file or URL, then get its CRS.
+                         */
+                        final Metadata metadata;
+                        try (DataStore store = DataStores.open(codeOrPath)) {
+                            metadata = store.getMetadata();
+                        }
+                        if (metadata != null) {
+                            for (final ReferenceSystem rs : metadata.getReferenceSystemInfo())
{
+                                if (rs instanceof CoordinateReferenceSystem) {
+                                    return rs;
+                                } else if (object == null) {
+                                    object = rs;                // Will be used as a fallback
if we find no CRS.
+                                }
+                            }
+                        }
+                        if (object == null) {
+                            throw new FactoryException(Errors.getResources(getJavaLocale()).getString(Errors.Keys.UnspecifiedCRS));
+                        }
                     }
                 }
             } finally {
@@ -163,17 +197,18 @@ public class Referencing extends CalcAdd
         final InternationalString name;
         try {
             final IdentifiedObject object;
-            switch (CodeType.guess(codeOrPath)) {
-                case URN:
-                case CRS: object = new CacheKey<>(IdentifiedObject.class, codeOrPath,
null, null).peek(); break;
-                default:  object = getIdentifiedObject(codeOrPath); break;
+            final CodeType type = CodeType.guess(codeOrPath);
+            if (type.isCRS) {
+                object = new CacheKey<>(IdentifiedObject.class, codeOrPath, null, null).peek();
+            } else {
+                object = getIdentifiedObject(codeOrPath, type);
             }
             if (object != null) {
                 return object.getName().getCode();
             }
             // In Apache SIS implementation, 'getDescriptionText' returns the name.
             name = CRS.getAuthorityFactory(null).getDescriptionText(codeOrPath);
-        } catch (FactoryException exception) {
+        } catch (Exception exception) {
             return getLocalizedMessage(exception);
         }
         return (name != null) ? name.toString(getJavaLocale()) : noResultString();
@@ -199,8 +234,8 @@ public class Referencing extends CalcAdd
                 if (name == null) {
                     final IdentifiedObject object;
                     try {
-                        object = getIdentifiedObject(codeOrPath);
-                    } catch (FactoryException exception) {
+                        object = getIdentifiedObject(codeOrPath, null);
+                    } catch (Exception exception) {
                         return getLocalizedMessage(exception);
                     }
                     final CoordinateSystemAxis axis;
@@ -255,12 +290,12 @@ public class Referencing extends CalcAdd
             try {
                 area = handler.peek();
                 if (area == null) try {
-                    final IdentifiedObject object = getIdentifiedObject(codeOrPath);
+                    final IdentifiedObject object = getIdentifiedObject(codeOrPath, null);
                     final Object domain = IdentifiedObjects.getProperties(object).get(ReferenceSystem.DOMAIN_OF_VALIDITY_KEY);
                     if (domain instanceof Extent) {
                         area = Extents.getGeographicBoundingBox((Extent) domain);
                     }
-                } catch (FactoryException exception) {
+                } catch (Exception exception) {
                     reportException("getGeographicArea", exception, THROW_EXCEPTION);
                 }
             } finally {
@@ -281,9 +316,10 @@ public class Referencing extends CalcAdd
      * @param  codeOrPath  the code allocated by an authority, or the path to a file.
      * @return the coordinate reference system for the given code.
      * @throws FactoryException if an error occurred while creating the object.
+     * @throws DataStoreException if an error occurred while reading a data file.
      */
-    final CoordinateReferenceSystem getCRS(final String codeOrPath) throws FactoryException
{
-        final IdentifiedObject object = getIdentifiedObject(codeOrPath);
+    final CoordinateReferenceSystem getCRS(final String codeOrPath) throws FactoryException,
DataStoreException {
+        final IdentifiedObject object = getIdentifiedObject(codeOrPath, null);
         if (object == null || object instanceof CoordinateReferenceSystem) {
             return (CoordinateReferenceSystem) object;
         }
@@ -307,7 +343,7 @@ public class Referencing extends CalcAdd
     {
         try {
             return new Transformer(this, getCRS(sourceCRS), targetCRS, points).getAccuracy();
-        } catch (FactoryException exception) {
+        } catch (Exception exception) {
             reportException("getAccuracy", exception, THROW_EXCEPTION);
             return Double.NaN;
         }
@@ -328,7 +364,7 @@ public class Referencing extends CalcAdd
     {
         try {
             return new Transformer(this, getCRS(sourceCRS), targetCRS, points).transform(points);
-        } catch (FactoryException exception) {
+        } catch (Exception exception) {
             reportException("transformCoordinates", exception, THROW_EXCEPTION);
             return getFailure(points.length, 2);
         }

Modified: sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
[UTF-8] (original)
+++ sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/Transformer.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -28,6 +28,7 @@ import org.apache.sis.util.collection.Ca
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
+import org.apache.sis.storage.DataStoreException;
 
 
 /**
@@ -62,7 +63,7 @@ final class Transformer {
      * Creates a new transformer.
      */
     Transformer(final Referencing caller, final CoordinateReferenceSystem sourceCRS,
-            final String targetCRS, final double[][] points) throws FactoryException
+            final String targetCRS, final double[][] points) throws FactoryException, DataStoreException
     {
         /*
          * Computes the area of interest.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -182,6 +182,9 @@ abstract class AuthorityFactoryProxy<T>
             @Override InternationalString createFromAPI(AuthorityFactory factory, String
code) throws FactoryException {
                 return factory.getDescriptionText(code);
             }
+            @Override AuthorityFactoryProxy<InternationalString> specialize(String
typeName) {
+                return this;
+            }
     };
 
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -748,7 +748,8 @@ public class MultiAuthoritiesFactory ext
                 if (code == null) {
                     message = Errors.format(Errors.Keys.MissingComponentInElement_2, s, "code");
                 } else {
-                    message = Errors.format(Errors.Keys.CanNotCreateObjectAsInstanceOf_2,
type, uri.type);
+                    message = Errors.format(Errors.Keys.CanNotCreateObjectAsInstanceOf_2,
type,
+                            DefinitionURI.PREFIX + DefinitionURI.SEPARATOR + uri.type);
                 }
                 throw new NoSuchAuthorityCodeException(message, authority, code, s);
             }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/AuthorityFactoriesTest.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -46,7 +46,7 @@ import static org.apache.sis.test.Assert
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.7
- * @version 0.7
+ * @version 0.8
  * @module
  */
 public final strictfp class AuthorityFactoriesTest extends TestCase {
@@ -66,6 +66,20 @@ public final strictfp class AuthorityFac
     }
 
     /**
+     * Tests {@link CRSAuthorityFactory#getDescriptionText(String)}.
+     *
+     * @throws FactoryException if the EPSG:4326 name can not be obtained.
+     *
+     * @since 0.8
+     */
+    @Test
+    public void testGetDescriptionText() throws FactoryException {
+        final CRSAuthorityFactory factory = AuthorityFactories.ALL;
+        assertEquals("WGS 84", factory.getDescriptionText("EPSG:4326").toString());
+        assertEquals("WGS 84", factory.getDescriptionText("urn:ogc:def:crs:epsg::4326").toString());
+    }
+
+    /**
      * Tests creation of {@code CRS:84} from various codes.
      *
      * @throws FactoryException if a CRS:84 creation failed.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -125,7 +125,7 @@ public final class DefinitionURI {
     /**
      * The domain of URLs in the OGC namespace.
      */
-    private static final String DOMAIN = "www.opengis.net";
+    public static final String DOMAIN = "www.opengis.net";
 
     /**
      * Server and path portions of HTTP URL for various types (currently {@code "crs"}).

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/logging/Logging.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -86,6 +86,12 @@ public final class Logging extends Stati
      */
     private static volatile LoggerFactory<?> factory;
     static {
+        /*
+         * Use ServiceLoader.load(…), not DefaultFactories.createServiceLoader(…), for
avoiding a never-ending
+         * loop if a warning occurs in DefaultFactories. This risk exists because DefaultFactories
may use the
+         * logging services. Anyway, Apache SIS does not define any custom logger factory,
so DefaultFactories
+         * is not needed in this case.
+         */
         LoggerFactory<?> factory = null;
         for (final LoggerFactory<?> found : ServiceLoader.load(LoggerFactory.class))
{
             if (factory == null) {

Copied: sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/CodeType.java
(from r1747421, sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/CodeType.java?p2=sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/CodeType.java&p1=sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java&r1=1747421&r2=1747422&rev=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/application/sis-openoffice/src/main/java/org/apache/sis/openoffice/CodeType.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/CodeType.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -14,36 +14,167 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.sis.openoffice;
+package org.apache.sis.internal.storage;
+
+import java.io.File;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
+import org.apache.sis.util.CharSequences;
+import org.apache.sis.internal.util.DefinitionURI;
 
 
 /**
- * Whether an authority code is defined in the URN namespace.
+ * Heuristic rules for determining whether an authority code seems to be actually a file
path,
+ * or a code defined in the URN namespace, or a simple code.
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.8
  * @version 0.8
  * @module
  */
-enum CodeType {
+public enum CodeType {
+    /**
+     * The code is a filename like {@code "/path/to/file"} or {@code "C:\path\to\file"}.
+     * Could also be a directory name.
+     */
+    FILE(false),
+
+    /**
+     * The code is a URL like {@code "http:"} or {@code "file:"},
+     * with the exception of HTTP in the "www.opengis.net" domain.
+     * The later case is identified by {@link #HTTP_OGC} instead than this enum.
+     */
+    URL(false),
+
+    /**
+     * The code is an authority code defined in the {@code "urn:"} namespace.
+     */
+    URN(true),
+
+    /**
+     * The code is an URL in the {@code "http://www.opengis.net"} namespace.
+     */
+    HTTP_OGC(true),
+
+    /**
+     * The code is not defined in the URN namespace but is nevertheless presumed to be an
authority code.
+     * Example: {@code "EPSG:4326"}.
+     */
+    IDENTIFIER(true),
+
+    /**
+     * Can not resolve whether the code is a local file like {@code "myfile.wkt"} or an identifier
without
+     * authority like {@code "4326"}. Such code without can not be decoded by {@code CRS.forCode(String)},
+     * but may be understood by a more specific authority factory.
+     */
+    UNKNOWN(false);
+
+    /**
+     * Whether the code may be understood by the {@link org.apache.sis.referencing.CRS#forCode(String)}.
+     * A value of {@code true} does not guaranteed the the code is valid. It only said that
there is some
+     * chances that the code is valid.
+     */
+    public final boolean isCRS;
+
     /**
-     * The authority code is defined in the {@code "urn:"} namespace.
+     * Creates a new enum value.
      */
-    URN,
+    private CodeType(final boolean isCRS) {
+        this.isCRS = isCRS;
+    }
 
     /**
-     * The code is not defined in the URN namespace but is nevertheless presumed to be a
CRS authority code.
+     * The types for a list of known protocols. Protocol must be lower-cases.
+     *
+     * <p>This map is used for resolving ambiguity between "PROTOCOL:FILE" and "AUTHORITY:CODE".
+     * If the given path begins with a file separator like "PROTOCOL:/PATH/FILE", then the
path
+     * is presumed to be a URL even if the protocol is not in this map.</p>
      */
-    CRS;
+    private static final Map<String,CodeType> FOR_PROTOCOL;
+    static {
+        FOR_PROTOCOL = new HashMap<>();
+        FOR_PROTOCOL.put("urn",   CodeType.URN);
+        FOR_PROTOCOL.put("http",  CodeType.HTTP_OGC);   // Will actually need verification.
+        FOR_PROTOCOL.put("https", CodeType.HTTP_OGC);   // Will actually need verification.
+        FOR_PROTOCOL.put("shttp", CodeType.HTTP_OGC);   // Not widely used but nevertheless
exist.
+        for (final String p : new String[] {"cvs", "dav", "file", "ftp", "git", "jar", "nfs",
"sftp", "ssh", "svn"}) {
+            if (FOR_PROTOCOL.put(p, CodeType.URL) != null) {
+                throw new AssertionError(p);
+            }
+        }
+    }
 
     /**
      * Infers the type for the given authority code.
+     *
+     * @param  codeOrPath the code or file path.
+     * @return whether the given argument seems to be a file path, URL, URN of authority
code.
      */
-    static CodeType guess(final String codeOrPath) {
-        if (codeOrPath.regionMatches(true, 0, "urn:", 0, 4)) {
-            return URN;
-        } else {
-            return CRS;
+    public static CodeType guess(final String codeOrPath) {
+        final int length = codeOrPath.length();
+        final int start  = CharSequences.skipLeadingWhitespaces(codeOrPath, 0, length);
+        int separator    = codeOrPath.indexOf(':', start);
+        final int end    = CharSequences.skipTrailingWhitespaces(codeOrPath, start, separator);
+        if (end <= start) {
+            // Check for presence of file separator, including the Unix and Windows ones.
+            if (codeOrPath.contains(File.separator) || codeOrPath.indexOf('/') >= 0 ||
codeOrPath.indexOf('\\') >= 0) {
+                return FILE;
+            }
+            return UNKNOWN;
+        }
+        /*
+         * Characters in the [start … end) range may be the authority ("EPSG", "CRS", "AUTO2",
etc.),
+         * the protocol ("http", "ftp", etc.) or a drive letter on a Windows system ("A",
"C", etc.).
+         * Skip following spaces and dots so if codeOrPath="C:.\path", then the separator
is at the
+         * position of \.
+         */
+        char c;
+        do {
+            separator = CharSequences.skipLeadingWhitespaces(codeOrPath, separator+1, length);
+            if (separator >= length) {
+                return FILE;            // Relative directory name, for example "C:..".
+            }
+            c = codeOrPath.charAt(separator);
+        } while (c == '.');
+        /*
+         * If the the ':' if followed by at least one '/' (ignoring spaces and dots), then
it is presumed
+         * to be a URL protocol. In the special case where the protocol is "http(s)" and
the domain after
+         * the '/' characters is "www.opengis.net", return HTTP_OGC instead than URL.
+         */
+        final CodeType known = FOR_PROTOCOL.get(codeOrPath.substring(start, end).toLowerCase(Locale.US));
+        if (known != null) {
+            if (known != HTTP_OGC) {
+                return known;
+            }
+            if (c == '/') {
+                while (++separator < length) {
+                    c = codeOrPath.charAt(separator);
+                    if (c != '/') {
+                        separator = CharSequences.skipLeadingWhitespaces(codeOrPath, separator,
length);
+                        if (CharSequences.regionMatches(codeOrPath, separator, DefinitionURI.DOMAIN,
true)) {
+                            separator += DefinitionURI.DOMAIN.length();
+                            if (separator >= length || codeOrPath.charAt(separator) ==
'/') {
+                                return known;
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+            return URL;
+        }
+        if (c == '/') {
+            return URL;
+        }
+        /*
+         * If the ':' is followed by '\', then the part before ':' is presumed to be a Windows
drive letter.
+         * Example "C:\file" or "C:..\file". Note that it does NOT include "C:file" since
the later can not
+         * be distinguished from an authority code. If a relative filename is desired, use
"C:.\file".
+         */
+        if (c == '\\' || c == File.separatorChar || end == start+1) {
+            return FILE;
         }
+        return IDENTIFIER;
     }
 }

Added: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java?rev=1747422&view=auto
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
(added)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -0,0 +1,131 @@
+/*
+ * 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.storage;
+
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests {@link CodeType}.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.8
+ * @version 0.8
+ * @module
+ */
+public final strictfp class CodeTypeTest  extends TestCase {
+    /**
+     * The expected value.
+     */
+    private CodeType expected;
+
+    /**
+     * Asserts that {@link CodeType#guess(String)} returns the expected value.
+     */
+    private void verify(final String code) {
+        assertEquals(code, expected, CodeType.guess(code));
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#IDENTIFIER} type.
+     */
+    @Test
+    public void testCRS() {
+        expected = CodeType.IDENTIFIER;
+        verify("EPSG:4326");
+        verify("epsg:4326");
+        verify(" ePsG : 4326 ");
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#URN} type.
+     */
+    @Test
+    public void testURN() {
+        expected = CodeType.URN;
+        verify("urn:ogc:def:crs:epsg::4326");
+        verify("URN:OGC:DEF:CRS:EPSG::4326");
+        verify("  uRn :ogc:def:crs:ogc::84");
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#URL} type.
+     */
+    @Test
+    public void testURL() {
+        expected = CodeType.URL;
+        verify("ftp://server/file.txt");
+        verify("http://server/file.txt");
+        verify("test://server/file.txt");
+        verify(" http : // server/file.txt");
+        verify("file:./file.txt");
+        verify("test:./file.txt");
+        verify("jar:file.txt");       // Special case required by some tests.
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#HTTP_OGC} type.
+     */
+    @Test
+    public void testHTTP() {
+        expected = CodeType.HTTP_OGC;
+        verify("http: // www.opengis.net/");
+        verify("http://www.opengis.net/gml/srs/epsg.xml#4326");
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#FILE} type.
+     */
+    @Test
+    public void testFile() {
+        expected = CodeType.FILE;
+        verify("path/file.txt");
+        verify("../file.txt");
+        verify("..\\file.txt");
+        verify("C:file.txt");
+        verify("C:.\\file.txt");
+        verify("ABC:.\\file.txt");
+        verify("C : \\path\\file.txt");
+        verify("ABC : \\path\\file.txt");
+        verify("C:..");
+        verify("ABC:..");
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#IDENTIFIER} type.
+     */
+    @Test
+    public void testIdentifier() {
+        expected = CodeType.IDENTIFIER;
+        verify("EPSG:4326");
+        verify("AB:C\\D.x");
+        verify("AB:C/D.x");
+    }
+
+    /**
+     * Tests {@link CodeType#guess(String)} for the {@link CodeType#UNKNOWN} type.
+     */
+    @Test
+    public void testUnknown() {
+        expected = CodeType.UNKNOWN;
+        verify("4326");
+        verify("file.txt");
+    }
+}

Propchange: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/CodeTypeTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java?rev=1747422&r1=1747421&r2=1747422&view=diff
==============================================================================
--- sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/storage/sis-storage/src/test/java/org/apache/sis/test/suite/StorageTestSuite.java
[UTF-8] Wed Jun  8 17:08:03 2016
@@ -26,10 +26,11 @@ import org.junit.BeforeClass;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.7
+ * @version 0.8
  * @module
  */
 @Suite.SuiteClasses({
+    org.apache.sis.internal.storage.CodeTypeTest.class,
     org.apache.sis.internal.storage.IOUtilitiesTest.class,
     org.apache.sis.internal.storage.ChannelDataInputTest.class,
     org.apache.sis.internal.storage.ChannelDataOutputTest.class,




Mime
View raw message