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}