/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2005-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.referencing.factory.epsg; // J2SE dependencies import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.FileInputStream; import java.util.Properties; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; // Geotools dependencies import org.geotools.util.logging.Logging; import org.geotools.factory.Hints; import org.geotools.referencing.factory.AbstractAuthorityFactory; /** * Connection to the EPSG database in Oracle database engine using a JDBC datasource. The EPSG * database can be downloaded from <A HREF="http://www.epsg.org">http://www.epsg.org</A>. * It should have been imported into an Oracle database, which doesn't need to be on * the local machine. * <p> * <h3>Connection parameters</h3> * The preferred way to specify connection parameters is through the JNDI interface. * However, this datasource provides the following alternative as a convenience: if a * {@value #CONFIGURATION_FILE} file is found in current directory or in the user's home * directory, then the following properties are fetched. Note that the default value may change * in a future version if a public server becomes available. * <P> * <TABLE BORDER="1"> * <TR> * <TH>Property</TH> * <TH>Type</TH> * <TH>Description</TH> * <TH>Geotools Default</TH> * </TR> * <TR> * <TD>{@code serverName}</TD> * <TD>String</TD> * <TD>Oracle database server host name</TD> * <TD>{@code localhost}</TD> * </TR> * <TR> * <TD>{@code databaseName}</TD> * <TD>String</TD> * <TD>Oracle database name</TD> * <TD>{@code EPSG}</TD> * </TR> * <TR> * <TD>{@code schema}</TD> * <TD>String</TD> * <TD>The schema for the EPSG tables</TD> * <TD></TD> * </TR> * <TR> * <TD>{@code portNumber}</TD> * <TD>int</TD> * <TD>TCP port which the Oracle database server is listening on</TD> * <TD>{@code 1521}</TD> * </TR> * <TR> * <TD>{@code user}</TD> * <TD>String</TD> * <TD>User used to make database connections</TD> * <TD>{@code GeoTools}</TD> * </TR> * <TR> * <TD>{@code password}</TD> * <TD>String</TD> * <TD>Password used to make database connections</TD> * <TD>{@code GeoTools}</TD></TR> * </TABLE> * <P> * The database version is given in the * {@linkplain org.opengis.metadata.citation.Citation#getEdition edition attribute} * of the {@linkplain org.opengis.referencing.AuthorityFactory#getAuthority authority}. * The Oracle database should be read only. * <P> * Just having this class accessible in the classpath, together with the registration in * the {@code META-INF/services/} directory, is sufficient to get a working EPSG authority * factory backed by this database. Vendors can create a copy of this class, modify it and * bundle it with their own distribution if they want to connect their users to an other * database. * * @since 2.4 * * * @source $URL$ * @version $Id$ * @author Didier Richard * @author Martin Desruisseaux * @author Jody Garnett */ public class ThreadedOracleEpsgFactory extends ThreadedEpsgFactory { /** * The user configuration file. This class search first for the first file found in the * following directories: * <ul> * <li>The current directory</li> * <li>The user's home directory</li> * </ul> */ public static final String CONFIGURATION_FILE = "EPSG-DataSource.properties"; /** * The schema name, or {@code null} if none. */ private String schema; /** * Creates a new instance of this factory. */ public ThreadedOracleEpsgFactory() { this(null); } /** * Creates a new instance of this factory with the specified hints. * The priority is set to a lower value than the {@linkplain FactoryOnAccess}'s one * in order to give the priority to any "official" database installed locally by the * user, when available. */ public ThreadedOracleEpsgFactory(final Hints hints) { super(hints, PRIORITY + 5); } /** * Loads the {@linkplain #CONFIGURATION_FILE configuration file}. */ private static Properties load() { final Properties p = new Properties(); File file = new File(CONFIGURATION_FILE); if (!file.isFile()) { file = new File(System.getProperty("user.home", "."), CONFIGURATION_FILE); if (!file.isFile()) { // Returns an empty set of properties. return p; } } try { final InputStream in = new FileInputStream(file); p.load(in); in.close(); } catch (IOException exception) { Logging.unexpectedException("org.geotools.referencing.factory", DataSource.class, "<init>", exception); // Continue. We will try to work with whatever properties are available. } return p; } /** * Returns a data source for the PostgreSQL database. */ protected DataSource createDataSource() throws SQLException { DataSource source = super.createDataSource(); if( source != null ){ return source; } final Properties p = load(); int portNumber; try { portNumber = Integer.parseInt(p.getProperty("portNumber", "5432")); } catch (NumberFormatException exception) { portNumber = 5432; Logging.unexpectedException("org.geotools.referencing.factory", DataSource.class, "<init>", exception); } String serverName = p.getProperty("serverName", "localhost"); String databaseName = p.getProperty("databaseName", "EPSG"); String user = p.getProperty("user", "Geotools"); String password = p.getProperty("password", "Geotools"); schema = p.getProperty("schema", null); return source; } /** * Returns the backing-store factory for Oracle syntax. * * @param hints A map of hints, including the low-level factories to use for CRS creation. * @return The EPSG factory using Oracle syntax. * @throws SQLException if connection to the database failed. */ protected AbstractAuthorityFactory createBackingStore(final Hints hints) throws SQLException { final Connection connection = getDataSource().getConnection(); final FactoryUsingOracleSQL factory = new FactoryUsingOracleSQL(hints, connection); if (schema != null) { factory.setSchema(schema); } return factory; } }