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