001package co.codewizards.cloudstore.core.repo.local;
002
003import java.util.Iterator;
004import java.util.ServiceLoader;
005import java.util.Set;
006
007import co.codewizards.cloudstore.core.oio.File;
008
009public interface LocalRepoManagerFactory {
010        class Helper {
011                private static LocalRepoManagerFactory instance;
012
013                public static synchronized LocalRepoManagerFactory getInstance() {
014                        if (instance == null) {
015                                final ServiceLoader<LocalRepoManagerFactory> serviceLoader = ServiceLoader.load(LocalRepoManagerFactory.class);
016                                final Iterator<LocalRepoManagerFactory> iterator = serviceLoader.iterator();
017                                if (!iterator.hasNext())
018                                        throw new IllegalStateException("There is no LocalRepoManagerFactory implementation registered! Maybe the JAR 'co.codewizards.cloudstore.local' is missing in the classpath?!");
019
020                                final LocalRepoManagerFactory localRepoManagerFactory = iterator.next();
021
022                                if (iterator.hasNext())
023                                        throw new IllegalStateException("There are multiple LocalRepoManagerFactory implementations registered! Maybe there are multiple versions of JAR 'co.codewizards.cloudstore.local' in the classpath?!");
024
025                                instance = localRepoManagerFactory;
026                        }
027                        return instance;
028                }
029        }
030
031        /**
032         * Creates a {@link LocalRepoManager} for the given {@code localRoot}.
033         * <p>
034         * <b>Important:</b> You must call {@link LocalRepoManager#close()}. Use a try-finally block or a
035         * similar construction to prevent resource leakage!
036         * <p>
037         * If there is already a {@code LocalRepoManager} implementation instance for this {@code localRoot}, the same
038         * instance is re-used in the background. If there is none, yet, it is implicitly instantiated and enlisted.
039         * However, this method always returns a new proxy instance! It never returns the same instance twice.
040         * <p>
041         * If {@code localRoot} is not an existing repository in the file system, one of the following
042         * exceptions is thrown:
043         * <ul>
044         * <li>{@link FileNotFoundException}
045         * <li>{@link FileNoDirectoryException}
046         * <li>{@link FileNoRepositoryException}
047         * </ul>
048         * @param localRoot the root-directory of the repository. Must not be <code>null</code>. Can be
049         * relative or absolute.
050         * @return the {@link LocalRepoManagerImpl} for the given {@code localRoot}. Never <code>null</code>.
051         * @see #createLocalRepoManagerForNewRepository(File)
052         * @throws LocalRepoManagerException if the given {@code localRoot} does not denote the root-directory
053         * of an existing repository.
054         */
055        LocalRepoManager createLocalRepoManagerForExistingRepository(File localRoot) throws LocalRepoManagerException;
056
057        /**
058         * Creates a {@link LocalRepoManager} for the given {@code localRoot}.
059         * <p>
060         * <b>Important:</b> You must call {@link LocalRepoManager#close()}. Use a try-finally block or a
061         * similar construction to prevent resource leakage!
062         * <p>
063         * This method turns an existing directory into a repository. If {@code localRoot} already is a repository,
064         * a {@link FileAlreadyRepositoryException} is thrown.
065         * <p>
066         * If {@code localRoot} is not an existing directory in the file system, one of the following
067         * exceptions is thrown:
068         * <ul>
069         * <li>{@link FileNotFoundException}
070         * <li>{@link FileNoDirectoryException}
071         * </ul>
072         * @param localRoot the directory which is turned into the repository's root. Must not be <code>null</code>.
073         * Can be relative or absolute.
074         * @return the {@link LocalRepoManager} for the given {@code localRoot}. Never <code>null</code>.
075         * @throws LocalRepoManagerException if the given {@code localRoot} does not denote an existing directory
076         * or if it is a directory inside an existing repository.
077         */
078        LocalRepoManager createLocalRepoManagerForNewRepository(File localRoot) throws LocalRepoManagerException;
079
080        void close();
081
082        void addLocalRepoManagerCloseListener(LocalRepoManagerCloseListener listener);
083
084        void removeLocalRepoManagerCloseListener(LocalRepoManagerCloseListener listener);
085
086        Set<File> getLocalRoots();
087
088}