View Javadoc

1   package liquibase.ext.spatial.sqlgenerator;
2   
3   import java.sql.Connection;
4   import java.sql.ResultSet;
5   import java.sql.SQLException;
6   import java.sql.Statement;
7   import java.util.Collections;
8   import java.util.HashMap;
9   import java.util.Map;
10  
11  import liquibase.database.Database;
12  import liquibase.database.jvm.JdbcConnection;
13  import liquibase.exception.UnexpectedLiquibaseException;
14  import liquibase.util.StringUtils;
15  
16  /**
17   * <code>OracleSpatialUtils</code> provides utility methods for Oracle Spatial.
18   */
19  public class OracleSpatialUtils {
20     /** The Oracle function that converts an EPSG SRID to the corresponding Oracle SRID. */
21     public static final String EPSG_TO_ORACLE_FUNCTION = "SDO_CS.MAP_EPSG_SRID_TO_ORACLE";
22  
23     /** The mapping of EPSG SRID to Oracle SRID. */
24     private final static Map<String, String> EPSG_TO_ORACLE_MAP = Collections
25           .synchronizedMap(new HashMap<String, String>());
26  
27     /** Hide the default constructor. */
28     private OracleSpatialUtils() {
29     }
30  
31     /**
32      * Converts the given Well-Known Text string to one that will work in Oracle. If the string is
33      * greater than 4000 characters, the string is broken into pieces where each piece is converted
34      * to a CLOB. The CLOB handling assumes that the result will be wrapped in single quotes so it
35      * wraps the result in "<code>' || TO_CLOB(...) || '</code>".
36      * 
37      * @param wkt
38      *           the Well-Known Text string to convert.
39      * @return the original WKT or a <code>TO_CLOB</code> concatenation of the WKT.
40      */
41     public static String getOracleWkt(final String wkt) {
42        final String oracleWkt;
43        // Strings longer than 4000 characters need to be converted to CLOBs.
44        if (wkt.length() > 4000) {
45           int index = 4000;
46           final StringBuilder clobs = new StringBuilder("' || TO_CLOB('").append(
47                 wkt.substring(0, index)).append("')");
48           while (index < wkt.length()) {
49              final int endIndex = Math.min(index + 4000, wkt.length());
50              clobs.append(" || TO_CLOB('").append(wkt.substring(index, endIndex)).append("')");
51              index = endIndex;
52           }
53           clobs.append(" || '");
54           oracleWkt = clobs.toString();
55        } else {
56           oracleWkt = wkt;
57        }
58        return oracleWkt;
59     }
60  
61     /**
62      * Converts the given EPSG SRID to the corresponding Oracle SRID.
63      * 
64      * @param srid
65      *           the EPSG SRID.
66      * @param database
67      *           the database instance.
68      * @return the corresponding Oracle SRID.
69      */
70     public static String getOracleSrid(final String srid, final Database database) {
71        final String oracleSrid;
72        if (StringUtils.trimToNull(srid) == null) {
73           oracleSrid = null;
74        } else if (EPSG_TO_ORACLE_MAP.containsKey(srid)) {
75           oracleSrid = EPSG_TO_ORACLE_MAP.get(srid);
76        } else {
77           oracleSrid = loadOracleSrid(srid, database);
78           EPSG_TO_ORACLE_MAP.put(srid, oracleSrid);
79        }
80        return oracleSrid;
81     }
82  
83     /**
84      * Queries to the database to convert the given EPSG SRID to the corresponding Oracle SRID.
85      * 
86      * @param srid
87      *           the EPSG SRID.
88      * @param database
89      *           the database instance.
90      * @return the corresponding Oracle SRID.
91      */
92     public static String loadOracleSrid(final String srid, final Database database) {
93        final String oracleSrid;
94        final JdbcConnection jdbcConnection = (JdbcConnection) database.getConnection();
95        final Connection connection = jdbcConnection.getUnderlyingConnection();
96        Statement statement = null;
97        try {
98           statement = connection.createStatement();
99           final ResultSet resultSet = statement.executeQuery("SELECT " + EPSG_TO_ORACLE_FUNCTION
100                + "(" + srid + ") FROM dual");
101          resultSet.next();
102          oracleSrid = resultSet.getString(1);
103       } catch (final SQLException e) {
104          throw new UnexpectedLiquibaseException("Failed to find the Oracle SRID for EPSG:" + srid,
105                e);
106       } finally {
107          try {
108             statement.close();
109          } catch (final SQLException ignore) {
110          }
111       }
112       return oracleSrid;
113    }
114 }