001package co.codewizards.cloudstore.client;
002
003import static co.codewizards.cloudstore.core.oio.OioFileFactory.*;
004import static java.util.Objects.*;
005
006import org.kohsuke.args4j.Argument;
007
008import co.codewizards.cloudstore.core.oio.File;
009import co.codewizards.cloudstore.core.repo.local.LocalRepoHelper;
010import co.codewizards.cloudstore.core.repo.local.LocalRepoRegistryImpl;
011import co.codewizards.cloudstore.core.util.IOUtil;
012
013public abstract class SubCommandWithExistingLocalRepo extends SubCommand {
014
015        @Argument(metaVar="<local>", required=true, index=0, usage="A path inside a repository in the local file system or a "
016                        + "repository-ID or a repository-alias (optionally with a path). If this matches both a locally "
017                        + "existing directory and a repository-ID/-alias, it is assumed to be a repository-ID/-alias. "
018                        + "Note, that it may be a sub-directory inside the repository specified in the form "
019                        + "<repositoryId>/path (this must be a '/' even on Windows).")
020        protected String local;
021
022        /** Must be an empty String ("") or start with the '/' character. */
023        protected String localPathPrefix;
024
025        /**
026         * {@link File} referencing a directory inside the repository (or its root).
027         */
028        protected File localFile;
029
030        /**
031         * The root directory of the repository.
032         * <p>
033         * This may be the same as {@link #localFile} or it may be
034         * a direct or indirect parent-directory of {@code #localFile}.
035         */
036        protected File localRoot;
037
038        @Override
039        public void prepare() throws Exception {
040                super.prepare();
041                requireNonNull(local, "local");
042
043                String repositoryName;
044                final int slashIndex = local.indexOf('/');
045                if (slashIndex < 0) {
046                        repositoryName = local;
047                        localPathPrefix = "";
048                }
049                else {
050                        repositoryName = local.substring(0, slashIndex);
051                        localPathPrefix = local.substring(slashIndex);
052
053                        if (!localPathPrefix.startsWith("/"))
054                                throw new IllegalStateException("localPathPrefix does not start with '/': " + localPathPrefix);
055                }
056
057                if ("/".equals(localPathPrefix))
058                        localPathPrefix = "";
059
060                localRoot = LocalRepoRegistryImpl.getInstance().getLocalRootForRepositoryName(repositoryName);
061                if (localRoot != null)
062                        localFile = localPathPrefix.isEmpty() ? localRoot : createFile(localRoot, localPathPrefix);
063                else {
064                        localFile = createFile(local).getAbsoluteFile();
065                        localRoot = LocalRepoHelper.getLocalRootContainingFile(localFile);
066                        if (localRoot == null)
067                                localRoot = localFile;
068
069                        if (localRoot.equals(localFile))
070                                localPathPrefix = "";
071                        else
072                                localPathPrefix = IOUtil.getRelativePath(localRoot, localFile).replace(FILE_SEPARATOR_CHAR, '/');
073
074                        if (! localPathPrefix.isEmpty() && ! localPathPrefix.startsWith("/"))
075                                localPathPrefix = "/" + localPathPrefix;
076                }
077                assertLocalRootNotNull();
078        }
079
080        protected void assertLocalRootNotNull() {
081                requireNonNull(localRoot, "localRoot");
082        }
083
084}