Author: jgarnett Date: 2007-06-29 14:45:12 -0700 (Fri, 29 Jun 2007) New Revision: 26096 Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AccessDialectEpsgFactory.java geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AnsiDialectEpsgFactory.java geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingAnsiSQL.java geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingSQL.java geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/SimpleDataSource.java geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/ThreadedEpsgFactory.java geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/AccessDataSource.java geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/ThreadedAccessEpsgFactory.java geotools/trunk/gt/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingHSQL.java geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/PostgreDataSource.java geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/ThreadedPostgreSQLEpsgFactory.java geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingOracleSQL.java geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/ThreadedOracleEpsgFactory.java Log: untangle the origional FactoryUsing code so it is out of the way Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AccessDialectEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AccessDialectEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AccessDialectEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -33,7 +33,7 @@ * @version $Id$ * @author Jody Garnett */ -public class AccessDialectEpsgFactory extends DirectEpsgFactory { +public class AccessDialectEpsgFactory extends AbstractEpsgFactory { /** * Constructs an authority factory using the specified connection. * Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AnsiDialectEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AnsiDialectEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/AnsiDialectEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -47,7 +47,7 @@ * @author Didier Richard * @author John Grange */ -public class AnsiDialectEpsgFactory extends DirectEpsgFactory { +public class AnsiDialectEpsgFactory extends AbstractEpsgFactory { /** * The default map using ANSI names. */ Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingAnsiSQL.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingAnsiSQL.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingAnsiSQL.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -38,18 +38,145 @@ * * @deprecated Please use {@link AnsiDialectEpsgFactory}. */ -public class FactoryUsingAnsiSQL extends AnsiDialectEpsgFactory { +public class FactoryUsingAnsiSQL extends FactoryUsingSQL { /** + * The default map using ANSI names. + */ + private static final String[] ANSI = { + "[Alias]", "epsg_alias", + "[Area]", "epsg_area", + "[Coordinate Axis]", "epsg_coordinateaxis", + "[Coordinate Axis Name]", "epsg_coordinateaxisname", + "[Coordinate_Operation]", "epsg_coordoperation", + "[Coordinate_Operation Method]", "epsg_coordoperationmethod", + "[Coordinate_Operation Parameter]", "epsg_coordoperationparam", + "[Coordinate_Operation Parameter Usage]", "epsg_coordoperationparamusage", + "[Coordinate_Operation Parameter Value]", "epsg_coordoperationparamvalue", + "[Coordinate_Operation Path]", "epsg_coordoperationpath", + "[Coordinate Reference System]", "epsg_coordinatereferencesystem", + "[Coordinate System]", "epsg_coordinatesystem", + "[Datum]", "epsg_datum", + "[Ellipsoid]", "epsg_ellipsoid", + "[Naming System]", "epsg_namingsystem", + "[Prime Meridian]", "epsg_primemeridian", + "[Supersession]", "epsg_supersession", + "[Unit of Measure]", "epsg_unitofmeasure", + "[Version History]", "epsg_versionhistory", + "[ORDER]", "coord_axis_order" // a field in epsg_coordinateaxis + }; + + /** + * Maps the MS-Access names to ANSI names. Keys are MS-Access names including bracket. + * Values are ANSI names. Keys and values are case-sensitive. The default content of + * this map is: + * + * <pre><table> + * <tr><th align="center">MS-Access name</th> <th align="center">ANSI name</th></tr> + * <tr><td>[Alias]</td> <td>epsg_alias</td></tr> + * <tr><td>[Area]</td> <td>epsg_area</td></tr> + * <tr><td>[Coordinate Axis]</td> <td>epsg_coordinateaxis</td></tr> + * <tr><td>[Coordinate Axis Name]</td> <td>epsg_coordinateaxisname</td></tr> + * <tr><td>[Coordinate_Operation]</td> <td>epsg_coordoperation</td></tr> + * <tr><td>[Coordinate_Operation Method]</td> <td>epsg_coordoperationmethod</td></tr> + * <tr><td>[Coordinate_Operation Parameter]</td> <td>epsg_coordoperationparam</td></tr> + * <tr><td>[Coordinate_Operation Parameter Usage]</td> <td>epsg_coordoperationparamusage</td></tr> + * <tr><td>[Coordinate_Operation Parameter Value]</td> <td>epsg_coordoperationparamvalue</td></tr> + * <tr><td>[Coordinate_Operation Path]</td> <td>epsg_coordoperationpath</td></tr> + * <tr><td>[Coordinate Reference System]</td> <td>epsg_coordinatereferencesystem</td></tr> + * <tr><td>[Coordinate System]</td> <td>epsg_coordinatesystem</td></tr> + * <tr><td>[Datum]</td> <td>epsg_datum</td></tr> + * <tr><td>[Naming System]</td> <td>epsg_namingsystem</td></tr> + * <tr><td>[Ellipsoid]</td> <td>epsg_ellipsoid</td></tr> + * <tr><td>[Prime Meridian]</td> <td>epsg_primemeridian</td></tr> + * <tr><td>[Supersession]</td> <td>epsg_supersession</td></tr> + * <tr><td>[Unit of Measure]</td> <td>epsg_unitofmeasure</td></tr> + * <tr><td>[CA.ORDER]</td> <td>coord_axis_order</td></tr> + * </table></pre> + * + * Subclasses can modify this map in their constructor in order to provide a different + * mapping. + */ + protected final Map map = new LinkedHashMap(); + + /** + * The prefix before any table name. May be replaced by a schema if {@link #setSchema} + * is invoked. + */ + private String prefix = "epsg_"; + + /** * Constructs an authority factory using the specified connection. * * @param userHints The underlying factories used for objects creation. * @param connection The connection to the underlying EPSG database. - * - * @since 2.2 */ public FactoryUsingAnsiSQL(final Hints userHints, - final Connection connection) + final Connection connection) { super(userHints, connection); + for (int i=0; i<ANSI.length; i++) { + map.put(ANSI[i], ANSI[++i]); + } } + + /** + * Replaces the {@code "epsg_"} prefix by the specified schema name. If the removal + * of the {@code "epsg_"} prefix is not wanted, append it to the schema name + * (e.g. {@code "myschema.epsg_"}). This method should be invoked at construction + * time only. + * + * @param schema The database schema in which the epsg tables are stored. + */ + protected void setSchema(String schema) { + schema = schema.trim(); + final int length = schema.length(); + if (length == 0) { + throw new IllegalArgumentException(schema); + } + final char separator = schema.charAt(length-1); + if (separator!='.' && separator!='_') { + schema += '.'; + } else if (length == 1) { + throw new IllegalArgumentException(schema); + } + for (final Iterator it=map.entrySet().iterator(); it.hasNext();) { + final Map.Entry entry = (Map.Entry) it.next(); + final String tableName = (String) entry.getValue(); + /** + * Update the map, prepending the schema name to the table name + * so long as the value is a table name and not a field. This + * algorithm assumes that all old table names start with "epsg_". + */ + if (tableName.startsWith(prefix)) { + entry.setValue(schema + tableName.substring(prefix.length())); + } + } + prefix = schema; + } + + /** + * Modifies the given SQL string to be suitable for non MS-Access databases. + * This replaces table and field names in the SQL with the new names + * in the SQL DDL scripts provided with EPSG database. + * + * @param statement The statement in MS-Access syntax. + * @return The SQL statement in ANSI syntax. + */ + protected String adaptSQL(final String statement) { + final StringBuffer modified = new StringBuffer(statement); + for (final Iterator it=map.entrySet().iterator(); it.hasNext();) { + final Map.Entry entry = (Map.Entry) it.next(); + final String oldName = (String) entry.getKey(); + final String newName = (String) entry.getValue(); + /* + * Replaces all occurences of 'oldName' by 'newName'. + */ + int start = 0; + while ((start=modified.indexOf(oldName, start)) >= 0) { + modified.replace(start, start+oldName.length(), newName); + start += newName.length(); + } + } + return modified.toString(); + } } Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingSQL.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingSQL.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingSQL.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -18,6 +18,7 @@ // J2SE dependencies and extensions import java.sql.Connection; +import java.sql.PreparedStatement; // Geotools dependencies import org.geotools.factory.Hints; @@ -33,7 +34,7 @@ * * @deprecated Please use {@link AccessDialectEpsgFactory}. */ -public class FactoryUsingSQL extends AccessDialectEpsgFactory { +public class FactoryUsingSQL extends DirectEpsgFactory { /** * Constructs an authority factory using the specified connection. * @@ -45,4 +46,16 @@ public FactoryUsingSQL(final Hints userHints, final Connection connection) { super(userHints, connection ); } -} + /** + * Invoked when a new {@link PreparedStatement} is about to be created from a SQL string. + * + * Since the <A HREF="http://www.epsg.org">EPSG database</A> is available mainly in MS-Access + * format, and this is the target of our super class, we have no work to do here. + * + * @param statement The statement in MS-Access syntax. + * @return The SQL statement to use. This implementation returns the string unchanged. + */ + protected String adaptSQL(final String statement) { + return statement; + } +} \ No newline at end of file Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/SimpleDataSource.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/SimpleDataSource.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/SimpleDataSource.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -244,8 +244,8 @@ } final String schema = properties.getProperty("schema"); if (schema != null) { - if (factory instanceof AnsiDialectEpsgFactory) { - ((AnsiDialectEpsgFactory) factory).setSchema(schema); + if (factory instanceof FactoryUsingAnsiSQL) { + ((FactoryUsingAnsiSQL) factory).setSchema(schema); } } return factory; Modified: geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/ThreadedEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/ThreadedEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/library/referencing/src/main/java/org/geotools/referencing/factory/epsg/ThreadedEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -362,9 +362,9 @@ * a way to distinguish the two cases. However I'm not sure that it is a robust * criterion. Subclasses should always override as a safety. */ - return new AnsiDialectEpsgFactory(hints, connection); + return new FactoryUsingAnsiSQL(hints, connection); } - return new AccessDialectEpsgFactory(hints, connection); + return new FactoryUsingSQL(hints, connection); } /** Modified: geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/AccessDataSource.java =================================================================== --- geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/AccessDataSource.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/AccessDataSource.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -84,6 +84,6 @@ e.initCause(exception); throw e; } - return new AccessDialectEpsgFactory(hints, connection); + return new FactoryUsingSQL(hints, connection); } } Modified: geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/ThreadedAccessEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/ThreadedAccessEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/plugin/epsg-access/src/main/java/org/geotools/referencing/factory/epsg/ThreadedAccessEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -95,6 +95,6 @@ e.initCause(exception); throw e; } - return new AccessDialectEpsgFactory(hints, connection); + return new FactoryUsingSQL(hints, connection); } } Modified: geotools/trunk/gt/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingHSQL.java =================================================================== --- geotools/trunk/gt/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingHSQL.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/plugin/epsg-hsql/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingHSQL.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -37,7 +37,7 @@ * @version $Id$ * @author Martin Desruisseaux */ -final class FactoryUsingHSQL extends AnsiDialectEpsgFactory { +final class FactoryUsingHSQL extends FactoryUsingAnsiSQL { /** * The regular expression pattern for searching the "FROM (" clause. * This is the pattern for the opening parenthesis. Modified: geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/PostgreDataSource.java =================================================================== --- geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/PostgreDataSource.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/PostgreDataSource.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -212,7 +212,7 @@ * @throws SQLException if connection to the database failed. */ public AbstractAuthorityFactory createFactory(final Hints hints) throws SQLException { - final AnsiDialectEpsgFactory factory = new AnsiDialectEpsgFactory(hints, getConnection()); + final FactoryUsingAnsiSQL factory = new FactoryUsingAnsiSQL(hints, getConnection()); if (schema != null) { factory.setSchema(schema); } Modified: geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/ThreadedPostgreSQLEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/ThreadedPostgreSQLEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/plugin/epsg-postgresql/src/main/java/org/geotools/referencing/factory/epsg/ThreadedPostgreSQLEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -206,7 +206,7 @@ */ protected AbstractAuthorityFactory createBackingStore(final Hints hints) throws SQLException { final Connection connection = getDataSource().getConnection(); - final AnsiDialectEpsgFactory factory = new AnsiDialectEpsgFactory(hints, connection); + final FactoryUsingAnsiSQL factory = new FactoryUsingAnsiSQL(hints, connection); if (schema != null) { factory.setSchema(schema); } Modified: geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingOracleSQL.java =================================================================== --- geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingOracleSQL.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/FactoryUsingOracleSQL.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -17,6 +17,9 @@ // J2SE dependencies import java.sql.Connection; +import java.util.Iterator; +import java.util.Map; +import java.util.regex.Pattern; // Geotools dependencies import org.geotools.factory.Hints; @@ -37,18 +40,79 @@ * * @deprecated Please use {@link OracleDialectEpsgFactory}. */ -public class FactoryUsingOracleSQL extends OracleDialectEpsgFactory { +public class FactoryUsingOracleSQL extends FactoryUsingAnsiSQL { /** + * The pattern to use for removing <code>" as "</code> elements from the SQL statements. + */ + private final Pattern pattern = Pattern.compile("\\sAS\\s"); + + /** * Constructs an authority factory using the specified connection. * * @param userHints The underlying factories used for objects creation. * @param connection The connection to the underlying EPSG database. + */ + public FactoryUsingOracleSQL(final Hints userHints, + final Connection connection) + { + super(userHints, connection); + } + + /** + * Constructs an authority factory using the specified connection to an EPSG database + * and a database schema. If the database schema is not supplied, or it is null + * or an empty string, then the tables are assumed to be in the same schema as + * the user which is being used to connect to the database. You <strong>MUST</strong> + * ensure that the connecting user has permissions to select from all the tables in the + * epsg user schema. * - * @since 2.2 + * @param userHints The underlying factories used for objects creation. + * @param connection The connection to the underlying EPSG database. + * @param epsgSchema The database schema in which the epsg tables are stored (optional). */ public FactoryUsingOracleSQL(final Hints userHints, - final Connection connection) + final Connection connection, + final String epsgSchema) { super(userHints, connection); + adaptTableNames(epsgSchema); } + + /** + * Modifies the given SQL string to be suitable for an Oracle databases. + * This removes {@code " AS "} elements from the SQL statements as + * these don't work in oracle. + * + * @param statement The statement in MS-Access syntax. + * @return The SQL statement to use, suitable for an Oracle database. + */ + protected String adaptSQL(final String statement) { + return pattern.matcher(super.adaptSQL(statement)).replaceAll(" "); + } + + /** + * If we have been supplied with a non null {@code epsgSchema}, + * prepend the schema to all the table names. + * + * @param epsgSchema The database schema in which the epsg tables are stored (optional). + */ + private void adaptTableNames(String epsgSchema) { + if (epsgSchema != null) { + epsgSchema = epsgSchema.trim(); + if (epsgSchema.length() != 0) { + for (final Iterator it=map.entrySet().iterator(); it.hasNext();) { + final Map.Entry entry = (Map.Entry) it.next(); + final String tableName = (String) entry.getValue(); + /** + * Update the map, prepending the schema name to the table name + * so long as the value is a table name and not a field. This + * algorithm assumes that all old table names start with "epsg_". + */ + if (tableName.startsWith("epsg_")) { + entry.setValue(epsgSchema + '.' + tableName); + } + } + } + } + } } Modified: geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/ThreadedOracleEpsgFactory.java =================================================================== --- geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/ThreadedOracleEpsgFactory.java 2007-06-29 21:34:10 UTC (rev 26095) +++ geotools/trunk/gt/modules/unsupported/epsg-oracle/src/main/java/org/geotools/referencing/factory/epsg/ThreadedOracleEpsgFactory.java 2007-06-29 21:45:12 UTC (rev 26096) @@ -198,7 +198,7 @@ */ protected AbstractAuthorityFactory createBackingStore(final Hints hints) throws SQLException { final Connection connection = getDataSource().getConnection(); - final AnsiDialectEpsgFactory factory = new OracleDialectEpsgFactory(hints, connection); + final FactoryUsingOracleSQL factory = new FactoryUsingOracleSQL(hints, connection); if (schema != null) { factory.setSchema(schema); } |