/activeobjects-plugin/src/main/java/com/atlassian/activeobjects/internal/JdbcDriverDatabaseProviderFactory.java

https://bitbucket.org/activeobjects/ao-plugin · Java · 152 lines · 131 code · 15 blank · 6 comment · 8 complexity · db430c5e445eb0cce43f1a58cfe2fd24 MD5 · raw file

  1. package com.atlassian.activeobjects.internal;
  2. import com.atlassian.activeobjects.spi.DatabaseType;
  3. import net.java.ao.DatabaseProvider;
  4. import net.java.ao.Disposable;
  5. import net.java.ao.DisposableDataSource;
  6. import net.java.ao.builder.DelegatingDisposableDataSourceHandler;
  7. import net.java.ao.db.ClientDerbyDatabaseProvider;
  8. import net.java.ao.db.EmbeddedDerbyDatabaseProvider;
  9. import net.java.ao.db.H2DatabaseProvider;
  10. import net.java.ao.db.HSQLDatabaseProvider;
  11. import net.java.ao.db.MsJdbcSQLServerDatabaseProvider;
  12. import net.java.ao.db.MySQLDatabaseProvider;
  13. import net.java.ao.db.NuoDBDatabaseProvider;
  14. import net.java.ao.db.NuoDBDisposableDataSourceHandler;
  15. import net.java.ao.db.OracleDatabaseProvider;
  16. import net.java.ao.db.PostgreSQLDatabaseProvider;
  17. import net.java.ao.db.SQLServerDatabaseProvider;
  18. import javax.sql.DataSource;
  19. import static com.atlassian.activeobjects.ao.ConverterUtils.toLowerCase;
  20. import static com.google.common.base.Preconditions.checkNotNull;
  21. public final class JdbcDriverDatabaseProviderFactory implements DatabaseProviderFactory {
  22. private final DriverNameExtractor driverNameExtractor;
  23. public JdbcDriverDatabaseProviderFactory(DriverNameExtractor driverNameExtractor) {
  24. this.driverNameExtractor = checkNotNull(driverNameExtractor);
  25. }
  26. public DatabaseProvider getDatabaseProvider(DataSource dataSource, DatabaseType databaseType, String schema) {
  27. final String driverName = getDriverName(dataSource);
  28. for (DatabaseProviderFactoryEnum dbProviderFactory : DatabaseProviderFactoryEnum.values()) {
  29. if (dbProviderFactory.accept(databaseType, driverName)) {
  30. return dbProviderFactory.getDatabaseProvider(dataSource, schema);
  31. }
  32. }
  33. throw new DatabaseProviderNotFoundException(driverName);
  34. }
  35. private String getDriverName(DataSource dataSource) {
  36. return driverNameExtractor.getDriverName(dataSource);
  37. }
  38. /**
  39. * TODO fix, this is actually not tested and needs to be. This is possibly quite fragile as well, as I don't know
  40. * yet what happens to the driver name when using connection pooling, but I'd bet it changes to something that doesn't
  41. * give much information
  42. */
  43. private static enum DatabaseProviderFactoryEnum {
  44. MYSQL(DatabaseType.MYSQL, "mysql", false) {
  45. @Override
  46. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  47. return new MySQLDatabaseProvider(getDisposableDataSource(dataSource));
  48. }
  49. },
  50. DERBY_NETWORK(DatabaseType.DERBY_NETWORK, "derby", false) {
  51. @Override
  52. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  53. return new ClientDerbyDatabaseProvider(getDisposableDataSource(dataSource));
  54. }
  55. },
  56. DERBY_EMBEDDED(DatabaseType.DERBY_EMBEDDED, "derby", false) {
  57. @Override
  58. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  59. return new EmbeddedDerbyDatabaseProvider(getDisposableDataSource(dataSource), "a-fake-uri"); // TODO handle the URI issue
  60. }
  61. },
  62. ORACLE(DatabaseType.ORACLE, "oracle", false) {
  63. @Override
  64. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  65. return new OracleDatabaseProvider(getDisposableDataSource(dataSource), schema);
  66. }
  67. },
  68. POSTGRESQL(DatabaseType.POSTGRESQL, "postgres", false) {
  69. @Override
  70. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  71. return new PostgreSQLDatabaseProvider(getDisposableDataSource(dataSource), schema);
  72. }
  73. },
  74. MSSQL(DatabaseType.MS_SQL, "microsoft", true) {
  75. @Override
  76. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  77. return new MsJdbcSQLServerDatabaseProvider(getDisposableDataSource(dataSource), schema);
  78. }
  79. },
  80. MSSQL_JTDS(DatabaseType.MS_SQL, "jtds", true) {
  81. @Override
  82. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  83. return new SQLServerDatabaseProvider(getDisposableDataSource(dataSource), schema);
  84. }
  85. },
  86. HSQLDB(DatabaseType.HSQL, "hsql", false) {
  87. @Override
  88. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  89. return new HSQLDatabaseProvider(getDisposableDataSource(dataSource), schema);
  90. }
  91. },
  92. H2(DatabaseType.H2, "h2", false) {
  93. @Override
  94. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  95. return new H2DatabaseProvider(getDisposableDataSource(dataSource), schema);
  96. }
  97. },
  98. NUODB(DatabaseType.NUODB, "nuodb", false) {
  99. @Override
  100. public DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema) {
  101. return new NuoDBDatabaseProvider(NuoDBDisposableDataSourceHandler.newInstance(dataSource), schema);
  102. }
  103. };
  104. private final DatabaseType databaseType;
  105. private final String driverName;
  106. private final boolean needsDatabaseTypeAndDriverName;
  107. DatabaseProviderFactoryEnum(DatabaseType databaseType, String driverName, boolean needsDatabaseTypeAndDriverName) {
  108. this.databaseType = checkNotNull(databaseType);
  109. this.driverName = checkNotNull(driverName);
  110. this.needsDatabaseTypeAndDriverName = needsDatabaseTypeAndDriverName;
  111. }
  112. boolean accept(DatabaseType otherDatabaseType, String otherDriverName) {
  113. final boolean acceptDatabaseType = acceptDatabaseType(otherDatabaseType);
  114. final boolean acceptDriverName = acceptDriverName(otherDriverName);
  115. if (needsDatabaseTypeAndDriverName) {
  116. return acceptDatabaseType && acceptDriverName;
  117. } else {
  118. return acceptDatabaseType || acceptDriverName;
  119. }
  120. }
  121. private boolean acceptDatabaseType(DatabaseType otherDatabaseType) {
  122. return databaseType.equals(otherDatabaseType);
  123. }
  124. private boolean acceptDriverName(String otherDriverName) {
  125. return otherDriverName != null && toLowerCase(otherDriverName).contains(this.driverName);
  126. }
  127. // apparently useless, I know, but the compiler complains if not there
  128. public abstract DatabaseProvider getDatabaseProvider(DataSource dataSource, String schema);
  129. }
  130. private static DisposableDataSource getDisposableDataSource(final DataSource dataSource) {
  131. return DelegatingDisposableDataSourceHandler.newInstance(dataSource, new Disposable() {
  132. @Override
  133. public void dispose() {
  134. }
  135. });
  136. }
  137. }