public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem()

in endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [1331:1592]


    public synchronized CoordinateReferenceSystem createCoordinateReferenceSystem(final String code)
            throws NoSuchAuthorityCodeException, FactoryException
    {
        ArgumentChecks.ensureNonNull("code", code);
        CoordinateReferenceSystem returnValue = null;
        try (ResultSet result = executeQuery("Coordinate Reference System", "COORD_REF_SYS_CODE", "COORD_REF_SYS_NAME",
                "SELECT COORD_REF_SYS_CODE,"          +     // [ 1]
                      " COORD_REF_SYS_NAME,"          +     // [ 2]
                      " AREA_OF_USE_CODE,"            +     // [ 3]
                      " CRS_SCOPE,"                   +     // [ 4]
                      " REMARKS,"                     +     // [ 5]
                      " DEPRECATED,"                  +     // [ 6]
                      " COORD_REF_SYS_KIND,"          +     // [ 7]
                      " COORD_SYS_CODE,"              +     // [ 8] Null for CompoundCRS
                      " DATUM_CODE,"                  +     // [ 9] Null for ProjectedCRS
                      " SOURCE_GEOGCRS_CODE,"         +     // [10] For ProjectedCRS
                      " PROJECTION_CONV_CODE,"        +     // [11] For ProjectedCRS
                      " CMPD_HORIZCRS_CODE,"          +     // [12] For CompoundCRS only
                      " CMPD_VERTCRS_CODE"            +     // [13] For CompoundCRS only
                " FROM [Coordinate Reference System]" +
                " WHERE COORD_REF_SYS_CODE = ?", code))
        {
            while (result.next()) {
                final Integer epsg       = getInteger  (code, result, 1);
                final String  name       = getString   (code, result, 2);
                final String  area       = getOptionalString (result, 3);
                final String  scope      = getOptionalString (result, 4);
                final String  remarks    = getOptionalString (result, 5);
                final boolean deprecated = getOptionalBoolean(result, 6);
                final String  type       = getString   (code, result, 7);
                /*
                 * Note: Do not invoke `createProperties` now, even if we have all required information,
                 *       because the `properties` map is going to overwritten by calls to `createDatum`, etc.
                 *
                 * The following switch statement should have a case for all "epsg_crs_kind" values enumerated
                 * in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases.
                 */
                final CRSFactory crsFactory = owner.crsFactory;
                final CoordinateReferenceSystem crs;
                switch (type.toLowerCase(Locale.US)) {
                    /* ----------------------------------------------------------------------
                     *   GEOGRAPHIC CRS
                     *
                     *   NOTE: `createProperties` MUST be invoked after any call to another
                     *         `createFoo` method. Consequently, do not factor out.
                     * ---------------------------------------------------------------------- */
                    case "geographic 2d":
                    case "geographic 3d": {
                        Integer csCode = getInteger(code, result, 8);
                        if (replaceDeprecatedCS) {
                            csCode = DEPRECATED_CS.getOrDefault(csCode, csCode);
                        }
                        final EllipsoidalCS cs = owner.createEllipsoidalCS(csCode.toString());
                        final String datumCode = getOptionalString(result, 9);
                        final GeodeticDatum datum;
                        if (datumCode != null) {
                            datum = owner.createGeodeticDatum(datumCode);
                        } else {
                            final String geoCode = getString(code, result, 10, 9);
                            result.close();     // Must be closed before call to createGeographicCRS(String)
                            ensureNoCycle(GeographicCRS.class, epsg);
                            try {
                                datum = owner.createGeographicCRS(geoCode).getDatum();
                            } finally {
                                endOfRecursion(GeographicCRS.class, epsg);
                            }
                        }
                        crs = crsFactory.createGeographicCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   PROJECTED CRS
                     *
                     *   NOTE: This method invokes itself indirectly, through createGeographicCRS.
                     *         Consequently, we cannot use `result` anymore after this block.
                     * ---------------------------------------------------------------------- */
                    case "projected": {
                        final String csCode  = getString(code, result,  8);
                        final String geoCode = getString(code, result, 10);
                        final String opCode  = getString(code, result, 11);
                        result.close();      // Must be closed before call to createFoo(String)
                        ensureNoCycle(ProjectedCRS.class, epsg);
                        try {
                            final CartesianCS cs = owner.createCartesianCS(csCode);
                            final Conversion op;
                            try {
                                op = (Conversion) owner.createCoordinateOperation(opCode);
                            } catch (ClassCastException e) {
                                // Should never happen in a well-formed EPSG database.
                                // If happen anyway, the ClassCastException cause will give more hints than just the message.
                                throw (NoSuchAuthorityCodeException) noSuchAuthorityCode(Conversion.class, opCode).initCause(e);
                            }
                            final CoordinateReferenceSystem baseCRS;
                            final boolean suspendParamChecks;
                            if (!deprecated) {
                                baseCRS = owner.createCoordinateReferenceSystem(geoCode);
                                suspendParamChecks = true;
                            } else {
                                /*
                                 * If the ProjectedCRS is deprecated, one reason among others may be that it uses one of
                                 * the deprecated coordinate systems. Those deprecated CS used non-linear units like DMS.
                                 * Apache SIS cannot instantiate a ProjectedCRS when the baseCRS uses such units, so we
                                 * set a flag asking to replace the deprecated CS by a supported one. Since that baseCRS
                                 * would not be exactly as defined by EPSG, we must not cache it because we do not want
                                 * `owner.createGeographicCRS(geoCode)` to return that modified CRS. Since the same CRS
                                 * may be recreated every time a deprecated ProjectedCRS is created, we temporarily
                                 * shutdown the loggings in order to avoid the same warning to be logged many time.
                                 */
                                final boolean old = quiet;
                                try {
                                    quiet = true;
                                    replaceDeprecatedCS = true;
                                    baseCRS = createCoordinateReferenceSystem(geoCode);         // Do not cache that CRS.
                                } finally {
                                    replaceDeprecatedCS = false;
                                    quiet = old;
                                }
                                /*
                                 * The crsFactory method calls will indirectly create a parameterized MathTransform.
                                 * Their constructor will try to verify the parameter validity. But some deprecated
                                 * CRS had invalid parameter values (they were deprecated precisely for that reason).
                                 * If and only if we are creating a deprecated CRS, temporarily suspend the parameter
                                 * checks.
                                 */
                                suspendParamChecks = Semaphores.queryAndSet(Semaphores.SUSPEND_PARAMETER_CHECK);
                                // Try block must be immediately after above line (do not insert any code between).
                            }
                            try {
                                /*
                                 * For a ProjectedCRS, the baseCRS is always geodetic. So in theory we would not
                                 * need the `instanceof` check. However, the EPSG dataset version 8.9 also uses the
                                 * "projected" type for CRS that are actually derived CRS. See EPSG:5820 and 5821.
                                 *
                                 * TODO: there is an ambiguity when the source CRS is geographic but the operation
                                 * is nevertheless considered as not a map projection. It is the case of EPSG:5819.
                                 * The problem is that the "COORD_REF_SYS_KIND" column still contains "Projected".
                                 * We need to check if EPSG database 10+ has more specific information.
                                 * See https://issues.apache.org/jira/browse/SIS-518
                                 */
                                @SuppressWarnings("LocalVariableHidesMemberVariable")
                                final Map<String,Object> properties = createProperties("Coordinate Reference System",
                                                                        name, epsg, area, scope, remarks, deprecated);
                                if (baseCRS instanceof GeographicCRS) {
                                    crs = crsFactory.createProjectedCRS(properties, (GeographicCRS) baseCRS, op, cs);
                                } else {
                                    crs = crsFactory.createDerivedCRS(properties, baseCRS, op, cs);
                                }
                            } finally {
                                Semaphores.clear(Semaphores.SUSPEND_PARAMETER_CHECK, suspendParamChecks);
                            }
                        } finally {
                            endOfRecursion(ProjectedCRS.class, epsg);
                        }
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   VERTICAL CRS
                     * ---------------------------------------------------------------------- */
                    case "vertical": {
                        final VerticalCS    cs    = owner.createVerticalCS   (getString(code, result, 8));
                        final VerticalDatum datum = owner.createVerticalDatum(getString(code, result, 9));
                        crs = crsFactory.createVerticalCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   TEMPORAL CRS
                     *
                     *   NOTE : The original EPSG database does not define any temporal CRS.
                     *          This block is a SIS-specific extension.
                     * ---------------------------------------------------------------------- */
                    case "time":
                    case "temporal": {
                        final TimeCS        cs    = owner.createTimeCS       (getString(code, result, 8));
                        final TemporalDatum datum = owner.createTemporalDatum(getString(code, result, 9));
                        crs = crsFactory.createTemporalCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   COMPOUND CRS
                     *
                     *   NOTE: This method invokes itself recursively.
                     *         Consequently, we cannot use `result` anymore.
                     * ---------------------------------------------------------------------- */
                    case "compound": {
                        final String code1 = getString(code, result, 12);
                        final String code2 = getString(code, result, 13);
                        result.close();
                        final CoordinateReferenceSystem crs1, crs2;
                        ensureNoCycle(CompoundCRS.class, epsg);
                        try {
                            crs1 = owner.createCoordinateReferenceSystem(code1);
                            crs2 = owner.createCoordinateReferenceSystem(code2);
                        } finally {
                            endOfRecursion(CompoundCRS.class, epsg);
                        }
                        // Note: Do not invoke `createProperties` sooner.
                        crs  = crsFactory.createCompoundCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), crs1, crs2);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   GEOCENTRIC CRS
                     * ---------------------------------------------------------------------- */
                    case "geocentric": {
                        final CoordinateSystem cs = owner.createCoordinateSystem(getString(code, result, 8));
                        final GeodeticDatum datum = owner.createGeodeticDatum   (getString(code, result, 9));
                        @SuppressWarnings("LocalVariableHidesMemberVariable")
                        final Map<String,Object> properties = createProperties("Coordinate Reference System",
                                                                name, epsg, area, scope, remarks, deprecated);
                        if (cs instanceof CartesianCS) {
                            crs = crsFactory.createGeocentricCRS(properties, datum, (CartesianCS) cs);
                        } else if (cs instanceof SphericalCS) {
                            crs = crsFactory.createGeocentricCRS(properties, datum, (SphericalCS) cs);
                        } else {
                            throw new FactoryDataException(error().getString(
                                    Errors.Keys.IllegalCoordinateSystem_1, cs.getName()));
                        }
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   ENGINEERING CRS
                     * ---------------------------------------------------------------------- */
                    case "engineering": {
                        final CoordinateSystem cs    = owner.createCoordinateSystem(getString(code, result, 8));
                        final EngineeringDatum datum = owner.createEngineeringDatum(getString(code, result, 9));
                        crs = crsFactory.createEngineeringCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), datum, cs);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   PARAMETRIC CRS
                     * ---------------------------------------------------------------------- */
                    case "parametric": {
                        final DefaultParametricCS    cs    = owner.createParametricCS   (getString(code, result, 8));
                        final DefaultParametricDatum datum = owner.createParametricDatum(getString(code, result, 9));
                        crs = ServicesForMetadata.createParametricCRS(createProperties("Coordinate Reference System",
                                name, epsg, area, scope, remarks, deprecated), datum, cs, crsFactory);
                        break;
                    }
                    /* ----------------------------------------------------------------------
                     *   UNKNOWN CRS
                     * ---------------------------------------------------------------------- */
                    default: {
                        throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
                    }
                }
                returnValue = ensureSingleton(crs, returnValue, code);
                if (result.isClosed()) {
                    return returnValue;
                }
            }
        } catch (SQLException exception) {
            throw databaseFailure(CoordinateReferenceSystem.class, code, exception);
        }
        if (returnValue == null) {
             throw noSuchAuthorityCode(CoordinateReferenceSystem.class, code);
        }
        return returnValue;
    }