*
* @author Sebastian Sdorra
* @since 1.23
@@ -45,13 +61,68 @@ package sonia.scm.store;
public interface BlobStoreFactory {
/**
- * Returns a {@link BlobStore} with the given name, if the {@link BlobStore}
- * with the given name does not exists the factory will create a new one.
+ * Creates a new or gets an existing {@link BlobStore}. Instead of calling this method you should use the floating API
+ * from {@link #withName(String)}.
*
- *
- * @param name name of the {@link BlobStore}
- *
- * @return {@link BlobStore} with the given name
+ * @param storeParameters The parameters for the blob store.
+ * @return A new or an existing {@link BlobStore} for the given parameters.
*/
- public BlobStore getBlobStore(String name);
+ BlobStore getStore(final StoreParameters storeParameters);
+
+ /**
+ * Use this to create a new or get an existing {@link BlobStore} with a floating API.
+ * @param name The name for the {@link BlobStore}.
+ * @return Floating API to either specify a repository or directly build a global {@link BlobStore}.
+ */
+ default FloatingStoreParameters.Builder withName(String name) {
+ return new FloatingStoreParameters(this).new Builder(name);
+ }
+}
+
+final class FloatingStoreParameters implements StoreParameters {
+
+ private String name;
+ private Repository repository;
+
+ private final BlobStoreFactory factory;
+
+ FloatingStoreParameters(BlobStoreFactory factory) {
+ this.factory = factory;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Repository getRepository() {
+ return repository;
+ }
+
+ public class Builder {
+
+ Builder(String name) {
+ FloatingStoreParameters.this.name = name;
+ }
+
+ /**
+ * Use this to create or get a {@link BlobStore} for a specific repository. This step is optional. If you want to
+ * have a global {@link BlobStore}, omit this.
+ * @param repository The optional repository for the {@link BlobStore}.
+ * @return Floating API to finish the call.
+ */
+ public FloatingStoreParameters.Builder forRepository(Repository repository) {
+ FloatingStoreParameters.this.repository = repository;
+ return this;
+ }
+
+ /**
+ * Creates or gets the {@link BlobStore} with the given name and (if specified) the given repository. If no
+ * repository is given, the {@link BlobStore} will be global.
+ */
+ public BlobStore build(){
+ return factory.getStore(FloatingStoreParameters.this);
+ }
+ }
}
diff --git a/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java
index 7cfebd69c1..80f9cb3df9 100644
--- a/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java
+++ b/scm-core/src/main/java/sonia/scm/store/ConfigurationEntryStoreFactory.java
@@ -32,31 +32,104 @@
package sonia.scm.store;
+import sonia.scm.repository.Repository;
+
/**
- * The ConfigurationEntryStoreFactory can be used to create new or get existing
- * {@link ConfigurationEntryStore}s. Note: the default implementation
- * uses the same location as the {@link StoreFactory}, so be sure that the
- * store names are unique for all {@link ConfigurationEntryStore}s and
- * {@link Store}s.
- *
+ * The ConfigurationEntryStoreFactory can be used to create new or get existing {@link ConfigurationEntryStore}s.
+ *
+ * Note: the default implementation uses the same location as the {@link ConfigurationStoreFactory}, so be sure
+ * that the store names are unique for all {@link ConfigurationEntryStore}s and {@link ConfigurationEntryStore}s.
+ *
+ * You can either create a global {@link ConfigurationEntryStore} or a {@link ConfigurationEntryStore} for a specific
+ * repository. To create a global {@link ConfigurationEntryStore} call:
+ *
+ *
* @author Sebastian Sdorra
* @since 1.31
*
* @apiviz.landmark
* @apiviz.uses sonia.scm.store.ConfigurationEntryStore
*/
-public interface ConfigurationEntryStoreFactory
-{
+public interface ConfigurationEntryStoreFactory {
/**
- * Get an existing {@link ConfigurationEntryStore} or create a new one.
+ * Creates a new or gets an existing {@link ConfigurationEntryStore}. Instead of calling this method you should use
+ * the floating API from {@link #withType(Class)}.
*
- *
- * @param type type of the store objects
- * @param name name of the store
- * @param type of the store objects
- *
- * @return {@link ConfigurationEntryStore} with given name and type
+ * @param storeParameters The parameters for the {@link ConfigurationEntryStore}.
+ * @return A new or an existing {@link ConfigurationEntryStore} for the given parameters.
*/
- public ConfigurationEntryStore getStore(Class type, String name);
+ ConfigurationEntryStore getStore(final TypedStoreParameters storeParameters);
+
+ /**
+ * Use this to create a new or get an existing {@link ConfigurationEntryStore} with a floating API.
+ * @param type The type for the {@link ConfigurationEntryStore}.
+ * @return Floating API to set the name and either specify a repository or directly build a global
+ * {@link ConfigurationEntryStore}.
+ */
+ default TypedFloatingConfigurationEntryStoreParameters.Builder withType(Class type) {
+ return new TypedFloatingConfigurationEntryStoreParameters(this).new Builder(type);
+ }
+}
+
+final class TypedFloatingConfigurationEntryStoreParameters {
+
+ private final TypedStoreParametersImpl parameters = new TypedStoreParametersImpl<>();
+ private final ConfigurationEntryStoreFactory factory;
+
+ TypedFloatingConfigurationEntryStoreParameters(ConfigurationEntryStoreFactory factory) {
+ this.factory = factory;
+ }
+
+ public class Builder {
+
+ Builder(Class type) {
+ parameters.setType(type);
+ }
+
+ /**
+ * Use this to set the name for the {@link ConfigurationEntryStore}.
+ * @param name The name for the {@link ConfigurationEntryStore}.
+ * @return Floating API to either specify a repository or directly build a global {@link ConfigurationEntryStore}.
+ */
+ public OptionalRepositoryBuilder withName(String name) {
+ parameters.setName(name);
+ return new OptionalRepositoryBuilder();
+ }
+ }
+
+ public class OptionalRepositoryBuilder {
+
+ /**
+ * Use this to create or get a {@link ConfigurationEntryStore} for a specific repository. This step is optional. If
+ * you want to have a global {@link ConfigurationEntryStore}, omit this.
+ * @param repository The optional repository for the {@link ConfigurationEntryStore}.
+ * @return Floating API to finish the call.
+ */
+ public OptionalRepositoryBuilder forRepository(Repository repository) {
+ parameters.setRepository(repository);
+ return this;
+ }
+
+ /**
+ * Creates or gets the {@link ConfigurationEntryStore} with the given name and (if specified) the given repository.
+ * If no repository is given, the {@link ConfigurationEntryStore} will be global.
+ */
+ public ConfigurationEntryStore build(){
+ return factory.getStore(parameters);
+ }
+ }
}
diff --git a/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java
index d9a97de98d..6624f307e7 100644
--- a/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java
+++ b/scm-core/src/main/java/sonia/scm/store/ConfigurationStoreFactory.java
@@ -33,27 +33,103 @@
package sonia.scm.store;
+import sonia.scm.repository.Repository;
+
/**
- * The ConfigurationStoreFactory can be used to create new or get existing
- * {@link ConfigurationStore} objects.
+ * The ConfigurationStoreFactory can be used to create new or get existing {@link ConfigurationStore} objects.
+ *
+ * Note: the default implementation uses the same location as the {@link ConfigurationEntryStoreFactory}, so be
+ * sure that the store names are unique for all {@link ConfigurationEntryStore}s and {@link ConfigurationStore}s.
+ *
+ * You can either create a global {@link ConfigurationStore} or a {@link ConfigurationStore} for a specific repository.
+ * To create a global {@link ConfigurationStore} call:
+ *
*
* @author Sebastian Sdorra
*
* @apiviz.landmark
* @apiviz.uses sonia.scm.store.ConfigurationStore
*/
-public interface ConfigurationStoreFactory
-{
+public interface ConfigurationStoreFactory {
/**
- * Get an existing {@link ConfigurationStore} or create a new one.
+ * Creates a new or gets an existing {@link ConfigurationStore}. Instead of calling this method you should use the
+ * floating API from {@link #withType(Class)}.
*
- *
- * @param type type of the store objects
- * @param name name of the store
- * @param type of the store objects
- *
- * @return {@link ConfigurationStore} of the given type and name
+ * @param storeParameters The parameters for the {@link ConfigurationStore}.
+ * @return A new or an existing {@link ConfigurationStore} for the given parameters.
*/
- public ConfigurationStore getStore(Class type, String name);
+ ConfigurationStore getStore(final TypedStoreParameters storeParameters);
+
+ /**
+ * Use this to create a new or get an existing {@link ConfigurationStore} with a floating API.
+ * @param type The type for the {@link ConfigurationStore}.
+ * @return Floating API to set the name and either specify a repository or directly build a global
+ * {@link ConfigurationStore}.
+ */
+ default TypedFloatingConfigurationStoreParameters.Builder withType(Class type) {
+ return new TypedFloatingConfigurationStoreParameters(this).new Builder(type);
+ }
+}
+
+final class TypedFloatingConfigurationStoreParameters {
+
+ private final TypedStoreParametersImpl parameters = new TypedStoreParametersImpl<>();
+ private final ConfigurationStoreFactory factory;
+
+ TypedFloatingConfigurationStoreParameters(ConfigurationStoreFactory factory) {
+ this.factory = factory;
+ }
+
+ public class Builder {
+
+ Builder(Class type) {
+ parameters.setType(type);
+ }
+
+ /**
+ * Use this to set the name for the {@link ConfigurationStore}.
+ * @param name The name for the {@link ConfigurationStore}.
+ * @return Floating API to either specify a repository or directly build a global {@link ConfigurationStore}.
+ */
+ public OptionalRepositoryBuilder withName(String name) {
+ parameters.setName(name);
+ return new OptionalRepositoryBuilder();
+ }
+ }
+
+ public class OptionalRepositoryBuilder {
+
+ /**
+ * Use this to create or get a {@link ConfigurationStore} for a specific repository. This step is optional. If you
+ * want to have a global {@link ConfigurationStore}, omit this.
+ * @param repository The optional repository for the {@link ConfigurationStore}.
+ * @return Floating API to finish the call.
+ */
+ public OptionalRepositoryBuilder forRepository(Repository repository) {
+ parameters.setRepository(repository);
+ return this;
+ }
+
+ /**
+ * Creates or gets the {@link ConfigurationStore} with the given name and (if specified) the given repository. If no
+ * repository is given, the {@link ConfigurationStore} will be global.
+ */
+ public ConfigurationStore build(){
+ return factory.getStore(parameters);
+ }
+ }
}
diff --git a/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java b/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java
index caed974ee4..564c339d3d 100644
--- a/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java
+++ b/scm-core/src/main/java/sonia/scm/store/DataStoreFactory.java
@@ -32,9 +32,27 @@
package sonia.scm.store;
+import sonia.scm.repository.Repository;
+
/**
- * The DataStoreFactory can be used to create new or get existing
- * {@link DataStore}s.
+ * The DataStoreFactory can be used to create new or get existing {@link DataStore}s.
+ *
+ * You can either create a global {@link DataStore} or a {@link DataStore} for a specific repository.
+ * To create a global {@link DataStore} call:
+ *
*
* @author Sebastian Sdorra
* @since 1.23
@@ -45,14 +63,70 @@ package sonia.scm.store;
public interface DataStoreFactory {
/**
- * Get an existing {@link DataStore} or create a new one.
+ * Creates a new or gets an existing {@link DataStore}. Instead of calling this method you should use the
+ * floating API from {@link #withType(Class)}.
*
- *
- * @param type type of the store objects
- * @param name name of the store
- * @param type of the store objects
- *
- * @return {@link DataStore} with given name and type
+ * @param storeParameters The parameters for the {@link DataStore}.
+ * @return A new or an existing {@link DataStore} for the given parameters.
*/
- public DataStore getStore(Class type, String name);
+ DataStore getStore(final TypedStoreParameters storeParameters);
+
+ /**
+ * Use this to create a new or get an existing {@link DataStore} with a floating API.
+ * @param type The type for the {@link DataStore}.
+ * @return Floating API to set the name and either specify a repository or directly build a global
+ * {@link DataStore}.
+ */
+ default TypedFloatingDataStoreParameters.Builder withType(Class type) {
+ return new TypedFloatingDataStoreParameters(this).new Builder(type);
+ }
+}
+
+final class TypedFloatingDataStoreParameters {
+
+ private final TypedStoreParametersImpl parameters = new TypedStoreParametersImpl<>();
+ private final DataStoreFactory factory;
+
+ TypedFloatingDataStoreParameters(DataStoreFactory factory) {
+ this.factory = factory;
+ }
+
+ public class Builder {
+
+ Builder(Class type) {
+ parameters.setType(type);
+ }
+
+ /**
+ * Use this to set the name for the {@link DataStore}.
+ * @param name The name for the {@link DataStore}.
+ * @return Floating API to either specify a repository or directly build a global {@link DataStore}.
+ */
+ public OptionalRepositoryBuilder withName(String name) {
+ parameters.setName(name);
+ return new OptionalRepositoryBuilder();
+ }
+ }
+
+ public class OptionalRepositoryBuilder {
+
+ /**
+ * Use this to create or get a {@link DataStore} for a specific repository. This step is optional. If you
+ * want to have a global {@link DataStore}, omit this.
+ * @param repository The optional repository for the {@link DataStore}.
+ * @return Floating API to finish the call.
+ */
+ public OptionalRepositoryBuilder forRepository(Repository repository) {
+ parameters.setRepository(repository);
+ return this;
+ }
+
+ /**
+ * Creates or gets the {@link DataStore} with the given name and (if specified) the given repository. If no
+ * repository is given, the {@link DataStore} will be global.
+ */
+ public DataStore build(){
+ return factory.getStore(parameters);
+ }
+ }
}
diff --git a/scm-core/src/main/java/sonia/scm/store/StoreParameters.java b/scm-core/src/main/java/sonia/scm/store/StoreParameters.java
new file mode 100644
index 0000000000..da8ee4c916
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/store/StoreParameters.java
@@ -0,0 +1,16 @@
+package sonia.scm.store;
+
+import sonia.scm.repository.Repository;
+
+/**
+ * The fields of the {@link StoreParameters} are used from the {@link BlobStoreFactory} to create a store.
+ *
+ * @author Mohamed Karray
+ * @since 2.0.0
+ */
+public interface StoreParameters {
+
+ String getName();
+
+ Repository getRepository();
+}
diff --git a/scm-core/src/main/java/sonia/scm/store/TypedStoreParameters.java b/scm-core/src/main/java/sonia/scm/store/TypedStoreParameters.java
new file mode 100644
index 0000000000..116bccac41
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/store/TypedStoreParameters.java
@@ -0,0 +1,19 @@
+package sonia.scm.store;
+
+import sonia.scm.repository.Repository;
+
+/**
+ * The fields of the {@link TypedStoreParameters} are used from the {@link ConfigurationStoreFactory},
+ * {@link ConfigurationEntryStoreFactory} and {@link DataStoreFactory} to create a type safe store.
+ *
+ * @author Mohamed Karray
+ * @since 2.0.0
+ */
+public interface TypedStoreParameters {
+
+ Class getType();
+
+ String getName();
+
+ Repository getRepository();
+}
diff --git a/scm-core/src/main/java/sonia/scm/store/TypedStoreParametersImpl.java b/scm-core/src/main/java/sonia/scm/store/TypedStoreParametersImpl.java
new file mode 100644
index 0000000000..50ce6a496b
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/store/TypedStoreParametersImpl.java
@@ -0,0 +1,36 @@
+package sonia.scm.store;
+
+import sonia.scm.repository.Repository;
+
+class TypedStoreParametersImpl implements TypedStoreParameters {
+ private Class type;
+ private String name;
+ private Repository repository;
+
+ @Override
+ public Class getType() {
+ return type;
+ }
+
+ void setType(Class type) {
+ this.type = type;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ void setName(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public Repository getRepository() {
+ return repository;
+ }
+
+ void setRepository(Repository repository) {
+ this.repository = repository;
+ }
+}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java b/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java
index 577d732317..d6b65b41bd 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/group/xml/XmlGroupDAO.java
@@ -64,9 +64,11 @@ public class XmlGroupDAO extends AbstractXmlDAO
* @param storeFactory
*/
@Inject
- public XmlGroupDAO(ConfigurationStoreFactory storeFactory)
- {
- super(storeFactory.getStore(XmlGroupDatabase.class, STORE_NAME));
+ public XmlGroupDAO(ConfigurationStoreFactory storeFactory) {
+ super(storeFactory
+ .withType(XmlGroupDatabase.class)
+ .withName(STORE_NAME)
+ .build());
}
//~--- methods --------------------------------------------------------------
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java
index 5bfc4f34b9..099ab53baa 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/FileBasedStoreFactory.java
@@ -31,18 +31,21 @@
package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import sonia.scm.SCMContextProvider;
+import sonia.scm.repository.Repository;
+import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.util.IOUtil;
-//~--- JDK imports ------------------------------------------------------------
import java.io.File;
+//~--- JDK imports ------------------------------------------------------------
+
/**
* Abstract store factory for file based stores.
- *
+ *
* @author Sebastian Sdorra
*/
public abstract class FileBasedStoreFactory {
@@ -51,39 +54,57 @@ public abstract class FileBasedStoreFactory {
* the logger for FileBasedStoreFactory
*/
private static final Logger LOG = LoggerFactory.getLogger(FileBasedStoreFactory.class);
+ private SCMContextProvider contextProvider;
+ private RepositoryLocationResolver repositoryLocationResolver;
+ private Store store;
- private static final String BASE_DIRECTORY = "var";
+ private File storeDirectory;
- private final SCMContextProvider context;
-
- private final String dataDirectoryName;
-
- private File dataDirectory;
-
- protected FileBasedStoreFactory(SCMContextProvider context,
- String dataDirectoryName) {
- this.context = context;
- this.dataDirectoryName = dataDirectoryName;
+ protected FileBasedStoreFactory(SCMContextProvider contextProvider , RepositoryLocationResolver repositoryLocationResolver, Store store) {
+ this.contextProvider = contextProvider;
+ this.repositoryLocationResolver = repositoryLocationResolver;
+ this.store = store;
}
- //~--- get methods ----------------------------------------------------------
- /**
- * Returns data directory for given name.
- *
- * @param name name of data directory
- *
- * @return data directory
- */
- protected File getDirectory(String name) {
- if (dataDirectory == null) {
- dataDirectory = new File(context.getBaseDirectory(),
- BASE_DIRECTORY.concat(File.separator).concat(dataDirectoryName));
- LOG.debug("create data directory {}", dataDirectory);
- }
+ protected File getStoreLocation(StoreParameters storeParameters) {
+ return getStoreLocation(storeParameters.getName(), null, storeParameters.getRepository());
+ }
- File storeDirectory = new File(dataDirectory, name);
- IOUtil.mkdirs(storeDirectory);
- return storeDirectory;
+ protected File getStoreLocation(TypedStoreParameters storeParameters) {
+ return getStoreLocation(storeParameters.getName(), storeParameters.getType(), storeParameters.getRepository());
+ }
+
+ protected File getStoreLocation(String name, Class type, Repository repository) {
+ if (storeDirectory == null) {
+ if (repository != null) {
+ LOG.debug("create store with type: {}, name: {} and repository: {}", type, name, repository.getNamespaceAndName());
+ storeDirectory = this.getStoreDirectory(store, repository);
+ } else {
+ LOG.debug("create store with type: {} and name: {} ", type, name);
+ storeDirectory = this.getStoreDirectory(store);
+ }
+ IOUtil.mkdirs(storeDirectory);
+ }
+ return new File(this.storeDirectory, name);
+ }
+
+ /**
+ * Get the store directory of a specific repository
+ * @param store the type of the store
+ * @param repository the repo
+ * @return the store directory of a specific repository
+ */
+ private File getStoreDirectory(Store store, Repository repository) {
+ return new File(repositoryLocationResolver.getPath(repository.getId()).toFile(), store.getRepositoryStoreDirectory());
+ }
+
+ /**
+ * Get the global store directory
+ * @param store the type of the store
+ * @return the global store directory
+ */
+ private File getStoreDirectory(Store store) {
+ return new File(contextProvider.getBaseDirectory(), store.getGlobalStoreDirectory());
}
}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java
index 8cc5b34ac2..7e2e5a9e29 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/FileBlobStoreFactory.java
@@ -31,14 +31,17 @@
package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
+
import com.google.inject.Inject;
import com.google.inject.Singleton;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
import sonia.scm.SCMContextProvider;
+import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.security.KeyGenerator;
+import sonia.scm.util.IOUtil;
+
+import java.io.File;
/**
* File based store factory.
@@ -48,8 +51,6 @@ import sonia.scm.security.KeyGenerator;
@Singleton
public class FileBlobStoreFactory extends FileBasedStoreFactory implements BlobStoreFactory {
- private static final String DIRECTORY_NAME = "blob";
-
/**
* the logger for FileBlobStoreFactory
*/
@@ -60,21 +61,22 @@ public class FileBlobStoreFactory extends FileBasedStoreFactory implements BlobS
/**
* Constructs a new instance.
*
- * @param context scm context
+ * @param repositoryLocationResolver location resolver
* @param keyGenerator key generator
*/
@Inject
- public FileBlobStoreFactory(SCMContextProvider context,
- KeyGenerator keyGenerator) {
- super(context, DIRECTORY_NAME);
+ public FileBlobStoreFactory(SCMContextProvider contextProvider ,RepositoryLocationResolver repositoryLocationResolver, KeyGenerator keyGenerator) {
+ super(contextProvider, repositoryLocationResolver, Store.BLOB);
this.keyGenerator = keyGenerator;
}
@Override
- public BlobStore getBlobStore(String name) {
- LOG.debug("create new blob with name {}", name);
-
- return new FileBlobStore(keyGenerator, getDirectory(name));
+ @SuppressWarnings("unchecked")
+ public BlobStore getStore(StoreParameters storeParameters) {
+ File storeLocation = getStoreLocation(storeParameters);
+ IOUtil.mkdirs(storeLocation);
+ return new FileBlobStore(keyGenerator, storeLocation);
}
+
}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java
index 261c36f8e4..96403140ef 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationEntryStoreFactory.java
@@ -1,19 +1,19 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
+ * this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -24,97 +24,42 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* http://bitbucket.org/sdorra/scm-manager
- *
*/
-
package sonia.scm.store;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import sonia.scm.SCMContextProvider;
+import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.security.KeyGenerator;
-import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
-import java.io.File;
-
/**
*
* @author Sebastian Sdorra
*/
@Singleton
-public class JAXBConfigurationEntryStoreFactory
- implements ConfigurationEntryStoreFactory
-{
+public class JAXBConfigurationEntryStoreFactory extends FileBasedStoreFactory
+ implements ConfigurationEntryStoreFactory {
- /**
- * the logger for JAXBConfigurationEntryStoreFactory
- */
- private static final Logger logger =
- LoggerFactory.getLogger(JAXBConfigurationEntryStoreFactory.class);
-
- //~--- constructors ---------------------------------------------------------
-
- /**
- * Constructs ...
- *
- *
- * @param keyGenerator
- * @param context
- */
- @Inject
- public JAXBConfigurationEntryStoreFactory(KeyGenerator keyGenerator,
- SCMContextProvider context)
- {
- this.keyGenerator = keyGenerator;
- directory = new File(context.getBaseDirectory(),
- StoreConstants.CONFIG_DIRECTORY_NAME);
- IOUtil.mkdirs(directory);
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param type
- * @param name
- * @param
- *
- * @return
- */
- @Override
- public ConfigurationEntryStore getStore(Class type, String name)
- {
- logger.debug("create new configuration store for type {} with name {}",
- type, name);
-
- //J-
- return new JAXBConfigurationEntryStore(
- new File(directory,name.concat(StoreConstants.FILE_EXTENSION)),
- keyGenerator,
- type
- );
- //J+
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private File directory;
-
- /** Field description */
private KeyGenerator keyGenerator;
+
+ @Inject
+ public JAXBConfigurationEntryStoreFactory(SCMContextProvider contextProvider , RepositoryLocationResolver repositoryLocationResolver, KeyGenerator keyGenerator) {
+ super(contextProvider, repositoryLocationResolver, Store.CONFIG);
+ this.keyGenerator = keyGenerator;
+ }
+
+ @Override
+ public ConfigurationEntryStore getStore(TypedStoreParameters storeParameters) {
+ return new JAXBConfigurationEntryStore<>(getStoreLocation(storeParameters.getName().concat(StoreConstants.FILE_EXTENSION), storeParameters.getType(), storeParameters.getRepository()), keyGenerator, storeParameters.getType());
+ }
+
}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java
index 4a87ea57f6..ac1477d7ea 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStore.java
@@ -61,7 +61,7 @@ public class JAXBConfigurationStore extends AbstractStore {
private JAXBContext context;
- JAXBConfigurationStore(Class type, File configFile) {
+ public JAXBConfigurationStore(Class type, File configFile) {
this.type = type;
try {
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java
index 705b0c1177..bb68ab93dc 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBConfigurationStoreFactory.java
@@ -32,14 +32,8 @@ package sonia.scm.store;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import sonia.scm.SCMContextProvider;
-import sonia.scm.util.IOUtil;
-
-import java.io.File;
+import sonia.scm.repository.RepositoryLocationResolver;
/**
* JAXB implementation of {@link ConfigurationStoreFactory}.
@@ -47,40 +41,20 @@ import java.io.File;
* @author Sebastian Sdorra
*/
@Singleton
-public class JAXBConfigurationStoreFactory implements ConfigurationStoreFactory {
-
- /**
- * the logger for JAXBConfigurationStoreFactory
- */
- private static final Logger LOG = LoggerFactory.getLogger(JAXBConfigurationStoreFactory.class);
-
- private final File configDirectory;
+public class JAXBConfigurationStoreFactory extends FileBasedStoreFactory implements ConfigurationStoreFactory {
/**
* Constructs a new instance.
*
- * @param context scm context
+ * @param repositoryLocationResolver Resolver to get the repository Directory
*/
@Inject
- public JAXBConfigurationStoreFactory(SCMContextProvider context) {
- configDirectory = new File(context.getBaseDirectory(), StoreConstants.CONFIG_DIRECTORY_NAME);
- IOUtil.mkdirs(configDirectory);
+ public JAXBConfigurationStoreFactory(SCMContextProvider contextProvider, RepositoryLocationResolver repositoryLocationResolver) {
+ super(contextProvider, repositoryLocationResolver, Store.CONFIG);
}
@Override
- public JAXBConfigurationStore getStore(Class type, String name) {
- if (configDirectory == null) {
- throw new IllegalStateException("store factory is not initialized");
- }
-
- File configFile = new File(configDirectory, name.concat(StoreConstants.FILE_EXTENSION));
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("create store for {} at {}", type.getName(),
- configFile.getPath());
- }
-
- return new JAXBConfigurationStore<>(type, configFile);
+ public JAXBConfigurationStore getStore(TypedStoreParameters storeParameters) {
+ return new JAXBConfigurationStore<>(storeParameters.getType(), getStoreLocation(storeParameters.getName().concat(StoreConstants.FILE_EXTENSION), storeParameters.getType(), storeParameters.getRepository()));
}
-
}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java
index 732b8c675b..5b5c00a298 100644
--- a/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/JAXBDataStoreFactory.java
@@ -41,7 +41,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContextProvider;
+import sonia.scm.repository.RepositoryLocationResolver;
import sonia.scm.security.KeyGenerator;
+import sonia.scm.util.IOUtil;
+
+import java.io.File;
/**
*
@@ -49,57 +53,20 @@ import sonia.scm.security.KeyGenerator;
*/
@Singleton
public class JAXBDataStoreFactory extends FileBasedStoreFactory
- implements DataStoreFactory
-{
+ implements DataStoreFactory {
- /** Field description */
- private static final String DIRECTORY_NAME = "data";
+ private KeyGenerator keyGenerator;
- /**
- * the logger for JAXBDataStoreFactory
- */
- private static final Logger logger =
- LoggerFactory.getLogger(JAXBDataStoreFactory.class);
-
- //~--- constructors ---------------------------------------------------------
-
- /**
- * Constructs ...
- *
- *
- * @param context
- * @param keyGenerator
- */
@Inject
- public JAXBDataStoreFactory(SCMContextProvider context,
- KeyGenerator keyGenerator)
- {
- super(context, DIRECTORY_NAME);
+ public JAXBDataStoreFactory(SCMContextProvider contextProvider , RepositoryLocationResolver repositoryLocationResolver, KeyGenerator keyGenerator) {
+ super(contextProvider, repositoryLocationResolver, Store.DATA);
this.keyGenerator = keyGenerator;
}
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param type
- * @param name
- * @param
- *
- * @return
- */
@Override
- public DataStore getStore(Class type, String name)
- {
- logger.debug("create new store for type {} with name {}", type, name);
-
- return new JAXBDataStore<>(keyGenerator, type, getDirectory(name));
+ public DataStore getStore(TypedStoreParameters storeParameters) {
+ File storeLocation = getStoreLocation(storeParameters);
+ IOUtil.mkdirs(storeLocation);
+ return new JAXBDataStore<>(keyGenerator, storeParameters.getType(), storeLocation);
}
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private KeyGenerator keyGenerator;
}
diff --git a/scm-dao-xml/src/main/java/sonia/scm/store/Store.java b/scm-dao-xml/src/main/java/sonia/scm/store/Store.java
new file mode 100644
index 0000000000..6e5cbcdf65
--- /dev/null
+++ b/scm-dao-xml/src/main/java/sonia/scm/store/Store.java
@@ -0,0 +1,49 @@
+package sonia.scm.store;
+
+import java.io.File;
+
+public enum Store {
+ CONFIG("config"),
+ DATA("data"),
+ BLOB("blob");
+
+ private static final String GLOBAL_STORE_BASE_DIRECTORY = "var";
+
+ private String directory;
+
+ Store(String directory) {
+
+ this.directory = directory;
+ }
+
+ /**
+ * Get the relkative store directory path to be stored in the repository root
+ *
+ * The repository store directories are:
+ * repo_base_dir/config/
+ * repo_base_dir/blob/
+ * repo_base_dir/data/
+ *
+ * @return the relative store directory path to be stored in the repository root
+ */
+ public String getRepositoryStoreDirectory() {
+ return directory;
+ }
+
+ /**
+ * Get the relative store directory path to be stored in the global root
+ *