in endorsed/src/org.apache.sis.referencing/main/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [1617:1748]
public synchronized Datum createDatum(final String code) throws NoSuchAuthorityCodeException, FactoryException {
ArgumentChecks.ensureNonNull("code", code);
Datum returnValue = null;
try (ResultSet result = executeQuery("Datum", "DATUM_CODE", "DATUM_NAME",
"SELECT DATUM_CODE," +
" DATUM_NAME," +
" DATUM_TYPE," +
" ORIGIN_DESCRIPTION," +
" REALIZATION_EPOCH," +
" AREA_OF_USE_CODE," +
" DATUM_SCOPE," +
" REMARKS," +
" DEPRECATED," +
" ELLIPSOID_CODE," + // Only for geodetic type
" PRIME_MERIDIAN_CODE" + // Only for geodetic type
" FROM [Datum]" +
" WHERE DATUM_CODE = ?", code))
{
while (result.next()) {
final Integer epsg = getInteger (code, result, 1);
final String name = getString (code, result, 2);
final String type = getString (code, result, 3);
final String anchor = getOptionalString (result, 4);
final String epoch = getOptionalString (result, 5);
final String area = getOptionalString (result, 6);
final String scope = getOptionalString (result, 7);
final String remarks = getOptionalString (result, 8);
final boolean deprecated = getOptionalBoolean(result, 9);
@SuppressWarnings("LocalVariableHidesMemberVariable")
Map<String,Object> properties = createProperties("Datum", name, epsg, area, scope, remarks, deprecated);
if (anchor != null) {
properties.put(Datum.ANCHOR_POINT_KEY, anchor);
}
if (epoch != null) try {
/*
* Parse the date manually because it is declared as a VARCHAR instead of DATE in original
* SQL scripts. Apache SIS installer replaces VARCHAR by DATE, but we have no guarantee that
* we are reading an EPSG database created by our installer. Furthermore, an older version of
* EPSG installer was using SMALLINT instead of DATE, because scripts before EPSG 9.0 were
* reporting only the epoch year.
*/
final CharSequence[] fields = CharSequences.split(epoch, '-');
int year = 0, month = 0, day = 1;
for (int i = Math.min(fields.length, 3); --i >= 0;) {
final int f = Integer.parseInt(fields[i].toString());
switch (i) {
case 0: year = f; break;
case 1: month = f-1; break;
case 2: day = f; break;
}
}
if (year != 0) {
@SuppressWarnings("LocalVariableHidesMemberVariable")
final Calendar calendar = getCalendar();
calendar.set(year, month, day);
properties.put(Datum.REALIZATION_EPOCH_KEY, calendar.getTime());
}
} catch (NumberFormatException exception) {
unexpectedException("createDatum", exception); // Not a fatal error.
}
/*
* The following switch statement should have a case for all "epsg_datum_kind" values enumerated
* in the "EPSG_Prepare.sql" file, except that the values in this Java code are in lower cases.
*/
final DatumFactory datumFactory = owner.datumFactory;
final Datum datum;
switch (type.toLowerCase(Locale.US)) {
/*
* The "geodetic" case invokes createProperties(…) indirectly through calls to
* createEllipsoid(String) and createPrimeMeridian(String), so we must protect
* the properties map from changes.
*/
case "geodetic": {
properties = new HashMap<>(properties); // Protect from changes
final Ellipsoid ellipsoid = owner.createEllipsoid (getString(code, result, 10));
final PrimeMeridian meridian = owner.createPrimeMeridian(getString(code, result, 11));
final BursaWolfParameters[] param = createBursaWolfParameters(meridian, epsg);
if (param != null) {
properties.put(DefaultGeodeticDatum.BURSA_WOLF_KEY, param);
}
datum = datumFactory.createGeodeticDatum(properties, ellipsoid, meridian);
break;
}
case "vertical": {
datum = datumFactory.createVerticalDatum(properties, VerticalDatumType.GEOIDAL);
break;
}
/*
* Origin date is stored in ORIGIN_DESCRIPTION field. A column of SQL type
* "date" type would have been better, but we do not modify the EPSG model.
*/
case "temporal": {
final Temporal originDate;
if (Strings.isNullOrEmpty(anchor)) {
throw new FactoryDataException(resources().getString(Resources.Keys.DatumOriginShallBeDate));
}
try {
originDate = LenientDateFormat.parseBest(anchor);
} catch (RuntimeException e) {
throw new FactoryDataException(resources().getString(Resources.Keys.DatumOriginShallBeDate), e);
}
datum = datumFactory.createTemporalDatum(properties, TemporalDate.toDate(originDate));
break;
}
/*
* Straightforward case.
*/
case "engineering": {
datum = datumFactory.createEngineeringDatum(properties);
break;
}
case "parametric": {
datum = ServicesForMetadata.createParametricDatum(properties, datumFactory);
break;
}
default: {
throw new FactoryDataException(error().getString(Errors.Keys.UnknownType_1, type));
}
}
returnValue = ensureSingleton(datum, returnValue, code);
if (result.isClosed()) {
break; // Because of the recursive call done by createBursaWolfParameters(…).
}
}
} catch (SQLException exception) {
throw databaseFailure(Datum.class, code, exception);
}
if (returnValue == null) {
throw noSuchAuthorityCode(Datum.class, code);
}
return returnValue;
}