001package co.codewizards.cloudstore.local.db;
002
003import static co.codewizards.cloudstore.core.oio.OioFileFactory.*;
004import static co.codewizards.cloudstore.core.repo.local.LocalRepoManager.*;
005import static java.util.Objects.*;
006
007import java.io.IOException;
008import java.util.HashMap;
009import java.util.Map;
010import java.util.UUID;
011
012import co.codewizards.cloudstore.core.appid.AppId;
013import co.codewizards.cloudstore.core.oio.File;
014import co.codewizards.cloudstore.core.util.IOUtil;
015
016public abstract class AbstractDatabaseAdapter implements DatabaseAdapter {
017        /**
018         * The template for the name of the persistence-properties-file.
019         * <p>
020         * The variables (most importantly "${databaseAdapter.name}") are replaced by the coordinates of the
021         * actual database being used (e.g. databaseAdapter.name = "derby") and the file then copied from the JAR
022         * {@code co.codewizards.cloudstore.local} using the class-loader (e.g. resource "/cloudstore-persistence.derby.properties").
023         * Since the class-loader is used, the file might exist in another JAR, too.
024         * <p>
025         * <b>Important:</b> This name is independent from the {@link AppId}, because obviously the resource in the JAR
026         * always has the same name - no matter in which application it is packaged!
027         * <p>
028         * <b>Important 2:</> The name of the generated file in the application's config directory is dependent on the {@code AppId}!
029         */
030        private static final String PERSISTENCE_PROPERTIES_TEMPLATE_FILE_NAME = "cloudstore-persistence.${databaseAdapter.name}.properties";
031
032        private AbstractDatabaseAdapterFactory factory;
033
034        private UUID repositoryId;
035        private File localRoot;
036
037        public AbstractDatabaseAdapterFactory getFactory() {
038                return factory;
039        }
040        public AbstractDatabaseAdapterFactory getFactoryOrFail() {
041                return requireNonNull(factory, "factory");
042        }
043        protected void setFactory(AbstractDatabaseAdapterFactory factory) {
044                this.factory = factory;
045        }
046
047        @Override
048        public UUID getRepositoryId() {
049                return repositoryId;
050        }
051        public UUID getRepositoryIdOrFail() {
052                return requireNonNull(repositoryId, "repositoryId");
053        }
054        @Override
055        public void setRepositoryId(UUID repositoryId) {
056                this.repositoryId = repositoryId;
057        }
058
059        @Override
060        public File getLocalRoot() {
061                return localRoot;
062        }
063        public File getLocalRootOrFail() {
064                return requireNonNull(localRoot, "localRoot");
065        }
066        @Override
067        public void setLocalRoot(File localRoot) {
068                this.localRoot = localRoot;
069        }
070
071        protected File getMetaDir() {
072                return createFile(localRoot, META_DIR_NAME);
073        }
074
075        protected File getPersistencePropertiesFile() {
076                return createFile(getMetaDir(), PERSISTENCE_PROPERTIES_FILE_NAME);
077        }
078
079        protected void createPersistencePropertiesFile() {
080                final Map<String, Object> variables = new HashMap<>();
081                variables.put("databaseAdapter.name", getFactoryOrFail().getName());
082                final String resolvedPersistencePropertiesTemplateFileName =
083                                IOUtil.replaceTemplateVariables(PERSISTENCE_PROPERTIES_TEMPLATE_FILE_NAME, variables);
084
085                try {
086                        IOUtil.copyResource(this.getClass(), "/" + resolvedPersistencePropertiesTemplateFileName,
087                                        getPersistencePropertiesFile());
088                } catch (final IOException e) {
089                        throw new RuntimeException(e);
090                }
091        }
092
093        @Override
094        public void createPersistencePropertiesFileAndDatabase() throws Exception {
095                createPersistencePropertiesFile();
096                createDatabase();
097        }
098
099        protected abstract void createDatabase() throws Exception;
100
101        @Override
102        public void close() throws Exception {
103                // nothing to do - sub-classes may extend
104        }
105}