001package co.codewizards.cloudstore.core.repo.local; 002 003import java.io.File; 004import java.lang.reflect.InvocationHandler; 005import java.net.URL; 006import java.util.UUID; 007import java.util.concurrent.locks.Lock; 008 009import co.codewizards.cloudstore.core.progress.ProgressMonitor; 010 011public interface LocalRepoManager { 012 013 String SYSTEM_PROPERTY_KEY_SIZE = "cloudstore.repository.asymmetricKey.size"; 014 int DEFAULT_KEY_SIZE = 4096; 015 016 String SYSTEM_PROPERTY_CLOSE_DEFERRED_MILLIS = "cloudstore.localRepoManager.closeDeferredMillis"; 017 long DEFAULT_CLOSE_DEFERRED_MILLIS = 20000; 018 019 String META_DIR_NAME = ".cloudstore-repo"; 020 String TEMP_DIR_NAME = ".cloudstore-tmp"; 021 String TEMP_NEW_FILE_PREFIX = ".cloudstore-new_"; 022 023 String REPOSITORY_PROPERTIES_FILE_NAME = "cloudstore-repository.properties"; 024 String PROP_REPOSITORY_ID = "repository.id"; 025 String PROP_VERSION = "repository.version"; 026 /** 027 * Aliases separated by '/' (because '/' is an illegal character for an alias). 028 * <p> 029 * To make scripting easier (e.g. using grep), the aliases start and end with a 030 * '/'. For example: "/alias1/alias2/alias3/" 031 */ 032 String PROP_REPOSITORY_ALIASES = "repository.aliases"; 033 034 String PERSISTENCE_PROPERTIES_FILE_NAME = "cloudstore-persistence.properties"; 035 036 String VAR_LOCAL_ROOT = "repository.localRoot"; 037 String VAR_META_DIR = "repository.metaDir"; 038 039 /** 040 * Gets the repository's local root directory. 041 * <p> 042 * This file is canonical (absolute and symbolic links resolved). 043 * @return the repository's local root directory. Never <code>null</code>. 044 */ 045 File getLocalRoot(); 046 047 /** 048 * Gets the local repository's unique ID. 049 * <p> 050 * This is {@link LocalRepository#getEntityID() LocalRepository.entityID} in the local repository database. 051 * @return the local repository's unique ID. Never <code>null</code>. 052 */ 053 UUID getRepositoryId(); 054 055 /** 056 * Gets the local repository's private key. 057 * <p> 058 * This is always an RSA key - other key types are not (yet) supported. 059 * @return the local repository's private key. Never <code>null</code>. 060 */ 061 byte[] getPrivateKey(); 062 063 /** 064 * Gets the local repository's public key. 065 * <p> 066 * This is always an RSA key - other key types are not (yet) supported. 067 * @return the local repository's public key. Never <code>null</code>. 068 */ 069 byte[] getPublicKey(); 070 071 /** 072 * Gets the remote repository's public key. 073 * <p> 074 * This is always an RSA key - other key types are not (yet) supported. 075 * @param repositoryId the remote repository's unique ID. Must not be <code>null</code>. 076 * @return the remote repository's public key. Never <code>null</code>. 077 * @throws IllegalArgumentException if there is no remote-repository with the given {@code repositoryId}. 078 */ 079 byte[] getRemoteRepositoryPublicKeyOrFail(UUID repositoryId); 080 081 void addLocalRepoManagerCloseListener(LocalRepoManagerCloseListener listener); 082 083 void removeLocalRepoManagerCloseListener(LocalRepoManagerCloseListener listener); 084 085 /** 086 * Gets the <i>open</i> state. 087 * <p> 088 * If this is <code>false</code>, the {@link LocalRepoManager} instance cannot be used anymore. 089 * Due to the proxy-mechanism, this does, however, not mean that the backend is really shut down. 090 * @return the <i>open</i> state. 091 */ 092 boolean isOpen(); 093 094 /** 095 * Closes this {@link LocalRepoManager}. 096 * <p> 097 * <b>Important:</b> The {@link LocalRepoManagerFactory} always returns a proxy. It never returns 098 * the real backend-instance. Calling {@code close()} closes the proxy and thus renders it unusable. 099 * It decrements the real backend-instance's reference counter. As soon as this reaches 0, the backend 100 * is really closed - which may happen delayed (for performance reasons). 101 */ 102 void close(); 103 104 /** 105 * Begin a JDO transaction for read operations only in the underlying database. 106 * @return the transaction handle. Never <code>null</code>. 107 */ 108 LocalRepoTransaction beginReadTransaction(); 109 110 /** 111 * Begin a JDO transaction for read and write operations in the underlying database. 112 * @return the transaction handle. Never <code>null</code>. 113 */ 114 LocalRepoTransaction beginWriteTransaction(); 115 116 /** 117 * Synchronises the local file system with the local database. 118 * <p> 119 * Registers every directory and file in the repository's {@link #getLocalRoot() local root} and its 120 * sub-directories. 121 */ 122 void localSync(ProgressMonitor monitor); 123 124 /** 125 * Adds or relocates a remote repository. 126 * @param repositoryId the remote repository's unique ID. Must not be <code>null</code>. This is 127 * {@link LocalRepository#getEntityID() LocalRepository.entityID} in the remote database and will become 128 * {@link RemoteRepository#getEntityID() RemoteRepository.entityID} in the local database. 129 * @param remoteRoot the URL of the remote repository. May be <code>null</code> (in the server, a 130 * {@code RemoteRepository} never has a {@code remoteRoot}). 131 * @param localPathPrefix TODO 132 */ 133 void putRemoteRepository(UUID repositoryId, URL remoteRoot, byte[] publicKey, String localPathPrefix); 134 135 /** 136 * Deletes a remote repository from the local database. 137 * <p> 138 * Does nothing, if the specified repository does not exist. 139 * @param repositoryId the remote repository's unique ID. Must not be <code>null</code>. 140 */ 141 void deleteRemoteRepository(UUID repositoryId); 142 143 /** 144 * Gets the local path-prefix (of the local repository managed by this {@code LocalRepoManager}) when syncing with 145 * the remote repository identified by the given {@code remoteRoot}. 146 * @param remoteRoot the remote repository's root-URL (not necessarily its real root, but the root URL connected 147 * to the local repository). Must not be <code>null</code>. 148 * @return the local path-prefix. Never <code>null</code>, but maybe empty. 149 * @throws IllegalArgumentException if there is no remote-repository with the given {@code remoteRoot}. 150 */ 151 String getLocalPathPrefixOrFail(URL remoteRoot); 152 153 /** 154 * Gets the local path-prefix (of the local repository managed by this {@code LocalRepoManager}) when syncing with 155 * the remote repository identified by the given {@code remoteRoot}. 156 * @param repositoryId the remote repository's unique ID. Must not be <code>null</code>. 157 * @return the local path-prefix. Never <code>null</code>, but maybe empty. 158 * @throws IllegalArgumentException if there is no remote-repository with the given {@code remoteRoot}. 159 */ 160 String getLocalPathPrefixOrFail(UUID repositoryId); 161 162 /** 163 * Gets the unique ID of the remote repository identified by the given {@code remoteRoot}. 164 * @param remoteRoot the remote repository's root-URL (not necessarily its real root, but the root URL connected 165 * to the local repository). Must not be <code>null</code>. 166 * @return the remote repository's unique ID. Never <code>null</code>. 167 * @throws IllegalArgumentException if there is no remote-repository with the given {@code remoteRoot}. 168 */ 169 UUID getRemoteRepositoryIdOrFail(URL remoteRoot); 170 171 Lock getLock(); 172 173 /** 174 * @deprecated <b>Do not invoke this method directly!</b> It is declared in this interface to make sure the 175 * proxy's {@link InvocationHandler} is invoked when the garbage-collector collects the proxy. 176 */ 177 @Deprecated 178 void finalize() throws Throwable; 179 180 void putRepositoryAlias(String repositoryAlias); 181 182 void removeRepositoryAlias(String repositoryAlias); 183 184}