/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.oracle;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import oracle.jdbc.OracleConnection;
import org.geotools.data.Transaction;
import org.geotools.data.DataAccessFactory.Param;
import org.geotools.jdbc.JDBCDataStore;
import org.geotools.jdbc.JDBCDataStoreFactory;
import org.geotools.jdbc.SQLDialect;
/**
* Oracle data store factory.
*
* @author Justin Deoliveira, OpenGEO
* @author Andrea Aime, OpenGEO
* @author Hendrik Peilke
*
*
* @source $URL$
*/
public class OracleNGDataStoreFactory extends JDBCDataStoreFactory {
private static final String JDBC_PATH = "jdbc:oracle:thin:@";
/** parameter for database type */
public static final Param DBTYPE = new Param("dbtype", String.class, "Type", true, "oracle");
/** parameter for database port */
public static final Param PORT = new Param("port", Integer.class, "Port", false, 1521);
/** parameter for database host */
public static final Param HOST = new Param("host", String.class, "Host", false, "localhost");
/** parameter for database instance */
public static final Param DATABASE = new Param("database", String.class, "Database", true);
/** parameter that enables estimated extends instead of exact ones */
public static final Param ESTIMATED_EXTENTS = new Param("Estimated extends", Boolean.class, "Use the spatial index information to quickly get an estimate of the data bounds", false, Boolean.TRUE);
/** parameter for namespace of the datastore */
public static final Param LOOSEBBOX = new Param("Loose bbox", Boolean.class, "Perform only primary filter on bbox", false, Boolean.TRUE);
/** Metadata table providing information about primary keys **/
public static final Param GEOMETRY_METADATA_TABLE = new Param("Geometry metadata table", String.class,
"The optional table containing geometry metadata (geometry type and srid). Can be expressed as 'schema.name' or just 'name'", false);
/** parameter for getting bbox from MDSYS.USER_SDO_GEOM_METADATA or MDSYS.ALL_SDO_GEOM_METADATA table */
public static final Param METADATA_BBOX = new Param("Metadata bbox", Boolean.class, "Get data bounds quickly from MDSYS.USER_SDO_GEOM_METADATA or MDSYS.ALL_SDO_GEOM_METADATA table", false, Boolean.FALSE);
@Override
protected SQLDialect createSQLDialect(JDBCDataStore dataStore) {
return new OracleDialect(dataStore);
}
@Override
protected String getDatabaseID() {
return (String) DBTYPE.sample;
}
@Override
public String getDisplayName() {
return "Oracle NG";
}
public String getDescription() {
return "Oracle Database";
}
@Override
protected String getDriverClassName() {
return "oracle.jdbc.driver.OracleDriver";
}
@Override
protected boolean checkDBType(Map params) {
if (super.checkDBType(params)) {
try {
//check for old factory
Class.forName("org.geotools.data.oracle.OracleDataStoreFactory");
//it is around, let it handle this connection
return false;
}
catch(ClassNotFoundException e) {
//old factory not around, pick up the connection
return true;
}
}
else {
//check for the old id
return checkDBType(params, "Oracle");
}
}
protected JDBCDataStore createDataStoreInternal(JDBCDataStore dataStore, Map params)
throws IOException {
// make the schema uppercase if it's not already
if(dataStore.getDatabaseSchema() != null) {
dataStore.setDatabaseSchema(dataStore.getDatabaseSchema().toUpperCase());
}
// setup loose bbox
OracleDialect dialect = (OracleDialect) dataStore.getSQLDialect();
Boolean loose = (Boolean) LOOSEBBOX.lookUp(params);
dialect.setLooseBBOXEnabled(loose == null || Boolean.TRUE.equals(loose));
// check the estimated extents
Boolean estimated = (Boolean) ESTIMATED_EXTENTS.lookUp(params);
dialect.setEstimatedExtentsEnabled(estimated == null || Boolean.TRUE.equals(estimated));
// check the geometry metadata table
String metadataTable = (String) GEOMETRY_METADATA_TABLE.lookUp(params);
dialect.setGeometryMetadataTable(metadataTable);
// check the metadata bbox option
Boolean metadateBbox = (Boolean) METADATA_BBOX.lookUp(params);
dialect.setMetadataBboxEnabled(Boolean.TRUE.equals(metadateBbox));
if (dataStore.getFetchSize() <= 0) {
// Oracle is dead slow with the fetch size at 0, let's have a sane default
dataStore.setFetchSize(200);
}
Connection cx = dataStore.getConnection(Transaction.AUTO_COMMIT);
try {
OracleConnection oracleConnection = dialect.unwrapConnection( cx );
} catch (SQLException e) {
throw new IOException(
"Unable to obtain Oracle Connection require for SDO Geometry access)."+
"Check connection pool implementation to unsure unwrap is available", e);
}
finally {
dataStore.closeSafe(cx);
}
return dataStore;
}
@Override
protected String getJDBCUrl(Map params) throws IOException {
String db = (String) DATABASE.lookUp(params);
String host = (String) HOST.lookUp(params);
Integer port =(Integer) PORT.lookUp(params);
if(db.startsWith("(") || db.startsWith("ldap://"))
// for Oracle LDAP:
// ldap://[host]/[db],cn=OracleContext,dc=[oracle_ldap_context]
// for Oracle RAC
// (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=[host])(PORT=[port, often 1521]))(LOAD_BALANCE=YES)(CONNECT_DATA=(SERVICE_NAME=[oracle_service_name])))
return JDBC_PATH + db;
else if(db.startsWith("/") && host != null && port != null)
return JDBC_PATH + "//" + host + ":" + port + db;
else if(host != null && port != null)
return JDBC_PATH + host + ":" + port + ":" + db;
else
throw new IOException("Unable to properly compose the JDBC URL string, some parameters as host and port may be null !");
}
@Override
protected void setupParameters(Map parameters) {
// NOTE: when adding parameters here remember to add them to OracleNGOCIDataStoreFactory and
// OracleNGJNDIDataStoreFactory
super.setupParameters(parameters);
parameters.put(LOOSEBBOX.key, LOOSEBBOX);
parameters.put(ESTIMATED_EXTENTS.key, ESTIMATED_EXTENTS);
parameters.put(MAX_OPEN_PREPARED_STATEMENTS.key, MAX_OPEN_PREPARED_STATEMENTS);
parameters.put(PORT.key, PORT);
parameters.put(HOST.key, HOST);
parameters.put(DATABASE.key, DATABASE);
parameters.put(DBTYPE.key, DBTYPE);
parameters.put(GEOMETRY_METADATA_TABLE.key, GEOMETRY_METADATA_TABLE);
parameters.put(METADATA_BBOX.key, METADATA_BBOX);
}
@Override
protected String getValidationQuery() {
return "select 1 from dual";
}
}