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}