//grab the primary key
PrimaryKey pkey = getDataStore().getPrimaryKey(entry);
VirtualTable virtualTable = getDataStore().getVirtualTables().get(entry.getTypeName());
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
AttributeTypeBuilder ab = new AttributeTypeBuilder();
// setup the read only marker if no pk or null pk or it's a view
boolean readOnly = false;
if(pkey == null || pkey instanceof NullPrimaryKey || virtualTable != null) {
readOnly = true;
}
//set up the name
String tableName = entry.getName().getLocalPart();
tb.setName(tableName);
//set the namespace, if not null
if (entry.getName().getNamespaceURI() != null) {
tb.setNamespaceURI(entry.getName().getNamespaceURI());
} else {
//use the data store
tb.setNamespaceURI(getDataStore().getNamespaceURI());
}
//grab the state
JDBCState state = getState();
//grab the schema
String databaseSchema = getDataStore().getDatabaseSchema();
//ensure we have a connection
Connection cx = getDataStore().getConnection(state);
// grab the dialect
SQLDialect dialect = getDataStore().getSQLDialect();
//get metadata about columns from database
try {
DatabaseMetaData metaData = cx.getMetaData();
// get metadata about columns from database
List<ColumnMetadata> columns;
if (virtualTable != null) {
columns = getColumnMetadata(cx, virtualTable, dialect, getDataStore());
} else {
columns = getColumnMetadata(cx, databaseSchema, tableName, dialect);
}
for (ColumnMetadata column : columns) {
String name = column.name;
//do not include primary key in the type if not exposing primary key columns
boolean pkColumn = false;
for ( PrimaryKeyColumn pkeycol : pkey.getColumns() ) {
if ( name.equals( pkeycol.getName() ) ) {
if ( !state.isExposePrimaryKeyColumns() ) {
name = null;
break;
} else {
pkColumn = true;
}
}
// in views we don't know the pk type, grab it now
if(pkeycol.type == null) {
pkeycol.type = column.binding;
}
}
if (name == null) {
continue;
}
//check for association
if (getDataStore().isAssociations()) {
getDataStore().ensureAssociationTablesExist(cx);
//check for an association
Statement st = null;
ResultSet relationships = null;
if ( getDataStore().getSQLDialect() instanceof PreparedStatementSQLDialect ) {
st = getDataStore().selectRelationshipSQLPS(tableName, name, cx);
relationships = ((PreparedStatement)st).executeQuery();
}
else {
String sql = getDataStore().selectRelationshipSQL(tableName, name);
getDataStore().getLogger().fine(sql);
st = cx.createStatement();
relationships = st.executeQuery(sql);
}
try {
if (relationships.next()) {
//found, create a special mapping
tb.add(name, Association.class);
continue;
}
} finally {
getDataStore().closeSafe(relationships);
getDataStore().closeSafe(st);
}
}
//first ask the dialect
Class binding = column.binding;
if (binding == null) {
//determine from type name mappings
binding = getDataStore().getMapping(column.typeName);
}
if (binding == null) {
//determine from type mappings
binding = getDataStore().getMapping(column.sqlType);
}
// if still not found, ignore the column we don't know about
if (binding == null) {
getDataStore().getLogger().warning("Could not find mapping for '" + name
+ "', ignoring the column and setting the feature type read only");
readOnly = true;
continue;
}
// store the native database type in the attribute descriptor user data
ab.addUserData(JDBCDataStore.JDBC_NATIVE_TYPENAME, column.typeName);
// nullability
if (!column.nullable) {
ab.nillable(false);
ab.minOccurs(1);
}
AttributeDescriptor att = null;
//determine if this attribute is a geometry or not
if (Geometry.class.isAssignableFrom(binding)) {
//add the attribute as a geometry, try to figure out
// its srid first
Integer srid = null;
CoordinateReferenceSystem crs = null;
try {
if(virtualTable != null) {
srid = virtualTable.getNativeSrid(name);
} else {
srid = dialect.getGeometrySRID(databaseSchema, tableName, name, cx);
}
if(srid != null)
crs = dialect.createCRS(srid, cx);
} catch (Exception e) {
String msg = "Error occured determing srid for " + tableName + "."
+ name;
getDataStore().getLogger().log(Level.WARNING, msg, e);
}
// compute the dimension too
int dimension = 2;
try {
if(virtualTable != null) {
dimension = virtualTable.getDimension(name);
} else {
dimension = dialect.getGeometryDimension(databaseSchema, tableName, name, cx);
}
} catch(Exception e) {
String msg = "Error occured determing dimension for " + tableName + "."
+ name;
getDataStore().getLogger().log(Level.WARNING, msg, e);
}
ab.setBinding(binding);
ab.setName(name);
ab.setCRS(crs);
if(srid != null) {
ab.addUserData(JDBCDataStore.JDBC_NATIVE_SRID, srid);
}
ab.addUserData(Hints.COORDINATE_DIMENSION, dimension);
att = ab.buildDescriptor(name, ab.buildGeometryType());
} else {
//add the attribute
ab.setName(name);
ab.setBinding(binding);
att = ab.buildDescriptor(name, ab.buildType());
}
// mark primary key columns
if (pkey.getColumn(att.getLocalName()) != null) {
att.getUserData().put(JDBCDataStore.JDBC_PRIMARY_KEY_COLUMN, true);
}