001package co.codewizards.cloudstore.client;
002
003import static co.codewizards.cloudstore.core.oio.OioFileFactory.*;
004
005import java.io.IOException;
006import java.util.UUID;
007
008import org.kohsuke.args4j.Argument;
009import org.kohsuke.args4j.Option;
010
011import co.codewizards.cloudstore.core.oio.File;
012import co.codewizards.cloudstore.core.repo.local.LocalRepoManager;
013import co.codewizards.cloudstore.core.repo.local.LocalRepoManagerFactory;
014import co.codewizards.cloudstore.core.repo.local.LocalRepoRegistry;
015import co.codewizards.cloudstore.core.repo.local.LocalRepoRegistryImpl;
016import co.codewizards.cloudstore.core.util.IOUtil;
017
018/**
019 * {@link SubCommand} implementation for creating a repository in the local file system.
020 *
021 * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
022 */
023public class CreateRepoSubCommand extends SubCommand
024{
025        @Argument(metaVar="<localRoot>", required=true, usage="The path of the repository's root in the local file system. This must be an existing directory. If it does not exist and the '-createDir' option is set, it is automatically created.")
026        private String localRoot;
027
028        private File localRootFile;
029
030        @Option(name="-createDir", required=false, usage="Whether to create the repository's root directory, if it does not yet exist. If specified, all parent-directories are created, too, if needed.")
031        private boolean createDir;
032
033        @Option(name="-noAlias", required=false, usage="Whether to suppress the automatic creation of a repository-alias with the local root's name.")
034        private boolean noAlias;
035
036        @Option(name="-alias", metaVar="<alias>", required=false, usage="Specify a different alias. By default, the root directory's name is used. For example, if the repository's root is '/home/user/Documents', the alias 'Documents' is chosen. If this option is present, the specified <alias> is used instead.")
037        private String alias;
038
039        @Override
040        public String getSubCommandDescription() {
041                return "Create a new repository.";
042        }
043
044        @Override
045        public void prepare() throws Exception {
046                super.prepare();
047
048                if (localRoot == null)
049                        localRootFile = createFile("").getAbsoluteFile();
050                else
051                        localRootFile = createFile(localRoot).getAbsoluteFile();
052
053                localRoot = localRootFile.getPath();
054
055                if (!noAlias && (alias == null || alias.isEmpty())) { // empty alias means the same as alias not specified.
056                        final String simplified = IOUtil.simplifyPath(localRootFile);
057                        alias = createFile(simplified).getName();
058                }
059
060                if (alias != null && alias.isEmpty())
061                        alias = null;
062        }
063
064        @Override
065        public void run() throws Exception {
066                if (alias != null && noAlias) {
067                        System.err.println("ERROR: You specified both '-alias' and '-noAlias'. These options exclude each other and cannot be combined!");
068                        System.exit(101);
069                }
070
071                if (!localRootFile.exists() && createDir) {
072                        localRootFile.mkdirs();
073
074                        if (!localRootFile.exists())
075                                throw new IOException("Could not create directory (permissions?): " + localRoot);
076                }
077
078                final LocalRepoManager localRepoManager = LocalRepoManagerFactory.Helper.getInstance().createLocalRepoManagerForNewRepository(localRootFile);
079                try {
080                        if (!noAlias && alias != null) {
081                                final LocalRepoRegistry localRepoRegistry = LocalRepoRegistryImpl.getInstance();
082                                UUID oldRepositoryId = localRepoRegistry.getRepositoryId(alias);
083
084                                File oldLocalRoot = null;
085                                if (oldRepositoryId != null) {
086                                        oldLocalRoot = localRepoRegistry.getLocalRoot(oldRepositoryId);
087                                        if (oldLocalRoot == null || !oldLocalRoot.exists()) {
088                                                // orphaned entry to be ignored (should be cleaned up after a while, anyway)
089                                                oldRepositoryId = null;
090                                                oldLocalRoot = null;
091                                        }
092                                }
093
094                                if (oldRepositoryId != null)
095                                        System.err.println(String.format("WARNING: There is already a repository registered with the alias '%s'! Skipping automatic alias registration. The existing repository's ID is '%s' and its local-root is '%s'.", alias, oldRepositoryId, oldLocalRoot));
096                                else
097                                        localRepoManager.putRepositoryAlias(alias);
098                        }
099                } finally {
100                        localRepoManager.close();
101                }
102
103                new RepoInfoSubCommand(localRootFile).run();
104        }
105}