package com.revolsys.oracle.recordstore.esri; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.io.PathName; import com.revolsys.io.PathUtil; import com.revolsys.jdbc.JdbcUtils; import com.revolsys.jdbc.field.JdbcFieldAdder; import com.revolsys.logging.Logs; import com.revolsys.oracle.recordstore.OracleRecordStore; import com.revolsys.record.io.RecordStoreExtension; import com.revolsys.record.schema.RecordDefinition; import com.revolsys.record.schema.RecordStore; import com.revolsys.record.schema.RecordStoreSchema; import com.revolsys.util.Property; public class ArcSdeStGeometryRecordStoreExtension implements RecordStoreExtension { public ArcSdeStGeometryRecordStoreExtension() { } @Override public void initialize(final RecordStore recordStore, final Map<String, Object> connectionProperties) { final OracleRecordStore oracleRecordStore = (OracleRecordStore)recordStore; final JdbcFieldAdder stGeometryAttributeAdder = new ArcSdeStGeometryFieldAdder( oracleRecordStore); oracleRecordStore.addFieldAdder("ST_GEOMETRY", stGeometryAttributeAdder); oracleRecordStore.addFieldAdder("SDE.ST_GEOMETRY", stGeometryAttributeAdder); } @Override public boolean isEnabled(final RecordStore recordStore) { return ArcSdeConstants.isSdeAvailable(recordStore); } private void loadColumnProperties(final RecordStoreSchema schema, final String schemaName, final Connection connection) throws SQLException { final String sql = "SELECT GC.F_TABLE_NAME, GC.F_GEOMETRY_COLUMN, GC.SRID, GC.GEOMETRY_TYPE, GC.COORD_DIMENSION, SG.GEOMETRY_TYPE GEOMETRY_DATA_TYPE FROM SDE.GEOMETRY_COLUMNS GC LEFT OUTER JOIN SDE.ST_GEOMETRY_COLUMNS SG ON GC.F_TABLE_SCHEMA = SG.OWNER AND GC.F_TABLE_NAME = SG.TABLE_NAME WHERE GC.F_TABLE_SCHEMA = ?"; final PreparedStatement statement = connection.prepareStatement(sql); try { statement.setString(1, schemaName); final ResultSet resultSet = statement.executeQuery(); try { while (resultSet.next()) { final String tableName = resultSet.getString(1); final String columnName = resultSet.getString(2); final PathName typePath = PathName.newPathName(PathUtil.toPath(schemaName, tableName)); final int esriSrid = resultSet.getInt(3); JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, ArcSdeConstants.ESRI_SRID_PROPERTY, esriSrid); int axisCount = resultSet.getInt(5); axisCount = Math.max(axisCount, 2); JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, JdbcFieldAdder.AXIS_COUNT, axisCount); final ArcSdeSpatialReference spatialReference = ArcSdeSpatialReferenceCache .getSpatialReference(connection, schema, esriSrid); JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, ArcSdeConstants.SPATIAL_REFERENCE, spatialReference); GeometryFactory geometryFactory = JdbcFieldAdder.getColumnProperty(schema, typePath, columnName, JdbcFieldAdder.GEOMETRY_FACTORY); int srid = spatialReference.getCoordinateSystemId(); final double scaleXy = spatialReference.getXyScale(); final double scaleZ = spatialReference.getZScale(); if (srid <= 0) { srid = geometryFactory.getCoordinateSystemId(); } axisCount = Math.min(axisCount, 3); geometryFactory = GeometryFactory.fixed(srid, axisCount, scaleXy, scaleXy, scaleZ); JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, JdbcFieldAdder.GEOMETRY_FACTORY, geometryFactory); final int geometryType = resultSet.getInt(4); JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, JdbcFieldAdder.GEOMETRY_TYPE, ArcSdeConstants.getGeometryDataType(geometryType)); String geometryColumnType = resultSet.getString(6); if (!Property.hasValue(geometryColumnType)) { geometryColumnType = ArcSdeConstants.SDEBINARY; } JdbcFieldAdder.setColumnProperty(schema, typePath, columnName, ArcSdeConstants.GEOMETRY_COLUMN_TYPE, geometryColumnType); } } finally { JdbcUtils.close(resultSet); } } finally { JdbcUtils.close(statement); } } private void loadTableProperties(final Connection connection, final RecordStoreSchema schema, final String schemaName) { final String sql = "SELECT registration_id, table_name, rowid_column FROM sde.table_registry WHERE owner = ?"; PreparedStatement statement = null; ResultSet resultSet = null; try { statement = connection.prepareStatement(sql); statement.setString(1, schemaName); resultSet = statement.executeQuery(); while (resultSet.next()) { final String tableName = resultSet.getString(2); final String typePath = PathUtil.toPath(schemaName, tableName).toUpperCase(); final int registrationId = resultSet.getInt(1); JdbcFieldAdder.setTableProperty(schema, typePath, ArcSdeConstants.REGISTRATION_ID, registrationId); final String rowidColumn = resultSet.getString(3); JdbcFieldAdder.setTableProperty(schema, typePath, ArcSdeConstants.ROWID_COLUMN, rowidColumn); } } catch (final Throwable e) { Logs.error(this, "Unable to load rowid columns for " + schemaName, e); } finally { JdbcUtils.close(statement, resultSet); } } @Override public void postProcess(final RecordStoreSchema schema) { final String schemaName = schema.getName(); for (final RecordDefinition recordDefinition : schema.getRecordDefinitions()) { final String typePath = recordDefinition.getPath(); final Integer registrationId = JdbcFieldAdder.getTableProperty(schema, typePath, ArcSdeConstants.REGISTRATION_ID); final String rowIdColumn = JdbcFieldAdder.getTableProperty(schema, typePath, ArcSdeConstants.ROWID_COLUMN); if (registrationId != null && rowIdColumn != null) { ArcSdeObjectIdJdbcFieldDefinition.replaceAttribute(schemaName, recordDefinition, registrationId, rowIdColumn); } } } @Override public void preProcess(final RecordStoreSchema schema) { final RecordStore recordStore = schema.getRecordStore(); final OracleRecordStore oracleRecordStore = (OracleRecordStore)recordStore; try { try ( final Connection connection = oracleRecordStore.getJdbcConnection()) { final String schemaName = oracleRecordStore.getDatabaseSchemaName(schema); loadTableProperties(connection, schema, schemaName); loadColumnProperties(schema, schemaName, connection); } } catch (final Throwable e) { Logs.error(this, "Unable to get ArcSDE metadata for schema " + schema.getName(), e); } } }