mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-03-04 03:10:50 +01:00
Multiply floating store factories for type safety
This commit is contained in:
@@ -74,8 +74,8 @@ public abstract class AbstractRepositoryHandler<C extends RepositoryConfig>
|
||||
*/
|
||||
protected AbstractRepositoryHandler(ConfigurationStoreFactory storeFactory) {
|
||||
this.store = storeFactory
|
||||
.withName(getType().getName())
|
||||
.withType(getConfigClass())
|
||||
.withName(getType().getName())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
package sonia.scm.store;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
/**
|
||||
* The BlobStoreFactory can be used to create new or get existing
|
||||
* {@link BlobStore}s.
|
||||
@@ -42,6 +44,51 @@ package sonia.scm.store;
|
||||
* @apiviz.landmark
|
||||
* @apiviz.uses sonia.scm.store.BlobStore
|
||||
*/
|
||||
public interface BlobStoreFactory extends StoreFactory<BlobStore> {
|
||||
public interface BlobStoreFactory {
|
||||
|
||||
BlobStore getStore(final StoreParameters storeParameters);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Class getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public class Builder {
|
||||
|
||||
Builder(String name) {
|
||||
FloatingStoreParameters.this.name = name;
|
||||
}
|
||||
|
||||
public FloatingStoreParameters.Builder forRepository(Repository repository) {
|
||||
FloatingStoreParameters.this.repository = repository;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlobStore build(){
|
||||
return factory.getStore(FloatingStoreParameters.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
package sonia.scm.store;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
/**
|
||||
* The ConfigurationEntryStoreFactory can be used to create new or get existing
|
||||
* {@link ConfigurationEntryStore}s.
|
||||
@@ -45,5 +47,59 @@ package sonia.scm.store;
|
||||
* @apiviz.landmark
|
||||
* @apiviz.uses sonia.scm.store.ConfigurationEntryStore
|
||||
*/
|
||||
public interface ConfigurationEntryStoreFactory extends StoreFactory<ConfigurationEntryStore> {
|
||||
public interface ConfigurationEntryStoreFactory {
|
||||
<T> ConfigurationEntryStore<T> getStore(final StoreParameters storeParameters);
|
||||
|
||||
default <T> TypedFloatingConfigurationEntryStoreParameters<T>.Builder withType(Class<T> type) {
|
||||
return new TypedFloatingConfigurationEntryStoreParameters<T>(this).new Builder(type);
|
||||
}
|
||||
}
|
||||
|
||||
final class TypedFloatingConfigurationEntryStoreParameters<T> implements StoreParameters {
|
||||
|
||||
private Class<T> type;
|
||||
private String name;
|
||||
private Repository repository;
|
||||
|
||||
private final ConfigurationEntryStoreFactory factory;
|
||||
|
||||
TypedFloatingConfigurationEntryStoreParameters(ConfigurationEntryStoreFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public class Builder {
|
||||
|
||||
Builder(Class<T> type) {
|
||||
TypedFloatingConfigurationEntryStoreParameters.this.type = type;
|
||||
}
|
||||
|
||||
public OptionalRepositoryBuilder withName(String name) {
|
||||
TypedFloatingConfigurationEntryStoreParameters.this.name = name;
|
||||
return new OptionalRepositoryBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptionalRepositoryBuilder {
|
||||
|
||||
public OptionalRepositoryBuilder forRepository(Repository repository) {
|
||||
TypedFloatingConfigurationEntryStoreParameters.this.repository = repository;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationEntryStore<T> build(){
|
||||
return factory.getStore(TypedFloatingConfigurationEntryStoreParameters.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
package sonia.scm.store;
|
||||
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
/**
|
||||
* The ConfigurationStoreFactory can be used to create new or get existing
|
||||
* {@link ConfigurationStore} objects.
|
||||
@@ -45,4 +47,59 @@ package sonia.scm.store;
|
||||
* @apiviz.landmark
|
||||
* @apiviz.uses sonia.scm.store.ConfigurationStore
|
||||
*/
|
||||
public interface ConfigurationStoreFactory extends StoreFactory<ConfigurationStore>{}
|
||||
public interface ConfigurationStoreFactory {
|
||||
<T> ConfigurationStore<T> getStore(final StoreParameters storeParameters);
|
||||
|
||||
default <T> TypedFloatingConfigurationStoreParameters<T>.Builder withType(Class<T> type) {
|
||||
return new TypedFloatingConfigurationStoreParameters<T>(this).new Builder(type);
|
||||
}
|
||||
}
|
||||
|
||||
final class TypedFloatingConfigurationStoreParameters<T> implements StoreParameters {
|
||||
|
||||
private Class<T> type;
|
||||
private String name;
|
||||
private Repository repository;
|
||||
|
||||
private final ConfigurationStoreFactory factory;
|
||||
|
||||
TypedFloatingConfigurationStoreParameters(ConfigurationStoreFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public class Builder {
|
||||
|
||||
Builder(Class<T> type) {
|
||||
TypedFloatingConfigurationStoreParameters.this.type = type;
|
||||
}
|
||||
|
||||
public OptionalRepositoryBuilder withName(String name) {
|
||||
TypedFloatingConfigurationStoreParameters.this.name = name;
|
||||
return new OptionalRepositoryBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptionalRepositoryBuilder {
|
||||
|
||||
public OptionalRepositoryBuilder forRepository(Repository repository) {
|
||||
TypedFloatingConfigurationStoreParameters.this.repository = repository;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationStore<T> build(){
|
||||
return factory.getStore(TypedFloatingConfigurationStoreParameters.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
package sonia.scm.store;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
/**
|
||||
* The DataStoreFactory can be used to create new or get existing
|
||||
* {@link DataStore}s.
|
||||
@@ -42,4 +44,59 @@ package sonia.scm.store;
|
||||
* @apiviz.landmark
|
||||
* @apiviz.uses sonia.scm.store.DataStore
|
||||
*/
|
||||
public interface DataStoreFactory extends StoreFactory<DataStore>{}
|
||||
public interface DataStoreFactory {
|
||||
<T> DataStore<T> getStore(final StoreParameters storeParameters);
|
||||
|
||||
default <T> TypedFloatingDataStoreParameters<T>.Builder withType(Class<T> type) {
|
||||
return new TypedFloatingDataStoreParameters<T>(this).new Builder(type);
|
||||
}
|
||||
}
|
||||
|
||||
final class TypedFloatingDataStoreParameters<T> implements StoreParameters {
|
||||
|
||||
private Class<T> type;
|
||||
private String name;
|
||||
private Repository repository;
|
||||
|
||||
private final DataStoreFactory factory;
|
||||
|
||||
TypedFloatingDataStoreParameters(DataStoreFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Class<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public class Builder {
|
||||
|
||||
Builder(Class<T> type) {
|
||||
TypedFloatingDataStoreParameters.this.type = type;
|
||||
}
|
||||
|
||||
public OptionalRepositoryBuilder withName(String name) {
|
||||
TypedFloatingDataStoreParameters.this.name = name;
|
||||
return new OptionalRepositoryBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptionalRepositoryBuilder {
|
||||
|
||||
public OptionalRepositoryBuilder forRepository(Repository repository) {
|
||||
TypedFloatingDataStoreParameters.this.repository = repository;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DataStore<T> build(){
|
||||
return factory.getStore(TypedFloatingDataStoreParameters.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package sonia.scm.store;
|
||||
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
public interface StoreFactory<STORE> {
|
||||
|
||||
STORE getStore(final StoreParameters storeParameters);
|
||||
|
||||
default FloatingStoreParameters<STORE>.Builder withName(String name) {
|
||||
return new FloatingStoreParameters<>(this).new Builder(name);
|
||||
}
|
||||
}
|
||||
|
||||
final class FloatingStoreParameters<STORE> implements StoreParameters {
|
||||
|
||||
private Class type;
|
||||
private String name;
|
||||
private Repository repository;
|
||||
|
||||
private final StoreFactory<STORE> factory;
|
||||
|
||||
FloatingStoreParameters(StoreFactory<STORE> factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public Class getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Repository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public class Builder {
|
||||
|
||||
Builder(String name) {
|
||||
FloatingStoreParameters.this.name = name;
|
||||
}
|
||||
|
||||
public FloatingStoreParameters<STORE>.Builder withType(Class type) {
|
||||
FloatingStoreParameters.this.type = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public FloatingStoreParameters<STORE>.Builder forRepository(Repository repository) {
|
||||
FloatingStoreParameters.this.repository = repository;
|
||||
return this;
|
||||
}
|
||||
|
||||
public STORE build(){
|
||||
return factory.getStore(FloatingStoreParameters.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,9 @@ import sonia.scm.repository.Repository;
|
||||
* @author Mohamed Karray
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface StoreParameters{
|
||||
public interface StoreParameters<T> {
|
||||
|
||||
Class getType();
|
||||
Class<T> getType();
|
||||
|
||||
String getName();
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ public class XmlGroupDAO extends AbstractXmlDAO<Group, XmlGroupDatabase>
|
||||
@Inject
|
||||
public XmlGroupDAO(ConfigurationStoreFactory storeFactory) {
|
||||
super(storeFactory
|
||||
.withName(STORE_NAME)
|
||||
.withType(XmlGroupDatabase.class)
|
||||
.withName(STORE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ public class XmlUserDAO extends AbstractXmlDAO<User, XmlUserDatabase>
|
||||
public XmlUserDAO(ConfigurationStoreFactory storeFactory)
|
||||
{
|
||||
super(storeFactory
|
||||
.withName(STORE_NAME)
|
||||
.withType(XmlUserDatabase.class)
|
||||
.withName(STORE_NAME)
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ public class FileBlobStoreTest extends BlobStoreTestBase
|
||||
public void shouldStoreAndLoadInRepository() {
|
||||
BlobStore store = createBlobStoreFactory()
|
||||
.withName("test")
|
||||
.withType(StoreObject.class)
|
||||
.forRepository(new Repository("id", "git", "ns", "n"))
|
||||
.build();
|
||||
|
||||
|
||||
@@ -133,8 +133,8 @@ public class JAXBConfigurationEntryStoreTest
|
||||
|
||||
store.put("a45", new AssignedPermission("tuser4", "repository:create"));
|
||||
store = createConfigurationStoreFactory()
|
||||
.withName(name)
|
||||
.withType(AssignedPermission.class)
|
||||
.withName(name)
|
||||
.build();
|
||||
|
||||
AssignedPermission ap = store.get("a45");
|
||||
@@ -232,8 +232,8 @@ public class JAXBConfigurationEntryStoreTest
|
||||
|
||||
copy(resource, name);
|
||||
return createConfigurationStoreFactory()
|
||||
.withName(name)
|
||||
.withType(AssignedPermission.class)
|
||||
.withName(name)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ public class JAXBConfigurationStoreTest extends StoreTestBase {
|
||||
public void shouldStoreAndLoadInRepository()
|
||||
{
|
||||
ConfigurationStore<StoreObject> store = createStoreFactory()
|
||||
.withName("test")
|
||||
.withType(StoreObject.class)
|
||||
.withName("test")
|
||||
.forRepository(new Repository("id", "git", "ns", "n"))
|
||||
.build();
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ public class JAXBDataStoreTest extends DataStoreTestBase {
|
||||
@Override
|
||||
protected DataStore getDataStore(Class type, Repository repository) {
|
||||
return createDataStoreFactory()
|
||||
.withName("test")
|
||||
.withType(type)
|
||||
.withName("test")
|
||||
.forRepository(repository)
|
||||
.build();
|
||||
}
|
||||
@@ -71,8 +71,8 @@ public class JAXBDataStoreTest extends DataStoreTestBase {
|
||||
@Override
|
||||
protected DataStore getDataStore(Class type) {
|
||||
return createDataStoreFactory()
|
||||
.withName("test")
|
||||
.withType(type)
|
||||
.withName("test")
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
|
||||
@Before
|
||||
public void initFactory() {
|
||||
when(factory.withName(any())).thenCallRealMethod();
|
||||
when(factory.withType(any())).thenCallRealMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -72,7 +72,7 @@ public class HgRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
|
||||
@Before
|
||||
public void initFactory() {
|
||||
when(factory.withName(any())).thenCallRealMethod();
|
||||
when(factory.withType(any())).thenCallRealMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -107,7 +107,7 @@ public class SvnRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase {
|
||||
|
||||
@Test
|
||||
public void getDirectory() {
|
||||
when(factory.withName(any())).thenCallRealMethod();
|
||||
when(factory.withType(any())).thenCallRealMethod();
|
||||
SvnRepositoryHandler repositoryHandler = new SvnRepositoryHandler(factory,
|
||||
facade, locationResolver);
|
||||
|
||||
|
||||
@@ -52,16 +52,16 @@ public abstract class ConfigurationEntryStoreTestBase extends KeyValueStoreTestB
|
||||
@Override
|
||||
protected ConfigurationEntryStore getDataStore(Class type) {
|
||||
return this.createConfigurationStoreFactory()
|
||||
.withName(storeName)
|
||||
.withType(type)
|
||||
.withName(storeName)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ConfigurationEntryStore getDataStore(Class type, Repository repository) {
|
||||
return this.createConfigurationStoreFactory()
|
||||
.withName(repoStoreName)
|
||||
.withType(type)
|
||||
.withName(repoStoreName)
|
||||
.forRepository(repository)
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -65,13 +65,13 @@ public abstract class DataStoreTestBase extends KeyValueStoreTestBase
|
||||
// TODO
|
||||
public void shouldStoreRepositorySpecificData()
|
||||
{
|
||||
StoreFactory<DataStore > dataStoreFactory = createDataStoreFactory();
|
||||
DataStoreFactory dataStoreFactory = createDataStoreFactory();
|
||||
StoreObject obj = new StoreObject("test-1");
|
||||
Repository repository = RepositoryTestData.createHeartOfGold();
|
||||
|
||||
DataStore<StoreObject> store = dataStoreFactory
|
||||
.withName("test")
|
||||
.withType(StoreObject.class)
|
||||
.withName("test")
|
||||
.forRepository(repository)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public abstract class StoreTestBase extends AbstractTestBase
|
||||
@Test
|
||||
public void testGet()
|
||||
{
|
||||
ConfigurationStore<StoreObject> store = createStoreFactory().withName("test").withType(StoreObject.class).build();
|
||||
ConfigurationStore<StoreObject> store = createStoreFactory().withType(StoreObject.class).withName("test").build();
|
||||
|
||||
assertNotNull(store);
|
||||
|
||||
@@ -82,7 +82,7 @@ public abstract class StoreTestBase extends AbstractTestBase
|
||||
@Test
|
||||
public void testSet()
|
||||
{
|
||||
ConfigurationStore<StoreObject> store = createStoreFactory().withName("test").withType(StoreObject.class).build();
|
||||
ConfigurationStore<StoreObject> store = createStoreFactory().withType(StoreObject.class).withName("test").build();
|
||||
|
||||
assertNotNull(store);
|
||||
|
||||
|
||||
@@ -112,8 +112,8 @@ public class DefaultSecuritySystem implements SecuritySystem
|
||||
public DefaultSecuritySystem(ConfigurationEntryStoreFactory storeFactory)
|
||||
{
|
||||
store = storeFactory
|
||||
.withName(NAME)
|
||||
.withType(AssignedPermission.class)
|
||||
.withName(NAME)
|
||||
.build();
|
||||
readAvailablePermissions();
|
||||
}
|
||||
|
||||
@@ -91,8 +91,8 @@ public class SecureKeyResolver extends SigningKeyResolverAdapter
|
||||
public SecureKeyResolver(ConfigurationEntryStoreFactory storeFactory)
|
||||
{
|
||||
store = storeFactory
|
||||
.withName(STORE_NAME)
|
||||
.withType(SecureKey.class)
|
||||
.withName(STORE_NAME)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public class AutoCompleteResourceTest {
|
||||
xmlDB = mock(XmlDatabase.class);
|
||||
when(storeConfig.get()).thenReturn(xmlDB);
|
||||
when(storeFactory.getStore(any())).thenReturn(storeConfig);
|
||||
when(storeFactory.withName(any())).thenCallRealMethod();
|
||||
when(storeFactory.withType(any())).thenCallRealMethod();
|
||||
XmlUserDAO userDao = new XmlUserDAO(storeFactory);
|
||||
this.userDao = spy(userDao);
|
||||
XmlGroupDAO groupDAO = new XmlGroupDAO(storeFactory);
|
||||
|
||||
@@ -126,8 +126,8 @@ public class SecureKeyResolverTest
|
||||
{
|
||||
ConfigurationEntryStoreFactory factory = mock(ConfigurationEntryStoreFactory.class);
|
||||
|
||||
when(factory.withName(any())).thenCallRealMethod();
|
||||
when(factory.getStore(argThat(storeParameters -> {
|
||||
when(factory.withType(any())).thenCallRealMethod();
|
||||
when(factory.<SecureKey>getStore(argThat(storeParameters -> {
|
||||
assertThat(storeParameters.getName()).isEqualTo(SecureKeyResolver.STORE_NAME);
|
||||
assertThat(storeParameters.getType()).isEqualTo(SecureKey.class);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user