sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1727561 [2/5] - in /sis/branches/JDK6: ./ 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/main/java/org/apache/sis/io/wkt/ core/s...
Date Fri, 29 Jan 2016 12:23:11 GMT
Modified: sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/CitationsTest.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.metadata.iso.citation;
 
+import java.util.List;
 import java.util.Locale;
 import java.lang.reflect.Field;
 import org.opengis.metadata.Identifier;
@@ -36,7 +37,7 @@ import static org.apache.sis.test.Metada
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.6
- * @version 0.6
+ * @version 0.7
  * @module
  */
 public final strictfp class CitationsTest extends TestCase {
@@ -64,6 +65,8 @@ public final strictfp class CitationsTes
         assertSame(ISSN,             fromName("ISSN"));
         assertSame(ISO_19115.get(0), fromName("ISO 19115-1"));
         assertSame(ISO_19115.get(1), fromName("ISO 19115-2"));
+        assertSame(WMS,              fromName("WMS"));
+        assertSame(WMS,              fromName(Constants.CRS));
         /*
          * Verify again, but using reflection for making sure that the field names
          * are consistent and that we did not forgot any citation constant.
@@ -84,6 +87,7 @@ public final strictfp class CitationsTes
     public void testGetIdentifier() {
         assertEquals("SIS",         getIdentifier(SIS));
         assertEquals("OGC",         getIdentifier(OGC));
+        assertEquals("IOGP",        getIdentifier(IOGP));
         assertEquals("EPSG",        getIdentifier(EPSG));
         assertEquals("ESRI",        getIdentifier(ESRI));
         assertEquals("NetCDF",      getIdentifier(NETCDF));
@@ -95,6 +99,11 @@ public final strictfp class CitationsTes
         assertEquals("S-57",        getIdentifier(S57));    // Not a valid Unicode identifier.
         assertEquals("ISO:19115-1", getIdentifier(ISO_19115.get(0)));  // The ':' separator is not usual in ISO references
         assertEquals("ISO:19115-2", getIdentifier(ISO_19115.get(1)));  // and could be changed in future SIS versions.
+        assertEquals("OGC:WMS",     getIdentifier(WMS));
+        assertIdentifierEquals("OGC:06-042", null, "OGC", null, "06-042",
+                ((List<? extends Identifier>) WMS.getIdentifiers()).get(1));
+        assertIdentifierEquals("ISO:19128", null, "ISO", "2005", "19128",
+                ((List<? extends Identifier>) WMS.getIdentifiers()).get(2));
     }
 
     /**
@@ -106,6 +115,7 @@ public final strictfp class CitationsTes
     public void testGetUnicodeIdentifier() {
         assertEquals("SIS",         getUnicodeIdentifier(SIS));
         assertEquals("OGC",         getUnicodeIdentifier(OGC));
+        assertEquals("IOGP",        getUnicodeIdentifier(IOGP));
         assertEquals("EPSG",        getUnicodeIdentifier(EPSG));
         assertEquals("ESRI",        getUnicodeIdentifier(ESRI));
         assertEquals("NetCDF",      getUnicodeIdentifier(NETCDF));
@@ -115,6 +125,7 @@ public final strictfp class CitationsTes
         assertEquals("ISSN",        getUnicodeIdentifier(ISSN));
         assertNull  ("Proj4",       getUnicodeIdentifier(PROJ4));      // Not yet publicly declared as an identifier.
         assertNull  ("S57",         getUnicodeIdentifier(S57));        // Not yet publicly declared as an identifier.
+        assertEquals("OGC_WMS",     getUnicodeIdentifier(WMS));
         assertNull  ("ISO_19115-1", getUnicodeIdentifier(ISO_19115.get(0)));  // Not a valid Unicode identifier.
         assertNull  ("ISO_19115-2", getUnicodeIdentifier(ISO_19115.get(1)));
     }
@@ -127,7 +138,9 @@ public final strictfp class CitationsTes
     @DependsOnMethod("testGetUnicodeIdentifier")
     public void testGetCodeSpace() {
         assertEquals("SIS",         org.apache.sis.internal.util.Citations.getCodeSpace(SIS));
+        assertEquals("OGC",         org.apache.sis.internal.util.Citations.getCodeSpace(WMS));
         assertEquals("OGC",         org.apache.sis.internal.util.Citations.getCodeSpace(OGC));
+        assertEquals("IOGP",        org.apache.sis.internal.util.Citations.getCodeSpace(IOGP));
         assertEquals("EPSG",        org.apache.sis.internal.util.Citations.getCodeSpace(EPSG));
         assertEquals("ESRI",        org.apache.sis.internal.util.Citations.getCodeSpace(ESRI));
         assertEquals("NetCDF",      org.apache.sis.internal.util.Citations.getCodeSpace(NETCDF));
@@ -147,7 +160,8 @@ public final strictfp class CitationsTes
     @Test
     public void testGetTitles() {
         assertTitleEquals("SIS",     "Apache Spatial Information System",    SIS);
-        assertTitleEquals("OGC",     "Identifier in OGC namespace",          OGC);
+        assertTitleEquals("WMS",     "Web Map Server",                       WMS);
+        assertTitleEquals("OGC",     "Identifiers in OGC namespace",         OGC);
         assertTitleEquals("EPSG",    "EPSG Geodetic Parameter Dataset",      EPSG);
         assertTitleEquals("ISBN",    "International Standard Book Number",   ISBN);
         assertTitleEquals("ISSN",    "International Standard Serial Number", ISSN);
@@ -157,6 +171,7 @@ public final strictfp class CitationsTes
         assertTitleEquals("S57",     "S-57",                                 S57);
         assertTitleEquals("ISO_19115", "Geographic Information — Metadata Part 1: Fundamentals", ISO_19115.get(0));
         assertTitleEquals("ISO_19115", "Geographic Information — Metadata Part 2: Extensions for imagery and gridded data", ISO_19115.get(1));
+        assertEquals     ("ISO_19128", "Geographic Information — Web map server interface", getSingleton(WMS.getAlternateTitles()).toString());
     }
 
     /**
@@ -168,6 +183,7 @@ public final strictfp class CitationsTes
         assertEquals("International Organization for Standardization",   getCitedResponsibleParty(ISO_19115.get(0)));
         assertEquals("International Organization for Standardization",   getCitedResponsibleParty(ISO_19115.get(1)));
         assertEquals("International Association of Oil & Gas producers", getCitedResponsibleParty(EPSG));
+        assertEquals("International Association of Oil & Gas producers", getCitedResponsibleParty(IOGP));
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -103,7 +103,7 @@ public final class Code {
         Citation authority = null;
         String version = null, cs = codeSpace;
         final DefinitionURI parsed = DefinitionURI.parse(c);
-        if (parsed != null) {
+        if (parsed != null && parsed.code != null) {
             /*
              * Case where the URN has been successfully parsed. The OGC's URN contains an "authority" component,
              * which we take as the Identifier.codeSpace value (not Identifier.authority despite what the names
@@ -193,9 +193,7 @@ public final class Code {
              */
             if (fallback != null) {
                 if (!isHTTP) {
-                    final String urn = DefinitionURI.format(NameMeaning.toObjectType(type),
-                                                            NameMeaning.authority(fallback.getCodeSpace()),
-                                                            fallback.getVersion(), fallback.getCode());
+                    final String urn = NameMeaning.toURN(type, fallback.getCodeSpace(), fallback.getVersion(), fallback.getCode());
                     if (urn != null) {
                         final Code code = new Code();
                         /*

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/provider/FranceGeocentricInterpolation.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -144,7 +144,7 @@ public class FranceGeocentricInterpolati
     private static final String DEFAULT = "gr3df97a.txt";
 
     /**
-     * The operation parameter descriptor for the <cite>Geocentric translations file</cite> parameter value.
+     * The operation parameter descriptor for the <cite>Geocentric translation file</cite> parameter value.
      */
     public static final ParameterDescriptor<File> FILE;
 
@@ -158,7 +158,7 @@ public class FranceGeocentricInterpolati
         final ParameterBuilder builder = builder();
         FILE = builder
                 .addIdentifier("8727")
-                .addName("Geocentric translations file")
+                .addName("Geocentric translation file")
                 .setRemarks(NTv2.WARNING).create(File.class, Paths.get(DEFAULT));
         PARAMETERS = builder
                 .addIdentifier("9655")

Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java (from r1727537, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java&r1=1727537&r2=1727561&rev=1727561&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/AuthorityFactories.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -57,10 +57,10 @@ final class AuthorityFactories<T extends
      * plus the EPSG factory.
      */
     static final MultiAuthoritiesFactory ALL = new MultiAuthoritiesFactory(
-            new AuthorityFactories<>(CRSAuthorityFactory.class),
-            new AuthorityFactories<>(CSAuthorityFactory.class),
-            new AuthorityFactories<>(DatumAuthorityFactory.class),
-            new AuthorityFactories<>(CoordinateOperationAuthorityFactory.class))
+            new AuthorityFactories<CRSAuthorityFactory>(CRSAuthorityFactory.class),
+            new AuthorityFactories<CSAuthorityFactory>(CSAuthorityFactory.class),
+            new AuthorityFactories<DatumAuthorityFactory>(DatumAuthorityFactory.class),
+            new AuthorityFactories<CoordinateOperationAuthorityFactory>(CoordinateOperationAuthorityFactory.class))
     {
         /** Anonymous constructor */ {
             setLenient(true);

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -22,8 +22,8 @@ import java.util.ArrayList;
 import java.util.Collections;
 import javax.measure.unit.NonSI;
 import org.opengis.util.FactoryException;
-import org.opengis.util.NoSuchIdentifierException;
 import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.cs.EllipsoidalCS;
 import org.opengis.referencing.cs.AxisDirection;
 import org.opengis.referencing.cs.CoordinateSystem;
@@ -39,13 +39,12 @@ import org.opengis.referencing.crs.Proje
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.EngineeringCRS;
+import org.opengis.metadata.citation.Citation;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
-import org.apache.sis.internal.util.DefinitionURI;
 import org.apache.sis.internal.metadata.AxisDirections;
 import org.apache.sis.internal.referencing.ReferencingUtilities;
 import org.apache.sis.internal.system.DefaultFactories;
-import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.referencing.cs.DefaultVerticalCS;
 import org.apache.sis.referencing.cs.DefaultEllipsoidalCS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
@@ -53,9 +52,6 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.crs.DefaultCompoundCRS;
 import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.util.ArgumentChecks;
-import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.logging.Logging;
-import org.apache.sis.util.CharSequences;
 import org.apache.sis.util.Utilities;
 import org.apache.sis.util.Static;
 
@@ -129,15 +125,21 @@ public final class CRS extends Static {
      * This method accepts also the URN and URL syntax.
      * For example the following codes are considered equivalent to {@code "EPSG:4326"}:
      * <ul>
+     *   <li>{@code "EPSG::4326"}</li>
      *   <li>{@code "urn:ogc:def:crs:EPSG::4326"}</li>
+     *   <li>{@code "http://www.opengis.net/def/crs/epsg/0/4326"}</li>
      *   <li>{@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}</li>
      * </ul>
      *
+     * Note that the {@link IdentifiedObjects#lookupURN(IdentifiedObject, Citation)}
+     * method can be seen as a converse of this method.
+     *
      * @param  code The authority code.
      * @return The Coordinate Reference System for the given authority code.
      * @throws NoSuchAuthorityCodeException If there is no known CRS associated to the given code.
      * @throws FactoryException if the CRS creation failed for an other reason.
      *
+     * @see #getAuthorityFactory(String)
      * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory
      *
      * @category factory
@@ -146,40 +148,7 @@ public final class CRS extends Static {
             throws NoSuchAuthorityCodeException, FactoryException
     {
         ArgumentChecks.ensureNonNull("code", code);
-        final String authority;
-        final String value;
-        final DefinitionURI uri = DefinitionURI.parse(code);
-        if (uri != null) {
-            final String type = uri.type;
-            if (type != null && !type.equalsIgnoreCase("crs")) {
-                throw new NoSuchIdentifierException(Errors.format(Errors.Keys.UnknownType_1, type), type);
-            }
-            authority = uri.authority;
-            value = uri.code;
-        } else {
-            final int s = code.indexOf(DefinitionURI.SEPARATOR);
-            authority = CharSequences.trimWhitespaces(code.substring(0, Math.max(0, s)));
-            value = CharSequences.trimWhitespaces(code.substring(s + 1));
-        }
-        if (authority == null || authority.isEmpty()) {
-            throw new NoSuchIdentifierException(Errors.format(Errors.Keys.MissingAuthority_1, code), code);
-        }
-        /*
-         * Delegate to the factory for the code space of the given code. If no authority factory
-         * is available, or if the factory failed to create the CRS, delegate to CommonCRS. Note
-         * that CommonCRS is not expected to succeed if the real EPSG factory threw an exception,
-         * so we will log a message at the warning level in such case.
-         */
-        final CRSAuthorityFactory factory = DefaultFactories.forClass(CRSAuthorityFactory.class);
-        if (factory != null) try {
-            return factory.createCoordinateReferenceSystem(value);
-        } catch (FactoryException failure) {
-            final CoordinateReferenceSystem crs = CommonCRS.forCode(authority, value, failure);
-            Logging.unexpectedException(Logging.getLogger(Loggers.CRS_FACTORY), CRS.class, "forCode", failure); // See above comment.
-            return crs;
-        } else {
-            return CommonCRS.forCode(authority, value, null);
-        }
+        return AuthorityFactories.ALL.createCoordinateReferenceSystem(code);
     }
 
     /**
@@ -291,6 +260,7 @@ public final class CRS extends Static {
          */
         final boolean isGeodetic = (crs instanceof GeodeticCRS);
         if (isGeodetic || crs instanceof ProjectedCRS || crs instanceof EngineeringCRS) {
+            @SuppressWarnings("null")
             final CoordinateSystem cs = crs.getCoordinateSystem();
             if (cs.getDimension() == 2) {
                 return !isGeodetic || (cs instanceof EllipsoidalCS);
@@ -579,4 +549,42 @@ check:  while (lower != 0 || upper != di
         ArgumentChecks.ensureNonNull("crs", crs);
         return ReferencingUtilities.getGreenwichLongitude(crs.getDatum().getPrimeMeridian(), NonSI.DEGREE_ANGLE);
     }
+
+    /**
+     * Returns the system-wide authority factory used by {@link #forCode(String)} and other SIS methods.
+     * If the given authority is non-null, then this method returns a factory specifically for that authority.
+     * Otherwise, this method returns the {@link org.apache.sis.referencing.factory.MultiAuthoritiesFactory}
+     * instance that manages all other factories.
+     *
+     * <p>The {@code authority} argument can be {@code "EPSG"}, {@code "OGC"} or any other authority found
+     * on the classpath. In the {@code "EPSG"} case, whether the full set of EPSG codes is supported or not
+     * depends on whether a {@linkplain org.apache.sis.referencing.factory.sql connection to the database}
+     * can be established. If no connection can be established, then this method returns a small embedded
+     * EPSG factory containing at least the CRS defined in the {@link #forCode(String)} method javadoc.</p>
+     *
+     * <p>User-defined authorities can be added to the SIS environment by creating a {@code CRSAuthorityFactory}
+     * implementation with a public no-argument constructor, and declaring the fully-qualified name of that class
+     * in a file at the following location:</p>
+     *
+     * {@preformat text
+     *     META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
+     * }
+     *
+     * @param  authority The authority of the desired factory (typically {@code "EPSG"} or {@code "OGC"}),
+     *         or {@code null} for the {@link org.apache.sis.referencing.factory.MultiAuthoritiesFactory}
+     *         instance that manage all factories.
+     * @return The system-wide authority factory used by SIS for the given authority.
+     * @throws FactoryException if no factory can be returned for the given authority.
+     *
+     * @see #forCode(String)
+     * @see org.apache.sis.referencing.factory.MultiAuthoritiesFactory
+     *
+     * @since 0.7
+     */
+    public static CRSAuthorityFactory getAuthorityFactory(final String authority) throws FactoryException {
+        if (authority == null) {
+            return AuthorityFactories.ALL;
+        }
+        return AuthorityFactories.ALL.getAuthorityFactory(CRSAuthorityFactory.class, authority, null);
+    }
 }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/CommonCRS.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -26,16 +26,14 @@ import javax.measure.unit.Unit;
 import javax.measure.quantity.Duration;
 import org.opengis.util.FactoryException;
 import org.opengis.util.InternationalString;
-import org.opengis.util.NoSuchIdentifierException;
-import org.opengis.referencing.NoSuchAuthorityCodeException;
 import org.opengis.referencing.IdentifiedObject;
+import org.opengis.referencing.AuthorityFactory;
 import org.opengis.referencing.crs.GeodeticCRS;
 import org.opengis.referencing.crs.VerticalCRS;
 import org.opengis.referencing.crs.TemporalCRS;
 import org.opengis.referencing.crs.GeographicCRS;
 import org.opengis.referencing.crs.GeocentricCRS;
 import org.opengis.referencing.crs.ProjectedCRS;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.opengis.referencing.crs.CRSAuthorityFactory;
 import org.opengis.referencing.cs.TimeCS;
 import org.opengis.referencing.cs.VerticalCS;
@@ -59,13 +57,13 @@ import org.apache.sis.referencing.crs.De
 import org.apache.sis.referencing.crs.DefaultVerticalCRS;
 import org.apache.sis.referencing.crs.DefaultGeographicCRS;
 import org.apache.sis.referencing.crs.DefaultGeocentricCRS;
+import org.apache.sis.metadata.iso.citation.Citations;
 import org.apache.sis.internal.referencing.provider.TransverseMercator;
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.system.SystemListener;
 import org.apache.sis.internal.system.Modules;
 import org.apache.sis.internal.system.Loggers;
 import org.apache.sis.util.resources.Vocabulary;
-import org.apache.sis.util.resources.Errors;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.math.MathFunctions;
@@ -74,11 +72,6 @@ import org.apache.sis.measure.Units;
 
 import static java.util.Collections.singletonMap;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
-import static org.apache.sis.internal.util.Constants.CRS;
-import static org.apache.sis.internal.util.Constants.EPSG;
-import static org.apache.sis.internal.util.Constants.CRS27;
-import static org.apache.sis.internal.util.Constants.CRS83;
-import static org.apache.sis.internal.util.Constants.CRS84;
 
 // Branch-dependent imports
 import org.apache.sis.internal.jdk8.JDK8;
@@ -583,7 +576,7 @@ public enum CommonCRS {
                     }
                     // Use same name and datum than the geographic CRS.
                     final GeographicCRS base = geographic();
-                    object = new DefaultGeographicCRS(IdentifiedObjects.getProperties(base), base.getDatum(), cs);
+                    object = new DefaultGeographicCRS(properties(base, geo3D), base.getDatum(), cs);
                     cachedGeo3D = object;
                 }
             }
@@ -641,7 +634,7 @@ public enum CommonCRS {
                     }
                     // Use same name and datum than the geographic CRS.
                     final GeographicCRS base = geographic();
-                    object = new DefaultGeocentricCRS(IdentifiedObjects.getProperties(base), base.getDatum(), cs);
+                    object = new DefaultGeocentricCRS(properties(base, geocentric), base.getDatum(), cs);
                     cachedGeocentric = object;
                 }
             }
@@ -922,26 +915,6 @@ public enum CommonCRS {
         return crs;
     }
 
-    /**
-     * Returns the CRS for the given EPSG code, or {@code null} if none.
-     * This is a helper method for {@link #forCode(String, String, FactoryException)} only.
-     */
-    private CoordinateReferenceSystem forCode(final int code) {
-        if (code == geographic) return geographic();
-        if (code == geocentric) return geocentric();
-        if (code == geo3D)      return geographic3D();
-        final double latitude;
-        int zone;
-        if (northUTM != 0 && (zone = code - northUTM) >= firstZone && zone <= lastZone) {
-            latitude = +1;
-        } else if (southUTM != 0 && (zone = code - southUTM) >= firstZone && zone <= lastZone) {
-            latitude = -1;
-        } else {
-            return null;
-        }
-        return UTM(latitude, TransverseMercator.centralMeridian(zone));
-    }
-
 
 
 
@@ -1526,11 +1499,26 @@ public enum CommonCRS {
     }
 
     /**
+     * Returns the same properties than the given object, except for the identifier which is set to the given code.
+     */
+    private static Map<String,?> properties(final IdentifiedObject template, final short code) {
+        final Map<String,Object> properties = new HashMap<String,Object>(IdentifiedObjects.getProperties(template));
+        properties.put(GeographicCRS.IDENTIFIERS_KEY, new NamedIdentifier(Citations.EPSG, String.valueOf(code)));
+        return properties;
+    }
+
+    /**
      * Returns the EPSG factory to use for creating CRS, or {@code null} if none.
      * If this method returns {@code null}, then the caller will silently fallback on hard-coded values.
      */
     static CRSAuthorityFactory crsFactory() {
-        return null; // TODO
+        if (!EPSGFactoryFallback.FORCE_HARDCODED) {
+            final AuthorityFactory factory = AuthorityFactories.EPSG();
+            if (!(factory instanceof EPSGFactoryFallback)) {
+                return (CRSAuthorityFactory) factory;
+            }
+        }
+        return null;
     }
 
     /**
@@ -1538,7 +1526,13 @@ public enum CommonCRS {
      * If this method returns {@code null}, then the caller will silently fallback on hard-coded values.
      */
     static DatumAuthorityFactory datumFactory() {
-        return null; // TODO
+        if (!EPSGFactoryFallback.FORCE_HARDCODED) {
+            final AuthorityFactory factory = AuthorityFactories.EPSG();
+            if (!(factory instanceof EPSGFactoryFallback)) {
+                return (DatumAuthorityFactory) factory;
+            }
+        }
+        return null;
     }
 
     /**
@@ -1548,61 +1542,4 @@ public enum CommonCRS {
     static void failure(final Object caller, final String method, final FactoryException e) {
         Logging.unexpectedException(Logging.getLogger(Loggers.CRS_FACTORY), caller.getClass(), method, e);
     }
-
-    /**
-     * Returns a coordinate reference system for the given authority code.
-     * This method is invoked as a fallback when {@link CRS#forCode(String)}
-     * can not create a CRS for a given code.
-     *
-     * @param authority The authority, either {@code "CRS"} or {@code "EPSG"} (case-insensitive).
-     * @param code      The code, to be parsed as an integer.
-     * @param failure   The exception to throw in case of failure, or {@code null} for creating our own.
-     *                  A non-null value is provided when a real EPSG factory exists but failed to create the CRS.
-     *                  In such case, we want to report the error from the real factory instead than from this fallback.
-     *
-     * @since 0.5
-     */
-    static CoordinateReferenceSystem forCode(final String authority, final String code, final FactoryException failure)
-            throws FactoryException
-    {
-        NumberFormatException cause = null;
-        try {
-            if (authority.equalsIgnoreCase(CRS)) {
-                switch (Integer.parseInt(code)) {
-                    case CRS27: return CommonCRS.NAD27.normalizedGeographic();
-                    case CRS83: return CommonCRS.NAD83.normalizedGeographic();
-                    case CRS84: return CommonCRS.WGS84.normalizedGeographic();
-                }
-            } else if (authority.equalsIgnoreCase(EPSG)) {
-                final int n = Integer.parseInt(code);
-                if (n != 0) { // CommonCRS uses 0 as a sentinel value for "no EPSG code".
-                    for (final CommonCRS candidate : CommonCRS.values()) {
-                        final CoordinateReferenceSystem crs = candidate.forCode(n);
-                        if (crs != null) {
-                            return crs;
-                        }
-                    }
-                    for (final CommonCRS.Vertical candidate : CommonCRS.Vertical.values()) {
-                        if (candidate.isEPSG && candidate.crs == n) {
-                            return candidate.crs();
-                        }
-                    }
-                }
-            } else if (failure != null) {
-                throw failure;
-            } else {
-                throw new NoSuchIdentifierException(Errors.format(Errors.Keys.UnknownAuthority_1, authority), authority);
-            }
-        } catch (NumberFormatException e) {
-            cause = e;
-        }
-        if (failure != null) {
-            throw failure;
-        }
-        final NoSuchAuthorityCodeException e = new NoSuchAuthorityCodeException(
-                Errors.format(Errors.Keys.NoSuchAuthorityCode_3, authority, CoordinateReferenceSystem.class, code),
-                authority, code, code);
-        e.initCause(cause);
-        throw e;
-    }
 }

Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java (from r1727537, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java&r1=1727537&r2=1727561&rev=1727561&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -87,7 +87,7 @@ final class EPSGFactoryFallback extends
         final boolean geographic = type.isAssignableFrom(GeographicCRS.class);
         final boolean geocentric = type.isAssignableFrom(GeocentricCRS.class);
         final boolean projected  = type.isAssignableFrom(ProjectedCRS .class);
-        final Set<String> codes = new LinkedHashSet<>();
+        final Set<String> codes = new LinkedHashSet<String>();
         for (final CommonCRS crs : CommonCRS.values()) {
             if (geographic) {
                 add(codes, crs.geographic);

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -24,6 +24,7 @@ import java.util.Collection;
 
 import org.opengis.util.NameSpace;
 import org.opengis.util.GenericName;
+import org.opengis.util.FactoryException;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.IdentifiedObject;
@@ -31,11 +32,17 @@ import org.opengis.referencing.operation
 
 import org.apache.sis.util.Static;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.iso.DefaultNameSpace;
-import org.apache.sis.metadata.iso.citation.Citations; // For javadoc.
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.metadata.NameMeaning;
 import org.apache.sis.internal.metadata.NameToIdentifier;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
+import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
 
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.internal.util.Citations.iterator;
 import static org.apache.sis.internal.util.Citations.identifierMatches;
 
@@ -46,7 +53,7 @@ import static org.apache.sis.internal.ut
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Guilhem Legal (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see CRS
@@ -99,8 +106,8 @@ public final class IdentifiedObjects ext
      * @return An view of the identified object as an immutable map.
      */
     public static Map<String,?> getProperties(final IdentifiedObject object, final String... excludes) {
-        ensureNonNull("object", object);
-        ensureNonNull("excludes", excludes);
+        ArgumentChecks.ensureNonNull("object", object);
+        ArgumentChecks.ensureNonNull("excludes", excludes);
         return new Properties(object, excludes);
     }
 
@@ -366,6 +373,148 @@ public final class IdentifiedObjects ext
     }
 
     /**
+     * Looks up a URN, such as {@code "urn:ogc:def:crs:EPSG:8.2:4326"}, of the specified object.
+     * This method searches in all {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory geodetic
+     * authority factories} known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE
+     * approximatively equals} to the specified object. If such an object is found, then the URN for the given
+     * authority is returned. Otherwise or if there is ambiguity, this method returns {@code null}.
+     *
+     * <p><strong>Note that this method checks the identifier validity.</strong>
+     * If the given object declares explicitly an identifier, then this method will instantiate an object from the
+     * authority factory using that identifier and compare it with the given object. If the comparison fails, then
+     * this method returns {@code null}. Consequently this method may return {@code null} even if the given object
+     * declares explicitly its identifier. If the declared identifier is wanted unconditionally,
+     * one can use the following pattern instead:
+     *
+     * {@preformat java
+     *     String urn = toURN(object.getClass(), getIdentifier(object, authority));
+     * }
+     *
+     * This method can be seen as a converse of {@link CRS#forCode(String)}.
+     *
+     * @param  object The object (usually a {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+     *         coordinate reference system}) whose identifier is to be found, or {@code null}.
+     * @param  authority The authority for the identifier to return, or {@code null} for
+     *         the first identifier regardless its authority.
+     * @return The identifier, or {@code null} if none was found without ambiguity or if the given object was null.
+     * @throws FactoryException if an error occurred during the search.
+     *
+     * @see #newFinder(String)
+     * @see #toURN(Class, Identifier)
+     *
+     * @since 0.7
+     */
+    public static String lookupURN(final IdentifiedObject object, final Citation authority) throws FactoryException {
+        String urn = null;
+        if (object != null) {
+            for (final IdentifiedObject candidate : newFinder(null).find(object)) {
+                final String c = toURN(candidate.getClass(), getIdentifier(candidate, authority));
+                if (c != null) {
+                    if (urn != null && !urn.equals(c)) {
+                        return null;
+                    }
+                    urn = c;
+                }
+            }
+        }
+        return urn;
+    }
+
+    /**
+     * Looks up an EPSG code, such as {@code 4326}, of the specified object. This method searches in EPSG factories
+     * known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE approximatively equals}
+     * to the specified object. If such an object is found, then its EPSG identifier is returned.
+     * Otherwise or if there is ambiguity, this method returns {@code null}.
+     *
+     * <p><strong>Note that this method checks the identifier validity.</strong>
+     * If the given object declares explicitly an identifier, then this method will instantiate an object from the
+     * EPSG factory using that identifier and compare it with the given object. If the comparison fails, then this
+     * method returns {@code null}. Consequently this method may return {@code null} even if the given object
+     * declares explicitly its identifier. If the declared identifier is wanted unconditionally,
+     * one can use the following pattern instead:
+     *
+     * {@preformat java
+     *     String code = toString(getIdentifier(object, Citations.EPSG));
+     * }
+     *
+     * This method can be seen as a converse of {@link CRS#forCode(String)}.
+     *
+     * @param  object The object (usually a {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+     *         coordinate reference system}) whose EPSG code is to be found, or {@code null}.
+     * @return The EPSG code, or {@code null} if none was found without ambiguity or if the given object was null.
+     * @throws FactoryException if an error occurred during the search.
+     *
+     * @see #newFinder(String)
+     *
+     * @since 0.7
+     */
+    public static Integer lookupEPSG(final IdentifiedObject object) throws FactoryException {
+        Integer code = null;
+        if (object != null) {
+            for (final IdentifiedObject candidate : newFinder(Constants.EPSG).find(object)) {
+                final Identifier id = getIdentifier(candidate, Citations.EPSG);
+                if (id != null) try {
+                    Integer previous = code;
+                    code = Integer.valueOf(id.getCode());
+                    if (previous != null && !previous.equals(code)) {
+                        return null;
+                    }
+                } catch (NumberFormatException e) {
+                    Logging.recoverableException(Logging.getLogger(Loggers.CRS_FACTORY), IdentifiedObjects.class, "lookupEPSG", e);
+                }
+            }
+        }
+        return code;
+    }
+
+    /**
+     * Creates a finder which can be used for looking up unidentified objects.
+     * This method is an alternative to {@code lookup(…)} methods when more control are desired.
+     *
+     * <div class="note"><b>Example 1: be lenient regarding axis order</b><br>
+     * By default, {@code lookup(…)} methods require that objects in the dataset have their axes in the
+     * same order than the given object. For relaxing this condition, one can use the following Java code.
+     * This example assumes that at most one object from the dataset will match the given object.
+     * If more than one object may match, then the call to {@code findSingleton(…)} should be replaced
+     * by {@code find(…)}.
+     *
+     * {@preformat java
+     *     IdentifiedObjectFinder finder = IdentifiedObjects.newFinder(null);
+     *     finder.setIgnoringAxes(true);
+     *     IdentifiedObject found = finder.findSingleton(object);
+     * }</div>
+     *
+     * <div class="note"><b>Example 2: extend the search to deprecated definitions</b><br>
+     * By default, {@code lookup(…)} methods exclude deprecated objects from the search.
+     * To search also among deprecated objects, one can use the following Java code:
+     * This example does not use the {@code findSingleton(…)} convenience method on the assumption
+     * that the search may find both deprecated and non-deprecated objects.
+     *
+     * {@preformat java
+     *     IdentifiedObjectFinder finder = IdentifiedObjects.newFinder(null);
+     *     finder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
+     *     Set<IdentifiedObject> found = finder.find(object);
+     * }</div>
+     *
+     * @param  authority The authority of the objects to search (typically {@code "EPSG"} or {@code "OGC"}),
+     *         or {@code null} for searching among the objects created by all authorities.
+     * @return A finder to use for looking up unidentified objects.
+     * @throws FactoryException if the finder can not be created.
+     *
+     * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#newIdentifiedObjectFinder()
+     * @see IdentifiedObjectFinder#find(IdentifiedObject)
+     */
+    public static IdentifiedObjectFinder newFinder(final String authority) throws FactoryException {
+        final GeodeticAuthorityFactory factory;
+        if (authority == null) {
+            factory = AuthorityFactories.ALL;
+        } else {
+            factory = AuthorityFactories.ALL.getAuthorityFactory(GeodeticAuthorityFactory.class, authority, null);
+        }
+        return factory.newIdentifiedObjectFinder();
+    }
+
+    /**
      * Returns {@code true} if either the {@linkplain AbstractIdentifiedObject#getName() primary name} or at least
      * one {@linkplain AbstractIdentifiedObject#getAlias() alias} matches the given string according heuristic rules.
      * If the given object is an instance of {@link AbstractIdentifiedObject}, then this method delegates to its
@@ -404,12 +553,80 @@ public final class IdentifiedObjects ext
             // We really need to delegate to the overridden method.
             return ((AbstractIdentifiedObject) object).isHeuristicMatchForName(name);
         } else {
-            ensureNonNull("object", object);
+            ArgumentChecks.ensureNonNull("object", object);
             return NameToIdentifier.isHeuristicMatchForName(object.getName(), object.getAlias(), name);
         }
     }
 
     /**
+     * Returns the URN of the given identifier, or {@code null} if no valid URN can be formed.
+     * This method builds a URN from the {@linkplain NamedIdentifier#getCodeSpace() codespace},
+     * {@linkplain NamedIdentifier#getVersion() version} and {@linkplain NamedIdentifier#getCode() code}
+     * of the given identifier, completed by the given {@link Class} argument.
+     *
+     * <p>First, this method starts the URN with {@code "urn:"} followed by a namespace determined
+     * from the identifier {@linkplain NamedIdentifier#getCodeSpace() codespace} (which is usually
+     * an abbreviation of the identifier {@linkplain NamedIdentifier#getAuthority() authority}).
+     * The recognized namespaces are listed in the following table
+     * (note that the list of authorities than can be used in the {@code "urn:ogc:def"} namespace
+     * is specified by the <a href="http://www.opengeospatial.org/ogcna">OGC Naming Authority</a>).
+     * If this method can not determine a namespace for the given identifier, it returns {@code null}.</p>
+     *
+     * <table class="sis">
+     *   <caption>Valid values for the authority component in URN</caption>
+     *   <tr><th>Namespace</th>           <th>Authority in URN</th> <th>Description</th></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code EPSG}</td>     <td>EPSG dataset</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code OGC}</td>      <td>Open Geospatial Consortium</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code OGC-WFS}</td>  <td>OGC Web Feature Service</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code SI}</td>       <td>Système International d'Unités</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code UCUM}</td>     <td>Unified Code for Units of Measure</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code UNSD}</td>     <td>United Nations Statistics Division</td></tr>
+     *   <tr><td>{@code urn:ogc:def}</td> <td>{@code USNO}</td>     <td>United States Naval Observatory</td></tr>
+     * </table>
+     *
+     * The namespace is followed by the authority, then by a type determined from the given {@link Class} argument.
+     * That class is usually determined simply by {@code IdentifiedObject.getClass()}.
+     * The given class shall be assignable to one of the following types, otherwise this method returns {@code null}:
+     *
+     * <table class="sis">
+     *   <caption>Valid values for the type component in URN</caption>
+     *   <tr><th>Interface</th>                                                     <th>Type in URN</th>                 <th>Description</th></tr>
+     *   <tr><td>{@link org.opengis.referencing.cs.CoordinateSystemAxis}</td>       <td>{@code axis}</td>                <td>Coordinate system axe definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.operation.CoordinateOperation}</td> <td>{@code coordinateOperation}</td> <td>Coordinate operation definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.crs.CoordinateReferenceSystem}</td> <td>{@code crs}</td>                 <td>Coordinate reference system definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.cs.CoordinateSystem}</td>           <td>{@code cs}</td>                  <td>Coordinate system definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.Datum}</td>                   <td>{@code datum}</td>               <td>Datum definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.Ellipsoid}</td>               <td>{@code ellipsoid}</td>           <td>Ellipsoid definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.PrimeMeridian}</td>           <td>{@code meridian}</td>            <td>Prime meridian definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.operation.OperationMethod}</td>     <td>{@code method}</td>              <td>Operation method definition</td></tr>
+     *   <tr><td>{@link org.opengis.parameter.ParameterDescriptor}</td>             <td>{@code parameter}</td>           <td>Operation parameter definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.ReferenceSystem}</td>               <td>{@code referenceSystem}</td>     <td>Value reference system definition</td></tr>
+     *   <tr><td>{@link javax.measure.unit.Unit}</td>                               <td>{@code uom}</td>                 <td>Unit of measure definition</td></tr>
+     * </table>
+     *
+     * The type is followed by the {@linkplain NamedIdentifier#getVersion() codespace version} if available,
+     * and finally by the {@linkplain NamedIdentifier#getCode() code} value.
+     *
+     * <p>The above tables may be expanded in any future SIS version.</p>
+     *
+     * @param  type A type assignable to one of the types listed in above table.
+     * @param  identifier The identifier for which to format a URN, or {@code null}.
+     * @return The URN for the given identifier, or {@code null} if the given identifier was null
+     *         or can not be formatted by this method.
+     *
+     * @see #lookupURN(IdentifiedObject, Citation)
+     *
+     * @since 0.7
+     */
+    public static String toURN(final Class<?> type, final Identifier identifier) {
+        ArgumentChecks.ensureNonNull("type", type);
+        if (identifier == null) {
+            return null;
+        }
+        return NameMeaning.toURN(type, identifier.getCodeSpace(), identifier.getVersion(), identifier.getCode());
+    }
+
+    /**
      * Returns a string representation of the given identifier.
      * This method applies the following rules:
      *

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -64,6 +64,7 @@ import org.apache.sis.measure.Latitude;
 import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
 import static org.opengis.referencing.IdentifiedObject.ALIAS_KEY;
 import static org.opengis.referencing.IdentifiedObject.IDENTIFIERS_KEY;
+import static org.opengis.referencing.crs.GeographicCRS.SCOPE_KEY;
 import static org.opengis.referencing.datum.Datum.DOMAIN_OF_VALIDITY_KEY;
 import static org.apache.sis.internal.metadata.ReferencingServices.AUTHALIC_RADIUS;
 
@@ -113,12 +114,12 @@ final class StandardDefinitions {
 
     /**
      * Adds to the given properties an additional identifier in the {@code "CRS"} namespace.
-     * This method presume that the only identifier that existed before this method call was the EPSG one.
+     * This method presumes that the only identifier that existed before this method call was the EPSG one.
      */
     private static void addWMS(final Map<String,Object> properties, final String code) {
         properties.put(IDENTIFIERS_KEY, new NamedIdentifier[] {
             (NamedIdentifier) properties.get(IDENTIFIERS_KEY),
-            new NamedIdentifier(Citations.OGC, code)
+            new NamedIdentifier(Citations.WMS, code)
         });
     }
 
@@ -163,9 +164,10 @@ final class StandardDefinitions {
     static GeographicCRS createGeographicCRS(final short code, final GeodeticDatum datum, final EllipsoidalCS cs) {
         final String name;
         String alias = null;
+        String scope = null;
         boolean world = false;
         switch (code) {
-            case 4326: name = "WGS 84"; world = true; break;
+            case 4326: name = "WGS 84"; world = true; scope = "Horizontal component of 3D system."; break;
             case 4322: name = "WGS 72"; world = true; break;
             case 4258: name = "ETRS89"; alias = "ETRS89-GRS80"; break;
             case 4269: name = "NAD83";  break;
@@ -174,7 +176,9 @@ final class StandardDefinitions {
             case 4047: name = "Unspecified datum based upon the GRS 1980 Authalic Sphere"; world = true; break;
             default:   throw new AssertionError(code);
         }
-        return new DefaultGeographicCRS(properties(code, name, alias, world), datum, cs);
+        final Map<String, Object> properties = properties(code, name, alias, world);
+        properties.put(SCOPE_KEY, scope);
+        return new DefaultGeographicCRS(properties, datum, cs);
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/DefaultGeographicCRS.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -260,7 +260,7 @@ public class DefaultGeographicCRS extend
                     final int i = Arrays.binarySearch(EPSG_CODES, Short.parseShort(identifier.getCode()));
                     if (i >= 0) {
                         final Map<String,Object> c = new HashMap<String,Object>(properties);
-                        c.put(IDENTIFIERS_KEY, new ImmutableIdentifier(Citations.OGC, CRS, Short.toString(CRS_CODES[i])));
+                        c.put(IDENTIFIERS_KEY, new ImmutableIdentifier(Citations.WMS, CRS, Short.toString(CRS_CODES[i])));
                         properties = c;
                     }
                 } catch (NumberFormatException e) {

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -72,24 +72,24 @@ import org.apache.sis.internal.jdk7.Obje
  * and apply the interpolated translations on coordinate values in their own step between above steps 3 and 4.
  *
  * <div class="note"><b>Use cases:</b>
- * <ul>
- *   <li><p><b>Datum shift by geographic translations</b><br>
+ * <ul class="verbose">
+ *   <li><b>Datum shift by geographic translations</b><br>
  *   NADCON and NTv2 grids are defined with longitude (<var>λ</var>) and latitude (<var>φ</var>) inputs in angular
  *   <em>degrees</em> and give (<var>Δλ</var>, <var>Δφ</var>) translations in angular <em>seconds</em>.
  *   However SIS stores the translation values in units of grid cell rather than angular seconds.
  *   The translations will be applied by {@link org.apache.sis.referencing.operation.transform.InterpolatedTransform}
  *   directly on the given (<var>λ</var>,<var>φ</var>) coordinates.
- *   </p></li>
+ *   </li>
  *
- *   <li><p><b>Datum shift by geocentric translations</b><br>
+ *   <li><b>Datum shift by geocentric translations</b><br>
  *   France interpolation grid is defined with longitude (<var>λ</var>) and latitude (<var>φ</var>) inputs in angular
  *   <em>degrees</em> and gives (<var>ΔX</var>, <var>ΔY</var>, <var>ΔZ</var>) geocentric translations in <em>metres</em>.
  *   Those translations will not be added directly to the given (<var>λ</var>,<var>φ</var>) coordinates since there is
  *   a geographic/geocentric conversion in the middle
  *   (see {@link org.apache.sis.referencing.operation.transform.InterpolatedGeocentricTransform}).
- *   </p></li>
+ *   </li>
  *
- *   <li><p><b>Localization grid of raster data</b><br>
+ *   <li><b>Localization grid of raster data</b><br>
  *   Some remote sensing raster data are provided with a <cite>localization grid</cite> giving pixel coordinates
  *   (e.g. latitude and longitude). This can been seen as a change from {@linkplain DefaultImageDatum image datum}
  *   to {@linkplain DefaultGeodeticDatum geodetic datum}. The coordinate transformation process can sometime be
@@ -97,7 +97,7 @@ import org.apache.sis.internal.jdk7.Obje
  *   {@linkplain org.apache.sis.referencing.operation.builder.LinearTransformBuilder first approximation},
  *   followed by small corrections for the residual part.
  *   {@code DatumShiftGrid} can describe the small corrections part.
- *   </p></li>
+ *   </li>
  * </ul></div>
  *
  * Implementations of this class shall be immutable and thread-safe.

Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java (from r1727537, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java&r1=1727537&r2=1727561&rev=1727561&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryIdentifier.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -35,7 +35,7 @@ import org.apache.sis.internal.system.Lo
 import org.apache.sis.internal.metadata.NameMeaning;
 
 // Branch-dependent imports
-import java.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
 
 
 /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java?rev=1727561&r1=1727560&r2=1727561&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java [UTF-8] Fri Jan 29 12:23:09 2016
@@ -16,6 +16,9 @@
  */
 package org.apache.sis.referencing.factory;
 
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Locale;
 import javax.measure.unit.Unit;
 import org.opengis.referencing.cs.*;
 import org.opengis.referencing.crs.*;
@@ -26,6 +29,7 @@ import org.opengis.referencing.Authority
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.util.FactoryException;
+import org.opengis.util.InternationalString;
 import org.apache.sis.util.resources.Errors;
 
 
@@ -64,10 +68,17 @@ abstract class AuthorityFactoryProxy<T>
     final Class<T> type;
 
     /**
+     * The type of factory needed for creating objects,
+     * as one of the constants defined in {@link AuthorityFactoryIdentifier}.
+     */
+    final byte factoryType;
+
+    /**
      * Creates a new proxy for objects of the given type.
      */
-    AuthorityFactoryProxy(final Class<T> type) {
+    AuthorityFactoryProxy(final Class<T> type, final byte factoryType) {
         this.type = type;
+        this.factoryType = factoryType;
     }
 
     /**
@@ -148,7 +159,9 @@ abstract class AuthorityFactoryProxy<T>
      * @return The object created from the given code.
      * @throws FactoryException If an error occurred while creating the object.
      */
-    abstract T create(GeodeticAuthorityFactory factory, String code) throws FactoryException;
+    T create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
+        return createFromAPI(factory, code);
+    }
 
     /**
      * Creates the object for the given code using only GeoAPI interfaces.
@@ -162,20 +175,27 @@ abstract class AuthorityFactoryProxy<T>
     abstract T createFromAPI(AuthorityFactory factory, String code) throws FactoryException;
 
     /**
-     * The proxy for the {@link GeodeticAuthorityFactory#createObject} method.
+     * The proxy for the {@link GeodeticAuthorityFactory#getDescriptionText(String)} method.
      */
-    static final AuthorityFactoryProxy<IdentifiedObject> OBJECT =
-        new AuthorityFactoryProxy<IdentifiedObject>(IdentifiedObject.class) {
-            @Override IdentifiedObject create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
-                return factory.createObject(code);
+    static final AuthorityFactoryProxy<InternationalString> DESCRIPTION =
+        new AuthorityFactoryProxy<InternationalString>(InternationalString.class, AuthorityFactoryIdentifier.ANY) {
+            @Override InternationalString createFromAPI(AuthorityFactory factory, String code) throws FactoryException {
+                return factory.getDescriptionText(code);
             }
+    };
+
+    /**
+     * The proxy for the {@link GeodeticAuthorityFactory#createObject(String)} method.
+     */
+    static final AuthorityFactoryProxy<IdentifiedObject> OBJECT =
+        new AuthorityFactoryProxy<IdentifiedObject>(IdentifiedObject.class, AuthorityFactoryIdentifier.ANY) {
             @Override IdentifiedObject createFromAPI(AuthorityFactory factory, String code) throws FactoryException {
                 return factory.createObject(code);
             }
     };
 
     static final AuthorityFactoryProxy<Datum> DATUM =
-        new AuthorityFactoryProxy<Datum>(Datum.class) {
+        new AuthorityFactoryProxy<Datum>(Datum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override Datum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createDatum(code);
             }
@@ -185,7 +205,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<EngineeringDatum> ENGINEERING_DATUM =
-        new AuthorityFactoryProxy<EngineeringDatum>(EngineeringDatum.class) {
+        new AuthorityFactoryProxy<EngineeringDatum>(EngineeringDatum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override EngineeringDatum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createEngineeringDatum(code);
             }
@@ -195,7 +215,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<ImageDatum> IMAGE_DATUM =
-        new AuthorityFactoryProxy<ImageDatum>(ImageDatum.class) {
+        new AuthorityFactoryProxy<ImageDatum>(ImageDatum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override ImageDatum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createImageDatum(code);
             }
@@ -205,7 +225,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<VerticalDatum> VERTICAL_DATUM =
-        new AuthorityFactoryProxy<VerticalDatum>(VerticalDatum.class) {
+        new AuthorityFactoryProxy<VerticalDatum>(VerticalDatum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override VerticalDatum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createVerticalDatum(code);
             }
@@ -215,7 +235,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<TemporalDatum> TEMPORAL_DATUM =
-        new AuthorityFactoryProxy<TemporalDatum>(TemporalDatum.class) {
+        new AuthorityFactoryProxy<TemporalDatum>(TemporalDatum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override TemporalDatum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createTemporalDatum(code);
             }
@@ -225,7 +245,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<GeodeticDatum> GEODETIC_DATUM =
-        new AuthorityFactoryProxy<GeodeticDatum>(GeodeticDatum.class) {
+        new AuthorityFactoryProxy<GeodeticDatum>(GeodeticDatum.class, AuthorityFactoryIdentifier.DATUM) {
             @Override GeodeticDatum create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createGeodeticDatum(code);
             }
@@ -235,7 +255,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<Ellipsoid> ELLIPSOID =
-        new AuthorityFactoryProxy<Ellipsoid>(Ellipsoid.class) {
+        new AuthorityFactoryProxy<Ellipsoid>(Ellipsoid.class, AuthorityFactoryIdentifier.DATUM) {
             @Override Ellipsoid create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createEllipsoid(code);
             }
@@ -245,7 +265,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<PrimeMeridian> PRIME_MERIDIAN =
-        new AuthorityFactoryProxy<PrimeMeridian>(PrimeMeridian.class) {
+        new AuthorityFactoryProxy<PrimeMeridian>(PrimeMeridian.class, AuthorityFactoryIdentifier.DATUM) {
             @Override PrimeMeridian create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createPrimeMeridian(code);
             }
@@ -255,7 +275,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<Extent> EXTENT =
-        new AuthorityFactoryProxy<Extent>(Extent.class) {
+        new AuthorityFactoryProxy<Extent>(Extent.class, AuthorityFactoryIdentifier.GEODETIC) {
             @Override Extent create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createExtent(code);
             }
@@ -265,7 +285,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CoordinateSystem> COORDINATE_SYSTEM =
-        new AuthorityFactoryProxy<CoordinateSystem>(CoordinateSystem.class) {
+        new AuthorityFactoryProxy<CoordinateSystem>(CoordinateSystem.class, AuthorityFactoryIdentifier.CS) {
             @Override CoordinateSystem create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCoordinateSystem(code);
             }
@@ -275,7 +295,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CartesianCS> CARTESIAN_CS =
-        new AuthorityFactoryProxy<CartesianCS>(CartesianCS.class) {
+        new AuthorityFactoryProxy<CartesianCS>(CartesianCS.class, AuthorityFactoryIdentifier.CS) {
             @Override CartesianCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCartesianCS(code);
             }
@@ -285,7 +305,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<PolarCS> POLAR_CS =
-        new AuthorityFactoryProxy<PolarCS>(PolarCS.class) {
+        new AuthorityFactoryProxy<PolarCS>(PolarCS.class, AuthorityFactoryIdentifier.CS) {
             @Override PolarCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createPolarCS(code);
             }
@@ -295,7 +315,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CylindricalCS> CYLINDRICAL_CS =
-        new AuthorityFactoryProxy<CylindricalCS>(CylindricalCS.class) {
+        new AuthorityFactoryProxy<CylindricalCS>(CylindricalCS.class, AuthorityFactoryIdentifier.CS) {
             @Override CylindricalCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCylindricalCS(code);
             }
@@ -305,7 +325,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<SphericalCS> SPHERICAL_CS =
-        new AuthorityFactoryProxy<SphericalCS>(SphericalCS.class) {
+        new AuthorityFactoryProxy<SphericalCS>(SphericalCS.class, AuthorityFactoryIdentifier.CS) {
             @Override SphericalCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createSphericalCS(code);
             }
@@ -315,7 +335,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<EllipsoidalCS> ELLIPSOIDAL_CS =
-        new AuthorityFactoryProxy<EllipsoidalCS>(EllipsoidalCS.class) {
+        new AuthorityFactoryProxy<EllipsoidalCS>(EllipsoidalCS.class, AuthorityFactoryIdentifier.CS) {
             @Override EllipsoidalCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createEllipsoidalCS(code);
             }
@@ -325,7 +345,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<VerticalCS> VERTICAL_CS =
-        new AuthorityFactoryProxy<VerticalCS>(VerticalCS.class) {
+        new AuthorityFactoryProxy<VerticalCS>(VerticalCS.class, AuthorityFactoryIdentifier.CS) {
             @Override VerticalCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createVerticalCS(code);
             }
@@ -335,7 +355,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<TimeCS> TIME_CS =
-        new AuthorityFactoryProxy<TimeCS>(TimeCS.class) {
+        new AuthorityFactoryProxy<TimeCS>(TimeCS.class, AuthorityFactoryIdentifier.CS) {
             @Override TimeCS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createTimeCS(code);
             }
@@ -345,7 +365,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CoordinateSystemAxis> AXIS =
-        new AuthorityFactoryProxy<CoordinateSystemAxis>(CoordinateSystemAxis.class) {
+        new AuthorityFactoryProxy<CoordinateSystemAxis>(CoordinateSystemAxis.class, AuthorityFactoryIdentifier.CS) {
             @Override CoordinateSystemAxis create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCoordinateSystemAxis(code);
             }
@@ -356,7 +376,7 @@ abstract class AuthorityFactoryProxy<T>
 
     @SuppressWarnings({"rawtypes","unchecked"})
     static final AuthorityFactoryProxy<Unit<?>> UNIT =
-        new AuthorityFactoryProxy<Unit<?>>((Class) Unit.class) {
+        new AuthorityFactoryProxy<Unit<?>>((Class) Unit.class, AuthorityFactoryIdentifier.CS) {
             @Override Unit<?> create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createUnit(code);
             }
@@ -366,7 +386,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CoordinateReferenceSystem> CRS =
-        new AuthorityFactoryProxy<CoordinateReferenceSystem>(CoordinateReferenceSystem.class) {
+        new AuthorityFactoryProxy<CoordinateReferenceSystem>(CoordinateReferenceSystem.class, AuthorityFactoryIdentifier.CRS) {
             @Override CoordinateReferenceSystem create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCoordinateReferenceSystem(code);
             }
@@ -376,7 +396,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CompoundCRS> COMPOUND_CRS =
-        new AuthorityFactoryProxy<CompoundCRS>(CompoundCRS.class) {
+        new AuthorityFactoryProxy<CompoundCRS>(CompoundCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override CompoundCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCompoundCRS(code);
             }
@@ -386,7 +406,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<DerivedCRS> DERIVED_CRS =
-        new AuthorityFactoryProxy<DerivedCRS>(DerivedCRS.class) {
+        new AuthorityFactoryProxy<DerivedCRS>(DerivedCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override DerivedCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createDerivedCRS(code);
             }
@@ -396,7 +416,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<EngineeringCRS> ENGINEERING_CRS =
-        new AuthorityFactoryProxy<EngineeringCRS>(EngineeringCRS.class) {
+        new AuthorityFactoryProxy<EngineeringCRS>(EngineeringCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override EngineeringCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createEngineeringCRS(code);
             }
@@ -406,7 +426,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<GeographicCRS> GEOGRAPHIC_CRS =
-        new AuthorityFactoryProxy<GeographicCRS>(GeographicCRS.class) {
+        new AuthorityFactoryProxy<GeographicCRS>(GeographicCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override GeographicCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createGeographicCRS(code);
             }
@@ -416,7 +436,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<GeocentricCRS> GEOCENTRIC_CRS =
-        new AuthorityFactoryProxy<GeocentricCRS>(GeocentricCRS.class) {
+        new AuthorityFactoryProxy<GeocentricCRS>(GeocentricCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override GeocentricCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createGeocentricCRS(code);
             }
@@ -426,7 +446,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<ImageCRS> IMAGE_CRS =
-        new AuthorityFactoryProxy<ImageCRS>(ImageCRS.class) {
+        new AuthorityFactoryProxy<ImageCRS>(ImageCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override ImageCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createImageCRS(code);
             }
@@ -436,7 +456,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<ProjectedCRS> PROJECTED_CRS =
-        new AuthorityFactoryProxy<ProjectedCRS>(ProjectedCRS.class) {
+        new AuthorityFactoryProxy<ProjectedCRS>(ProjectedCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override ProjectedCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createProjectedCRS(code);
             }
@@ -446,7 +466,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<TemporalCRS> TEMPORAL_CRS =
-        new AuthorityFactoryProxy<TemporalCRS>(TemporalCRS.class) {
+        new AuthorityFactoryProxy<TemporalCRS>(TemporalCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override TemporalCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createTemporalCRS(code);
             }
@@ -456,7 +476,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<VerticalCRS> VERTICAL_CRS =
-        new AuthorityFactoryProxy<VerticalCRS>(VerticalCRS.class) {
+        new AuthorityFactoryProxy<VerticalCRS>(VerticalCRS.class, AuthorityFactoryIdentifier.CRS) {
             @Override VerticalCRS create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createVerticalCRS(code);
             }
@@ -467,7 +487,7 @@ abstract class AuthorityFactoryProxy<T>
 
     @SuppressWarnings("rawtypes")
     static final AuthorityFactoryProxy<ParameterDescriptor> PARAMETER =
-        new AuthorityFactoryProxy<ParameterDescriptor>(ParameterDescriptor.class) {
+        new AuthorityFactoryProxy<ParameterDescriptor>(ParameterDescriptor.class, AuthorityFactoryIdentifier.GEODETIC) {
             @Override ParameterDescriptor<?> create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createParameterDescriptor(code);
             }
@@ -477,7 +497,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<OperationMethod> METHOD =
-        new AuthorityFactoryProxy<OperationMethod>(OperationMethod.class) {
+        new AuthorityFactoryProxy<OperationMethod>(OperationMethod.class, AuthorityFactoryIdentifier.OPERATION) {
             @Override OperationMethod create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createOperationMethod(code);
             }
@@ -487,7 +507,7 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     static final AuthorityFactoryProxy<CoordinateOperation> OPERATION =
-        new AuthorityFactoryProxy<CoordinateOperation>(CoordinateOperation.class) {
+        new AuthorityFactoryProxy<CoordinateOperation>(CoordinateOperation.class, AuthorityFactoryIdentifier.OPERATION) {
             @Override CoordinateOperation create(GeodeticAuthorityFactory factory, String code) throws FactoryException {
                 return factory.createCoordinateOperation(code);
             }
@@ -497,6 +517,71 @@ abstract class AuthorityFactoryProxy<T>
     };
 
     /**
+     * The list of all proxies. The most specific types must appear first in this array,
+     * with a preference for those who are more likely to be requested.
+     * This field can be declared only after all the above constants.
+     */
+    static final AuthorityFactoryProxy<?>[] PROXIES = new AuthorityFactoryProxy<?>[] {
+        PROJECTED_CRS,      // Special kind of GeneralDerivedCRS.
+        GEOGRAPHIC_CRS,     // Special kind of GeodeticCRS.
+        GEOCENTRIC_CRS,     // Special kind of GeodeticCRS.
+        VERTICAL_CRS,
+        TEMPORAL_CRS,
+        IMAGE_CRS,          // Can been seen as a special kind of EngineeringCRS (even if not shown in hierarchy).
+        ENGINEERING_CRS,
+        DERIVED_CRS,        // DerivedCRS can be also Vertical, Temporal or Engineering CRS. Give precedence to those.
+        COMPOUND_CRS,
+        CRS,
+        GEODETIC_DATUM,
+        VERTICAL_DATUM,
+        TEMPORAL_DATUM,
+        IMAGE_DATUM,        // Can been seen as a special kind of EngineeringDatum (even if not shown in hierarchy).
+        ENGINEERING_DATUM,
+        DATUM,
+        ELLIPSOID,
+        PRIME_MERIDIAN,
+        CARTESIAN_CS,       // Special case of AffineCS.
+        ELLIPSOIDAL_CS,
+        SPHERICAL_CS,
+        CYLINDRICAL_CS,
+        POLAR_CS,
+        VERTICAL_CS,
+        TIME_CS,
+        COORDINATE_SYSTEM,
+        AXIS,
+        OPERATION,
+        METHOD,
+        PARAMETER,
+        UNIT,
+        EXTENT,
+        OBJECT,
+        DESCRIPTION
+    };
+
+    /**
+     * The proxy to use for a given type declared in a URN.
+     * For example in the {@code "urn:ogc:def:crs:EPSG::4326"} URN, the proxy to use is {@link #CRS}.
+     *
+     * <p>Keys must be in lower case.</p>
+     */
+    private static final Map<String, AuthorityFactoryProxy<?>> BY_URN_TYPE;
+    static {
+        final Map<String, AuthorityFactoryProxy<?>> map = new HashMap<String, AuthorityFactoryProxy<?>>(14);
+        map.put("crs",                  CRS);
+        map.put("datum",                DATUM);
+        map.put("ellipsoid",            ELLIPSOID);
+        map.put("meridian",             PRIME_MERIDIAN);
+        map.put("cs",                   COORDINATE_SYSTEM);
+        map.put("axis",                 AXIS);
+        map.put("coordinateoperation",  OPERATION);
+        map.put("method",               METHOD);
+        map.put("parameter",            PARAMETER);
+        map.put("referencesystem",      CRS);
+        map.put("uom",                  UNIT);
+        BY_URN_TYPE = map;
+    }
+
+    /**
      * Returns the instance for the given type. The {@code type} argument can be a GeoAPI interface
      * or some implementation class like {@link org.apache.sis.referencing.crs.DefaultProjectedCRS}.
      * This method returns the most specific proxy for the given type.
@@ -519,42 +604,23 @@ abstract class AuthorityFactoryProxy<T>
     }
 
     /**
-     * The types of proxies. The most specific types must appear first in this list.
-     * This field can be declared only after all the above constants.
+     * The proxy to use for a given type declared in a URN.
+     * For example in the {@code "urn:ogc:def:crs:EPSG::4326"} URN, the proxy to use is {@link #CRS}.
+     *
+     * @param  typeName The URN type.
+     * @return The proxy for the given type, or {@code null} if the given type is illegal.
      */
-    static final AuthorityFactoryProxy<?>[] PROXIES = new AuthorityFactoryProxy<?>[] {
-        OPERATION,
-        METHOD,
-        PARAMETER,
-        PROJECTED_CRS,
-        GEOGRAPHIC_CRS,
-        GEOCENTRIC_CRS,
-        IMAGE_CRS,
-        DERIVED_CRS,
-        VERTICAL_CRS,
-        TEMPORAL_CRS,
-        ENGINEERING_CRS,
-        COMPOUND_CRS,
-        CRS,
-        AXIS,
-        CARTESIAN_CS,
-        ELLIPSOIDAL_CS,
-        SPHERICAL_CS,
-        CYLINDRICAL_CS,
-        POLAR_CS,
-        VERTICAL_CS,
-        TIME_CS,
-        COORDINATE_SYSTEM,
-        PRIME_MERIDIAN,
-        ELLIPSOID,
-        GEODETIC_DATUM,
-        IMAGE_DATUM,
-        VERTICAL_DATUM,
-        TEMPORAL_DATUM,
-        ENGINEERING_DATUM,
-        DATUM,
-        EXTENT,
-        UNIT,
-        OBJECT
-    };
+    @SuppressWarnings("unchecked")
+    AuthorityFactoryProxy<? extends T> specialize(final String typeName) {
+        final AuthorityFactoryProxy<?> c = BY_URN_TYPE.get(typeName.toLowerCase(Locale.US));
+        if (c != null) {
+            if (c.type.isAssignableFrom(type)) {
+                return this;
+            }
+            if (type.isAssignableFrom(c.type)) {
+                return (AuthorityFactoryProxy<? extends T>) c;
+            }
+        }
+        return null;
+    }
 }



Mime
View raw message