View Javadoc
1   package com.atlassian.activeobjects.internal;
2   
3   import com.atlassian.activeobjects.ActiveObjectsPluginException;
4   import com.atlassian.activeobjects.config.ActiveObjectsConfiguration;
5   import com.atlassian.activeobjects.config.PluginKey;
6   import com.atlassian.activeobjects.external.ActiveObjects;
7   import com.atlassian.activeobjects.spi.ActiveObjectsPluginConfiguration;
8   import com.atlassian.activeobjects.spi.DatabaseType;
9   import com.atlassian.beehive.ClusterLockService;
10  import com.atlassian.sal.api.ApplicationProperties;
11  import com.atlassian.sal.api.transaction.TransactionTemplate;
12  import com.atlassian.tenancy.api.Tenant;
13  import net.java.ao.EntityManager;
14  import net.java.ao.builder.EntityManagerBuilder;
15  import org.slf4j.Logger;
16  import org.slf4j.LoggerFactory;
17  
18  import java.io.File;
19  
20  import static com.google.common.base.Preconditions.checkNotNull;
21  
22  public final class DatabaseDirectoryAwareActiveObjectsFactory extends AbstractActiveObjectsFactory {
23      private static final String USER_NAME = "sa";
24      private static final String PASSWORD = "";
25  
26      private final Logger log = LoggerFactory.getLogger(this.getClass());
27  
28      private final ApplicationProperties applicationProperties;
29      private final ActiveObjectsPluginConfiguration dbConfiguration;
30  
31      public DatabaseDirectoryAwareActiveObjectsFactory(ActiveObjectUpgradeManager aoUpgradeManager,
32                                                        ApplicationProperties applicationProperties, ActiveObjectsPluginConfiguration dbConfiguration,
33                                                        TransactionTemplate transactionTemplate, ClusterLockService clusterLockService) {
34          super(DataSourceType.HSQLDB, aoUpgradeManager, transactionTemplate, clusterLockService);
35          this.applicationProperties = checkNotNull(applicationProperties);
36          this.dbConfiguration = checkNotNull(dbConfiguration);
37      }
38  
39      @Override
40      protected ActiveObjects doCreate(ActiveObjectsConfiguration configuration, Tenant tenant) {
41          final File dbDir = getDatabaseDirectory(getDatabasesDirectory(getHomeDirectory()), configuration.getPluginKey());
42          final EntityManager entityManager = getEntityManager(dbDir, configuration);
43          return new DatabaseDirectoryAwareEntityManagedActiveObjects(entityManager, new EntityManagedTransactionManager(entityManager));
44      }
45  
46      private EntityManager getEntityManager(File dbDirectory, ActiveObjectsConfiguration configuration) {
47          return EntityManagerBuilder.url(getUri(dbDirectory)).username(USER_NAME).password(PASSWORD).auto()
48                  .tableNameConverter(configuration.getNameConverters().getTableNameConverter())
49                  .fieldNameConverter(configuration.getNameConverters().getFieldNameConverter())
50                  .sequenceNameConverter(configuration.getNameConverters().getSequenceNameConverter())
51                  .triggerNameConverter(configuration.getNameConverters().getTriggerNameConverter())
52                  .indexNameConverter(configuration.getNameConverters().getIndexNameConverter())
53                  .schemaConfiguration(configuration.getSchemaConfiguration())
54                  .build();
55      }
56  
57      private static String getUri(File dbDirectory) {
58          return "jdbc:hsqldb:file:" + dbDirectory.getAbsolutePath() + "/db;hsqldb.default_table_type=cached";
59      }
60  
61      private File getDatabaseDirectory(File databasesDirectory, PluginKey pluginKey) {
62          final File dbDir = new File(databasesDirectory, pluginKey.asString());
63          if (!dbDir.exists() && !dbDir.mkdir()) {
64              throw new ActiveObjectsPluginException("Could not create database directory for plugin <" + pluginKey + "> at  <" + dbDir.getAbsolutePath() + ">");
65          }
66  
67          log.debug("Database directory {} initialised", dbDir);
68  
69          return dbDir;
70      }
71  
72      private File getDatabasesDirectory(File home) {
73          String path = dbConfiguration.getDatabaseBaseDirectory();
74          if (path.startsWith("/")) {
75              path = path.substring(1);
76          }
77          final File dbDirectory = new File(home, path);
78  
79          if (dbDirectory.exists() && dbDirectory.isFile()) {
80              throw new ActiveObjectsPluginException("Database directory already exists, but is a file, at <" + dbDirectory.getPath() + ">");
81          }
82  
83          if (!dbDirectory.exists() && !dbDirectory.mkdirs()) {
84              throw new ActiveObjectsPluginException("Could not create directory for database at <" + dbDirectory.getPath() + ">");
85          }
86  
87          log.debug("ActiveObjects databases directory {} initialized", dbDirectory.getAbsolutePath());
88  
89          return dbDirectory;
90      }
91  
92      private File getHomeDirectory() {
93          final File home = applicationProperties.getHomeDirectory();
94          if (home == null) {
95              throw new ActiveObjectsPluginException("Home directory undefined!");
96          }
97          if (!home.exists() || !home.isDirectory()) {
98              throw new ActiveObjectsPluginException("The ActiveObjects plugin couldn't find a home directory at <" + home.getAbsolutePath() + ">");
99          }
100         return home;
101     }
102 
103     private static final class DatabaseDirectoryAwareEntityManagedActiveObjects extends EntityManagedActiveObjects implements DatabaseDirectoryAware {
104         DatabaseDirectoryAwareEntityManagedActiveObjects(EntityManager entityManager, TransactionManager transactionManager) {
105             super(entityManager, transactionManager, DatabaseType.HSQL);
106         }
107     }
108 }